From 29c99c9681b2b9282367784083bc5dffcc3569e4 Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 20 Aug 2024 13:58:23 +0200 Subject: [PATCH 001/203] fix: broken exfils with empty stashes --- src/stash-controller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stash-controller.ts b/src/stash-controller.ts index b6b31388..1a3d1f55 100644 --- a/src/stash-controller.ts +++ b/src/stash-controller.ts @@ -23,7 +23,8 @@ export class StashController { private readonly debug: (data: string) => void, ) {} - initSecondaryStashTemplates(stashConfigs: StashConfig[]): number { + initSecondaryStashTemplates(givenStashConfigs: StashConfig[]): number { + const stashConfigs = [EMPTY_STASH, ...givenStashConfigs]; const standardTemplate = this.db.getTables()?.templates?.items[STANDARD_STASH_ID]; if (!standardTemplate) { From 5476f26a1ce4e15a1c6adf095851e887a2b018bd Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 20 Aug 2024 13:58:31 +0200 Subject: [PATCH 002/203] 5.3.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 00caaa82..b7b68c76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "path-to-tarkov", - "version": "5.3.0", + "version": "5.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "path-to-tarkov", - "version": "5.3.0", + "version": "5.3.1", "license": "MIT", "devDependencies": { "@mermaid-js/mermaid-cli": "^9.1.7", diff --git a/package.json b/package.json index 1e869ef4..314b17e7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "path-to-tarkov", "displayName": "Path To Tarkov", "fullName": "Trap-PathToTarkov", - "version": "5.3.0", + "version": "5.3.1", "main": "src/mod.js", "license": "MIT", "author": "Trap", From 99ad95753acdce3e965559eba42dbcbb2ef76cc5 Mon Sep 17 00:00:00 2001 From: Guillaume ARM Date: Sat, 24 Aug 2024 21:33:29 +0200 Subject: [PATCH 003/203] fix: FoundInRaid tweak was not working as intended (#55) * fix: FoundInRaid tweak was not working as intended * chore: cleanup --------- Co-authored-by: Trap --- src/keep-fir-tweak.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/keep-fir-tweak.ts b/src/keep-fir-tweak.ts index a2055619..06c911fc 100644 --- a/src/keep-fir-tweak.ts +++ b/src/keep-fir-tweak.ts @@ -1,4 +1,4 @@ -import type { MatchCallbacks } from '@spt/callbacks/MatchCallbacks'; +import type { MatchController } from '@spt/controllers/MatchController'; import type { IPmcData } from '@spt/models/eft/common/IPmcData'; import type { Item } from '@spt/models/eft/common/tables/IItem'; import type { SaveServer } from '@spt/servers/SaveServer'; @@ -31,22 +31,20 @@ const setSpawnedInSessionOnAllItems = (items: Item[]): number => { export const enableKeepFoundInRaidTweak = (ptt: PTTInstance): void => { const saveServer = ptt.container.resolve('SaveServer'); - ptt.container.afterResolution( - 'MatchCallbacks', + ptt.container.afterResolution( + 'MatchController', (_t, result): void => { - const matchCallbacks = Array.isArray(result) ? result[0] : result; + const matchController = Array.isArray(result) ? result[0] : result; - const originalEndOfflineRaid = matchCallbacks.endOfflineRaid.bind(matchCallbacks); + const originalEndOfflineRaid = matchController.endOfflineRaid.bind(matchController); - matchCallbacks.endOfflineRaid = (url, info, sessionId) => { - const result = originalEndOfflineRaid(url, info, sessionId); + matchController.endOfflineRaid = (info, sessionId) => { + originalEndOfflineRaid(info, sessionId); const profile = saveServer.getProfile(sessionId); const pmcData: IPmcData = profile.characters.pmc; const count = setSpawnedInSessionOnAllItems(pmcData.Inventory.items); ptt.debug(`added 'SpawnedInSession' flag on ${count} items`); - - return result; }; }, { frequency: 'Always' }, From c722af44fe66683bf56606430377289c33ece943 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 12:15:50 +0100 Subject: [PATCH 004/203] chore: update spt types for 3.10 --- PTT-Extracts/Patch.cs | 4 +- types/callbacks/BotCallbacks.d.ts | 10 +- types/callbacks/DataCallbacks.d.ts | 13 +- types/callbacks/DialogueCallbacks.d.ts | 6 +- types/callbacks/GameCallbacks.d.ts | 21 + types/callbacks/HealthCallbacks.d.ts | 9 - types/callbacks/HideoutCallbacks.d.ts | 10 + types/callbacks/InraidCallbacks.d.ts | 31 +- types/callbacks/InventoryCallbacks.d.ts | 2 + types/callbacks/LocationCallbacks.d.ts | 10 +- types/callbacks/MatchCallbacks.d.ts | 24 +- types/callbacks/ProfileCallbacks.d.ts | 4 +- types/callbacks/TraderCallbacks.d.ts | 7 +- types/callbacks/WeatherCallbacks.d.ts | 3 + types/callbacks/WishlistCallbacks.d.ts | 10 +- types/context/ContextVariableType.d.ts | 6 +- types/controllers/BotController.d.ts | 34 +- .../controllers/CustomizationController.d.ts | 10 +- types/controllers/DialogueController.d.ts | 18 +- types/controllers/GameController.d.ts | 59 +- types/controllers/HealthController.d.ts | 10 - types/controllers/HideoutController.d.ts | 64 +- types/controllers/InraidController.d.ts | 160 +---- types/controllers/InsuranceController.d.ts | 47 +- types/controllers/InventoryController.d.ts | 10 + types/controllers/LauncherController.d.ts | 4 +- types/controllers/LocationController.d.ts | 67 +-- types/controllers/MatchController.d.ts | 78 +-- types/controllers/ProfileController.d.ts | 4 +- types/controllers/QuestController.d.ts | 62 +- types/controllers/RagfairController.d.ts | 17 +- .../RepeatableQuestController.d.ts | 22 +- types/controllers/TradeController.d.ts | 4 +- types/controllers/TraderController.d.ts | 7 +- types/controllers/WeatherController.d.ts | 16 +- types/controllers/WishlistController.d.ts | 10 +- types/di/Serializer.d.ts | 3 +- .../generators/BotEquipmentModGenerator.d.ts | 92 ++- types/generators/BotGenerator.d.ts | 78 ++- types/generators/BotInventoryGenerator.d.ts | 38 +- types/generators/BotLevelGenerator.d.ts | 18 +- types/generators/BotLootGenerator.d.ts | 32 +- types/generators/BotWeaponGenerator.d.ts | 54 +- .../generators/FenceBaseAssortGenerator.d.ts | 4 +- ...erator.d.ts => LocationLootGenerator.d.ts} | 24 +- types/generators/LootGenerator.d.ts | 51 +- types/generators/PlayerScavGenerator.d.ts | 12 +- types/generators/RagfairAssortGenerator.d.ts | 10 +- types/generators/RagfairOfferGenerator.d.ts | 46 +- .../generators/RepeatableQuestGenerator.d.ts | 11 +- .../RepeatableQuestRewardGenerator.d.ts | 26 +- types/generators/ScavCaseRewardGenerator.d.ts | 18 +- types/generators/WeatherGenerator.d.ts | 27 +- .../generators/weapongen/InventoryMagGen.d.ts | 10 +- types/helpers/BotDifficultyHelper.d.ts | 30 +- types/helpers/BotGeneratorHelper.d.ts | 19 +- types/helpers/BotHelper.d.ts | 27 +- types/helpers/BotWeaponGeneratorHelper.d.ts | 14 +- .../helpers/Dialogue/SptDialogueChatBot.d.ts | 6 +- types/helpers/DialogueHelper.d.ts | 10 +- types/helpers/HandbookHelper.d.ts | 8 +- types/helpers/HealthHelper.d.ts | 22 +- types/helpers/HideoutHelper.d.ts | 58 +- types/helpers/InRaidHelper.d.ts | 145 +---- types/helpers/InventoryHelper.d.ts | 57 +- types/helpers/ItemHelper.d.ts | 119 ++-- types/helpers/NotificationSendHelper.d.ts | 4 +- types/helpers/NotifierHelper.d.ts | 6 +- types/helpers/PresetHelper.d.ts | 6 +- types/helpers/ProfileHelper.d.ts | 45 +- types/helpers/QuestHelper.d.ts | 114 +++- types/helpers/RagfairHelper.d.ts | 4 +- types/helpers/RagfairOfferHelper.d.ts | 15 +- types/helpers/RagfairSellHelper.d.ts | 4 +- types/helpers/RagfairServerHelper.d.ts | 8 +- types/helpers/RepairHelper.d.ts | 8 +- types/helpers/SecureContainerHelper.d.ts | 10 +- types/helpers/TradeHelper.d.ts | 9 +- types/helpers/TraderAssortHelper.d.ts | 6 +- types/helpers/TraderHelper.d.ts | 16 +- types/helpers/WeatherHelper.d.ts | 25 + types/helpers/WeightedRandomHelper.d.ts | 9 - types/loaders/BundleLoader.d.ts | 8 +- types/loaders/PreSptModLoader.d.ts | 4 +- .../eft/bot/IGenerateBotsRequestData.d.ts | 4 +- types/models/eft/common/IGlobals.d.ts | 233 +++++++- types/models/eft/common/ILocation.d.ts | 18 +- types/models/eft/common/ILocationBase.d.ts | 138 +++-- .../ILocationsSourceDestinationBase.d.ts | 4 +- types/models/eft/common/ILooseLoot.d.ts | 34 +- types/models/eft/common/tables/IBotBase.d.ts | 245 ++++---- types/models/eft/common/tables/IBotType.d.ts | 113 ++-- .../eft/common/tables/ICustomizationItem.d.ts | 11 +- .../eft/common/tables/IHandbookBase.d.ts | 8 +- types/models/eft/common/tables/IItem.d.ts | 122 ++-- .../eft/common/tables/ILocationServices.d.ts | 71 +++ .../eft/common/tables/ILocationsBase.d.ts | 8 +- types/models/eft/common/tables/IMatch.d.ts | 4 +- .../eft/common/tables/IProfileTemplate.d.ts | 8 +- types/models/eft/common/tables/IQuest.d.ts | 47 +- .../eft/common/tables/IRepeatableQuests.d.ts | 8 +- .../eft/common/tables/ITemplateItem.d.ts | 83 +-- types/models/eft/common/tables/ITrader.d.ts | 27 +- .../IBuyClothingRequestData.d.ts | 4 +- .../dialog/IGetAllAttachmentsResponse.d.ts | 4 +- .../IGetMailDialogViewResponseData.d.ts | 4 +- .../models/eft/game/IGameConfigResponse.d.ts | 4 +- .../eft/game/ISendSurveyOpinionRequest.d.ts | 9 + .../models/eft/game/ISurveyResponseData.d.ts | 35 ++ .../eft/game/IVersionValidateRequestData.d.ts | 4 +- .../health/IHealthTreatmentRequestData.d.ts | 28 +- .../eft/health/ISyncHealthRequestData.d.ts | 20 +- types/models/eft/health/IWorkoutData.d.ts | 36 +- .../HideoutUpgradeCompleteRequestData.d.ts | 5 - types/models/eft/hideout/IHideoutArea.d.ts | 14 +- ...leOfCultistProductionStartRequestData.d.ts | 4 + .../IHideoutDeleteProductionRequestData.d.ts | 5 + .../IHideoutImproveAreaRequestData.d.ts | 4 +- .../eft/hideout/IHideoutProduction.d.ts | 29 +- .../models/eft/hideout/IHideoutScavCase.d.ts | 18 - .../IHideoutScavCaseStartRequestData.d.ts | 8 +- .../eft/hideout/IHideoutSettingsBase.d.ts | 1 + ...deoutSingleProductionStartRequestData.d.ts | 6 +- .../hideout/IHideoutUpgradeRequestData.d.ts | 4 +- .../eft/inRaid/IItemDeliveryRequestData.d.ts | 4 +- .../eft/inRaid/ISaveProgressRequestData.d.ts | 11 - .../eft/inRaid/IScavSaveRequestData.d.ts | 3 + .../eft/inventory/IAddItemDirectRequest.d.ts | 4 +- .../eft/inventory/IAddItemRequestData.d.ts | 4 +- .../eft/inventory/IAddItemTempObject.d.ts | 6 +- .../eft/inventory/IAddItemsDirectRequest.d.ts | 4 +- .../inventory/IInventoryAddRequestData.d.ts | 4 +- .../IInventoryBaseActionRequestData.d.ts | 18 +- .../IInventoryCreateMarkerRequestData.d.ts | 4 +- .../IInventoryEditMarkerRequestData.d.ts | 4 +- .../inventory/IInventoryMoveRequestData.d.ts | 4 +- .../inventory/IInventorySortRequestData.d.ts | 18 +- .../inventory/IInventorySplitRequestData.d.ts | 4 +- .../inventory/IInventorySwapRequestData.d.ts | 6 +- .../IOpenRandomLootContainerRequestData.d.ts | 4 +- .../eft/inventory/IPinOrLockItemRequest.d.ts | 8 + .../eft/itemEvent/IItemEventRouterBase.d.ts | 55 +- .../itemEvent/IItemEventRouterRequest.d.ts | 12 +- types/models/eft/launcher/IMiniProfile.d.ts | 8 +- .../eft/location/IAirdropLootResult.d.ts | 4 +- .../eft/location/IGetAirdropLootRequest.d.ts | 3 + .../eft/location/IGetAirdropLootResponse.d.ts | 6 + .../eft/match/IEndLocalRaidRequestData.d.ts | 44 ++ .../IGetRaidConfigurationRequestData.d.ts | 1 - types/models/eft/match/IGroupCharacter.d.ts | 4 +- .../eft/match/IPutMetricsRequestData.d.ts | 53 +- types/models/eft/match/IRaidSettings.d.ts | 19 +- .../eft/match/IStartLocalRaidRequestData.d.ts | 17 + .../match/IStartLocalRaidResponseData.d.ts | 19 + ...IPlayerIncrementSkillLevelRequestData.d.ts | 4 +- .../IPresetBuildActionRequestData.d.ts | 4 +- .../profile/GetProfileStatusResponseData.d.ts | 6 +- .../eft/profile/IGetOtherProfileResponse.d.ts | 12 +- types/models/eft/profile/ISptProfile.d.ts | 110 ++-- .../eft/quests/IHandoverQuestRequestData.d.ts | 4 +- .../eft/ragfair/IAddOfferRequestData.d.ts | 4 +- types/models/eft/ragfair/IRagfairOffer.d.ts | 13 +- .../eft/repair/IRepairActionDataRequest.d.ts | 4 +- .../ITraderRepairActionDataRequest.d.ts | 4 +- .../trade/IProcessBuyTradeRequestData.d.ts | 4 +- .../trade/IProcessSellTradeRequestData.d.ts | 4 +- types/models/eft/weather/IWeatherData.d.ts | 3 + .../eft/wishlist/IAddToWishlistRequest.d.ts | 4 + .../IChangeWishlistItemCategoryRequest.d.ts | 5 + .../wishlist/IRemoveFromWishlistRequest.d.ts | 4 + .../eft/wishlist/IWishlistActionData.d.ts | 4 - .../models/eft/ws/IWsChatMessageReceived.d.ts | 4 +- types/models/enums/AirdropType.d.ts | 15 +- types/models/enums/BaseClasses.d.ts | 2 +- types/models/enums/ConfigTypes.d.ts | 3 +- types/models/enums/ExitStatis.d.ts | 11 +- types/models/enums/HideoutAreas.d.ts | 4 +- types/models/enums/HideoutEventActions.d.ts | 4 +- types/models/enums/ItemEventActions.d.ts | 3 +- types/models/enums/ItemTpl.d.ts | 547 +++++++++++++----- types/models/enums/QuestRewardType.d.ts | 3 +- types/models/enums/Season.d.ts | 4 +- types/models/enums/SeasonalEventType.d.ts | 2 +- types/models/enums/TraderServiceType.d.ts | 3 +- types/models/enums/Weapons.d.ts | 17 + types/models/enums/WildSpawnTypeNumber.d.ts | 23 +- types/models/enums/hideout/QteEffectType.d.ts | 6 +- types/models/external/HttpFramework.d.ts | 5 +- .../models/spt/bots/BotGenerationDetails.d.ts | 2 +- .../models/spt/bots/GenerateWeaponResult.d.ts | 10 - .../bots/IGenerateEquipmentProperties.d.ts | 20 +- .../spt/bots/IGenerateWeaponRequest.d.ts | 12 +- .../spt/bots/IGenerateWeaponResult.d.ts | 10 + types/models/spt/bots/IModToSpawnRequest.d.ts | 14 +- .../models/spt/callbacks/IDataCallbacks.d.ts | 23 - .../spt/callbacks/IDialogueCallbacks.d.ts | 4 +- .../spt/callbacks/IInraidCallbacks.d.ts | 14 - .../spt/callbacks/IWishlistCallbacks.d.ts | 7 - types/models/spt/config/IAirdropConfig.d.ts | 31 +- types/models/spt/config/IBTRConfig.d.ts | 13 - types/models/spt/config/IBotConfig.d.ts | 46 +- types/models/spt/config/IBotDurability.d.ts | 54 +- types/models/spt/config/ICoreConfig.d.ts | 6 + types/models/spt/config/IGiftsConfig.d.ts | 8 +- types/models/spt/config/IHealthConfig.d.ts | 8 +- types/models/spt/config/IHideoutConfig.d.ts | 25 + types/models/spt/config/IInRaidConfig.d.ts | 13 +- types/models/spt/config/IInsuranceConfig.d.ts | 5 +- types/models/spt/config/IInventoryConfig.d.ts | 6 +- types/models/spt/config/IItemConfig.d.ts | 8 +- types/models/spt/config/ILocationConfig.d.ts | 28 +- types/models/spt/config/ILootConfig.d.ts | 4 +- .../models/spt/config/ILostOnDeathConfig.d.ts | 4 +- .../models/spt/config/IPlayerScavConfig.d.ts | 22 +- types/models/spt/config/IPmcConfig.d.ts | 36 +- types/models/spt/config/IQuestConfig.d.ts | 5 + types/models/spt/config/IRagfairConfig.d.ts | 30 +- types/models/spt/config/IRepairConfig.d.ts | 16 +- types/models/spt/config/IScavCaseConfig.d.ts | 18 +- .../spt/config/ISeasonalEventConfig.d.ts | 19 +- types/models/spt/config/ITraderConfig.d.ts | 28 +- types/models/spt/config/IWeatherConfig.d.ts | 14 +- .../spt/controllers/IBotController.d.ts | 4 +- .../spt/dialog/ISendMessageDetails.d.ts | 8 +- .../spt/fence/ICreateFenceAssortsResult.d.ts | 4 +- .../models/spt/generators/IBotGenerator.d.ts | 6 +- .../spt/generators/ILocationGenerator.d.ts | 4 +- .../generators/IRagfairAssortGenerator.d.ts | 4 +- .../generators/IRagfairOfferGenerator.d.ts | 4 +- types/models/spt/hideout/IHideout.d.ts | 6 +- .../ScavCaseRewardCountsAndPrices.d.ts | 10 +- .../spt/inventory/IOwnerInventoryItems.d.ts | 6 +- types/models/spt/mod/NewItemDetails.d.ts | 4 +- .../models/spt/ragfair/ITplWithFleaPrice.d.ts | 5 + types/models/spt/server/ISettingsBase.d.ts | 16 +- types/models/spt/services/CustomPreset.d.ts | 5 - .../spt/services/CustomTraderAssortData.d.ts | 6 - .../spt/services/IInsuranceEquipmentPkg.d.ts | 4 +- types/models/spt/services/ILootRequest.d.ts | 33 ++ types/models/spt/services/LootItem.d.ts | 2 +- types/models/spt/services/LootRequest.d.ts | 15 - types/models/spt/templates/ITemplates.d.ts | 3 + types/models/spt/utils/ILogger.d.ts | 4 +- .../weather/IGetLocalWeatherResponseData.d.ts | 5 + types/routers/EventOutputHolder.d.ts | 11 +- types/routers/HttpRouter.d.ts | 1 - types/routers/ImageRouter.d.ts | 3 +- .../item_events/WishlistItemEventRouter.d.ts | 2 +- .../routers/serializers/BundleSerializer.d.ts | 3 +- .../routers/serializers/ImageSerializer.d.ts | 3 +- .../routers/serializers/NotifySerializer.d.ts | 3 +- types/routers/static/GameStaticRouter.d.ts | 4 +- types/servers/HttpServer.d.ts | 7 +- types/servers/WebSocketServer.d.ts | 1 - types/servers/http/IHttpListener.d.ts | 1 - types/servers/http/SptHttpListener.d.ts | 22 +- .../ws/IWebSocketConnectionHandler.d.ts | 1 - .../ws/SptWebSocketConnectionHandler.d.ts | 4 +- types/services/AirdropService.d.ts | 56 ++ types/services/BotEquipmentFilterService.d.ts | 24 +- .../services/BotEquipmentModPoolService.d.ts | 6 +- types/services/BotGenerationCacheService.d.ts | 4 +- types/services/BotLootCacheService.d.ts | 10 +- types/services/BotNameService.d.ts | 47 ++ types/services/BotWeaponModLimitService.d.ts | 4 +- types/services/CircleOfCultistService.d.ts | 132 +++++ types/services/CustomLocationWaveService.d.ts | 6 +- types/services/DatabaseService.d.ts | 26 +- types/services/FenceService.d.ts | 38 +- types/services/GiftService.d.ts | 10 +- types/services/InMemoryCacheService.d.ts | 29 + types/services/InsuranceService.d.ts | 89 +-- .../LegacyLocationLifecycleService.d.ts | 105 ++++ types/services/LocaleService.d.ts | 2 +- types/services/LocationLifecycleService.d.ts | 220 +++++++ types/services/MailSendService.d.ts | 24 +- types/services/MapMarkerService.d.ts | 8 +- types/services/PaymentService.d.ts | 11 +- types/services/PmcChatResponseService.d.ts | 26 +- types/services/PostDbLoadService.d.ts | 77 +++ types/services/ProfileFixerService.d.ts | 118 +--- types/services/ProfileSnapshotService.d.ts | 30 - types/services/RagfairLinkedItemService.d.ts | 4 +- types/services/RagfairOfferService.d.ts | 10 +- types/services/RagfairPriceService.d.ts | 16 +- types/services/RagfairTaxService.d.ts | 12 +- types/services/RaidTimeAdjustmentService.d.ts | 4 +- types/services/RaidWeatherService.d.ts | 43 ++ types/services/RepairService.d.ts | 18 +- types/services/SeasonalEventService.d.ts | 59 +- .../TraderPurchasePersisterService.d.ts | 6 +- types/services/TraderServicesService.d.ts | 13 - types/services/mod/CustomItemService.d.ts | 4 +- .../mod/httpListener/HttpListenerMod.d.ts | 1 - .../httpListener/HttpListenerModService.d.ts | 1 - .../tools/ItemTplGenerator/itemOverrides.d.ts | 5 + .../ProductionQuestsGen.d.ts | 16 + .../ProductionQuestsGenProgram.d.ts | 7 + types/utils/App.d.ts | 4 +- types/utils/HashUtil.d.ts | 8 +- types/utils/HttpFileUtil.d.ts | 3 +- types/utils/ObjectId.d.ts | 1 - types/utils/TimeUtil.d.ts | 12 + types/utils/VFS.d.ts | 2 - .../utils/logging/AbstractWinstonLogger.d.ts | 5 +- 305 files changed, 4345 insertions(+), 2677 deletions(-) rename types/generators/{LocationGenerator.d.ts => LocationLootGenerator.d.ts} (88%) create mode 100644 types/helpers/WeatherHelper.d.ts create mode 100644 types/models/eft/common/tables/ILocationServices.d.ts create mode 100644 types/models/eft/game/ISendSurveyOpinionRequest.d.ts create mode 100644 types/models/eft/game/ISurveyResponseData.d.ts delete mode 100644 types/models/eft/hideout/HideoutUpgradeCompleteRequestData.d.ts create mode 100644 types/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData.d.ts create mode 100644 types/models/eft/hideout/IHideoutDeleteProductionRequestData.d.ts delete mode 100644 types/models/eft/hideout/IHideoutScavCase.d.ts delete mode 100644 types/models/eft/inRaid/ISaveProgressRequestData.d.ts create mode 100644 types/models/eft/inRaid/IScavSaveRequestData.d.ts create mode 100644 types/models/eft/inventory/IPinOrLockItemRequest.d.ts create mode 100644 types/models/eft/location/IGetAirdropLootRequest.d.ts create mode 100644 types/models/eft/location/IGetAirdropLootResponse.d.ts create mode 100644 types/models/eft/match/IEndLocalRaidRequestData.d.ts create mode 100644 types/models/eft/match/IStartLocalRaidRequestData.d.ts create mode 100644 types/models/eft/match/IStartLocalRaidResponseData.d.ts create mode 100644 types/models/eft/wishlist/IAddToWishlistRequest.d.ts create mode 100644 types/models/eft/wishlist/IChangeWishlistItemCategoryRequest.d.ts create mode 100644 types/models/eft/wishlist/IRemoveFromWishlistRequest.d.ts delete mode 100644 types/models/eft/wishlist/IWishlistActionData.d.ts delete mode 100644 types/models/spt/bots/GenerateWeaponResult.d.ts create mode 100644 types/models/spt/bots/IGenerateWeaponResult.d.ts delete mode 100644 types/models/spt/callbacks/IDataCallbacks.d.ts delete mode 100644 types/models/spt/callbacks/IInraidCallbacks.d.ts delete mode 100644 types/models/spt/callbacks/IWishlistCallbacks.d.ts delete mode 100644 types/models/spt/config/IBTRConfig.d.ts create mode 100644 types/models/spt/ragfair/ITplWithFleaPrice.d.ts delete mode 100644 types/models/spt/services/CustomPreset.d.ts delete mode 100644 types/models/spt/services/CustomTraderAssortData.d.ts create mode 100644 types/models/spt/services/ILootRequest.d.ts delete mode 100644 types/models/spt/services/LootRequest.d.ts create mode 100644 types/models/spt/weather/IGetLocalWeatherResponseData.d.ts create mode 100644 types/services/AirdropService.d.ts create mode 100644 types/services/BotNameService.d.ts create mode 100644 types/services/CircleOfCultistService.d.ts create mode 100644 types/services/InMemoryCacheService.d.ts create mode 100644 types/services/LegacyLocationLifecycleService.d.ts create mode 100644 types/services/LocationLifecycleService.d.ts create mode 100644 types/services/PostDbLoadService.d.ts delete mode 100644 types/services/ProfileSnapshotService.d.ts create mode 100644 types/services/RaidWeatherService.d.ts delete mode 100644 types/services/TraderServicesService.d.ts create mode 100644 types/tools/ProductionQuestsGen/ProductionQuestsGen.d.ts create mode 100644 types/tools/ProductionQuestsGen/ProductionQuestsGenProgram.d.ts diff --git a/PTT-Extracts/Patch.cs b/PTT-Extracts/Patch.cs index 6b1d5860..53c8ae62 100644 --- a/PTT-Extracts/Patch.cs +++ b/PTT-Extracts/Patch.cs @@ -95,7 +95,7 @@ private static bool PatchPrefix(ref ExfiltrationControllerClass __instance, Loca AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").SetValue(__instance, list_0); AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").SetValue(__instance, list_1); - UnityEngine.Random.InitState((int) DateTimeOffset.UtcNow.ToUnixTimeSeconds()); + UnityEngine.Random.InitState((int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()); foreach (ExfiltrationPoint exfiltrationPoint in __instance.ExfiltrationPoints) { @@ -104,7 +104,7 @@ private static bool PatchPrefix(ref ExfiltrationControllerClass __instance, Loca LocationExitClass gclass = settings.FirstOrDefault(new Func(NameMatches)); if (gclass != null) { - exfiltrationPoint.LoadSettings(gclass, giveAuthority); + exfiltrationPoint.LoadSettings(exfiltrationPoint.Id, gclass, giveAuthority); if (!justLoadSettings && !RandomRange(exfiltrationPoint)) { exfiltrationPoint.SetStatusLogged(EExfiltrationStatus.NotPresent, "ExfiltrationController.InitAllExfiltrationPoints-2"); diff --git a/types/callbacks/BotCallbacks.d.ts b/types/callbacks/BotCallbacks.d.ts index 7d22dcfe..909e93ee 100644 --- a/types/callbacks/BotCallbacks.d.ts +++ b/types/callbacks/BotCallbacks.d.ts @@ -1,14 +1,16 @@ +import { ApplicationContext } from "@spt/context/ApplicationContext"; import { BotController } from "@spt/controllers/BotController"; import { IGenerateBotsRequestData } from "@spt/models/eft/bot/IGenerateBotsRequestData"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; import { IBotBase } from "@spt/models/eft/common/tables/IBotBase"; -import { Difficulties } from "@spt/models/eft/common/tables/IBotType"; +import { IDifficulties } from "@spt/models/eft/common/tables/IBotType"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; export declare class BotCallbacks { protected botController: BotController; protected httpResponse: HttpResponseUtil; - constructor(botController: BotController, httpResponse: HttpResponseUtil); + protected applicationContext: ApplicationContext; + constructor(botController: BotController, httpResponse: HttpResponseUtil, applicationContext: ApplicationContext); /** * Handle singleplayer/settings/bot/limit * Is called by client to define each bot roles wave limit @@ -24,7 +26,7 @@ export declare class BotCallbacks { * Handle singleplayer/settings/bot/difficulties * @returns dictionary of every bot and its diffiulty settings */ - getAllBotDifficulties(url: string, info: IEmptyRequestData, sessionID: string): Record; + getAllBotDifficulties(url: string, info: IEmptyRequestData, sessionID: string): Record; /** * Handle client/game/bot/generate * @returns IGetBodyResponseData @@ -34,7 +36,7 @@ export declare class BotCallbacks { * Handle singleplayer/settings/bot/maxCap * @returns string */ - getBotCap(url: string, info: any, sessionID: string): string; + getBotCap(url: string, info: IEmptyRequestData, sessionID: string): string; /** * Handle singleplayer/settings/bot/getBotBehaviours * @returns string diff --git a/types/callbacks/DataCallbacks.d.ts b/types/callbacks/DataCallbacks.d.ts index 41f1d0ca..5b501e1e 100644 --- a/types/callbacks/DataCallbacks.d.ts +++ b/types/callbacks/DataCallbacks.d.ts @@ -1,5 +1,5 @@ import { HideoutController } from "@spt/controllers/HideoutController"; -import { RagfairController } from "@spt/controllers/RagfairController"; +import { TraderController } from "@spt/controllers/TraderController"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; import { IGlobals } from "@spt/models/eft/common/IGlobals"; @@ -7,8 +7,7 @@ import { ICustomizationItem } from "@spt/models/eft/common/tables/ICustomization import { IHandbookBase } from "@spt/models/eft/common/tables/IHandbookBase"; import { IGetItemPricesResponse } from "@spt/models/eft/game/IGetItemPricesResponse"; import { IHideoutArea } from "@spt/models/eft/hideout/IHideoutArea"; -import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction"; -import { IHideoutScavCase } from "@spt/models/eft/hideout/IHideoutScavCase"; +import { IHideoutProductionData } from "@spt/models/eft/hideout/IHideoutProduction"; import { IHideoutSettingsBase } from "@spt/models/eft/hideout/IHideoutSettingsBase"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { ISettingsBase } from "@spt/models/spt/server/ISettingsBase"; @@ -23,9 +22,9 @@ export declare class DataCallbacks { protected timeUtil: TimeUtil; protected traderHelper: TraderHelper; protected databaseService: DatabaseService; - protected ragfairController: RagfairController; + protected traderController: TraderController; protected hideoutController: HideoutController; - constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, traderHelper: TraderHelper, databaseService: DatabaseService, ragfairController: RagfairController, hideoutController: HideoutController); + constructor(httpResponse: HttpResponseUtil, timeUtil: TimeUtil, traderHelper: TraderHelper, databaseService: DatabaseService, traderController: TraderController, hideoutController: HideoutController); /** * Handle client/settings * @returns ISettingsBase @@ -62,8 +61,7 @@ export declare class DataCallbacks { */ getHideoutSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutAreas(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gethideoutProduction(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getHideoutScavcase(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getHideoutProduction(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; /** * Handle client/languages */ @@ -83,7 +81,6 @@ export declare class DataCallbacks { /** * Handle client/items/prices/ * Called when viewing a traders assorts - * TODO - fully implement this */ getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/types/callbacks/DialogueCallbacks.d.ts b/types/callbacks/DialogueCallbacks.d.ts index baee279d..e65749ff 100644 --- a/types/callbacks/DialogueCallbacks.d.ts +++ b/types/callbacks/DialogueCallbacks.d.ts @@ -27,7 +27,7 @@ import { ISendMessageRequest } from "@spt/models/eft/dialog/ISendMessageRequest" import { ISetDialogReadRequestData } from "@spt/models/eft/dialog/ISetDialogReadRequestData"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; -import { DialogueInfo } from "@spt/models/eft/profile/ISptProfile"; +import { IDialogueInfo } from "@spt/models/eft/profile/ISptProfile"; import { HashUtil } from "@spt/utils/HashUtil"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; import { TimeUtil } from "@spt/utils/TimeUtil"; @@ -48,11 +48,11 @@ export declare class DialogueCallbacks implements OnUpdate { */ getChatServerList(url: string, info: IGetChatServerListRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/mail/dialog/list */ - getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; + getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/mail/dialog/view */ getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/mail/dialog/info */ - getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; + getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/mail/dialog/remove */ removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/mail/dialog/pin */ diff --git a/types/callbacks/GameCallbacks.d.ts b/types/callbacks/GameCallbacks.d.ts index b41454f1..fc866ce7 100644 --- a/types/callbacks/GameCallbacks.d.ts +++ b/types/callbacks/GameCallbacks.d.ts @@ -13,7 +13,9 @@ import { IGameModeResponse } from "@spt/models/eft/game/IGameModeResponse"; import { IGameStartResponse } from "@spt/models/eft/game/IGameStartResponse"; import { IGetRaidTimeRequest } from "@spt/models/eft/game/IGetRaidTimeRequest"; import { IGetRaidTimeResponse } from "@spt/models/eft/game/IGetRaidTimeResponse"; +import { ISendSurveyOpinionRequest } from "@spt/models/eft/game/ISendSurveyOpinionRequest"; import { IServerDetails } from "@spt/models/eft/game/IServerDetails"; +import { ISurveyResponseData } from "@spt/models/eft/game/ISurveyResponseData"; import { IVersionValidateRequestData } from "@spt/models/eft/game/IVersionValidateRequestData"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; @@ -76,10 +78,29 @@ export declare class GameCallbacks implements OnLoad { * @returns string */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle /client/report/send & /client/reports/lobby/send + * @returns INullResponseData + */ reportNickname(url: string, info: IUIDRequestData, sessionID: string): INullResponseData; /** * Handle singleplayer/settings/getRaidTime * @returns string */ getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): IGetRaidTimeResponse; + /** + * Handle /client/survey + * @returns INullResponseData + */ + getSurvey(url: string, request: IEmptyRequestData, sessionId: string): INullResponseData | IGetBodyResponseData; + /** + * Handle client/survey/view + * @returns INullResponseData + */ + getSurveyView(url: string, request: any, sessionId: string): INullResponseData; + /** + * Handle client/survey/opinion + * @returns INullResponseData + */ + sendSurveyOpinion(url: string, request: ISendSurveyOpinionRequest, sessionId: string): INullResponseData; } diff --git a/types/callbacks/HealthCallbacks.d.ts b/types/callbacks/HealthCallbacks.d.ts index 840c9b16..8523479d 100644 --- a/types/callbacks/HealthCallbacks.d.ts +++ b/types/callbacks/HealthCallbacks.d.ts @@ -4,7 +4,6 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IHealthTreatmentRequestData } from "@spt/models/eft/health/IHealthTreatmentRequestData"; import { IOffraidEatRequestData } from "@spt/models/eft/health/IOffraidEatRequestData"; import { IOffraidHealRequestData } from "@spt/models/eft/health/IOffraidHealRequestData"; -import { ISyncHealthRequestData } from "@spt/models/eft/health/ISyncHealthRequestData"; import { IWorkoutData } from "@spt/models/eft/health/IWorkoutData"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; @@ -14,14 +13,6 @@ export declare class HealthCallbacks { protected profileHelper: ProfileHelper; protected healthController: HealthController; constructor(httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, healthController: HealthController); - /** - * Custom spt server request found in modules/HealthSynchronizer.cs - * @param url - * @param info HealthListener.Instance.CurrentHealth class - * @param sessionID session id - * @returns empty response, no data sent back to client - */ - syncHealth(url: string, info: ISyncHealthRequestData, sessionID: string): IGetBodyResponseData; /** * Custom spt server request found in modules/QTEPatch.cs * @param url diff --git a/types/callbacks/HideoutCallbacks.d.ts b/types/callbacks/HideoutCallbacks.d.ts index fadab9bf..d63bcd60 100644 --- a/types/callbacks/HideoutCallbacks.d.ts +++ b/types/callbacks/HideoutCallbacks.d.ts @@ -3,7 +3,9 @@ import { OnUpdate } from "@spt/di/OnUpdate"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IHandleQTEEventRequestData } from "@spt/models/eft/hideout/IHandleQTEEventRequestData"; import { IHideoutCancelProductionRequestData } from "@spt/models/eft/hideout/IHideoutCancelProductionRequestData"; +import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; import { IHideoutContinuousProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutContinuousProductionStartRequestData"; +import { IHideoutDeleteProductionRequestData } from "@spt/models/eft/hideout/IHideoutDeleteProductionRequestData"; import { IHideoutImproveAreaRequestData } from "@spt/models/eft/hideout/IHideoutImproveAreaRequestData"; import { IHideoutPutItemInRequestData } from "@spt/models/eft/hideout/IHideoutPutItemInRequestData"; import { IHideoutScavCaseStartRequestData } from "@spt/models/eft/hideout/IHideoutScavCaseStartRequestData"; @@ -75,6 +77,14 @@ export declare class HideoutCallbacks implements OnUpdate { * Handle client/game/profile/items/moving - HideoutCancelProductionCommand */ cancelProduction(pmcData: IPmcData, request: IHideoutCancelProductionRequestData, sessionId: string): IItemEventRouterResponse; + /** + * Handle client/game/profile/items/moving - HideoutCircleOfCultistProductionStart + */ + circleOfCultistProductionStart(pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData, sessionId: string): IItemEventRouterResponse; + /** + * Handle client/game/profile/items/moving - HideoutDeleteProductionCommand + */ + hideoutDeleteProductionCommand(pmcData: IPmcData, request: IHideoutDeleteProductionRequestData, sessionId: string): IItemEventRouterResponse; onUpdate(timeSinceLastRun: number): Promise; getRoute(): string; } diff --git a/types/callbacks/InraidCallbacks.d.ts b/types/callbacks/InraidCallbacks.d.ts index dc6ede45..02b46f39 100644 --- a/types/callbacks/InraidCallbacks.d.ts +++ b/types/callbacks/InraidCallbacks.d.ts @@ -1,9 +1,8 @@ import { InraidController } from "@spt/controllers/InraidController"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; -import { IItemDeliveryRequestData } from "@spt/models/eft/inRaid/IItemDeliveryRequestData"; import { IRegisterPlayerRequestData } from "@spt/models/eft/inRaid/IRegisterPlayerRequestData"; -import { ISaveProgressRequestData } from "@spt/models/eft/inRaid/ISaveProgressRequestData"; +import { IScavSaveRequestData } from "@spt/models/eft/inRaid/IScavSaveRequestData"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; /** * Handle client requests @@ -22,42 +21,18 @@ export declare class InraidCallbacks { */ registerPlayer(url: string, info: IRegisterPlayerRequestData, sessionID: string): INullResponseData; /** - * Handle raid/profile/save + * Handle raid/profile/scavsave * @param url * @param info Save progress request * @param sessionID Session id * @returns Null http response */ - saveProgress(url: string, info: ISaveProgressRequestData, sessionID: string): INullResponseData; - /** - * Handle singleplayer/settings/raid/endstate - * @returns - */ - getRaidEndState(): string; + saveProgress(url: string, info: IScavSaveRequestData, sessionID: string): INullResponseData; /** * Handle singleplayer/settings/raid/menu * @returns JSON as string */ getRaidMenuSettings(): string; - /** - * Handle singleplayer/airdrop/config - * @returns JSON as string - */ - getAirdropConfig(): string; - /** - * Handle singleplayer/btr/config - * @returns JSON as string - */ - getBTRConfig(): string; - /** - * Handle singleplayer/traderServices/getTraderServices - */ - getTraderServices(url: string, info: IEmptyRequestData, sessionId: string): string; - /** - * Handle singleplayer/traderServices/itemDelivery - */ - itemDelivery(url: string, request: IItemDeliveryRequestData, sessionId: string): INullResponseData; getTraitorScavHostileChance(url: string, info: IEmptyRequestData, sessionId: string): string; - getSandboxMaxPatrolValue(url: string, info: IEmptyRequestData, sessionId: string): string; getBossConvertSettings(url: string, info: IEmptyRequestData, sessionId: string): string; } diff --git a/types/callbacks/InventoryCallbacks.d.ts b/types/callbacks/InventoryCallbacks.d.ts index e0968e64..cfbf6f37 100644 --- a/types/callbacks/InventoryCallbacks.d.ts +++ b/types/callbacks/InventoryCallbacks.d.ts @@ -18,6 +18,7 @@ import { IInventoryTagRequestData } from "@spt/models/eft/inventory/IInventoryTa import { IInventoryToggleRequestData } from "@spt/models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "@spt/models/eft/inventory/IInventoryTransferRequestData"; import { IOpenRandomLootContainerRequestData } from "@spt/models/eft/inventory/IOpenRandomLootContainerRequestData"; +import { IPinOrLockItemRequest } from "@spt/models/eft/inventory/IPinOrLockItemRequest"; import { IRedeemProfileRequestData } from "@spt/models/eft/inventory/IRedeemProfileRequestData"; import { ISetFavoriteItems } from "@spt/models/eft/inventory/ISetFavoriteItems"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; @@ -58,4 +59,5 @@ export declare class InventoryCallbacks { * Handle game/profile/items/moving - QuestFail */ failQuest(pmcData: IPmcData, request: IFailQuestRequestData, sessionID: string, output: IItemEventRouterResponse): IItemEventRouterResponse; + pinOrLock(pmcData: IPmcData, request: IPinOrLockItemRequest, sessionID: string, output: IItemEventRouterResponse): IItemEventRouterResponse; } diff --git a/types/callbacks/LocationCallbacks.d.ts b/types/callbacks/LocationCallbacks.d.ts index 28250504..f3ffea37 100644 --- a/types/callbacks/LocationCallbacks.d.ts +++ b/types/callbacks/LocationCallbacks.d.ts @@ -1,9 +1,9 @@ import { LocationController } from "@spt/controllers/LocationController"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; -import { ILocationBase } from "@spt/models/eft/common/ILocationBase"; import { ILocationsGenerateAllResponse } from "@spt/models/eft/common/ILocationsSourceDestinationBase"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; -import { IGetLocationRequestData } from "@spt/models/eft/location/IGetLocationRequestData"; +import { IGetAirdropLootRequest } from "@spt/models/eft/location/IGetAirdropLootRequest"; +import { IGetAirdropLootResponse } from "@spt/models/eft/location/IGetAirdropLootResponse"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; export declare class LocationCallbacks { protected httpResponse: HttpResponseUtil; @@ -11,8 +11,6 @@ export declare class LocationCallbacks { constructor(httpResponse: HttpResponseUtil, locationController: LocationController); /** Handle client/locations */ getLocationData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - /** Handle client/location/getLocalloot */ - getLocation(url: string, info: IGetLocationRequestData, sessionID: string): IGetBodyResponseData; - /** Handle client/location/getAirdropLoot */ - getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): string; + /** Handle client/airdrop/loot */ + getAirdropLoot(url: string, info: IGetAirdropLootRequest, sessionID: string): IGetBodyResponseData; } diff --git a/types/callbacks/MatchCallbacks.d.ts b/types/callbacks/MatchCallbacks.d.ts index 73f7564c..f8342606 100644 --- a/types/callbacks/MatchCallbacks.d.ts +++ b/types/callbacks/MatchCallbacks.d.ts @@ -1,8 +1,9 @@ import { MatchController } from "@spt/controllers/MatchController"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; +import { IMetrics } from "@spt/models/eft/common/tables/IMatch"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; -import { IEndOfflineRaidRequestData } from "@spt/models/eft/match/IEndOfflineRaidRequestData"; +import { IEndLocalRaidRequestData } from "@spt/models/eft/match/IEndLocalRaidRequestData"; import { IGetRaidConfigurationRequestData } from "@spt/models/eft/match/IGetRaidConfigurationRequestData"; import { IGroupCharacter } from "@spt/models/eft/match/IGroupCharacter"; import { IMatchGroupCurrentResponse } from "@spt/models/eft/match/IMatchGroupCurrentResponse"; @@ -15,6 +16,8 @@ import { IMatchGroupTransferRequest } from "@spt/models/eft/match/IMatchGroupTra import { IProfileStatusResponse } from "@spt/models/eft/match/IProfileStatusResponse"; import { IPutMetricsRequestData } from "@spt/models/eft/match/IPutMetricsRequestData"; import { IRequestIdRequest } from "@spt/models/eft/match/IRequestIdRequest"; +import { IStartLocalRaidRequestData } from "@spt/models/eft/match/IStartLocalRaidRequestData"; +import { IStartLocalRaidResponseData } from "@spt/models/eft/match/IStartLocalRaidResponseData"; import { IUpdatePingRequestData } from "@spt/models/eft/match/IUpdatePingRequestData"; import { DatabaseService } from "@spt/services/DatabaseService"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; @@ -29,9 +32,12 @@ export declare class MatchCallbacks { updatePing(url: string, info: IUpdatePingRequestData, sessionID: string): INullResponseData; exitMatch(url: string, info: IEmptyRequestData, sessionID: string): INullResponseData; /** Handle client/match/group/exit_from_menu */ - exitToMenu(url: string, info: IEmptyRequestData, sessionID: string): INullResponseData; + exitFromMenu(url: string, info: IEmptyRequestData, sessionID: string): INullResponseData; + /** Handle client/match/group/current */ groupCurrent(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** Handle client/match/group/looking/start */ startGroupSearch(url: string, info: IEmptyRequestData, sessionID: string): INullResponseData; + /** Handle client/match/group/looking/stop */ stopGroupSearch(url: string, info: IEmptyRequestData, sessionID: string): INullResponseData; /** Handle client/match/group/invite/send */ sendGroupInvite(url: string, info: IMatchGroupInviteSendRequest, sessionID: string): IGetBodyResponseData; @@ -45,13 +51,15 @@ export declare class MatchCallbacks { transferGroup(url: string, info: IMatchGroupTransferRequest, sessionId: string): IGetBodyResponseData; /** Handle client/match/group/invite/cancel-all */ cancelAllGroupInvite(url: string, info: IEmptyRequestData, sessionId: string): IGetBodyResponseData; - /** @deprecated - not called on raid start/end or game start/exit */ - putMetrics(url: string, info: IPutMetricsRequestData, sessionId: string): INullResponseData; + /** Handle client/putMetrics */ + putMetrics(url: string, request: IPutMetricsRequestData, sessionId: string): INullResponseData; + /** Handle client/analytics/event-disconnect */ + eventDisconnect(url: string, request: IPutMetricsRequestData, sessionId: string): INullResponseData; serverAvailable(url: string, info: IEmptyRequestData, sessionId: string): IGetBodyResponseData; /** Handle match/group/start_game */ joinMatch(url: string, info: IMatchGroupStartGameRequest, sessionID: string): IGetBodyResponseData; /** Handle client/getMetricsConfig */ - getMetrics(url: string, info: any, sessionID: string): IGetBodyResponseData; + getMetrics(url: string, info: any, sessionID: string): IGetBodyResponseData; /** * Called periodically while in a group * Handle client/match/group/status @@ -63,8 +71,10 @@ export declare class MatchCallbacks { leaveGroup(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/match/group/player/remove */ removePlayerFromGroup(url: string, info: IMatchGroupPlayerRemoveRequest, sessionID: string): IGetBodyResponseData; - /** Handle client/match/offline/end */ - endOfflineRaid(url: string, info: IEndOfflineRaidRequestData, sessionID: string): INullResponseData; + /** Handle client/match/local/start */ + startLocalRaid(url: string, info: IStartLocalRaidRequestData, sessionID: string): IGetBodyResponseData; + /** Handle client/match/local/end */ + endLocalRaid(url: string, info: IEndLocalRaidRequestData, sessionID: string): INullResponseData; /** Handle client/raid/configuration */ getRaidConfiguration(url: string, info: IGetRaidConfigurationRequestData, sessionID: string): INullResponseData; /** Handle client/raid/configuration-by-profile */ diff --git a/types/callbacks/ProfileCallbacks.d.ts b/types/callbacks/ProfileCallbacks.d.ts index ba35f5e6..3824a8cc 100644 --- a/types/callbacks/ProfileCallbacks.d.ts +++ b/types/callbacks/ProfileCallbacks.d.ts @@ -5,7 +5,7 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; import { IGetMiniProfileRequestData } from "@spt/models/eft/launcher/IGetMiniProfileRequestData"; -import { GetProfileStatusResponseData } from "@spt/models/eft/profile/GetProfileStatusResponseData"; +import { IGetProfileStatusResponseData } from "@spt/models/eft/profile/GetProfileStatusResponseData"; import { ICreateProfileResponse } from "@spt/models/eft/profile/ICreateProfileResponse"; import { IGetOtherProfileRequest } from "@spt/models/eft/profile/IGetOtherProfileRequest"; import { IGetOtherProfileResponse } from "@spt/models/eft/profile/IGetOtherProfileResponse"; @@ -65,7 +65,7 @@ export declare class ProfileCallbacks { * Handle client/profile/status * Called when creating a character when choosing a character face/voice */ - getProfileStatus(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getProfileStatus(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; /** * Handle client/profile/view * Called when viewing another players profile diff --git a/types/callbacks/TraderCallbacks.d.ts b/types/callbacks/TraderCallbacks.d.ts index c081a9b1..7bebe559 100644 --- a/types/callbacks/TraderCallbacks.d.ts +++ b/types/callbacks/TraderCallbacks.d.ts @@ -4,12 +4,15 @@ import { OnUpdate } from "@spt/di/OnUpdate"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; import { ITraderAssort, ITraderBase } from "@spt/models/eft/common/tables/ITrader"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; +import { IModdedTraders } from "@spt/models/spt/config/ITraderConfig"; +import { ConfigServer } from "@spt/servers/ConfigServer"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; export declare class TraderCallbacks implements OnLoad, OnUpdate { protected httpResponse: HttpResponseUtil; protected traderController: TraderController; + protected configServer: ConfigServer; constructor(httpResponse: HttpResponseUtil, // TODO: delay required - traderController: TraderController); + traderController: TraderController, configServer: ConfigServer); onLoad(): Promise; onUpdate(): Promise; getRoute(): string; @@ -19,4 +22,6 @@ export declare class TraderCallbacks implements OnLoad, OnUpdate { getTrader(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; /** Handle client/trading/api/getTraderAssort */ getAssort(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** Handle /singleplayer/moddedTraders */ + getModdedTraderData(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/types/callbacks/WeatherCallbacks.d.ts b/types/callbacks/WeatherCallbacks.d.ts index 5ba5aab0..ef5808fa 100644 --- a/types/callbacks/WeatherCallbacks.d.ts +++ b/types/callbacks/WeatherCallbacks.d.ts @@ -2,6 +2,7 @@ import { WeatherController } from "@spt/controllers/WeatherController"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { IWeatherData } from "@spt/models/eft/weather/IWeatherData"; +import { IGetLocalWeatherResponseData } from "@spt/models/spt/weather/IGetLocalWeatherResponseData"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; export declare class WeatherCallbacks { protected httpResponse: HttpResponseUtil; @@ -12,4 +13,6 @@ export declare class WeatherCallbacks { * @returns IWeatherData */ getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** Handle client/localGame/weather */ + getLocalWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/types/callbacks/WishlistCallbacks.d.ts b/types/callbacks/WishlistCallbacks.d.ts index f5b500f4..414eb91e 100644 --- a/types/callbacks/WishlistCallbacks.d.ts +++ b/types/callbacks/WishlistCallbacks.d.ts @@ -1,12 +1,16 @@ import { WishlistController } from "@spt/controllers/WishlistController"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IWishlistActionData } from "@spt/models/eft/wishlist/IWishlistActionData"; +import { IAddToWishlistRequest } from "@spt/models/eft/wishlist/IAddToWishlistRequest"; +import { IChangeWishlistItemCategoryRequest } from "@spt/models/eft/wishlist/IChangeWishlistItemCategoryRequest"; +import { IRemoveFromWishlistRequest } from "@spt/models/eft/wishlist/IRemoveFromWishlistRequest"; export declare class WishlistCallbacks { protected wishlistController: WishlistController; constructor(wishlistController: WishlistController); /** Handle AddToWishList event */ - addToWishlist(pmcData: IPmcData, body: IWishlistActionData, sessionID: string): IItemEventRouterResponse; + addToWishlist(pmcData: IPmcData, request: IAddToWishlistRequest, sessionID: string): IItemEventRouterResponse; /** Handle RemoveFromWishList event */ - removeFromWishlist(pmcData: IPmcData, body: IWishlistActionData, sessionID: string): IItemEventRouterResponse; + removeFromWishlist(pmcData: IPmcData, request: IRemoveFromWishlistRequest, sessionID: string): IItemEventRouterResponse; + /** Handle ChangeWishlistItemCategory */ + changeWishlistItemCategory(pmcData: IPmcData, request: IChangeWishlistItemCategoryRequest, sessionID: string): IItemEventRouterResponse; } diff --git a/types/context/ContextVariableType.d.ts b/types/context/ContextVariableType.d.ts index 0722a987..03a51882 100644 --- a/types/context/ContextVariableType.d.ts +++ b/types/context/ContextVariableType.d.ts @@ -3,9 +3,11 @@ export declare enum ContextVariableType { SESSION_ID = 0, /** Currently acive raid information */ RAID_CONFIGURATION = 1, - /** Timestamp when client first connected */ + /** SessionID + Timestamp when client first connected, has _ between values */ CLIENT_START_TIMESTAMP = 2, /** When player is loading into map and loot is requested */ REGISTER_PLAYER_REQUEST = 3, - RAID_ADJUSTMENTS = 4 + RAID_ADJUSTMENTS = 4, + /** Data returned from client request object from endLocalRaid() */ + TRANSIT_INFO = 5 } diff --git a/types/controllers/BotController.d.ts b/types/controllers/BotController.d.ts index 475f51b8..a7cb6ae7 100644 --- a/types/controllers/BotController.d.ts +++ b/types/controllers/BotController.d.ts @@ -5,12 +5,13 @@ import { BotHelper } from "@spt/helpers/BotHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { MinMax } from "@spt/models/common/MinMax"; -import { Condition, IGenerateBotsRequestData } from "@spt/models/eft/bot/IGenerateBotsRequestData"; +import { ICondition, IGenerateBotsRequestData } from "@spt/models/eft/bot/IGenerateBotsRequestData"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotBase } from "@spt/models/eft/common/tables/IBotBase"; import { IBotCore } from "@spt/models/eft/common/tables/IBotCore"; -import { Difficulty } from "@spt/models/eft/common/tables/IBotType"; -import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; +import { IDifficultyCategories } from "@spt/models/eft/common/tables/IBotType"; +import { IGetRaidConfigurationRequestData } from "@spt/models/eft/match/IGetRaidConfigurationRequestData"; +import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -58,10 +59,11 @@ export declare class BotController { * Adjust PMC settings to ensure they engage the correct bot types * @param type what bot the server is requesting settings for * @param diffLevel difficulty level server requested settings for + * @param raidConfig OPTIONAL - applicationContext Data stored at start of raid * @param ignoreRaidSettings should raid settings chosen pre-raid be ignored * @returns Difficulty object */ - getBotDifficulty(type: string, diffLevel: string, ignoreRaidSettings?: boolean): Difficulty; + getBotDifficulty(type: string, diffLevel: string, raidConfig?: IGetRaidConfigurationRequestData, ignoreRaidSettings?: boolean): IDifficultyCategories; getAllBotDifficulties(): Record; /** * Generate bot profiles and store in cache @@ -75,20 +77,27 @@ export declare class BotController { * @param request Bot generation request object * @param pmcProfile Player profile * @param sessionId Session id - * @returns + * @returns IBotBase[] + */ + protected generateMultipleBotsAndCache(request: IGenerateBotsRequestData, pmcProfile: IPmcData, sessionId: string): Promise; + protected getMostRecentRaidSettings(): IGetRaidConfigurationRequestData; + /** + * Get min/max level range values for a specific map + * @param location Map name e.g. factory4_day + * @returns MinMax */ - generateBotsFirstTime(request: IGenerateBotsRequestData, pmcProfile: IPmcData, sessionId: string): Promise; + protected getPmcLevelRangeForMap(location: string): MinMax; /** * Create a BotGenerationDetails for the bot generator to use * @param condition Client data defining bot type and difficulty * @param pmcProfile Player who is generating bots * @param allPmcsHaveSameNameAsPlayer Should all PMCs have same name as player - * @param pmcLevelRangeForMap Min/max levels for PMCs to generate within + * @param raidSettings Settings chosen pre-raid by player * @param botCountToGenerate How many bots to generate * @param generateAsPmc Force bot being generated a PMC * @returns BotGenerationDetails */ - protected getBotGenerationDetailsForWave(condition: Condition, pmcProfile: IPmcData, allPmcsHaveSameNameAsPlayer: boolean, pmcLevelRangeForMap: MinMax, botCountToGenerate: number, generateAsPmc: boolean): BotGenerationDetails; + protected getBotGenerationDetailsForWave(condition: ICondition, pmcProfile: IPmcData, allPmcsHaveSameNameAsPlayer: boolean, raidSettings: IGetRaidConfigurationRequestData, botCountToGenerate: number, generateAsPmc: boolean): IBotGenerationDetails; /** * Get players profile level * @param pmcProfile Profile to get level from @@ -102,7 +111,7 @@ export declare class BotController { * @param sessionId Session id * @returns A promise for the bots to be done generating */ - protected generateWithBotDetails(condition: Condition, botGenerationDetails: BotGenerationDetails, sessionId: string): Promise; + protected generateWithBotDetails(condition: ICondition, botGenerationDetails: IBotGenerationDetails, sessionId: string): Promise; /** * Generate a single bot and store in the cache * @param botGenerationDetails the bot details to generate the bot with @@ -110,15 +119,16 @@ export declare class BotController { * @param cacheKey the cache key to store the bot with * @returns A promise for the bot to be stored */ - protected generateSingleBotAndStoreInCache(botGenerationDetails: BotGenerationDetails, sessionId: string, cacheKey: string): Promise; + protected generateSingleBotAndStoreInCache(botGenerationDetails: IBotGenerationDetails, sessionId: string, cacheKey: string): Promise; /** * Pull a single bot out of cache and return, if cache is empty add bots to it and then return * @param sessionId Session id * @param request Bot generation request object * @returns Single IBotBase object */ - returnSingleBotFromCache(sessionId: string, request: IGenerateBotsRequestData): Promise; - protected updateBotGenerationDetailsToRandomBoss(botGenerationDetails: BotGenerationDetails, possibleBossTypeWeights: Record): void; + protected returnSingleBotFromCache(sessionId: string, request: IGenerateBotsRequestData): Promise; + protected getPmcConversionMinMaxForLocation(requestedBotRole: string, location: string): MinMax; + protected updateBotGenerationDetailsToRandomBoss(botGenerationDetails: IBotGenerationDetails, possibleBossTypeWeights: Record): void; /** * Get the difficulty passed in, if its not "asonline", get selected difficulty from config * @param requestedDifficulty diff --git a/types/controllers/CustomizationController.d.ts b/types/controllers/CustomizationController.d.ts index 028341a7..8aef9e96 100644 --- a/types/controllers/CustomizationController.d.ts +++ b/types/controllers/CustomizationController.d.ts @@ -1,7 +1,7 @@ import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { ISuit } from "@spt/models/eft/common/tables/ITrader"; -import { ClothingItem, IBuyClothingRequestData } from "@spt/models/eft/customization/IBuyClothingRequestData"; +import { IBuyClothingRequestData, IPaymentItemForClothing } from "@spt/models/eft/customization/IBuyClothingRequestData"; import { IWearClothingRequestData } from "@spt/models/eft/customization/IWearClothingRequestData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -54,17 +54,17 @@ export declare class CustomizationController { * Update output object and player profile with purchase details * @param sessionId Session id * @param pmcData Player profile - * @param clothingItems Clothing purchased + * @param itemsToPayForClothingWith Clothing purchased * @param output Client response */ - protected payForClothingItems(sessionId: string, pmcData: IPmcData, clothingItems: ClothingItem[], output: IItemEventRouterResponse): void; + protected payForClothingItems(sessionId: string, pmcData: IPmcData, itemsToPayForClothingWith: IPaymentItemForClothing[], output: IItemEventRouterResponse): void; /** * Update output object and player profile with purchase details for single piece of clothing * @param sessionId Session id * @param pmcData Player profile - * @param clothingItem Clothing item purchased + * @param paymentItemDetails Payment details * @param output Client response */ - protected payForClothingItem(sessionId: string, pmcData: IPmcData, clothingItem: ClothingItem, output: IItemEventRouterResponse): void; + protected payForClothingItem(sessionId: string, pmcData: IPmcData, paymentItemDetails: IPaymentItemForClothing, output: IItemEventRouterResponse): void; protected getAllTraderSuits(sessionID: string): ISuit[]; } diff --git a/types/controllers/DialogueController.d.ts b/types/controllers/DialogueController.d.ts index c15d724d..2f00b131 100644 --- a/types/controllers/DialogueController.d.ts +++ b/types/controllers/DialogueController.d.ts @@ -7,7 +7,7 @@ import { IGetFriendListDataResponse } from "@spt/models/eft/dialog/IGetFriendLis import { IGetMailDialogViewRequestData } from "@spt/models/eft/dialog/IGetMailDialogViewRequestData"; import { IGetMailDialogViewResponseData } from "@spt/models/eft/dialog/IGetMailDialogViewResponseData"; import { ISendMessageRequest } from "@spt/models/eft/dialog/ISendMessageRequest"; -import { Dialogue, DialogueInfo, ISptProfile, IUserDialogInfo, Message } from "@spt/models/eft/profile/ISptProfile"; +import { IDialogue, IDialogueInfo, IMessage, ISptProfile, IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; import { MessageType } from "@spt/models/enums/MessageType"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -40,14 +40,14 @@ export declare class DialogueController { * @param sessionID Session Id * @returns array of dialogs */ - generateDialogueList(sessionID: string): DialogueInfo[]; + generateDialogueList(sessionID: string): IDialogueInfo[]; /** * Get the content of a dialogue * @param dialogueID Dialog id * @param sessionID Session Id * @returns DialogueInfo */ - getDialogueInfo(dialogueID: string, sessionID: string): DialogueInfo; + getDialogueInfo(dialogueID: string, sessionID: string): IDialogueInfo; /** * Get the users involved in a dialog (player + other party) * @param dialog The dialog to check for users @@ -55,7 +55,7 @@ export declare class DialogueController { * @param sessionID Player id * @returns IUserDialogInfo array */ - getDialogueUsers(dialog: Dialogue, messageType: MessageType, sessionID: string): IUserDialogInfo[] | undefined; + getDialogueUsers(dialog: IDialogue, messageType: MessageType, sessionID: string): IUserDialogInfo[] | undefined; /** * Handle client/mail/dialog/view * Handle player clicking 'messenger' and seeing all the messages they've recieved @@ -72,7 +72,7 @@ export declare class DialogueController { * @param request get dialog request (params used when dialog doesnt exist in profile) * @returns Dialogue */ - protected getDialogByIdFromProfile(profile: ISptProfile, request: IGetMailDialogViewRequestData): Dialogue; + protected getDialogByIdFromProfile(profile: ISptProfile, request: IGetMailDialogViewRequestData): IDialogue; /** * Get the users involved in a mail between two entities * @param fullProfile Player profile @@ -92,7 +92,7 @@ export declare class DialogueController { * @param messages Messages to check * @returns true if uncollected rewards found */ - protected messagesHaveUncollectedRewards(messages: Message[]): boolean; + protected messagesHaveUncollectedRewards(messages: IMessage[]): boolean; /** * Handle client/mail/dialog/remove * Remove an entire dialog with an entity (trader/user) @@ -125,13 +125,13 @@ export declare class DialogueController { * @param dialogueId Dialog to get mail attachments from * @returns Message array */ - protected getActiveMessagesFromDialog(sessionId: string, dialogueId: string): Message[]; + protected getActiveMessagesFromDialog(sessionId: string, dialogueId: string): IMessage[]; /** * Return array of messages with uncollected items (includes expired) * @param messages Messages to parse * @returns messages with items to collect */ - protected getMessagesWithAttachments(messages: Message[]): Message[]; + protected getMessagesWithAttachments(messages: IMessage[]): IMessage[]; /** * Delete expired items from all messages in player profile. triggers when updating traders. * @param sessionId Session id @@ -148,7 +148,7 @@ export declare class DialogueController { * @param message Message to check expiry of * @returns true or false */ - protected messageHasExpired(message: Message): boolean; + protected messageHasExpired(message: IMessage): boolean; /** Handle client/friend/request/send */ sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse; } diff --git a/types/controllers/GameController.d.ts b/types/controllers/GameController.d.ts index e219c04d..2717c3f9 100644 --- a/types/controllers/GameController.d.ts +++ b/types/controllers/GameController.d.ts @@ -1,6 +1,7 @@ import { ApplicationContext } from "@spt/context/ApplicationContext"; import { HideoutHelper } from "@spt/helpers/HideoutHelper"; import { HttpServerHelper } from "@spt/helpers/HttpServerHelper"; +import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { PreSptModLoader } from "@spt/loaders/PreSptModLoader"; import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; @@ -13,14 +14,12 @@ import { IGameModeRequestData } from "@spt/models/eft/game/IGameModeRequestData" import { IGetRaidTimeRequest } from "@spt/models/eft/game/IGetRaidTimeRequest"; import { IGetRaidTimeResponse } from "@spt/models/eft/game/IGetRaidTimeResponse"; import { IServerDetails } from "@spt/models/eft/game/IServerDetails"; +import { ISurveyResponseData } from "@spt/models/eft/game/ISurveyResponseData"; import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; import { IHttpConfig } from "@spt/models/spt/config/IHttpConfig"; -import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; -import { ILootConfig } from "@spt/models/spt/config/ILootConfig"; -import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -30,6 +29,7 @@ import { GiftService } from "@spt/services/GiftService"; import { ItemBaseClassService } from "@spt/services/ItemBaseClassService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { OpenZoneService } from "@spt/services/OpenZoneService"; +import { PostDbLoadService } from "@spt/services/PostDbLoadService"; import { ProfileActivityService } from "@spt/services/ProfileActivityService"; import { ProfileFixerService } from "@spt/services/ProfileFixerService"; import { RaidTimeAdjustmentService } from "@spt/services/RaidTimeAdjustmentService"; @@ -45,11 +45,13 @@ export declare class GameController { protected hashUtil: HashUtil; protected preSptModLoader: PreSptModLoader; protected httpServerHelper: HttpServerHelper; + protected inventoryHelper: InventoryHelper; protected randomUtil: RandomUtil; protected hideoutHelper: HideoutHelper; protected profileHelper: ProfileHelper; protected profileFixerService: ProfileFixerService; protected localisationService: LocalisationService; + protected postDbLoadService: PostDbLoadService; protected customLocationWaveService: CustomLocationWaveService; protected openZoneService: OpenZoneService; protected seasonalEventService: SeasonalEventService; @@ -62,32 +64,16 @@ export declare class GameController { protected cloner: ICloner; protected httpConfig: IHttpConfig; protected coreConfig: ICoreConfig; - protected locationConfig: ILocationConfig; protected ragfairConfig: IRagfairConfig; protected hideoutConfig: IHideoutConfig; - protected pmcConfig: IPmcConfig; - protected lootConfig: ILootConfig; protected botConfig: IBotConfig; - constructor(logger: ILogger, databaseService: DatabaseService, timeUtil: TimeUtil, hashUtil: HashUtil, preSptModLoader: PreSptModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, profileActivityService: ProfileActivityService, applicationContext: ApplicationContext, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, databaseService: DatabaseService, timeUtil: TimeUtil, hashUtil: HashUtil, preSptModLoader: PreSptModLoader, httpServerHelper: HttpServerHelper, inventoryHelper: InventoryHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, postDbLoadService: PostDbLoadService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, profileActivityService: ProfileActivityService, applicationContext: ApplicationContext, configServer: ConfigServer, cloner: ICloner); load(): void; /** * Handle client/game/start */ gameStart(_url: string, _info: IEmptyRequestData, sessionID: string, startTimeStampMS: number): void; - protected adjustHideoutCraftTimes(overrideSeconds: number): void; - /** - * Adjust all hideout craft times to be no higher than the override - */ - protected adjustHideoutBuildTimes(overrideSeconds: number): void; - protected adjustLocationBotValues(): void; - /** - * Out of date/incorrectly made trader mods forget this data - */ - protected checkTraderRepairValuesExist(): void; - protected addCustomLooseLootPositions(): void; - protected adjustLooseLootSpawnProbabilities(): void; - /** Apply custom limits on bot types as defined in configs/location.json/botTypeLimits */ - protected adjustMapBotLimits(): void; + protected migrate39xProfile(fullProfile: ISptProfile): void; /** * Handle client/game/config */ @@ -116,48 +102,26 @@ export declare class GameController { * 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 - */ - protected fixShotgunDispersions(): void; /** * Players set botReload to a high value and don't expect the crazy fast reload speeds, give them a warn about it * @param pmcProfile Player profile */ protected warnOnActiveBotReloadSkill(pmcProfile: IPmcData): void; - protected setAllDbItemsAsSellableOnFlea(): void; /** * When player logs in, iterate over all active effects and reduce timer * @param pmcProfile Profile to adjust values for */ protected updateProfileHealthValues(pmcProfile: IPmcData): void; - /** - * Waves with an identical min/max values spawn nothing, the number of bots that spawn is the difference between min and max - */ - protected fixBrokenOfflineMapWaves(): void; - /** - * Make Rogues spawn later to allow for scavs to spawn first instead of rogues filling up all spawn positions - */ - protected fixRoguesSpawningInstantlyOnLighthouse(): void; /** * Send starting gifts to profile after x days * @param pmcProfile Profile to add gifts to */ protected sendPraporGiftsToNewProfiles(pmcProfile: IPmcData): void; - /** - * Find and split waves with large numbers of bots into smaller waves - BSG appears to reduce the size of these - * waves to one bot when they're waiting to spawn for too long - */ - protected splitBotWavesIntoSingleWaves(): void; /** * Get a list of installed mods and save their details to the profile being used * @param fullProfile Profile to add mod details to */ protected saveActiveModsToProfile(fullProfile: ISptProfile): void; - /** - * Check for any missing assorts inside each traders assort.json data, checking against traders questassort.json - */ - protected validateQuestAssortUnlocksExist(): void; /** * Add the logged in players name to PMC name pool * @param pmcProfile Profile of player to get name from @@ -168,13 +132,6 @@ export declare class GameController { * @param fullProfile Profile to check for dialog in */ protected checkForAndRemoveUndefinedDialogs(fullProfile: ISptProfile): void; - /** - * Blank out the "test" mail message from prapor - */ - protected removePraporTestMessage(): void; - /** - * Make non-trigger-spawned raiders spawn earlier + always - */ - protected adjustLabsRaiderSpawnRate(): void; protected logProfileDetails(fullProfile: ISptProfile): void; + getSurvey(sessionId: string): ISurveyResponseData; } diff --git a/types/controllers/HealthController.d.ts b/types/controllers/HealthController.d.ts index 5a0a0a69..a17efe37 100644 --- a/types/controllers/HealthController.d.ts +++ b/types/controllers/HealthController.d.ts @@ -5,7 +5,6 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IHealthTreatmentRequestData } from "@spt/models/eft/health/IHealthTreatmentRequestData"; import { IOffraidEatRequestData } from "@spt/models/eft/health/IOffraidEatRequestData"; import { IOffraidHealRequestData } from "@spt/models/eft/health/IOffraidHealRequestData"; -import { ISyncHealthRequestData } from "@spt/models/eft/health/ISyncHealthRequestData"; import { IWorkoutData } from "@spt/models/eft/health/IWorkoutData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -25,15 +24,6 @@ export declare class HealthController { protected healthHelper: HealthHelper; protected cloner: ICloner; constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, itemHelper: ItemHelper, paymentService: PaymentService, inventoryHelper: InventoryHelper, localisationService: LocalisationService, httpResponse: HttpResponseUtil, healthHelper: HealthHelper, cloner: ICloner); - /** - * stores in-raid player health - * @param pmcData Player profile - * @param info Request data - * @param sessionID Player id - * @param addEffects Should effects found be added or removed from profile - * @param deleteExistingEffects Should all prior effects be removed before apply new ones - */ - saveVitality(pmcData: IPmcData, info: ISyncHealthRequestData, sessionID: string, addEffects?: boolean, deleteExistingEffects?: boolean): void; /** * When healing in menu * @param pmcData Player profile diff --git a/types/controllers/HideoutController.d.ts b/types/controllers/HideoutController.d.ts index 89a428c5..7bbd4833 100644 --- a/types/controllers/HideoutController.d.ts +++ b/types/controllers/HideoutController.d.ts @@ -6,12 +6,13 @@ import { PaymentHelper } from "@spt/helpers/PaymentHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { HideoutArea, ITaskConditionCounter, Product } from "@spt/models/eft/common/tables/IBotBase"; -import { HideoutUpgradeCompleteRequestData } from "@spt/models/eft/hideout/HideoutUpgradeCompleteRequestData"; +import { IBotHideoutArea, IProduct, ITaskConditionCounter } from "@spt/models/eft/common/tables/IBotBase"; import { IHandleQTEEventRequestData } from "@spt/models/eft/hideout/IHandleQTEEventRequestData"; -import { IHideoutArea, Stage } from "@spt/models/eft/hideout/IHideoutArea"; +import { IHideoutArea, IStage } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCancelProductionRequestData } from "@spt/models/eft/hideout/IHideoutCancelProductionRequestData"; +import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; import { IHideoutContinuousProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutContinuousProductionStartRequestData"; +import { IHideoutDeleteProductionRequestData } from "@spt/models/eft/hideout/IHideoutDeleteProductionRequestData"; import { IHideoutImproveAreaRequestData } from "@spt/models/eft/hideout/IHideoutImproveAreaRequestData"; import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction"; import { IHideoutPutItemInRequestData } from "@spt/models/eft/hideout/IHideoutPutItemInRequestData"; @@ -20,8 +21,9 @@ import { IHideoutSingleProductionStartRequestData } from "@spt/models/eft/hideou import { IHideoutTakeItemOutRequestData } from "@spt/models/eft/hideout/IHideoutTakeItemOutRequestData"; import { IHideoutTakeProductionRequestData } from "@spt/models/eft/hideout/IHideoutTakeProductionRequestData"; import { IHideoutToggleAreaRequestData } from "@spt/models/eft/hideout/IHideoutToggleAreaRequestData"; +import { IHideoutUpgradeCompleteRequestData } from "@spt/models/eft/hideout/IHideoutUpgradeCompleteRequestData"; import { IHideoutUpgradeRequestData } from "@spt/models/eft/hideout/IHideoutUpgradeRequestData"; -import { IQteData } from "@spt/models/eft/hideout/IQteData"; +import { IQteData, IQteResult } from "@spt/models/eft/hideout/IQteData"; import { IRecordShootingRangePoints } from "@spt/models/eft/hideout/IRecordShootingRangePoints"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { HideoutAreas } from "@spt/models/enums/HideoutAreas"; @@ -30,6 +32,7 @@ import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; +import { CircleOfCultistService } from "@spt/services/CircleOfCultistService"; import { DatabaseService } from "@spt/services/DatabaseService"; import { FenceService } from "@spt/services/FenceService"; import { LocalisationService } from "@spt/services/LocalisationService"; @@ -61,11 +64,12 @@ export declare class HideoutController { protected profileActivityService: ProfileActivityService; protected configServer: ConfigServer; protected fenceService: FenceService; + protected circleOfCultistService: CircleOfCultistService; protected cloner: ICloner; /** Key used in TaskConditionCounters array */ - protected static nameTaskConditionCountersCrafting: string; + protected static nameTaskConditionCountersCraftingId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseService: DatabaseService, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, itemHelper: ItemHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, localisationService: LocalisationService, profileActivityService: ProfileActivityService, configServer: ConfigServer, fenceService: FenceService, cloner: ICloner); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseService: DatabaseService, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, itemHelper: ItemHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, localisationService: LocalisationService, profileActivityService: ProfileActivityService, configServer: ConfigServer, fenceService: FenceService, circleOfCultistService: CircleOfCultistService, cloner: ICloner); /** * Handle HideoutUpgrade event * Start a hideout area upgrade @@ -83,12 +87,12 @@ export declare class HideoutController { * @param sessionID Session id * @param output Client response */ - upgradeComplete(pmcData: IPmcData, request: HideoutUpgradeCompleteRequestData, sessionID: string, output: IItemEventRouterResponse): void; + upgradeComplete(pmcData: IPmcData, request: IHideoutUpgradeCompleteRequestData, sessionID: string, output: IItemEventRouterResponse): void; /** * Upgrade wall status to visible in profile if medstation/water collector are both level 1 * @param pmcData Player profile */ - protected checkAndUpgradeWall(pmcData: IPmcData): void; + protected SetWallVisibleIfPrereqsMet(pmcData: IPmcData): void; /** * @param pmcData Profile to edit * @param output Object to send back to client @@ -97,14 +101,23 @@ export declare class HideoutController { * @param dbHideoutArea Hideout area being upgraded * @param hideoutStage Stage hideout area is being upgraded to */ - protected addContainerImprovementToProfile(output: IItemEventRouterResponse, sessionID: string, pmcData: IPmcData, profileParentHideoutArea: HideoutArea, dbHideoutArea: IHideoutArea, hideoutStage: Stage): void; + protected addContainerImprovementToProfile(output: IItemEventRouterResponse, sessionID: string, pmcData: IPmcData, profileParentHideoutArea: IBotHideoutArea, dbHideoutArea: IHideoutArea, hideoutStage: IStage): void; + /** + * Add stand1/stand2/stand3 inventory items to profile, depending on passed in hideout stage + * @param sessionId Session id + * @param equipmentPresetStage Current EQUIPMENT_PRESETS_STAND stage data + * @param pmcData Player profile + * @param equipmentPresetHideoutArea + * @param output Response to send back to client + */ + protected addMissingPresetStandItemsToProfile(sessionId: string, equipmentPresetStage: IStage, pmcData: IPmcData, equipmentPresetHideoutArea: IHideoutArea, output: IItemEventRouterResponse): void; /** * Add an inventory item to profile from a hideout area stage data * @param pmcData Profile to update - * @param dbHideoutData Hideout area from db being upgraded + * @param dbHideoutArea Hideout area from db being upgraded * @param hideoutStage Stage area upgraded to */ - protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; + protected addUpdateInventoryItemToProfile(sessionId: string, pmcData: IPmcData, dbHideoutArea: IHideoutArea, hideoutStage: IStage): void; /** * @param output Object to send to client * @param sessionID Session/player id @@ -112,7 +125,7 @@ export declare class HideoutController { * @param hideoutDbData Hideout area that caused addition of stash * @param hideoutStage Hideout area upgraded to this */ - protected addContainerUpgradeToClientOutput(output: IItemEventRouterResponse, sessionID: string, areaType: HideoutAreas, hideoutDbData: IHideoutArea, hideoutStage: Stage): void; + protected addContainerUpgradeToClientOutput(sessionID: string, areaType: HideoutAreas, hideoutDbData: IHideoutArea, hideoutStage: IStage, output: IItemEventRouterResponse): void; /** * Handle HideoutPutItemsInAreaSlots * Create item in hideout slot item array, remove item from player inventory @@ -140,7 +153,7 @@ export declare class HideoutController { * @param hideoutArea Area fuel is being removed from * @returns IItemEventRouterResponse response */ - protected removeResourceFromArea(sessionID: string, pmcData: IPmcData, removeResourceRequest: IHideoutTakeItemOutRequestData, output: IItemEventRouterResponse, hideoutArea: HideoutArea): IItemEventRouterResponse; + protected removeResourceFromArea(sessionID: string, pmcData: IPmcData, removeResourceRequest: IHideoutTakeItemOutRequestData, output: IItemEventRouterResponse, hideoutArea: IBotHideoutArea): IItemEventRouterResponse; /** * Handle HideoutToggleArea event * Toggle area on/off @@ -182,7 +195,7 @@ export declare class HideoutController { * @param rewards reward items to add to profile * @param recipeId recipe id to save into Production dict */ - protected addScavCaseRewardsToProfile(pmcData: IPmcData, rewards: Product[], recipeId: string): void; + protected addScavCaseRewardsToProfile(pmcData: IPmcData, rewards: IProduct[], recipeId: string): void; /** * Start production of continuously created item * @param pmcData Player profile @@ -239,6 +252,12 @@ export declare class HideoutController { * @param request QTE result object */ handleQTEEventOutcome(sessionId: string, pmcData: IPmcData, request: IHandleQTEEventRequestData, output: IItemEventRouterResponse): void; + /** + * Apply mild/severe muscle pain after gym use + * @param pmcData Profile to apply effect to + * @param finishEffect Effect data to apply after completing QTE gym event + */ + protected handleMusclePain(pmcData: IPmcData, finishEffect: IQteResult): void; /** * Record a high score from the shooting range into a player profiles overallcounters * @param sessionId Session id @@ -263,7 +282,22 @@ export declare class HideoutController { */ cancelProduction(sessionId: string, pmcData: IPmcData, request: IHideoutCancelProductionRequestData): IItemEventRouterResponse; /** - * Function called every x seconds as part of onUpdate event + * Handle client/game/profile/items/moving - HideoutCircleOfCultistProductionStart + * @param sessionId Session id + * @param pmcData Profile of crafter + * @param request Request data + */ + circleOfCultistProductionStart(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Handle HideoutDeleteProductionCommand event + * @param sessionId Session id + * @param pmcData Player profile + * @param request Client request data + * @returns IItemEventRouterResponse + */ + hideoutDeleteProductionCommand(sessionId: string, pmcData: IPmcData, request: IHideoutDeleteProductionRequestData): IItemEventRouterResponse; + /** + * Function called every `hideoutConfig.runIntervalSeconds` seconds as part of onUpdate event */ update(): void; } diff --git a/types/controllers/InraidController.d.ts b/types/controllers/InraidController.d.ts index 9f0c4094..b9f69c22 100644 --- a/types/controllers/InraidController.d.ts +++ b/types/controllers/InraidController.d.ts @@ -1,70 +1,26 @@ import { ApplicationContext } from "@spt/context/ApplicationContext"; -import { PlayerScavGenerator } from "@spt/generators/PlayerScavGenerator"; -import { HealthHelper } from "@spt/helpers/HealthHelper"; -import { InRaidHelper } from "@spt/helpers/InRaidHelper"; -import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; -import { QuestHelper } from "@spt/helpers/QuestHelper"; -import { TraderHelper } from "@spt/helpers/TraderHelper"; -import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; import { IRegisterPlayerRequestData } from "@spt/models/eft/inRaid/IRegisterPlayerRequestData"; -import { ISaveProgressRequestData } from "@spt/models/eft/inRaid/ISaveProgressRequestData"; -import { PlayerRaidEndState } from "@spt/models/enums/PlayerRaidEndState"; -import { IAirdropConfig } from "@spt/models/spt/config/IAirdropConfig"; -import { IBTRConfig } from "@spt/models/spt/config/IBTRConfig"; +import { IScavSaveRequestData } from "@spt/models/eft/inRaid/IScavSaveRequestData"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; -import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; import { IInRaidConfig } from "@spt/models/spt/config/IInRaidConfig"; -import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; -import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; -import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; -import { ITraderServiceModel } from "@spt/models/spt/services/ITraderServiceModel"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; -import { DatabaseService } from "@spt/services/DatabaseService"; -import { InsuranceService } from "@spt/services/InsuranceService"; import { LocalisationService } from "@spt/services/LocalisationService"; -import { MailSendService } from "@spt/services/MailSendService"; -import { MatchBotDetailsCacheService } from "@spt/services/MatchBotDetailsCacheService"; -import { PmcChatResponseService } from "@spt/services/PmcChatResponseService"; -import { TraderServicesService } from "@spt/services/TraderServicesService"; -import { RandomUtil } from "@spt/utils/RandomUtil"; -import { TimeUtil } from "@spt/utils/TimeUtil"; /** * Logic for handling In Raid callbacks */ export declare class InraidController { protected logger: ILogger; protected saveServer: SaveServer; - protected timeUtil: TimeUtil; - protected databaseService: DatabaseService; - protected pmcChatResponseService: PmcChatResponseService; - protected matchBotDetailsCacheService: MatchBotDetailsCacheService; - protected questHelper: QuestHelper; - protected itemHelper: ItemHelper; protected profileHelper: ProfileHelper; - protected playerScavGenerator: PlayerScavGenerator; - protected healthHelper: HealthHelper; - protected traderHelper: TraderHelper; - protected traderServicesService: TraderServicesService; protected localisationService: LocalisationService; - protected insuranceService: InsuranceService; - protected inRaidHelper: InRaidHelper; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; - protected mailSendService: MailSendService; - protected randomUtil: RandomUtil; - protected airdropConfig: IAirdropConfig; - protected btrConfig: IBTRConfig; protected inRaidConfig: IInRaidConfig; - protected traderConfig: ITraderConfig; - protected locationConfig: ILocationConfig; - protected ragfairConfig: IRagfairConfig; - protected hideoutConfig: IHideoutConfig; protected botConfig: IBotConfig; - constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, databaseService: DatabaseService, pmcChatResponseService: PmcChatResponseService, matchBotDetailsCacheService: MatchBotDetailsCacheService, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, traderServicesService: TraderServicesService, localisationService: LocalisationService, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, applicationContext: ApplicationContext, configServer: ConfigServer, mailSendService: MailSendService, randomUtil: RandomUtil); + constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, localisationService: LocalisationService, applicationContext: ApplicationContext, configServer: ConfigServer); /** * Save locationId to active profiles inraid object AND app context * @param sessionID Session id @@ -72,124 +28,18 @@ export declare class InraidController { */ addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; /** - * Handle raid/profile/save + * Handle raid/profile/scavsave * Save profile state to disk * Handles pmc/pscav - * @param offraidData post-raid request data + * @param offraidProfileData Post-raid scav profile data * @param sessionID Session id */ - savePostRaidProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; - /** - * Handle updating player profile post-pmc raid - * @param sessionID Session id - * @param postRaidRequest Post-raid data - */ - protected savePmcProgress(sessionID: string, postRaidRequest: ISaveProgressRequestData): void; - /** - * Make changes to PMC profile after they've died in raid, - * Alter body part hp, handle insurance, delete inventory items, remove carried quest items - * @param postRaidSaveRequest Post-raid save request - * @param pmcData Pmc profile - * @param sessionID Session id - * @returns Updated profile object - */ - protected performPostRaidActionsWhenDead(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData, sessionID: string): IPmcData; - /** - * Adjust player characters body part hp post-raid - * @param postRaidSaveRequest post raid data - * @param pmcData player profile - */ - protected updatePmcHealthPostRaid(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData): void; - /** - * Reduce body part hp to % of max - * @param pmcData profile to edit - * @param multiplier multiplier to apply to max health - */ - protected reducePmcHealthToPercent(pmcData: IPmcData, multiplier: number): void; - /** - * Handle updating the profile post-pscav raid - * @param sessionID Session id - * @param postRaidRequest Post-raid data of raid - */ - protected savePlayerScavProgress(sessionID: string, postRaidRequest: ISaveProgressRequestData): void; - /** - * merge two dictionaries together - * Prioritise pair that has true as a value - * @param primary main dictionary - * @param secondary Secondary dictionary - */ - protected mergePmcAndScavEncyclopedias(primary: IPmcData, secondary: IPmcData): void; - /** - * Post-scav-raid any charisma increase must be propigated into PMC profile - * @param postRaidServerScavProfile Scav profile after adjustments made from raid - * @param postRaidServerPmcProfile Pmc profile after raid - * @param preRaidScavCharismaProgress charisma progress value pre-raid - */ - protected updatePmcCharismaSkillPostScavRaid(postRaidServerScavProfile: IPmcData, postRaidServerPmcProfile: IPmcData, preRaidScavCharismaProgress: number): void; - /** - * Does provided profile contain any condition counters - * @param profile Profile to check for condition counters - * @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" - * @param statusOnExit exit value from offraidData object - * @returns true if dead - */ - protected isPlayerDead(statusOnExit: PlayerRaidEndState): boolean; - /** - * Mark inventory items as FiR if player survived raid, otherwise remove FiR from them - * @param offraidData Save Progress Request - */ - protected markOrRemoveFoundInRaidItems(offraidData: ISaveProgressRequestData): void; - /** - * Update profile after player completes scav raid - * @param scavData Scav profile - * @param sessionID Session id - * @param offraidData Post-raid save request - * @param pmcData Pmc profile - * @param isDead Is player dead - */ - protected handlePostRaidPlayerScavProcess(scavData: IPmcData, sessionID: string, offraidData: ISaveProgressRequestData, pmcData: IPmcData, isDead: boolean): void; - /** - * Update profile with scav karma values based on in-raid actions - * @param pmcData Pmc profile - * @param offraidData Post-raid save request - * @param scavData Scav profile - */ - protected handlePostRaidPlayerScavKarmaChanges(pmcData: IPmcData, offraidData: ISaveProgressRequestData, scavData: IPmcData): void; + savePostRaidProfileForScav(offraidProfileData: IScavSaveRequestData, sessionID: string): void; /** * Get the inraid config from configs/inraid.json * @returns InRaid Config */ getInraidConfig(): IInRaidConfig; - /** - * Get airdrop config from configs/airdrop.json - * @returns Airdrop config - */ - getAirdropConfig(): IAirdropConfig; - /** - * Get BTR config from configs/btr.json - * @returns Airdrop config - */ - getBTRConfig(): IBTRConfig; - /** - * Handle singleplayer/traderServices/getTraderServices - * @returns Trader services data - */ - getTraderServices(sessionId: string, traderId: string): ITraderServiceModel[]; - /** - * Handle singleplayer/traderServices/itemDelivery - */ - itemDelivery(sessionId: string, traderId: string, items: Item[]): void; getTraitorScavHostileChance(url: string, sessionID: string): number; - getSandboxMaxPatrolValue(url: string, sessionID: string): number; getBossConvertSettings(url: string, sessionId: string): string[]; } diff --git a/types/controllers/InsuranceController.d.ts b/types/controllers/InsuranceController.d.ts index 543e915c..c9825292 100644 --- a/types/controllers/InsuranceController.d.ts +++ b/types/controllers/InsuranceController.d.ts @@ -4,12 +4,12 @@ import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IGetInsuranceCostRequestData } from "@spt/models/eft/insurance/IGetInsuranceCostRequestData"; import { IGetInsuranceCostResponseData } from "@spt/models/eft/insurance/IGetInsuranceCostResponseData"; import { IInsureRequestData } from "@spt/models/eft/insurance/IInsureRequestData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { Insurance } from "@spt/models/eft/profile/ISptProfile"; +import { IInsurance } from "@spt/models/eft/profile/ISptProfile"; import { IInsuranceConfig } from "@spt/models/spt/config/IInsuranceConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; @@ -68,7 +68,7 @@ export declare class InsuranceController { * @param time The time to check ready status against. Current time by default. * @returns All insured items that are ready to be processed. */ - protected filterInsuredItems(sessionID: string, time?: number): Insurance[]; + protected filterInsuredItems(sessionID: string, time?: number): IInsurance[]; /** * This method orchestrates the processing of insured items in a profile. * @@ -76,13 +76,13 @@ export declare class InsuranceController { * @param sessionID The session ID that should receive the processed items. * @returns void */ - protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void; + protected processInsuredItems(insuranceDetails: IInsurance[], sessionID: string): void; /** * Count all items in all insurance packages. * @param insurance * @returns */ - protected countAllInsuranceItems(insurance: Insurance[]): number; + protected countAllInsuranceItems(insurance: IInsurance[]): number; /** * Remove an insurance package from a profile using the package's system data information. * @@ -90,7 +90,7 @@ export declare class InsuranceController { * @param index The array index of the insurance package to remove. * @returns void */ - protected removeInsurancePackageFromProfile(sessionID: string, insPackage: Insurance): void; + protected removeInsurancePackageFromProfile(sessionID: string, insPackage: IInsurance): void; /** * Finds the items that should be deleted based on the given Insurance object. * @@ -98,7 +98,7 @@ export declare class InsuranceController { * @param insured - The insurance object containing the items to evaluate for deletion. * @returns A Set containing the IDs of items that should be deleted. */ - protected findItemsToDelete(rootItemParentID: string, insured: Insurance): Set; + protected findItemsToDelete(rootItemParentID: string, insured: IInsurance): Set; /** * Initialize a Map object that holds main-parents to all of their attachments. Note that "main-parent" in this * context refers to the parent item that an attachment is attached to. For example, a suppressor attached to a gun, @@ -109,7 +109,7 @@ export declare class InsuranceController { * @param itemsMap - A Map object for quick item look-up by item ID. * @returns A Map object containing parent item IDs to arrays of their attachment items. */ - protected populateParentAttachmentsMap(rootItemParentID: string, insured: Insurance, itemsMap: Map): Map; + protected populateParentAttachmentsMap(rootItemParentID: string, insured: IInsurance, itemsMap: Map): Map; /** * Remove attachments that can not be moddable in-raid from the parentAttachmentsMap. If no moddable attachments * remain, the parent is removed from the map as well. @@ -118,7 +118,7 @@ export declare class InsuranceController { * @param itemsMap - A Map object for quick item look-up by item ID. * @returns A Map object containing parent item IDs to arrays of their attachment items which are not moddable in-raid. */ - protected removeNonModdableAttachments(parentAttachmentsMap: Map, itemsMap: Map): Map; + protected removeNonModdableAttachments(parentAttachmentsMap: Map, itemsMap: Map): Map; /** * Process "regular" insurance items. Any insured item that is not an attached, attachment is considered a "regular" * item. This method iterates over them, preforming item deletion rolls to see if they should be deleted. If so, @@ -129,7 +129,7 @@ export declare class InsuranceController { * @param parentAttachmentsMap A Map object containing parent item IDs to arrays of their attachment items. * @returns void */ - protected processRegularItems(insured: Insurance, toDelete: Set, parentAttachmentsMap: Map): void; + protected processRegularItems(insured: IInsurance, toDelete: Set, parentAttachmentsMap: Map): void; /** * Process parent items and their attachments, updating the toDelete Set accordingly. * @@ -138,7 +138,7 @@ export declare class InsuranceController { * @param traderId The trader ID from the Insurance object. * @param toDelete A Set object to keep track of items marked for deletion. */ - protected processAttachments(mainParentToAttachmentsMap: Map, itemsMap: Map, traderId: string, toDelete: Set): void; + protected processAttachments(mainParentToAttachmentsMap: Map, itemsMap: Map, traderId: string, toDelete: Set): void; /** * Takes an array of attachment items that belong to the same main-parent item, sorts them in descending order by * their maximum price. For each attachment, a roll is made to determine if a deletion should be made. Once the @@ -150,9 +150,9 @@ export declare class InsuranceController { * @param toDelete The array that accumulates the IDs of the items to be deleted. * @returns void */ - protected processAttachmentByParent(attachments: Item[], traderId: string, toDelete: Set): void; - protected logAttachmentsBeingRemoved(attachmentIdsToRemove: string[], attachments: Item[], attachmentPrices: Record): void; - protected weightAttachmentsByPrice(attachments: Item[]): Record; + protected processAttachmentByParent(attachments: IItem[], traderId: string, toDelete: Set): void; + protected logAttachmentsBeingRemoved(attachmentIdsToRemove: string[], attachments: IItem[], attachmentPrices: Record): void; + protected weightAttachmentsByPrice(attachments: IItem[]): Record; /** * Get count of items to remove from weapon (take into account trader + price of attachment) * @param weightedAttachmentByPrice Dict of item Tpls and thier rouble price @@ -167,7 +167,7 @@ export declare class InsuranceController { * @param toDelete The items that should be deleted. * @returns void */ - protected removeItemsFromInsurance(insured: Insurance, toDelete: Set): void; + protected removeItemsFromInsurance(insured: IInsurance, toDelete: Set): void; /** * Handle sending the insurance message to the user that potentially contains the valid insurance items. * @@ -175,7 +175,12 @@ export declare class InsuranceController { * @param insurance The context of insurance to use. * @returns void */ - protected sendMail(sessionID: string, insurance: Insurance): void; + protected sendMail(sessionID: string, insurance: IInsurance): void; + protected IsMapLabsAndInsuranceDisabled(insurance: IInsurance, labsId?: string): boolean; + /** + * Update IInsurance object with new messageTemplateId and wipe out items array data + */ + protected handleLabsInsurance(traderDialogMessages: Record, insurance: IInsurance): void; /** * Determines whether an insured item should be removed from the player's inventory based on a random roll and * trader-specific return chance. @@ -184,7 +189,7 @@ export declare class InsuranceController { * @param insuredItem Optional. The item to roll for. Only used for logging. * @returns true if the insured item should be removed from inventory, false otherwise, or undefined on error. */ - protected rollForDelete(traderId: string, insuredItem?: Item): boolean | undefined; + protected rollForDelete(traderId: string, insuredItem?: IItem): boolean | undefined; /** * Handle Insure event * Add insurance to an item @@ -195,6 +200,14 @@ export declare class InsuranceController { * @returns IItemEventRouterResponse object to send to client */ insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Insure softinserts of Armor that has softinsert slots + * Allows armors to come back after being lost correctly + * @param item Armor item to be insured + * @param pmcData Player profile + * @param body Insurance request data + */ + insureSoftInserts(item: IItem, pmcData: IPmcData, body: IInsureRequestData): void; /** * Handle client/insurance/items/list/cost * Calculate insurance cost diff --git a/types/controllers/InventoryController.d.ts b/types/controllers/InventoryController.d.ts index c986ce8c..fb81a2ff 100644 --- a/types/controllers/InventoryController.d.ts +++ b/types/controllers/InventoryController.d.ts @@ -25,6 +25,7 @@ import { IInventoryTagRequestData } from "@spt/models/eft/inventory/IInventoryTa import { IInventoryToggleRequestData } from "@spt/models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "@spt/models/eft/inventory/IInventoryTransferRequestData"; import { IOpenRandomLootContainerRequestData } from "@spt/models/eft/inventory/IOpenRandomLootContainerRequestData"; +import { IPinOrLockItemRequest } from "@spt/models/eft/inventory/IPinOrLockItemRequest"; import { IRedeemProfileRequestData } from "@spt/models/eft/inventory/IRedeemProfileRequestData"; import { ISetFavoriteItems } from "@spt/models/eft/inventory/ISetFavoriteItems"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; @@ -228,4 +229,13 @@ export declare class InventoryController { openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string, output: IItemEventRouterResponse): void; redeemProfileReward(pmcData: IPmcData, request: IRedeemProfileRequestData, sessionId: string): void; setFavoriteItem(pmcData: IPmcData, request: ISetFavoriteItems, sessionId: string): void; + /** + * Handle /client/game/profile/items/moving - PinLock + * Requires no response to client, only server change + * @param pmcData Players profile + * @param request Pin/Lock request data + * @param sessionID Session id + * @param output data to send back to client + */ + pinOrLock(pmcData: IPmcData, request: IPinOrLockItemRequest, sessionID: string, output: IItemEventRouterResponse): IItemEventRouterResponse; } diff --git a/types/controllers/LauncherController.d.ts b/types/controllers/LauncherController.d.ts index 789fc004..3a715dad 100644 --- a/types/controllers/LauncherController.d.ts +++ b/types/controllers/LauncherController.d.ts @@ -5,7 +5,7 @@ import { IChangeRequestData } from "@spt/models/eft/launcher/IChangeRequestData" import { ILoginRequestData } from "@spt/models/eft/launcher/ILoginRequestData"; import { IRegisterData } from "@spt/models/eft/launcher/IRegisterData"; import { IConnectResponse } from "@spt/models/eft/profile/IConnectResponse"; -import { Info, ModDetails } from "@spt/models/eft/profile/ISptProfile"; +import { IModDetails, Info } from "@spt/models/eft/profile/ISptProfile"; import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; import { IPackageJsonData } from "@spt/models/spt/mod/IPackageJsonData"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -61,5 +61,5 @@ export declare class LauncherController { * @param sessionId Player id * @returns Array of mod details */ - getServerModsProfileUsed(sessionId: string): ModDetails[]; + getServerModsProfileUsed(sessionId: string): IModDetails[]; } diff --git a/types/controllers/LocationController.d.ts b/types/controllers/LocationController.d.ts index a541b9ce..1321d63e 100644 --- a/types/controllers/LocationController.d.ts +++ b/types/controllers/LocationController.d.ts @@ -1,57 +1,20 @@ -import { ApplicationContext } from "@spt/context/ApplicationContext"; -import { LocationGenerator } from "@spt/generators/LocationGenerator"; -import { LootGenerator } from "@spt/generators/LootGenerator"; -import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; -import { ILocationBase } from "@spt/models/eft/common/ILocationBase"; import { ILocationsGenerateAllResponse } from "@spt/models/eft/common/ILocationsSourceDestinationBase"; -import { IAirdropLootResult } from "@spt/models/eft/location/IAirdropLootResult"; -import { IGetLocationRequestData } from "@spt/models/eft/location/IGetLocationRequestData"; -import { AirdropTypeEnum } from "@spt/models/enums/AirdropType"; -import { IAirdropConfig } from "@spt/models/spt/config/IAirdropConfig"; +import { IGetAirdropLootRequest } from "@spt/models/eft/location/IGetAirdropLootRequest"; +import { IGetAirdropLootResponse } from "@spt/models/eft/location/IGetAirdropLootResponse"; import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; -import { LootRequest } from "@spt/models/spt/services/LootRequest"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; +import { AirdropService } from "@spt/services/AirdropService"; import { DatabaseService } from "@spt/services/DatabaseService"; -import { ItemFilterService } from "@spt/services/ItemFilterService"; -import { LocalisationService } from "@spt/services/LocalisationService"; -import { RaidTimeAdjustmentService } from "@spt/services/RaidTimeAdjustmentService"; -import { HashUtil } from "@spt/utils/HashUtil"; -import { RandomUtil } from "@spt/utils/RandomUtil"; -import { TimeUtil } from "@spt/utils/TimeUtil"; import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class LocationController { - protected hashUtil: HashUtil; - protected randomUtil: RandomUtil; - protected weightedRandomHelper: WeightedRandomHelper; protected logger: ILogger; - protected locationGenerator: LocationGenerator; - protected localisationService: LocalisationService; - protected raidTimeAdjustmentService: RaidTimeAdjustmentService; - protected itemFilterService: ItemFilterService; - protected lootGenerator: LootGenerator; protected databaseService: DatabaseService; - protected timeUtil: TimeUtil; + protected airdropService: AirdropService; protected configServer: ConfigServer; - protected applicationContext: ApplicationContext; protected cloner: ICloner; - protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, itemFilterService: ItemFilterService, lootGenerator: LootGenerator, databaseService: DatabaseService, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext, cloner: ICloner); - /** - * Handle client/location/getLocalloot - * Get a location (map) with generated loot data - * @param sessionId Player id - * @param request Map request to generate - * @returns ILocationBase - */ - get(sessionId: string, request: IGetLocationRequestData): ILocationBase; - /** - * Generate a maps base location and loot - * @param name Map name - * @returns ILocationBase - */ - protected generate(name: string): ILocationBase; + constructor(logger: ILogger, databaseService: DatabaseService, airdropService: AirdropService, configServer: ConfigServer, cloner: ICloner); /** * Handle client/locations * Get all maps base location properties without loot data @@ -59,22 +22,6 @@ export declare class LocationController { * @returns ILocationsGenerateAllResponse */ generateAll(sessionId: string): ILocationsGenerateAllResponse; - /** - * Handle client/location/getAirdropLoot - * Get loot for an airdrop container - * Generates it randomly based on config/airdrop.json values - * @returns Array of LootItem objects - */ - getAirdropLoot(): IAirdropLootResult; - /** - * Randomly pick a type of airdrop loot using weighted values from config - * @returns airdrop type value - */ - protected chooseAirdropType(): AirdropTypeEnum; - /** - * Get the configuration for a specific type of airdrop - * @param airdropType Type of airdrop to get settings for - * @returns LootRequest - */ - protected getAirdropLootConfigByType(airdropType: AirdropTypeEnum): LootRequest; + /** Handle client/airdrop/loot */ + getAirdropLoot(request: IGetAirdropLootRequest): IGetAirdropLootResponse; } diff --git a/types/controllers/MatchController.d.ts b/types/controllers/MatchController.d.ts index c08ebb0f..7e6a34e7 100644 --- a/types/controllers/MatchController.d.ts +++ b/types/controllers/MatchController.d.ts @@ -1,50 +1,31 @@ import { ApplicationContext } from "@spt/context/ApplicationContext"; -import { LootGenerator } from "@spt/generators/LootGenerator"; -import { ProfileHelper } from "@spt/helpers/ProfileHelper"; -import { TraderHelper } from "@spt/helpers/TraderHelper"; -import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { IEndOfflineRaidRequestData } from "@spt/models/eft/match/IEndOfflineRaidRequestData"; +import { IEndLocalRaidRequestData } from "@spt/models/eft/match/IEndLocalRaidRequestData"; import { IGetRaidConfigurationRequestData } from "@spt/models/eft/match/IGetRaidConfigurationRequestData"; import { IMatchGroupStartGameRequest } from "@spt/models/eft/match/IMatchGroupStartGameRequest"; import { IMatchGroupStatusRequest } from "@spt/models/eft/match/IMatchGroupStatusRequest"; import { IMatchGroupStatusResponse } from "@spt/models/eft/match/IMatchGroupStatusResponse"; import { IProfileStatusResponse } from "@spt/models/eft/match/IProfileStatusResponse"; -import { IInRaidConfig } from "@spt/models/spt/config/IInRaidConfig"; +import { IStartLocalRaidRequestData } from "@spt/models/eft/match/IStartLocalRaidRequestData"; +import { IStartLocalRaidResponseData } from "@spt/models/eft/match/IStartLocalRaidResponseData"; import { IMatchConfig } from "@spt/models/spt/config/IMatchConfig"; import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; -import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; -import { BotGenerationCacheService } from "@spt/services/BotGenerationCacheService"; -import { BotLootCacheService } from "@spt/services/BotLootCacheService"; -import { MailSendService } from "@spt/services/MailSendService"; +import { LocationLifecycleService } from "@spt/services/LocationLifecycleService"; import { MatchLocationService } from "@spt/services/MatchLocationService"; -import { ProfileSnapshotService } from "@spt/services/ProfileSnapshotService"; -import { HashUtil } from "@spt/utils/HashUtil"; -import { RandomUtil } from "@spt/utils/RandomUtil"; -import { TimeUtil } from "@spt/utils/TimeUtil"; +import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class MatchController { protected logger: ILogger; protected saveServer: SaveServer; - protected timeUtil: TimeUtil; - protected randomUtil: RandomUtil; - protected hashUtil: HashUtil; - protected profileHelper: ProfileHelper; protected matchLocationService: MatchLocationService; - protected traderHelper: TraderHelper; - protected botLootCacheService: BotLootCacheService; protected configServer: ConfigServer; - protected profileSnapshotService: ProfileSnapshotService; - protected botGenerationCacheService: BotGenerationCacheService; - protected mailSendService: MailSendService; - protected lootGenerator: LootGenerator; protected applicationContext: ApplicationContext; + protected locationLifecycleService: LocationLifecycleService; + protected cloner: ICloner; protected matchConfig: IMatchConfig; - protected inRaidConfig: IInRaidConfig; - protected traderConfig: ITraderConfig; protected pmcConfig: IPmcConfig; - constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, randomUtil: RandomUtil, hashUtil: HashUtil, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, mailSendService: MailSendService, lootGenerator: LootGenerator, applicationContext: ApplicationContext); + constructor(logger: ILogger, saveServer: SaveServer, matchLocationService: MatchLocationService, configServer: ConfigServer, applicationContext: ApplicationContext, locationLifecycleService: LocationLifecycleService, cloner: ICloner); getEnabled(): boolean; /** Handle client/match/group/delete */ deleteGroup(info: any): void; @@ -57,48 +38,15 @@ export declare class MatchController { * @param request Raid config request * @param sessionID Session id */ - startOfflineRaid(request: IGetRaidConfigurationRequestData, sessionID: string): void; + configureOfflineRaid(request: IGetRaidConfigurationRequestData, sessionID: string): void; /** * Convert a difficulty value from pre-raid screen to a bot difficulty * @param botDifficulty dropdown difficulty value * @returns bot difficulty */ protected convertDifficultyDropdownIntoBotDifficulty(botDifficulty: string): string; - /** Handle client/match/offline/end */ - endOfflineRaid(info: IEndOfflineRaidRequestData, sessionId: string): void; - /** - * Did player take a COOP extract - * @param extractName Name of extract player took - * @returns True if coop extract - */ - protected extractWasViaCoop(extractName: string): boolean; - protected sendCoopTakenFenceMessage(sessionId: string): void; - /** - * Handle when a player extracts using a coop extract - add rep to fence - * @param sessionId Session/player id - * @param pmcData Profile - * @param extractName Name of extract taken - */ - protected handleCoopExtract(sessionId: string, pmcData: IPmcData, extractName: string): void; - /** - * Was extract by car - * @param extractName name of extract - * @returns true if car extract - */ - protected extractWasViaCar(extractName: string): boolean; - /** - * Handle when a player extracts using a car - Add rep to fence - * @param extractName name of the extract used - * @param pmcData Player profile - * @param sessionId Session id - */ - protected handleCarExtract(extractName: string, pmcData: IPmcData, sessionId: string): void; - /** - * Get the fence rep gain from using a car or coop extract - * @param pmcData Profile - * @param baseGain amount gained for the first extract - * @param extractCount Number of times extract was taken - * @returns Fence standing after taking extract - */ - protected getFenceStandingAfterExtract(pmcData: IPmcData, baseGain: number, extractCount: number): number; + /** Handle client/match/local/start */ + startLocalRaid(sessionId: string, request: IStartLocalRaidRequestData): IStartLocalRaidResponseData; + /** Handle client/match/local/end */ + endLocalRaid(sessionId: string, request: IEndLocalRaidRequestData): void; } diff --git a/types/controllers/ProfileController.d.ts b/types/controllers/ProfileController.d.ts index 7e6d35c1..71fd9e6e 100644 --- a/types/controllers/ProfileController.d.ts +++ b/types/controllers/ProfileController.d.ts @@ -7,7 +7,7 @@ import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { IMiniProfile } from "@spt/models/eft/launcher/IMiniProfile"; -import { GetProfileStatusResponseData } from "@spt/models/eft/profile/GetProfileStatusResponseData"; +import { IGetProfileStatusResponseData } from "@spt/models/eft/profile/GetProfileStatusResponseData"; import { IGetOtherProfileRequest } from "@spt/models/eft/profile/IGetOtherProfileRequest"; import { IGetOtherProfileResponse } from "@spt/models/eft/profile/IGetOtherProfileResponse"; import { IGetProfileSettingsRequest } from "@spt/models/eft/profile/IGetProfileSettingsRequest"; @@ -117,7 +117,7 @@ export declare class ProfileController { /** * Handle client/profile/status */ - getProfileStatus(sessionId: string): GetProfileStatusResponseData; + getProfileStatus(sessionId: string): IGetProfileStatusResponseData; getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/types/controllers/QuestController.d.ts b/types/controllers/QuestController.d.ts index 6a5b415a..ac486e38 100644 --- a/types/controllers/QuestController.d.ts +++ b/types/controllers/QuestController.d.ts @@ -5,8 +5,7 @@ import { QuestConditionHelper } from "@spt/helpers/QuestConditionHelper"; import { QuestHelper } from "@spt/helpers/QuestHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { IQuestStatus } from "@spt/models/eft/common/tables/IBotBase"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IQuest, IQuestCondition } from "@spt/models/eft/common/tables/IQuest"; import { IRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; @@ -54,13 +53,6 @@ export declare class QuestController { * @returns array of IQuest */ getClientQuests(sessionID: string): IQuest[]; - /** - * Does a provided quest have a level requirement equal to or below defined level - * @param quest Quest to check - * @param playerLevel level of player to test against quest - * @returns true if quest can be seen/accepted by player of defined level - */ - protected playerLevelFulfillsQuestRequirement(quest: IQuest, playerLevel: number): boolean; /** * Handle QuestAccept event * Handle the client accepting a quest and starting it @@ -72,6 +64,13 @@ export declare class QuestController { * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; + /** + * + * @param questConditions Conditions to iterate over and possibly add to profile + * @param pmcData Profile to add to + * @param questId Quest conditions came from + */ + protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void; /** * Handle the client accepting a repeatable quest and starting it * Send starting rewards if any to player and @@ -101,49 +100,6 @@ export declare class QuestController { * @returns ItemEvent client response */ completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse; - /** - * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects - */ - protected getQuestsFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; - /** - * Remove a quest entirely from a profile - * @param sessionId Player id - * @param questIdToRemove Qid of quest to remove - */ - protected removeQuestFromScavProfile(sessionId: string, questIdToRemove: string): void; - /** - * Return quests that have different statuses - * @param preQuestStatusus Quests before - * @param postQuestStatuses Quests after - * @returns QuestStatusChange array - */ - protected getQuestsWithDifferentStatuses(preQuestStatusus: IQuestStatus[], postQuestStatuses: IQuestStatus[]): IQuestStatus[] | undefined; - /** - * Send a popup to player on successful completion of a quest - * @param sessionID session id - * @param pmcData Player profile - * @param completedQuestId Completed quest id - * @param questRewards Rewards given to player - */ - protected sendSuccessDialogMessageOnQuestComplete(sessionID: string, pmcData: IPmcData, completedQuestId: string, questRewards: Item[]): void; - /** - * Look for newly available quests after completing a quest with a requirement to wait x minutes (time-locked) before being available and add data to profile - * @param pmcData Player profile to update - * @param quests Quests to look for wait conditions in - * @param completedQuestId Quest just completed - */ - protected addTimeLockedQuestsToProfile(pmcData: IPmcData, quests: IQuest[], completedQuestId: string): void; - /** - * Fail the provided quests - * Update quest in profile, otherwise add fresh quest object with failed status - * @param sessionID session id - * @param pmcData player profile - * @param questsToFail quests to fail - * @param output Client output - */ - protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[], output: IItemEventRouterResponse): void; /** * Handle QuestHandover event * @param pmcData Player profile @@ -167,7 +123,7 @@ export declare class QuestController { * @param output Response to send to user * @returns IItemEventRouterResponse */ - protected showQuestItemHandoverMatchError(handoverQuestRequest: IHandoverQuestRequestData, itemHandedOver: Item, handoverRequirements: IQuestCondition, output: IItemEventRouterResponse): IItemEventRouterResponse; + protected showQuestItemHandoverMatchError(handoverQuestRequest: IHandoverQuestRequestData, itemHandedOver: IItem, handoverRequirements: IQuestCondition, output: IItemEventRouterResponse): IItemEventRouterResponse; /** * Increment a backend counter stored value by an amount, * Create counter if it does not exist diff --git a/types/controllers/RagfairController.d.ts b/types/controllers/RagfairController.d.ts index fbd25e0d..978558bc 100644 --- a/types/controllers/RagfairController.d.ts +++ b/types/controllers/RagfairController.d.ts @@ -10,11 +10,11 @@ import { RagfairSellHelper } from "@spt/helpers/RagfairSellHelper"; import { RagfairSortHelper } from "@spt/helpers/RagfairSortHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITraderAssort } from "@spt/models/eft/common/tables/ITrader"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; -import { IAddOfferRequestData, Requirement } from "@spt/models/eft/ragfair/IAddOfferRequestData"; +import { IAddOfferRequestData, IRequirement } from "@spt/models/eft/ragfair/IAddOfferRequestData"; import { IExtendOfferRequestData } from "@spt/models/eft/ragfair/IExtendOfferRequestData"; import { IGetItemPriceResult } from "@spt/models/eft/ragfair/IGetItemPriceResult"; import { IGetMarketPriceRequestData } from "@spt/models/eft/ragfair/IGetMarketPriceRequestData"; @@ -137,10 +137,11 @@ export declare class RagfairController { update(): void; /** * Called when creating an offer on flea, fills values in top right corner - * @param getPriceRequest + * @param getPriceRequest Client request object + * @param ignoreTraderOffers Should trader offers be ignored in the calcualtion * @returns min/avg/max values for an item based on flea offers available */ - getItemMinAvgMaxFleaPriceValues(getPriceRequest: IGetMarketPriceRequestData): IGetItemPriceResult; + getItemMinAvgMaxFleaPriceValues(getPriceRequest: IGetMarketPriceRequestData, ignoreTraderOffers?: boolean): IGetItemPriceResult; /** * List item(s) on flea for sale * @param pmcData Player profile @@ -199,7 +200,7 @@ export declare class RagfairController { * @param output IItemEventRouterResponse * @returns True if charging tax to player failed */ - protected chargePlayerTaxFee(sessionID: string, rootItem: Item, pmcData: IPmcData, requirementsPriceInRub: number, itemStackCount: number, offerRequest: IAddOfferRequestData, output: IItemEventRouterResponse): boolean; + protected chargePlayerTaxFee(sessionID: string, rootItem: IItem, pmcData: IPmcData, requirementsPriceInRub: number, itemStackCount: number, offerRequest: IAddOfferRequestData, output: IItemEventRouterResponse): boolean; /** * Is the item to be listed on the flea valid * @param offerRequest Client offer request @@ -212,7 +213,7 @@ export declare class RagfairController { * @param requirements * @returns Rouble price */ - protected calculateRequirementsPriceInRub(requirements: Requirement[]): number; + protected calculateRequirementsPriceInRub(requirements: IRequirement[]): number; /** * Using item ids from flea offer request, find corresponding items from player inventory and return as array * @param pmcData Player profile @@ -220,10 +221,10 @@ export declare class RagfairController { * @returns Array of items from player inventory */ protected getItemsToListOnFleaFromInventory(pmcData: IPmcData, itemIdsFromFleaOfferRequest: string[]): { - items: Item[][] | undefined; + items: IItem[][] | undefined; errorMessage: string | undefined; }; - createPlayerOffer(sessionId: string, requirements: Requirement[], items: Item[], sellInOnePiece: boolean): IRagfairOffer; + createPlayerOffer(sessionId: string, requirements: IRequirement[], items: IItem[], sellInOnePiece: boolean): IRagfairOffer; getAllFleaPrices(): Record; getStaticPrices(): Record; /** diff --git a/types/controllers/RepeatableQuestController.d.ts b/types/controllers/RepeatableQuestController.d.ts index 2d715c4d..016f8c61 100644 --- a/types/controllers/RepeatableQuestController.d.ts +++ b/types/controllers/RepeatableQuestController.d.ts @@ -24,23 +24,23 @@ import { RandomUtil } from "@spt/utils/RandomUtil"; import { TimeUtil } from "@spt/utils/TimeUtil"; import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class RepeatableQuestController { - public logger: ILogger; + protected logger: ILogger; protected databaseService: DatabaseService; - public timeUtil: TimeUtil; - public randomUtil: RandomUtil; + protected timeUtil: TimeUtil; + protected randomUtil: RandomUtil; protected httpResponse: HttpResponseUtil; - public profileHelper: ProfileHelper; + protected profileHelper: ProfileHelper; protected profileFixerService: ProfileFixerService; protected localisationService: LocalisationService; protected eventOutputHolder: EventOutputHolder; protected paymentService: PaymentService; protected objectId: ObjectId; - public repeatableQuestGenerator: RepeatableQuestGenerator; + protected repeatableQuestGenerator: RepeatableQuestGenerator; protected repeatableQuestHelper: RepeatableQuestHelper; protected questHelper: QuestHelper; protected configServer: ConfigServer; protected cloner: ICloner; - public questConfig: IQuestConfig; + protected questConfig: IQuestConfig; constructor(logger: ILogger, databaseService: DatabaseService, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer, cloner: ICloner); /** * Handle client/repeatalbeQuests/activityPeriods @@ -73,14 +73,14 @@ export declare class RepeatableQuestController { * @param generatedRepeatables Repeatables to process (daily/weekly) * @param pmcData Player profile */ - public processExpiredQuests(generatedRepeatables: IPmcDataRepeatableQuest, pmcData: IPmcData): void; + protected processExpiredQuests(generatedRepeatables: IPmcDataRepeatableQuest, pmcData: IPmcData): void; /** * Check if a repeatable quest type (daily/weekly) is active for the given profile * @param repeatableConfig Repeatable quest config * @param pmcData Player profile * @returns True if profile is allowed to access dailies */ - public canProfileAccessRepeatableQuests(repeatableConfig: IRepeatableQuestConfig, pmcData: IPmcData): boolean; + protected canProfileAccessRepeatableQuests(repeatableConfig: IRepeatableQuestConfig, pmcData: IPmcData): boolean; /** * Does player have daily scav quests unlocked * @param pmcData Player profile to check @@ -100,14 +100,14 @@ export declare class RepeatableQuestController { * @param pmcData Player profile * @returns Quest count */ - public getQuestCount(repeatableConfig: IRepeatableQuestConfig, pmcData: IPmcData): number; + protected getQuestCount(repeatableConfig: IRepeatableQuestConfig, pmcData: IPmcData): number; /** * Get repeatable quest data from profile from name (daily/weekly), creates base repeatable quest object if none exists * @param repeatableConfig daily/weekly config * @param pmcData Profile to search * @returns IPmcDataRepeatableQuest */ - public getRepeatableQuestSubTypeFromProfile(repeatableConfig: IRepeatableQuestConfig, pmcData: IPmcData): IPmcDataRepeatableQuest; + protected getRepeatableQuestSubTypeFromProfile(repeatableConfig: IRepeatableQuestConfig, pmcData: IPmcData): IPmcDataRepeatableQuest; /** * Just for debug reasons. Draws dailies a random assort of dailies extracted from dumps */ @@ -120,7 +120,7 @@ export declare class RepeatableQuestController { * @param pmcLevel level of pmc generating quest pool * @returns IQuestTypePool */ - public generateQuestPool(repeatableConfig: IRepeatableQuestConfig, pmcLevel: number): IQuestTypePool; + protected generateQuestPool(repeatableConfig: IRepeatableQuestConfig, pmcLevel: number): IQuestTypePool; protected createBaseQuestPool(repeatableConfig: IRepeatableQuestConfig): IQuestTypePool; /** * Return the locations this PMC is allowed to get daily quests for based on their level diff --git a/types/controllers/TradeController.d.ts b/types/controllers/TradeController.d.ts index 842a97b4..517446a4 100644 --- a/types/controllers/TradeController.d.ts +++ b/types/controllers/TradeController.d.ts @@ -4,7 +4,7 @@ import { RagfairOfferHelper } from "@spt/helpers/RagfairOfferHelper"; import { TradeHelper } from "@spt/helpers/TradeHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITraderBase } from "@spt/models/eft/common/tables/ITrader"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; @@ -101,5 +101,5 @@ export declare class TradeController { * @param traderDetails Trader being sold to to perform buy category check against * @returns Rouble price */ - protected getPriceOfItemAndChildren(parentItemId: string, items: Item[], handbookPrices: Record, traderDetails: ITraderBase): number; + protected getPriceOfItemAndChildren(parentItemId: string, items: IItem[], handbookPrices: Record, traderDetails: ITraderBase): number; } diff --git a/types/controllers/TraderController.d.ts b/types/controllers/TraderController.d.ts index 3592fc66..bdc9b512 100644 --- a/types/controllers/TraderController.d.ts +++ b/types/controllers/TraderController.d.ts @@ -3,11 +3,13 @@ import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderAssortHelper } from "@spt/helpers/TraderAssortHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { ITraderAssort, ITraderBase } from "@spt/models/eft/common/tables/ITrader"; +import { IGetItemPricesResponse } from "@spt/models/eft/game/IGetItemPricesResponse"; import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { DatabaseService } from "@spt/services/DatabaseService"; import { FenceService } from "@spt/services/FenceService"; +import { RagfairPriceService } from "@spt/services/RagfairPriceService"; import { TraderAssortService } from "@spt/services/TraderAssortService"; import { TraderPurchasePersisterService } from "@spt/services/TraderPurchasePersisterService"; import { TimeUtil } from "@spt/utils/TimeUtil"; @@ -20,13 +22,14 @@ export declare class TraderController { protected profileHelper: ProfileHelper; protected traderHelper: TraderHelper; protected traderAssortService: TraderAssortService; + protected ragfairPriceService: RagfairPriceService; protected traderPurchasePersisterService: TraderPurchasePersisterService; protected fenceService: FenceService; protected fenceBaseAssortGenerator: FenceBaseAssortGenerator; protected configServer: ConfigServer; protected cloner: ICloner; protected traderConfig: ITraderConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, databaseService: DatabaseService, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, timeUtil: TimeUtil, databaseService: DatabaseService, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, ragfairPriceService: RagfairPriceService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, configServer: ConfigServer, cloner: ICloner); /** * Runs when onLoad event is fired * Iterate over traders, ensure a pristine copy of their assorts is stored in traderAssortService @@ -58,4 +61,6 @@ export declare class TraderController { getTrader(sessionID: string, traderID: string): ITraderBase; /** Handle client/trading/api/getTraderAssort */ getAssort(sessionId: string, traderId: string): ITraderAssort; + /** Handle client/items/prices/TRADERID */ + getItemPrices(sessionId: string, traderId: string): IGetItemPricesResponse; } diff --git a/types/controllers/WeatherController.d.ts b/types/controllers/WeatherController.d.ts index 7d24954c..7cf71a62 100644 --- a/types/controllers/WeatherController.d.ts +++ b/types/controllers/WeatherController.d.ts @@ -1,19 +1,23 @@ import { WeatherGenerator } from "@spt/generators/WeatherGenerator"; +import { WeatherHelper } from "@spt/helpers/WeatherHelper"; import { IWeatherData } from "@spt/models/eft/weather/IWeatherData"; import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { IGetLocalWeatherResponseData } from "@spt/models/spt/weather/IGetLocalWeatherResponseData"; import { ConfigServer } from "@spt/servers/ConfigServer"; +import { RaidWeatherService } from "@spt/services/RaidWeatherService"; +import { SeasonalEventService } from "@spt/services/SeasonalEventService"; export declare class WeatherController { protected weatherGenerator: WeatherGenerator; protected logger: ILogger; protected configServer: ConfigServer; + protected seasonalEventService: SeasonalEventService; + protected raidWeatherService: RaidWeatherService; + protected weatherHelper: WeatherHelper; protected weatherConfig: IWeatherConfig; - constructor(weatherGenerator: WeatherGenerator, logger: ILogger, configServer: ConfigServer); + constructor(weatherGenerator: WeatherGenerator, logger: ILogger, configServer: ConfigServer, seasonalEventService: SeasonalEventService, raidWeatherService: RaidWeatherService, weatherHelper: WeatherHelper); /** Handle client/weather */ generate(): IWeatherData; - /** - * Get the current in-raid time (MUST HAVE PLAYER LOGGED INTO CLIENT TO WORK) - * @returns Date object - */ - getCurrentInRaidTime(): Date; + /** Handle client/localGame/weather */ + generateLocal(sesssionId: string): IGetLocalWeatherResponseData; } diff --git a/types/controllers/WishlistController.d.ts b/types/controllers/WishlistController.d.ts index ee4d970e..7559dc66 100644 --- a/types/controllers/WishlistController.d.ts +++ b/types/controllers/WishlistController.d.ts @@ -1,12 +1,16 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IWishlistActionData } from "@spt/models/eft/wishlist/IWishlistActionData"; +import { IAddToWishlistRequest } from "@spt/models/eft/wishlist/IAddToWishlistRequest"; +import { IChangeWishlistItemCategoryRequest } from "@spt/models/eft/wishlist/IChangeWishlistItemCategoryRequest"; +import { IRemoveFromWishlistRequest } from "@spt/models/eft/wishlist/IRemoveFromWishlistRequest"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; export declare class WishlistController { protected eventOutputHolder: EventOutputHolder; constructor(eventOutputHolder: EventOutputHolder); /** Handle AddToWishList */ - addToWishList(pmcData: IPmcData, body: IWishlistActionData, sessionID: string): IItemEventRouterResponse; + addToWishList(pmcData: IPmcData, request: IAddToWishlistRequest, sessionID: string): IItemEventRouterResponse; /** Handle RemoveFromWishList event */ - removeFromWishList(pmcData: IPmcData, body: IWishlistActionData, sessionID: string): IItemEventRouterResponse; + removeFromWishList(pmcData: IPmcData, request: IRemoveFromWishlistRequest, sessionID: string): IItemEventRouterResponse; + /** Handle changeWishlistItemCategory event */ + changeWishlistItemCategory(pmcData: IPmcData, request: IChangeWishlistItemCategoryRequest, sessionID: string): IItemEventRouterResponse; } diff --git a/types/di/Serializer.d.ts b/types/di/Serializer.d.ts index b760b8bf..a48dd584 100644 --- a/types/di/Serializer.d.ts +++ b/types/di/Serializer.d.ts @@ -1,6 +1,5 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; export declare class Serializer { - serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void; + serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise; canHandle(something: string): boolean; } diff --git a/types/generators/BotEquipmentModGenerator.d.ts b/types/generators/BotEquipmentModGenerator.d.ts index 3952293f..40c361f0 100644 --- a/types/generators/BotEquipmentModGenerator.d.ts +++ b/types/generators/BotEquipmentModGenerator.d.ts @@ -7,16 +7,17 @@ import { ProbabilityHelper } from "@spt/helpers/ProbabilityHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { IPreset } from "@spt/models/eft/common/IGlobals"; -import { Mods, ModsChances } from "@spt/models/eft/common/tables/IBotType"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { ITemplateItem, Slot } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IMods, IModsChances } from "@spt/models/eft/common/tables/IBotType"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { ISlot, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { ModSpawn } from "@spt/models/enums/ModSpawn"; import { IChooseRandomCompatibleModResult } from "@spt/models/spt/bots/IChooseRandomCompatibleModResult"; import { IFilterPlateModsForSlotByLevelResult } from "@spt/models/spt/bots/IFilterPlateModsForSlotByLevelResult"; import { IGenerateEquipmentProperties } from "@spt/models/spt/bots/IGenerateEquipmentProperties"; import { IGenerateWeaponRequest } from "@spt/models/spt/bots/IGenerateWeaponRequest"; import { IModToSpawnRequest } from "@spt/models/spt/bots/IModToSpawnRequest"; -import { EquipmentFilterDetails, EquipmentFilters, IBotConfig } from "@spt/models/spt/config/IBotConfig"; +import { EquipmentFilters, IBotConfig, IEquipmentFilterDetails } from "@spt/models/spt/config/IBotConfig"; +import { ExhaustableArray } from "@spt/models/spt/server/ExhaustableArray"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService"; @@ -55,11 +56,12 @@ export declare class BotEquipmentModGenerator { * @param equipment Equipment item to add mods to * @param modPool Mod list to choose frm * @param parentId parentid of item to add mod to - * @param parentTemplate template objet of item to add mods to + * @param parentTemplate Template object of item to add mods to + * @param specificBlacklist The relevant blacklist from bot.json equipment dictionary * @param forceSpawn should this mod be forced to spawn * @returns Item + compatible mods as an array */ - generateModsForEquipment(equipment: Item[], parentId: string, parentTemplate: ITemplateItem, settings: IGenerateEquipmentProperties, shouldForceSpawn?: boolean): Item[]; + generateModsForEquipment(equipment: IItem[], parentId: string, parentTemplate: ITemplateItem, settings: IGenerateEquipmentProperties, specificBlacklist: IEquipmentFilterDetails, shouldForceSpawn?: boolean): IItem[]; /** * Filter a bots plate pool based on its current level * @param settings Bot equipment generation settings @@ -75,7 +77,15 @@ export declare class BotEquipmentModGenerator { * @param request Data used to generate the weapon * @returns Weapon + mods array */ - generateModsForWeapon(sessionId: string, request: IGenerateWeaponRequest): Item[]; + generateModsForWeapon(sessionId: string, request: IGenerateWeaponRequest): IItem[]; + /** + * Should the provided bot have its stock chance values altered to 100% + * @param modSlot Slot to check + * @param botEquipConfig Bots equipment config/chance values + * @param modToAddTemplate Mod being added to bots weapon + * @returns True if it should + */ + protected shouldForceSubStockSlots(modSlot: string, botEquipConfig: EquipmentFilters, modToAddTemplate: ITemplateItem): boolean; /** * Is this modslot a front or rear sight * @param modSlot Slot to check @@ -93,7 +103,7 @@ export declare class BotEquipmentModGenerator { * Set mod spawn chances to defined amount * @param modSpawnChances Chance dictionary to update */ - protected adjustSlotSpawnChances(modSpawnChances: ModsChances, modSlotsToAdjust: string[], newChancePercent: number): void; + protected adjustSlotSpawnChances(modSpawnChances: IModsChances, modSlotsToAdjust: string[], newChancePercent: number): void; /** * Does the provided modSlot allow muzzle-related items * @param modSlot Slot id to check @@ -113,16 +123,16 @@ export declare class BotEquipmentModGenerator { * @param parentTemplate item template * @returns Slot item */ - protected getModItemSlotFromDb(modSlot: string, parentTemplate: ITemplateItem): Slot; + protected getModItemSlotFromDb(modSlot: string, parentTemplate: ITemplateItem): ISlot; /** * Randomly choose if a mod should be spawned, 100% for required mods OR mod is ammo slot - * @param itemSlot slot the item sits in - * @param modSlot slot the mod sits in + * @param itemSlot slot the item sits in from db + * @param modSlotName Name of slot the mod sits in * @param modSpawnChances Chances for various mod spawns * @param botEquipConfig Various config settings for generating this type of bot * @returns ModSpawn.SPAWN when mod should be spawned, ModSpawn.DEFAULT_MOD when default mod should spawn, ModSpawn.SKIP when mod is skipped */ - protected shouldModBeSpawned(itemSlot: Slot, modSlot: string, modSpawnChances: ModsChances, botEquipConfig: EquipmentFilters): ModSpawn; + protected shouldModBeSpawned(itemSlot: ISlot, modSlotName: string, modSpawnChances: IModsChances, botEquipConfig: EquipmentFilters): ModSpawn; /** * Choose a mod to fit into the desired slot * @param request Data used to choose an appropriate mod with @@ -130,7 +140,15 @@ export declare class BotEquipmentModGenerator { */ protected chooseModToPutIntoSlot(request: IModToSpawnRequest): [boolean, ITemplateItem] | undefined; /** - * + * Given the passed in array of magaizne tpls, look up the min size set in config and return only those that have that size or larger + * @param modSpawnRequest Request data + * @param modPool Pool of magazine tpls to filter + * @returns Filtered pool of magazine tpls + */ + protected getFilterdMagazinePoolByCapacity(modSpawnRequest: IModToSpawnRequest, modPool: string[]): string[]; + /** + * Choose a weapon mod tpl for a given slot from a pool of choices + * Checks chosen tpl is compatible with all existing weapon items * @param modPool Pool of mods that can be picked from * @param parentSlot Slot the picked mod will have as a parent * @param choiceTypeEnum How should chosen tpl be treated: DEFAULT_MOD/SPAWN/SKIP @@ -138,22 +156,36 @@ export declare class BotEquipmentModGenerator { * @param modSlotName Name of slot picked mod will be placed into * @returns Chosen weapon details */ - protected pickWeaponModTplForSlotFromPool(modPool: string[], parentSlot: Slot, choiceTypeEnum: ModSpawn, weapon: Item[], modSlotName: string): IChooseRandomCompatibleModResult; + protected getCompatibleWeaponModTplForSlotFromPool(request: IModToSpawnRequest, modPool: string[], parentSlot: ISlot, choiceTypeEnum: ModSpawn, weapon: IItem[], modSlotName: string): IChooseRandomCompatibleModResult; + /** + * + * @param modPool Pool of item Tpls to choose from + * @param modSpawnType How should the slot choice be handled - forced/normal etc + * @param weapon Weapon mods at current time + * @param modSlotName Name of mod slot being filled + * @returns IChooseRandomCompatibleModResult + */ + protected getCompatibleModFromPool(modPool: string[], modSpawnType: ModSpawn, weapon: IItem[]): IChooseRandomCompatibleModResult; + protected createExhaustableArray(itemsToAddToArray: T[]): ExhaustableArray; + /** + * Get a list of mod tpls that are compatible with the current weapon + * @param modPool + * @param tplBlacklist Tpls that are incompatible and should not be used + * @returns string array of compatible mod tpls with weapon + */ + protected getFilteredModPool(modPool: string[], tplBlacklist: Set): string[]; /** * Filter mod pool down based on various criteria: * Is slot flagged as randomisable * Is slot required * Is slot flagged as default mod only - * @param itemModPool Existing pool of mods to choose - * @param itemSpawnCategory How should slot be handled - * @param parentTemplate Mods parent + * @param request * @param weaponTemplate Mods root parent (weapon/equipment) - * @param modSlot name of mod slot to choose for - * @param botEquipBlacklist A blacklist of items not allowed to be picked - * @param isRandomisableSlot Slot is flagged as a randomisable slot * @returns Array of mod tpls */ - protected getModPoolForSlot(itemModPool: Record, itemSpawnCategory: ModSpawn, parentTemplate: ITemplateItem, weaponTemplate: ITemplateItem, modSlot: string, botEquipBlacklist: EquipmentFilterDetails, isRandomisableSlot: boolean): string[]; + protected getModPoolForSlot(request: IModToSpawnRequest, weaponTemplate: ITemplateItem): string[]; + protected getModPoolForDefaultSlot(request: IModToSpawnRequest, weaponTemplate: ITemplateItem): string[]; + protected getMatchingModFromPreset(request: IModToSpawnRequest, weaponTemplate: ITemplateItem): IItem; /** * Get default preset for weapon OR get specific weapon presets for edge cases (mp5/silenced dvl) * @param weaponTemplate Weapons db template @@ -167,7 +199,7 @@ export declare class BotEquipmentModGenerator { * @param modTpl Mod to check compatibility with weapon * @returns True if incompatible */ - protected weaponModComboIsIncompatible(weapon: Item[], modTpl: string): boolean; + protected weaponModComboIsIncompatible(weapon: IItem[], modTpl: string): boolean; /** * Create a mod item with provided parameters as properties + add upd property * @param modId _id @@ -178,7 +210,7 @@ export declare class BotEquipmentModGenerator { * @param botRole The bots role mod is being created for * @returns Item object */ - protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem, botRole: string): Item; + protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem, botRole: string): IItem; /** * Get a list of containers that hold ammo * e.g. mod_magazine / patron_in_weapon_000 @@ -193,7 +225,7 @@ export declare class BotEquipmentModGenerator { * @param items Items to ensure picked mod is compatible with * @returns Item tpl */ - protected getRandomModTplFromItemDb(fallbackModTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string | undefined; + protected getRandomModTplFromItemDb(fallbackModTpl: string, parentSlot: ISlot, modSlot: string, items: IItem[]): string | undefined; /** * Check if mod exists in db + is for a required slot * @param modToAdd Db template of mod to check @@ -203,7 +235,7 @@ export declare class BotEquipmentModGenerator { * @param botRole Bots wildspawntype (assault/pmcBot/exUsec etc) * @returns True if valid for slot */ - protected isModValidForSlot(modToAdd: [boolean, ITemplateItem], slotAddedToTemplate: Slot, modSlot: string, parentTemplate: ITemplateItem, botRole: string): boolean; + protected isModValidForSlot(modToAdd: [boolean, ITemplateItem], slotAddedToTemplate: ISlot, modSlot: string, parentTemplate: ITemplateItem, botRole: string): boolean; /** * Find mod tpls of a provided type and add to modPool * @param desiredSlotName Slot to look up and add we are adding tpls for (e.g mod_scope) @@ -211,7 +243,7 @@ export declare class BotEquipmentModGenerator { * @param modPool Pool of mods we are adding to * @param botEquipBlacklist A blacklist of items that cannot be picked */ - protected addCompatibleModsForProvidedMod(desiredSlotName: string, modTemplate: ITemplateItem, modPool: Mods, botEquipBlacklist: EquipmentFilterDetails): void; + protected addCompatibleModsForProvidedMod(desiredSlotName: string, modTemplate: ITemplateItem, modPool: IMods, botEquipBlacklist: IEquipmentFilterDetails): void; /** * Get the possible items that fit a slot * @param parentItemId item tpl to get compatible items for @@ -219,7 +251,7 @@ export declare class BotEquipmentModGenerator { * @param botEquipBlacklist Equipment that should not be picked * @returns Array of compatible items for that slot */ - protected getDynamicModPool(parentItemId: string, modSlot: string, botEquipBlacklist: EquipmentFilterDetails): string[]; + protected getDynamicModPool(parentItemId: string, modSlot: string, botEquipBlacklist: IEquipmentFilterDetails): string[]; /** * Take a list of tpls and filter out blacklisted values using itemFilterService + botEquipmentBlacklist * @param allowedMods Base mods to filter @@ -227,7 +259,7 @@ export declare class BotEquipmentModGenerator { * @param modSlot Slot mods belong to * @returns Filtered array of mod tpls */ - protected filterWeaponModsByBlacklist(allowedMods: string[], botEquipBlacklist: EquipmentFilterDetails, modSlot: string): string[]; + protected filterModsByBlacklist(allowedMods: string[], botEquipBlacklist: IEquipmentFilterDetails, modSlot: string): string[]; /** * With the shotgun revolver (60db29ce99594040e04c4a27) 12.12 introduced CylinderMagazines. * Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0. @@ -238,7 +270,7 @@ export declare class BotEquipmentModGenerator { * @param cylinderMagParentId The CylinderMagazine's UID * @param cylinderMagTemplate The CylinderMagazine's template */ - protected fillCamora(items: Item[], modPool: Mods, cylinderMagParentId: string, cylinderMagTemplate: ITemplateItem): void; + protected fillCamora(items: IItem[], modPool: IMods, cylinderMagParentId: string, cylinderMagTemplate: ITemplateItem): void; /** * Take a record of camoras and merge the compatible shells into one array * @param camorasWithShells Dictionary of camoras we want to merge into one array @@ -254,5 +286,5 @@ export declare class BotEquipmentModGenerator { * @param botWeaponSightWhitelist Whitelist of scope types by weapon base type * @returns Array of scope tpls that have been filtered to just ones allowed for that weapon type */ - protected filterSightsByWeaponType(weapon: Item, scopes: string[], botWeaponSightWhitelist: Record): string[]; + protected filterSightsByWeaponType(weapon: IItem, scopes: string[], botWeaponSightWhitelist: Record): string[]; } diff --git a/types/generators/BotGenerator.d.ts b/types/generators/BotGenerator.d.ts index ebb8a599..2c7bba68 100644 --- a/types/generators/BotGenerator.d.ts +++ b/types/generators/BotGenerator.d.ts @@ -1,20 +1,21 @@ import { BotInventoryGenerator } from "@spt/generators/BotInventoryGenerator"; import { BotLevelGenerator } from "@spt/generators/BotLevelGenerator"; -import { BotDifficultyHelper } from "@spt/helpers/BotDifficultyHelper"; +import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper"; import { BotHelper } from "@spt/helpers/BotHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; -import { IBaseJsonSkills, IBaseSkill, IBotBase, Info, Health as PmcHealth, Skills as botSkills } from "@spt/models/eft/common/tables/IBotBase"; -import { Appearance, Health, IBotType, Inventory } from "@spt/models/eft/common/tables/IBotType"; -import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; +import { MinMax } from "@spt/models/common/MinMax"; +import { IBaseJsonSkills, IBaseSkill, IBotBase, IInfo, IHealth as PmcHealth, ISkills as botSkills } from "@spt/models/eft/common/tables/IBotBase"; +import { IAppearance, IBodyPart, IBotType, IHealth, IInventory } from "@spt/models/eft/common/tables/IBotType"; +import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService"; +import { BotNameService } from "@spt/services/BotNameService"; import { DatabaseService } from "@spt/services/DatabaseService"; import { ItemFilterService } from "@spt/services/ItemFilterService"; -import { LocalisationService } from "@spt/services/LocalisationService"; import { SeasonalEventService } from "@spt/services/SeasonalEventService"; import { HashUtil } from "@spt/utils/HashUtil"; import { RandomUtil } from "@spt/utils/RandomUtil"; @@ -32,15 +33,15 @@ export declare class BotGenerator { protected botEquipmentFilterService: BotEquipmentFilterService; protected weightedRandomHelper: WeightedRandomHelper; protected botHelper: BotHelper; - protected botDifficultyHelper: BotDifficultyHelper; + protected botGeneratorHelper: BotGeneratorHelper; protected seasonalEventService: SeasonalEventService; - protected localisationService: LocalisationService; protected itemFilterService: ItemFilterService; + protected botNameService: BotNameService; protected configServer: ConfigServer; protected cloner: ICloner; protected botConfig: IBotConfig; protected pmcConfig: IPmcConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, profileHelper: ProfileHelper, databaseService: DatabaseService, botInventoryGenerator: BotInventoryGenerator, botLevelGenerator: BotLevelGenerator, botEquipmentFilterService: BotEquipmentFilterService, weightedRandomHelper: WeightedRandomHelper, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, seasonalEventService: SeasonalEventService, localisationService: LocalisationService, itemFilterService: ItemFilterService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, profileHelper: ProfileHelper, databaseService: DatabaseService, botInventoryGenerator: BotInventoryGenerator, botLevelGenerator: BotLevelGenerator, botEquipmentFilterService: BotEquipmentFilterService, weightedRandomHelper: WeightedRandomHelper, botHelper: BotHelper, botGeneratorHelper: BotGeneratorHelper, seasonalEventService: SeasonalEventService, itemFilterService: ItemFilterService, botNameService: BotNameService, configServer: ConfigServer, cloner: ICloner); /** * Generate a player scav bot object * @param role e.g. assault / pmcbot @@ -50,12 +51,12 @@ export declare class BotGenerator { */ generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase; /** - * Create 1 bots of the type/side/difficulty defined in botGenerationDetails + * Create 1 bot of the type/side/difficulty defined in botGenerationDetails * @param sessionId Session id * @param botGenerationDetails details on how to generate bots * @returns constructed bot */ - prepareAndGenerateBot(sessionId: string, botGenerationDetails: BotGenerationDetails): IBotBase; + prepareAndGenerateBot(sessionId: string, botGenerationDetails: IBotGenerationDetails): IBotBase; /** * Get a clone of the default bot base object and adjust its role/side/difficulty values * @param botRole Role bot should have @@ -77,31 +78,50 @@ export declare class BotGenerator { * @param botGenerationDetails details on how to generate the bot * @returns IBotBase object */ - protected generateBot(sessionId: string, bot: IBotBase, botJsonTemplate: IBotType, botGenerationDetails: BotGenerationDetails): IBotBase; + protected generateBot(sessionId: string, bot: IBotBase, botJsonTemplate: IBotType, botGenerationDetails: IBotGenerationDetails): IBotBase; + /** + * Get exp for kill by bot difficulty + * @param experience Dict of difficulties and experience + * @param botDifficulty the killed bots difficulty + * @param role Role of bot (optional, used for error logging) + * @returns Experience for kill + */ + protected getExperienceRewardForKillByDifficulty(experience: Record, botDifficulty: string, role: string): number; + /** + * Get the standing value change when player kills a bot + * @param standingForKill Dictionary of standing values keyed by bot difficulty + * @param botDifficulty Difficulty of bot to look up + * @param role Role of bot (optional, used for error logging) + * @returns Standing change value + */ + protected getStandingChangeForKillByDifficulty(standingForKill: Record, botDifficulty: string, role: string): number; + /** + * Get the agressor bonus value when player kills a bot + * @param standingForKill Dictionary of standing values keyed by bot difficulty + * @param botDifficulty Difficulty of bot to look up + * @param role Role of bot (optional, used for error logging) + * @returns Standing change value + */ + protected getAgressorBonusByDifficulty(aggressorBonus: Record, botDifficulty: string, role: string): number; + /** + * Set weighting of flagged equipment to 0 + * @param botJsonTemplate Bot data to adjust + * @param botGenerationDetails Generation details of bot + */ + protected filterBlacklistedGear(botJsonTemplate: IBotType, botGenerationDetails: IBotGenerationDetails): void; protected addAdditionalPocketLootWeightsForUnheardBot(botJsonTemplate: IBotType): void; /** * Remove items from item.json/lootableItemBlacklist from bots inventory * @param botInventory Bot to filter */ - protected removeBlacklistedLootFromBotTemplate(botInventory: Inventory): void; + protected removeBlacklistedLootFromBotTemplate(botInventory: IInventory): void; /** * Choose various appearance settings for a bot using weights: head/body/feet/hands * @param bot Bot to adjust * @param appearance Appearance settings to choose from * @param botGenerationDetails Generation details */ - protected setBotAppearance(bot: IBotBase, appearance: Appearance, botGenerationDetails: BotGenerationDetails): void; - /** - * Create a bot nickname - * @param botJsonTemplate x.json from database - * @param botGenerationDetails - * @param botRole role of bot e.g. assault - * @param sessionId OPTIONAL: profile session id - * @returns Nickname for bot - */ - protected generateBotNickname(botJsonTemplate: IBotType, botGenerationDetails: BotGenerationDetails, botRole: string, sessionId?: string): string; - protected shouldSimulatePlayerScavName(botRole: string, isPlayerScav: boolean): boolean; - protected addPlayerScavNameSimulationSuffix(nickname: string): string; + protected setBotAppearance(bot: IBotBase, appearance: IAppearance, botGenerationDetails: IBotGenerationDetails): void; /** * Log the number of PMCs generated to the debug console * @param output Generated bot array, ready to send to client @@ -113,7 +133,13 @@ export declare class BotGenerator { * @param playerScav Is a pscav bot being generated * @returns PmcHealth object */ - protected generateHealth(healthObj: Health, playerScav?: boolean): PmcHealth; + protected generateHealth(healthObj: IHealth, playerScav?: boolean): PmcHealth; + /** + * Sum up body parts max hp values, return the bodypart collection with lowest value + * @param bodies Body parts to sum up + * @returns Lowest hp collection + */ + protected getLowestHpBody(bodies: IBodyPart[]): IBodyPart | undefined; /** * Get a bots skills with randomsied progress value between the min and max values * @param botSkills Skills that should have their progress value randomised @@ -146,7 +172,7 @@ export declare class BotGenerator { * @param botInfo bot info object to update * @returns Chosen game version */ - protected setRandomisedGameVersionAndCategory(botInfo: Info): string; + protected setRandomisedGameVersionAndCategory(botInfo: IInfo): string; /** * Add a side-specific (usec/bear) dogtag item to a bots inventory * @param bot bot to add dogtag to diff --git a/types/generators/BotInventoryGenerator.d.ts b/types/generators/BotInventoryGenerator.d.ts index 1ea549cb..163c6519 100644 --- a/types/generators/BotInventoryGenerator.d.ts +++ b/types/generators/BotInventoryGenerator.d.ts @@ -1,17 +1,22 @@ +import { ApplicationContext } from "@spt/context/ApplicationContext"; import { BotEquipmentModGenerator } from "@spt/generators/BotEquipmentModGenerator"; import { BotLootGenerator } from "@spt/generators/BotLootGenerator"; import { BotWeaponGenerator } from "@spt/generators/BotWeaponGenerator"; import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper"; import { BotHelper } from "@spt/helpers/BotHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { WeatherHelper } from "@spt/helpers/WeatherHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; -import { Inventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; -import { Chances, Equipment, Generation, IBotType, Inventory } from "@spt/models/eft/common/tables/IBotType"; +import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IBotType, IChances, IEquipment, IGeneration, IInventory } from "@spt/models/eft/common/tables/IBotType"; +import { IGetRaidConfigurationRequestData } from "@spt/models/eft/match/IGetRaidConfigurationRequestData"; import { EquipmentSlots } from "@spt/models/enums/EquipmentSlots"; import { IGenerateEquipmentProperties } from "@spt/models/spt/bots/IGenerateEquipmentProperties"; -import { EquipmentFilterDetails, IBotConfig } from "@spt/models/spt/config/IBotConfig"; +import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; +import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService"; import { BotEquipmentModPoolService } from "@spt/services/BotEquipmentModPoolService"; import { DatabaseService } from "@spt/services/DatabaseService"; import { LocalisationService } from "@spt/services/LocalisationService"; @@ -22,18 +27,22 @@ export declare class BotInventoryGenerator { protected hashUtil: HashUtil; protected randomUtil: RandomUtil; protected databaseService: DatabaseService; + protected applicationContext: ApplicationContext; protected botWeaponGenerator: BotWeaponGenerator; protected botLootGenerator: BotLootGenerator; protected botGeneratorHelper: BotGeneratorHelper; + protected profileHelper: ProfileHelper; protected botHelper: BotHelper; protected weightedRandomHelper: WeightedRandomHelper; protected itemHelper: ItemHelper; + protected weatherHelper: WeatherHelper; protected localisationService: LocalisationService; + protected botEquipmentFilterService: BotEquipmentFilterService; protected botEquipmentModPoolService: BotEquipmentModPoolService; protected botEquipmentModGenerator: BotEquipmentModGenerator; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseService: DatabaseService, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, botHelper: BotHelper, weightedRandomHelper: WeightedRandomHelper, itemHelper: ItemHelper, localisationService: LocalisationService, botEquipmentModPoolService: BotEquipmentModPoolService, botEquipmentModGenerator: BotEquipmentModGenerator, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseService: DatabaseService, applicationContext: ApplicationContext, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, profileHelper: ProfileHelper, botHelper: BotHelper, weightedRandomHelper: WeightedRandomHelper, itemHelper: ItemHelper, weatherHelper: WeatherHelper, localisationService: LocalisationService, botEquipmentFilterService: BotEquipmentFilterService, botEquipmentModPoolService: BotEquipmentModPoolService, botEquipmentModGenerator: BotEquipmentModGenerator, configServer: ConfigServer); /** * Add equipment/weapons/loot to bot * @param sessionId Session id @@ -52,6 +61,7 @@ export declare class BotInventoryGenerator { protected generateInventoryBase(): PmcInventory; /** * Add equipment to a bot + * @param sessionId Session id * @param templateInventory bot/x.json data from db * @param wornItemChances Chances items will be added to bot * @param botRole Role bot has (assault/pmcBot) @@ -59,19 +69,23 @@ export declare class BotInventoryGenerator { * @param botLevel Level of bot * @param chosenGameVersion Game version for bot, only really applies for PMCs */ - protected generateAndAddEquipmentToBot(templateInventory: Inventory, wornItemChances: Chances, botRole: string, botInventory: PmcInventory, botLevel: number, chosenGameVersion: string): void; + protected generateAndAddEquipmentToBot(sessionId: string, templateInventory: IInventory, wornItemChances: IChances, botRole: string, botInventory: PmcInventory, botLevel: number, chosenGameVersion: string, raidConfig: IGetRaidConfigurationRequestData): void; /** * Remove non-armored rigs from parameter data * @param templateEquipment Equpiment to filter TacticalVest of + * @param botRole Role of bot vests are being filtered for */ - protected filterRigsToThoseWithProtection(templateEquipment: Equipment): void; + protected filterRigsToThoseWithProtection(templateEquipment: IEquipment, botRole: string): void; /** * Remove armored rigs from parameter data * @param templateEquipment Equpiment to filter TacticalVest of + * @param botRole Role of bot vests are being filtered for + * @param allowEmptyResult Should the function return all rigs when 0 unarmored are found */ - protected filterRigsToThoseWithoutProtection(templateEquipment: Equipment): void; + protected filterRigsToThoseWithoutProtection(templateEquipment: IEquipment, botRole: string, allowEmptyResult?: boolean): void; /** * Add a piece of equipment with mods to inventory from the provided pools + * @param sessionId Session id * @param settings Values to adjust how item is chosen and added to bot * @returns true when item added */ @@ -79,10 +93,10 @@ export declare class BotInventoryGenerator { /** * Get all possible mods for item and filter down based on equipment blacklist from bot.json config * @param itemTpl Item mod pool is being retrieved and filtered - * @param equipmentBlacklist blacklist to filter mod pool with + * @param equipmentBlacklist Blacklist to filter mod pool with * @returns Filtered pool of mods */ - protected getFilteredDynamicModsForItem(itemTpl: string, equipmentBlacklist: EquipmentFilterDetails[]): Record; + protected getFilteredDynamicModsForItem(itemTpl: string, equipmentBlacklist: Record): Record; /** * Work out what weapons bot should have equipped and add them to bot inventory * @param templateInventory bot/x.json data from db @@ -94,13 +108,13 @@ export declare class BotInventoryGenerator { * @param itemGenerationLimitsMinMax Limits for items the bot can have * @param botLevel level of bot having weapon generated */ - protected generateAndAddWeaponsToBot(templateInventory: Inventory, equipmentChances: Chances, sessionId: string, botInventory: PmcInventory, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; + protected generateAndAddWeaponsToBot(templateInventory: IInventory, equipmentChances: IChances, sessionId: string, botInventory: PmcInventory, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: IGeneration, botLevel: number): void; /** * Calculate if the bot should have weapons in Primary/Secondary/Holster slots * @param equipmentChances Chances bot has certain equipment * @returns What slots bot should have weapons generated for */ - protected getDesiredWeaponsForBot(equipmentChances: Chances): { + protected getDesiredWeaponsForBot(equipmentChances: IChances): { slot: EquipmentSlots; shouldSpawn: boolean; }[]; @@ -118,5 +132,5 @@ export declare class BotInventoryGenerator { protected addWeaponAndMagazinesToInventory(sessionId: string, weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean; - }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationWeights: Generation, botLevel: number): void; + }, templateInventory: IInventory, botInventory: PmcInventory, equipmentChances: IChances, botRole: string, isPmc: boolean, itemGenerationWeights: IGeneration, botLevel: number): void; } diff --git a/types/generators/BotLevelGenerator.d.ts b/types/generators/BotLevelGenerator.d.ts index a8a88951..0dada8f4 100644 --- a/types/generators/BotLevelGenerator.d.ts +++ b/types/generators/BotLevelGenerator.d.ts @@ -1,7 +1,7 @@ import { MinMax } from "@spt/models/common/MinMax"; import { IRandomisedBotLevelResult } from "@spt/models/eft/bot/IRandomisedBotLevelResult"; import { IBotBase } from "@spt/models/eft/common/tables/IBotBase"; -import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; +import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseService } from "@spt/services/DatabaseService"; import { MathUtil } from "@spt/utils/MathUtil"; @@ -19,22 +19,14 @@ export declare class BotLevelGenerator { * @param bot Bot the level is being generated for * @returns IRandomisedBotLevelResult object */ - generateBotLevel(levelDetails: MinMax, botGenerationDetails: BotGenerationDetails, bot: IBotBase): IRandomisedBotLevelResult; + generateBotLevel(levelDetails: MinMax, botGenerationDetails: IBotGenerationDetails, bot: IBotBase): IRandomisedBotLevelResult; protected chooseBotLevel(min: number, max: number, shift: number, number: number): number; /** - * Get the highest level a bot can be relative to the players level, but no further than the max size from globals.exp_table - * @param botGenerationDetails Details to help generate a bot - * @param levelDetails - * @param maxLevel Max possible level - * @returns Highest level possible for bot - */ - protected getHighestRelativeBotLevel(botGenerationDetails: BotGenerationDetails, levelDetails: MinMax, maxLevel: number): number; - /** - * Get the lowest level a bot can be relative to the players level, but no lower than 1 + * Return the min and max bot level based on a relative delta from the PMC level * @param botGenerationDetails Details to help generate a bot * @param levelDetails * @param maxlevel Max level allowed - * @returns Lowest level possible for bot + * @returns A MinMax of the lowest and highest level to generate the bots */ - protected getLowestRelativeBotLevel(botGenerationDetails: BotGenerationDetails, levelDetails: MinMax, maxlevel: number): number; + protected getRelativeBotLevelRange(botGenerationDetails: IBotGenerationDetails, levelDetails: MinMax, maxAvailableLevel: number): MinMax; } diff --git a/types/generators/BotLootGenerator.d.ts b/types/generators/BotLootGenerator.d.ts index c0583c6c..6bea7877 100644 --- a/types/generators/BotLootGenerator.d.ts +++ b/types/generators/BotLootGenerator.d.ts @@ -5,9 +5,9 @@ import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; -import { Inventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; -import { IBotType, Inventory, ModsChances } from "@spt/models/eft/common/tables/IBotType"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IBotType, IInventory, IModsChances } from "@spt/models/eft/common/tables/IBotType"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { EquipmentSlots } from "@spt/models/enums/EquipmentSlots"; import { IItemSpawnLimitSettings } from "@spt/models/spt/bots/IItemSpawnLimitSettings"; @@ -51,6 +51,14 @@ export declare class BotLootGenerator { * @param botLevel Level of bot */ generateLoot(sessionId: string, botJsonTemplate: IBotType, isPmc: boolean, botRole: string, botInventory: PmcInventory, botLevel: number): void; + /** + * Gets the rouble cost total for loot in a bots backpack by the bots levl + * Will return 0 for non PMCs + * @param botLevel Bots level + * @param isPmc Is the bot a PMC + * @returns number + */ + protected getBackpackRoubleTotalByLevel(botLevel: number, isPmc: boolean): number; /** * Get an array of the containers a bot has on them (pockets/backpack/vest) * @param botInventory Bot to check @@ -63,14 +71,6 @@ export declare class BotLootGenerator { * @param botRole Role of bot (pmcBEAR/pmcUSEC) */ protected addForcedMedicalItemsToPmcSecure(botInventory: PmcInventory, botRole: string): void; - /** - * Get a biased random number - * @param min Smallest size - * @param max Biggest size - * @param nValue Value to bias choice - * @returns Chosen number - */ - protected getRandomisedCount(min: number, max: number, nValue: number): number; /** * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit or space limit is reached * @param pool Pool of items to pick from with weight @@ -83,7 +83,7 @@ export declare class BotLootGenerator { * @param isPmc Is bot being generated for a pmc */ protected addLootFromPool(pool: Record, equipmentSlots: string[], totalItemCount: number, inventoryToAddItemsTo: PmcInventory, botRole: string, itemSpawnLimits?: IItemSpawnLimitSettings, totalValueLimitRub?: number, isPmc?: boolean, containersIdFull?: Set): void; - protected createWalletLoot(walletId: string): Item[][]; + protected createWalletLoot(walletId: string): IItem[][]; /** * Some items need child items to function, add them to the itemToAddChildrenTo array * @param itemToAddTemplate Db template of item to check @@ -91,7 +91,7 @@ export declare class BotLootGenerator { * @param isPmc Is the item being generated for a pmc (affects money/ammo stack sizes) * @param botRole role bot has that owns item */ - protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean, botRole: string): void; + protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: IItem[], isPmc: boolean, botRole: string): void; /** * Add generated weapons to inventory as loot * @param botInventory inventory to add preset to @@ -101,7 +101,7 @@ export declare class BotLootGenerator { * @param botRole bots role .e.g. pmcBot * @param isPmc are we generating for a pmc */ - protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number, containersIdFull?: Set): void; + protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: IInventory, modChances: IModsChances, botRole: string, isPmc: boolean, botLevel: number, containersIdFull?: Set): void; /** * Hydrate item limit array to contain items that have a limit for a specific bot type * All values are set to 0 @@ -123,14 +123,14 @@ export declare class BotLootGenerator { * @param itemTemplate item details from db * @param moneyItem Money item to randomise */ - protected randomiseMoneyStackSize(botRole: string, itemTemplate: ITemplateItem, moneyItem: Item): void; + protected randomiseMoneyStackSize(botRole: string, itemTemplate: ITemplateItem, moneyItem: IItem): void; /** * Randomise the size of an ammo stack * @param isPmc Is ammo on a PMC bot * @param itemTemplate item details from db * @param ammoItem Ammo item to randomise */ - protected randomiseAmmoStackSize(isPmc: boolean, itemTemplate: ITemplateItem, ammoItem: Item): void; + protected randomiseAmmoStackSize(isPmc: boolean, itemTemplate: ITemplateItem, ammoItem: IItem): void; /** * Get spawn limits for a specific bot type from bot.json config * If no limit found for a non pmc bot, fall back to defaults diff --git a/types/generators/BotWeaponGenerator.d.ts b/types/generators/BotWeaponGenerator.d.ts index 8e03b35e..c5c871fb 100644 --- a/types/generators/BotWeaponGenerator.d.ts +++ b/types/generators/BotWeaponGenerator.d.ts @@ -4,11 +4,11 @@ import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper"; import { BotWeaponGeneratorHelper } from "@spt/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; -import { Inventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; -import { GenerationData, Inventory, ModsChances } from "@spt/models/eft/common/tables/IBotType"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IGenerationData, IInventory, IModsChances } from "@spt/models/eft/common/tables/IBotType"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; -import { GenerateWeaponResult } from "@spt/models/spt/bots/GenerateWeaponResult"; +import { IGenerateWeaponResult } from "@spt/models/spt/bots/IGenerateWeaponResult"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; import { IRepairConfig } from "@spt/models/spt/config/IRepairConfig"; @@ -52,18 +52,18 @@ export declare class BotWeaponGenerator { * @param isPmc Is weapon generated for a pmc * @returns GenerateWeaponResult object */ - generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; + generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: IInventory, weaponParentId: string, modChances: IModsChances, botRole: string, isPmc: boolean, botLevel: number): IGenerateWeaponResult; /** * Get a random weighted weapon from a bots pool of weapons * @param equipmentSlot Primary/secondary/holster * @param botTemplateInventory e.g. assault.json * @returns weapon tpl */ - pickWeightedWeaponTplFromPool(equipmentSlot: string, botTemplateInventory: Inventory): string; + pickWeightedWeaponTplFromPool(equipmentSlot: string, botTemplateInventory: IInventory): string; /** * Generated a weapon based on the supplied weapon tpl - * @param weaponTpl weapon tpl to generate (use pickWeightedWeaponTplFromPool()) - * @param equipmentSlot slot to fit into, primary/secondary/holster + * @param weaponTpl Weapon tpl to generate (use pickWeightedWeaponTplFromPool()) + * @param slotName Slot to fit into, primary/secondary/holster * @param botTemplateInventory e.g. assault.json * @param weaponParentId ParentId of the weapon being generated * @param modChances Dictionary of item types and % chance weapon will have that mod @@ -71,7 +71,7 @@ export declare class BotWeaponGenerator { * @param isPmc Is weapon being generated for a pmc * @returns GenerateWeaponResult object */ - generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; + generateWeaponByTpl(sessionId: string, weaponTpl: string, slotName: string, botTemplateInventory: IInventory, weaponParentId: string, modChances: IModsChances, botRole: string, isPmc: boolean, botLevel: number): IGenerateWeaponResult; /** * Insert a cartridge(s) into a weapon * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc @@ -79,7 +79,7 @@ export declare class BotWeaponGenerator { * @param ammoTpl Cartridge to add to weapon * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; + protected addCartridgeToChamber(weaponWithModsArray: IItem[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type @@ -90,7 +90,7 @@ export declare class BotWeaponGenerator { * @param botRole for durability values * @returns Base weapon item in array */ - protected constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): Item[]; + protected constructWeaponBaseArray(weaponTpl: string, weaponParentId: string, equipmentSlot: string, weaponItemTemplate: ITemplateItem, botRole: string): IItem[]; /** * Get the mods necessary to kit out a weapon to its preset level * @param weaponTpl weapon to find preset for @@ -98,14 +98,14 @@ export declare class BotWeaponGenerator { * @param weaponParentId Value used for the parentid * @returns array of weapon mods */ - protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): Item[]; + protected getPresetWeaponMods(weaponTpl: string, equipmentSlot: string, weaponParentId: string, itemTemplate: ITemplateItem, botRole: string): IItem[]; /** * Checks if all required slots are occupied on a weapon and all it's mods * @param weaponItemArray Weapon + mods * @param botRole role of bot weapon is for * @returns true if valid */ - protected isWeaponValid(weaponItemArray: Item[], botRole: string): boolean; + protected isWeaponValid(weaponItemArray: IItem[], botRole: string): boolean; /** * Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets. * Additionally, adds extra bullets to SecuredContainer @@ -114,14 +114,14 @@ export declare class BotWeaponGenerator { * @param inventory Inventory to add magazines to * @param botRole The bot type we're getting generating extra mags for */ - addExtraMagazinesToInventory(generatedWeaponResult: GenerateWeaponResult, magWeights: GenerationData, inventory: PmcInventory, botRole: string): void; + addExtraMagazinesToInventory(generatedWeaponResult: IGenerateWeaponResult, magWeights: IGenerationData, inventory: PmcInventory, botRole: string): void; /** * Add Grendaes for UBGL to bots vest and secure container * @param weaponMods Weapon array with mods * @param generatedWeaponResult result of weapon generation * @param inventory bot inventory to add grenades to */ - protected addUbglGrenadesToBotInventory(weaponMods: Item[], generatedWeaponResult: GenerateWeaponResult, inventory: PmcInventory): void; + protected addUbglGrenadesToBotInventory(weaponMods: IItem[], generatedWeaponResult: IGenerateWeaponResult, inventory: PmcInventory): void; /** * Add ammo to the secure container * @param stackCount How many stacks of ammo to add @@ -137,14 +137,20 @@ export declare class BotWeaponGenerator { * @param botRole the bot type we are getting the magazine for * @returns magazine tpl string */ - protected getMagazineTplFromWeaponTemplate(weaponMods: Item[], weaponTemplate: ITemplateItem, botRole: string): string; + protected getMagazineTplFromWeaponTemplate(weaponMods: IItem[], weaponTemplate: ITemplateItem, botRole: string): string; /** * Finds and return a compatible ammo tpl based on the bots ammo weightings (x.json/inventory/equipment/ammo) - * @param ammo a list of ammo tpls the weapon can use - * @param weaponTemplate the weapon we want to pick ammo for - * @returns an ammo tpl that works with the desired gun + * @param cartridgePool Dict of all cartridges keyed by type e.g. Caliber556x45NATO + * @param weaponTemplate Weapon details from db we want to pick ammo for + * @returns Ammo tpl that works with the desired gun */ - protected getWeightedCompatibleAmmo(ammo: Record>, weaponTemplate: ITemplateItem): string; + protected getWeightedCompatibleAmmo(cartridgePool: Record>, weaponTemplate: ITemplateItem): string; + /** + * Get the cartridge ids from a weapon template that work with the weapon + * @param weaponTemplate Weapon db template to get cartridges for + * @returns Array of cartridge tpls + */ + protected getCompatibleCartridgesFromWeaponTemplate(weaponTemplate: ITemplateItem): string[]; /** * Get a weapons compatible cartridge caliber * @param weaponTemplate Weapon to look up caliber of @@ -157,14 +163,14 @@ export declare class BotWeaponGenerator { * @param magazine Magazine item * @param cartridgeTpl Cartridge to insert into magazine */ - protected fillExistingMagazines(weaponMods: Item[], magazine: Item, cartridgeTpl: string): void; + protected fillExistingMagazines(weaponMods: IItem[], magazine: IItem, cartridgeTpl: string): void; /** * Add desired ammo tpl as item to weaponmods array, placed as child to UBGL * @param weaponMods Weapon with children * @param ubglMod UBGL item * @param ubglAmmoTpl Grenade ammo tpl */ - protected fillUbgl(weaponMods: Item[], ubglMod: Item, ubglAmmoTpl: string): void; + protected fillUbgl(weaponMods: IItem[], ubglMod: IItem, ubglAmmoTpl: string): void; /** * Add cartridge item to weapon Item array, if it already exists, update * @param weaponWithMods Weapon items array to amend @@ -173,12 +179,12 @@ export declare class BotWeaponGenerator { * @param newStackSize how many cartridges should go into the magazine * @param magazineTemplate magazines db template */ - protected addOrUpdateMagazinesChildWithAmmo(weaponWithMods: Item[], magazine: Item, chosenAmmoTpl: string, magazineTemplate: ITemplateItem): void; + protected addOrUpdateMagazinesChildWithAmmo(weaponWithMods: IItem[], magazine: IItem, chosenAmmoTpl: string, magazineTemplate: ITemplateItem): void; /** * Fill each Camora with a bullet * @param weaponMods Weapon mods to find and update camora mod(s) from * @param magazineId magazine id to find and add to * @param ammoTpl ammo template id to hydate with */ - protected fillCamorasWithAmmo(weaponMods: Item[], magazineId: string, ammoTpl: string): void; + protected fillCamorasWithAmmo(weaponMods: IItem[], magazineId: string, ammoTpl: string): void; } diff --git a/types/generators/FenceBaseAssortGenerator.d.ts b/types/generators/FenceBaseAssortGenerator.d.ts index 784022f5..b6ef72b1 100644 --- a/types/generators/FenceBaseAssortGenerator.d.ts +++ b/types/generators/FenceBaseAssortGenerator.d.ts @@ -1,7 +1,7 @@ import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -47,7 +47,7 @@ export declare class FenceBaseAssortGenerator { * @param armor Armor item array to add mods into * @param itemDbDetails Armor items db template */ - protected addChildrenToArmorModSlots(armor: Item[], itemDbDetails: ITemplateItem): void; + protected addChildrenToArmorModSlots(armor: IItem[], itemDbDetails: ITemplateItem): void; /** * Check if item is valid for being added to fence assorts * @param item Item to check diff --git a/types/generators/LocationGenerator.d.ts b/types/generators/LocationLootGenerator.d.ts similarity index 88% rename from types/generators/LocationGenerator.d.ts rename to types/generators/LocationLootGenerator.d.ts index 9a2b0c45..79dddb2b 100644 --- a/types/generators/LocationGenerator.d.ts +++ b/types/generators/LocationLootGenerator.d.ts @@ -3,8 +3,8 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { IContainerMinMax, IStaticAmmoDetails, IStaticContainer, IStaticContainerData, IStaticForcedProps, IStaticLootDetails } from "@spt/models/eft/common/ILocation"; import { ILocationBase } from "@spt/models/eft/common/ILocationBase"; -import { ILooseLoot, Spawnpoint, SpawnpointTemplate, SpawnpointsForced } from "@spt/models/eft/common/ILooseLoot"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { ILooseLoot, ISpawnpointTemplate, ISpawnpointsForced } from "@spt/models/eft/common/ILooseLoot"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -17,7 +17,7 @@ import { ObjectId } from "@spt/utils/ObjectId"; import { ProbabilityObjectArray, RandomUtil } from "@spt/utils/RandomUtil"; import { ICloner } from "@spt/utils/cloners/ICloner"; export interface IContainerItem { - items: Item[]; + items: IItem[]; width: number; height: number; } @@ -27,7 +27,7 @@ export interface IContainerGroupCount { /** How many containers the map should spawn with this group id */ chosenCount: number; } -export declare class LocationGenerator { +export declare class LocationLootGenerator { protected logger: ILogger; protected databaseService: DatabaseService; protected objectId: ObjectId; @@ -49,7 +49,7 @@ export declare class LocationGenerator { * @param staticAmmoDist Static ammo distribution * @returns Array of container objects */ - generateStaticContainers(locationBase: ILocationBase, staticAmmoDist: Record): SpawnpointTemplate[]; + generateStaticContainers(locationBase: ILocationBase, staticAmmoDist: Record): ISpawnpointTemplate[]; /** * Get containers with a non-100% chance to spawn OR are NOT on the container type randomistion blacklist * @param staticContainers @@ -117,14 +117,14 @@ export declare class LocationGenerator { * @param locationName Location to generate loot for * @returns Array of spawn points with loot in them */ - generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; + generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): ISpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array * @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(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: ISpawnpointTemplate[], forcedSpawnPoints: ISpawnpointsForced[], locationName: string, staticAmmoDist: Record): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for @@ -132,19 +132,13 @@ export declare class LocationGenerator { * @param staticAmmoDist ammo distributions * @returns IContainerItem */ - protected createDynamicLootItem(chosenComposedKey: string, spawnPoint: Spawnpoint, staticAmmoDist: Record): IContainerItem; - /** - * Replace the _id value for base item + all children items parentid value - * @param itemWithChildren Item with mods to update - * @param newId new id to add on chidren of base item - */ - protected reparentItemAndChildren(itemWithChildren: Item[], newId?: string): void; + protected createDynamicLootItem(chosenComposedKey: string, items: IItem[], staticAmmoDist: Record): IContainerItem; /** * Find an item in array by its _tpl, handle differently if chosenTpl is a weapon * @param items Items array to search * @param chosenTpl Tpl we want to get item with * @returns Item object */ - protected getItemInArray(items: Item[], chosenTpl: string): Item | undefined; + protected getItemInArray(items: IItem[], chosenTpl: string): IItem | undefined; protected createStaticLootItem(chosenTpl: string, staticAmmoDist: Record, parentId?: string): IContainerItem; } diff --git a/types/generators/LootGenerator.d.ts b/types/generators/LootGenerator.d.ts index 953ac3de..a82f24f1 100644 --- a/types/generators/LootGenerator.d.ts +++ b/types/generators/LootGenerator.d.ts @@ -2,12 +2,12 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; +import { MinMax } from "@spt/models/common/MinMax"; import { IPreset } from "@spt/models/eft/common/IGlobals"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; -import { ISealedAirdropContainerSettings, RewardDetails } from "@spt/models/spt/config/IInventoryConfig"; -import { LootItem } from "@spt/models/spt/services/LootItem"; -import { LootRequest } from "@spt/models/spt/services/LootRequest"; +import { IRewardDetails, ISealedAirdropContainerSettings } from "@spt/models/spt/config/IInventoryConfig"; +import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseService } from "@spt/services/DatabaseService"; import { ItemFilterService } from "@spt/services/ItemFilterService"; @@ -37,14 +37,33 @@ export declare class LootGenerator { * @param options parameters to adjust how loot is generated * @returns An array of loot items */ - createRandomLoot(options: LootRequest): LootItem[]; + createRandomLoot(options: ILootRequest): IItem[]; + /** + * Generate An array of items + * TODO - handle weapon presets/ammo packs + * @param forcedLootDict Dictionary of item tpls with minmax values + * @returns Array of IItem + */ + createForcedLoot(forcedLootDict: Record): IItem[]; + /** + * Get pool of items from item db that fit passed in param criteria + * @param itemTplBlacklist Prevent these items + * @param itemTypeWhitelist Only allow these items + * @param useRewardItemBlacklist Should item.json reward item config be used + * @param allowBossItems Should boss items be allowed in result + * @returns results of filtering + blacklist used + */ + protected getItemRewardPool(itemTplBlacklist: string[], itemTypeWhitelist: string[], useRewardItemBlacklist: boolean, allowBossItems: boolean): { + itemPool: [string, ITemplateItem][]; + blacklist: Set; + }; /** * Filter armor items by their front plates protection level - top if its a helmet * @param armor Armor preset to check * @param options Loot request options - armor level etc * @returns True if item has desired armor level */ - protected isArmorOfDesiredProtectionLevel(armor: IPreset, options: LootRequest): boolean; + protected isArmorOfDesiredProtectionLevel(armor: IPreset, options: ILootRequest): boolean; /** * Construct item limit record to hold max and current item count for each item type * @param limits limits as defined in config @@ -62,14 +81,14 @@ export declare class LootGenerator { protected findAndAddRandomItemToLoot(items: [string, ITemplateItem][], itemTypeCounts: Record, options: LootRequest, result: LootItem[]): boolean; + }>, options: ILootRequest, result: IItem[]): boolean; /** * Get a randomised stack count for an item between its StackMinRandom and StackMaxSize values * @param item item to get stack count of * @param options loot options * @returns stack count */ - protected getRandomisedStackCount(item: ITemplateItem, options: LootRequest): number; + protected getRandomisedStackCount(item: ITemplateItem, options: ILootRequest): number; /** * Find a random item in items.json and add to result array * @param presetPool Presets to choose from @@ -81,20 +100,20 @@ export declare class LootGenerator { protected findAndAddRandomPresetToLoot(presetPool: IPreset[], itemTypeCounts: Record, itemBlacklist: string[], result: LootItem[]): boolean; + }>, itemBlacklist: string[], result: IItem[]): boolean; /** * Sealed weapon containers have a weapon + associated mods inside them + assortment of other things (food/meds) * @param containerSettings sealed weapon container settings * @returns Array of item with children arrays */ - getSealedWeaponCaseLoot(containerSettings: ISealedAirdropContainerSettings): Item[][]; + getSealedWeaponCaseLoot(containerSettings: ISealedAirdropContainerSettings): IItem[][]; /** * Get non-weapon mod rewards for a sealed container * @param containerSettings Sealed weapon container settings * @param weaponDetailsDb Details for the weapon to reward player * @returns Array of item with children arrays */ - protected getSealedContainerNonWeaponModRewards(containerSettings: ISealedAirdropContainerSettings, weaponDetailsDb: ITemplateItem): Item[][]; + protected getSealedContainerNonWeaponModRewards(containerSettings: ISealedAirdropContainerSettings, weaponDetailsDb: ITemplateItem): IItem[][]; /** * Iterate over the container weaponModRewardLimits settings and create an array of weapon mods to reward player * @param containerSettings Sealed weapon container settings @@ -102,12 +121,18 @@ export declare class LootGenerator { * @param chosenWeaponPreset The weapon preset given to player as reward * @returns Array of item with children arrays */ - protected getSealedContainerWeaponModRewards(containerSettings: ISealedAirdropContainerSettings, linkedItemsToWeapon: ITemplateItem[], chosenWeaponPreset: IPreset): Item[][]; + protected getSealedContainerWeaponModRewards(containerSettings: ISealedAirdropContainerSettings, linkedItemsToWeapon: ITemplateItem[], chosenWeaponPreset: IPreset): IItem[][]; /** * Handle event-related loot containers - currently just the halloween jack-o-lanterns that give food rewards * @param rewardContainerDetails * @returns Array of item with children arrays */ - getRandomLootContainerLoot(rewardContainerDetails: RewardDetails): Item[][]; + getRandomLootContainerLoot(rewardContainerDetails: IRewardDetails): IItem[][]; + /** + * Pick a reward item based on the reward details data + * @param rewardContainerDetails + * @returns Single tpl + */ + protected pickRewardItem(rewardContainerDetails: IRewardDetails): string; } export {}; diff --git a/types/generators/PlayerScavGenerator.d.ts b/types/generators/PlayerScavGenerator.d.ts index e317bf68..7a8e0e76 100644 --- a/types/generators/PlayerScavGenerator.d.ts +++ b/types/generators/PlayerScavGenerator.d.ts @@ -4,9 +4,9 @@ import { BotHelper } from "@spt/helpers/BotHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { IBotBase, Skills, Stats } from "@spt/models/eft/common/tables/IBotBase"; +import { IBotBase, ISkills, IStats } from "@spt/models/eft/common/tables/IBotBase"; import { IBotType } from "@spt/models/eft/common/tables/IBotType"; -import { IPlayerScavConfig, KarmaLevel } from "@spt/models/spt/config/IPlayerScavConfig"; +import { IKarmaLevel, IPlayerScavConfig } from "@spt/models/spt/config/IPlayerScavConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; @@ -67,10 +67,10 @@ export declare class PlayerScavGenerator { * @param karmaSettings Values to modify the bot template with * @param baseBotNode bot template to modify according to karama level settings */ - protected adjustBotTemplateWithKarmaSpecificSettings(karmaSettings: KarmaLevel, baseBotNode: IBotType): void; - protected getScavSkills(scavProfile: IPmcData): Skills; - protected getDefaultScavSkills(): Skills; - protected getScavStats(scavProfile: IPmcData): Stats; + protected adjustBotTemplateWithKarmaSpecificSettings(karmaSettings: IKarmaLevel, baseBotNode: IBotType): void; + protected getScavSkills(scavProfile: IPmcData): ISkills; + protected getDefaultScavSkills(): ISkills; + protected getScavStats(scavProfile: IPmcData): IStats; protected getScavLevel(scavProfile: IPmcData): number; protected getScavExperience(scavProfile: IPmcData): number; /** diff --git a/types/generators/RagfairAssortGenerator.d.ts b/types/generators/RagfairAssortGenerator.d.ts index 4c6cf1c7..60c4c86f 100644 --- a/types/generators/RagfairAssortGenerator.d.ts +++ b/types/generators/RagfairAssortGenerator.d.ts @@ -1,7 +1,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { IPreset } from "@spt/models/eft/common/IGlobals"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { DatabaseServer } from "@spt/servers/DatabaseServer"; @@ -14,7 +14,7 @@ export declare class RagfairAssortGenerator { protected databaseServer: DatabaseServer; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; - protected generatedAssortItems: Item[][]; + protected generatedAssortItems: IItem[][]; protected ragfairConfig: IRagfairConfig; protected ragfairItemInvalidBaseTypes: string[]; constructor(hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, seasonalEventService: SeasonalEventService, configServer: ConfigServer); @@ -23,7 +23,7 @@ export declare class RagfairAssortGenerator { * Each sub array contains item + children (if any) * @returns array of arrays */ - getAssortItems(): Item[][]; + getAssortItems(): IItem[][]; /** * Check internal generatedAssortItems array has objects * @returns true if array has objects @@ -33,7 +33,7 @@ export declare class RagfairAssortGenerator { * Generate an array of arrays (item + children) the flea can sell * @returns array of arrays (item + children) */ - protected generateRagfairAssortItems(): Item[][]; + protected generateRagfairAssortItems(): IItem[][]; /** * Get presets from globals to add to flea * ragfairConfig.dynamic.showDefaultPresetsOnly decides if its all presets or just defaults @@ -46,5 +46,5 @@ export declare class RagfairAssortGenerator { * @param id id to add to item * @returns Hydrated Item object */ - protected createRagfairAssortRootItem(tplId: string, id?: string): Item; + protected createRagfairAssortRootItem(tplId: string, id?: string): IItem; } diff --git a/types/generators/RagfairOfferGenerator.d.ts b/types/generators/RagfairOfferGenerator.d.ts index ca097293..60d6c9d1 100644 --- a/types/generators/RagfairOfferGenerator.d.ts +++ b/types/generators/RagfairOfferGenerator.d.ts @@ -6,11 +6,13 @@ import { PaymentHelper } from "@spt/helpers/PaymentHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { RagfairServerHelper } from "@spt/helpers/RagfairServerHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; -import { IRagfairOffer, IRagfairOfferUser, OfferRequirement } from "@spt/models/eft/ragfair/IRagfairOffer"; -import { Dynamic, IArmorPlateBlacklistSettings, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; +import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; +import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; @@ -45,6 +47,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; price: number; @@ -62,7 +65,7 @@ export declare class RagfairOfferGenerator { * @param sellInOnePiece Flags sellInOnePiece to be true * @returns Created flea offer */ - createAndAddFleaOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, sellInOnePiece?: boolean): IRagfairOffer; + createAndAddFleaOffer(userID: string, time: number, items: IItem[], barterScheme: IBarterScheme[], loyalLevel: number, sellInOnePiece?: boolean): IRagfairOffer; /** * Create an offer object ready to send to ragfairOfferService.addOffer() * @param userID Owner of the offer @@ -73,7 +76,7 @@ export declare class RagfairOfferGenerator { * @param isPackOffer Is offer being created flaged as a pack * @returns IRagfairOffer */ - protected createOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, isPackOffer?: boolean): IRagfairOffer; + protected createOffer(userID: string, time: number, items: IItem[], barterScheme: IBarterScheme[], loyalLevel: number, isPackOffer?: boolean): IRagfairOffer; /** * Create the user object stored inside each flea offer object * @param userID user creating the offer @@ -86,7 +89,7 @@ export declare class RagfairOfferGenerator { * @param offerRequirements barter requirements for offer * @returns rouble cost of offer */ - protected convertOfferRequirementsIntoRoubles(offerRequirements: OfferRequirement[]): number; + protected convertOfferRequirementsIntoRoubles(offerRequirements: IOfferRequirement[]): number; /** * Get avatar url from trader table in db * @param isTrader Is user we're getting avatar for a trader @@ -130,28 +133,29 @@ export declare class RagfairOfferGenerator { * Create multiple offers for items by using a unique list of items we've generated previously * @param expiredOffers optional, expired offers to regenerate */ - generateDynamicOffers(expiredOffers?: Item[][]): Promise; + generateDynamicOffers(expiredOffers?: IItem[][]): Promise; /** * @param assortItemWithChildren Item with its children to process into offers * @param isExpiredOffer is an expired offer * @param config Ragfair dynamic config */ - protected createOffersFromAssort(assortItemWithChildren: Item[], isExpiredOffer: boolean, config: Dynamic): Promise; + protected createOffersFromAssort(assortItemWithChildren: IItem[], isExpiredOffer: boolean, config: IDynamic): Promise; /** * iterate over an items chidren and look for plates above desired level and remove them * @param presetWithChildren preset to check for plates * @param plateSettings Settings * @returns True if plate removed */ - protected removeBannedPlatesFromPreset(presetWithChildren: Item[], plateSettings: IArmorPlateBlacklistSettings): boolean; + protected removeBannedPlatesFromPreset(presetWithChildren: IItem[], plateSettings: IArmorPlateBlacklistSettings): boolean; /** * Create one flea offer for a specific item + * @param sellerId Id of seller * @param itemWithChildren Item to create offer for * @param isPreset Is item a weapon preset - * @param itemDetails raw db item details + * @param itemToSellDetails Raw db item details * @returns Item array */ - protected createSingleOfferForItem(itemWithChildren: Item[], isPreset: boolean, itemDetails: [boolean, ITemplateItem]): Promise; + protected createSingleOfferForItem(sellerId: string, itemWithChildren: IItem[], isPreset: boolean, itemToSellDetails: ITemplateItem): Promise; /** * Generate trader offers on flea using the traders assort data * @param traderID Trader to generate offers for @@ -164,7 +168,7 @@ export declare class RagfairOfferGenerator { * @param itemWithMods Item and mods, get condition of first item (only first array item is modified) * @param itemDetails db details of first item */ - protected randomiseOfferItemUpdProperties(userID: string, itemWithMods: Item[], itemDetails: ITemplateItem): void; + protected randomiseOfferItemUpdProperties(userID: string, itemWithMods: IItem[], itemDetails: ITemplateItem): void; /** * Get the relevant condition id if item tpl matches in ragfair.json/condition * @param tpl Item to look for matching condition object @@ -177,7 +181,7 @@ export declare class RagfairOfferGenerator { * @param itemWithMods Item to adjust condition details of * @param itemDetails db item details of first item in array */ - protected randomiseItemCondition(conditionSettingsId: string, itemWithMods: Item[], itemDetails: ITemplateItem): void; + protected randomiseItemCondition(conditionSettingsId: string, itemWithMods: IItem[], itemDetails: ITemplateItem): void; /** * Adjust an items durability/maxDurability value * @param item item (weapon/armor) to Adjust @@ -185,35 +189,33 @@ export declare class RagfairOfferGenerator { * @param maxMultiplier Value to multiply max durability by * @param currentMultiplier Value to multiply current durability by */ - protected randomiseWeaponDurability(item: Item, itemDbDetails: ITemplateItem, maxMultiplier: number, currentMultiplier: number): void; + protected randomiseWeaponDurability(item: IItem, itemDbDetails: ITemplateItem, maxMultiplier: number, currentMultiplier: number): void; /** * Randomise the durabiltiy values for an armors plates and soft inserts * @param armorWithMods Armor item with its child mods * @param currentMultiplier Chosen multipler to use for current durability value * @param maxMultiplier Chosen multipler to use for max durability value */ - protected randomiseArmorDurabilityValues(armorWithMods: Item[], currentMultiplier: number, maxMultiplier: number): void; + protected randomiseArmorDurabilityValues(armorWithMods: IItem[], currentMultiplier: number, maxMultiplier: number): void; /** * Add missing conditions to an item if needed * Durabiltiy for repairable items * HpResource for medical items * @param item item to add conditions to */ - protected addMissingConditions(item: Item): void; + protected addMissingConditions(item: IItem): void; /** * Create a barter-based barter scheme, if not possible, fall back to making barter scheme currency based * @param offerItems Items for sale in offer + * @param barterConfig Barter config from ragfairConfig.dynamic.barter * @returns Barter scheme */ - protected createBarterBarterScheme(offerItems: Item[]): IBarterScheme[]; + protected createBarterBarterScheme(offerItems: IItem[], barterConfig: IBarterDetails): IBarterScheme[]; /** * Get an array of flea prices + item tpl, cached in generator class inside `allowedFleaPriceItemsForBarter` * @returns array with tpl/price values */ - protected getFleaPricesAsArray(): { - tpl: string; - price: number; - }[]; + protected getFleaPricesAsArray(): ITplWithFleaPrice[]; /** * Create a random currency-based barter scheme for an array of items * @param offerWithChildren Items on offer @@ -221,5 +223,5 @@ export declare class RagfairOfferGenerator { * @param multipler What to multiply the resulting price by * @returns Barter scheme for offer */ - protected createCurrencyBarterScheme(offerWithChildren: Item[], isPackOffer: boolean, multipler?: number): IBarterScheme[]; + protected createCurrencyBarterScheme(offerWithChildren: IItem[], isPackOffer: boolean, multipler?: number): IBarterScheme[]; } diff --git a/types/generators/RepeatableQuestGenerator.d.ts b/types/generators/RepeatableQuestGenerator.d.ts index 339f322e..79a10fc3 100644 --- a/types/generators/RepeatableQuestGenerator.d.ts +++ b/types/generators/RepeatableQuestGenerator.d.ts @@ -1,8 +1,8 @@ import { RepeatableQuestRewardGenerator } from "@spt/generators/RepeatableQuestRewardGenerator"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { RepeatableQuestHelper } from "@spt/helpers/RepeatableQuestHelper"; -import { Exit } from "@spt/models/eft/common/ILocationBase"; -import { TraderInfo } from "@spt/models/eft/common/tables/IBotBase"; +import { IExit } from "@spt/models/eft/common/ILocationBase"; +import { ITraderInfo } from "@spt/models/eft/common/tables/IBotBase"; import { IQuestCondition, IQuestConditionCounterCondition } from "@spt/models/eft/common/tables/IQuest"; import { IRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests"; import { IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt/models/spt/config/IQuestConfig"; @@ -28,6 +28,7 @@ export declare class RepeatableQuestGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected questConfig: IQuestConfig; + protected maxRandomNumberAttempts: number; constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, localisationService: LocalisationService, objectId: ObjectId, repeatableQuestHelper: RepeatableQuestHelper, repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator, configServer: ConfigServer, cloner: ICloner); /** * This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json). @@ -38,7 +39,7 @@ export declare class RepeatableQuestGenerator { * @param repeatableConfig Repeatable quest config * @returns IRepeatableQuest */ - generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Generate a randomised Elimination quest * @param pmcLevel Player's level for requested items and reward generation @@ -108,7 +109,7 @@ export declare class RepeatableQuestGenerator { * @param playerSide Scav/Pmc * @returns Array of Exit objects */ - protected getLocationExitsForSide(locationKey: string, playerSide: string): Exit[]; + protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[]; protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567) @@ -123,7 +124,7 @@ export declare class RepeatableQuestGenerator { * @param {string} exit The exit name to generate the condition for * @returns {object} Exit condition */ - protected generateExplorationExitCondition(exit: Exit): IQuestConditionCounterCondition; + protected generateExplorationExitCondition(exit: IExit): IQuestConditionCounterCondition; /** * Generates the base object of quest type format given as templates in assets/database/templates/repeatableQuests.json * The templates include Elimination, Completion and Extraction quest types diff --git a/types/generators/RepeatableQuestRewardGenerator.d.ts b/types/generators/RepeatableQuestRewardGenerator.d.ts index 713a394a..bc78ccad 100644 --- a/types/generators/RepeatableQuestRewardGenerator.d.ts +++ b/types/generators/RepeatableQuestRewardGenerator.d.ts @@ -1,7 +1,7 @@ import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IQuestReward, IQuestRewards } from "@spt/models/eft/common/tables/IQuest"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IBaseQuestConfig, IQuestConfig, IRepeatableQuestConfig, IRewardScaling } from "@spt/models/spt/config/IQuestConfig"; @@ -33,26 +33,30 @@ export declare class RepeatableQuestRewardGenerator { protected questConfig: IQuestConfig; constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner); /** - * Generate the reward for a mission. A reward can consist of + * Generate the reward for a mission. A reward can consist of: * - Experience * - Money + * - GP coins + * - Weapon preset * - Items * - Trader Reputation + * - Skill level experience * * The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to * experience / money / items / trader reputation can be defined in QuestConfig.js * - * There's also a random variation of the reward the spread of which can be also defined in the config. + * There's also a random variation of the reward the spread of which can be also defined in the config * * Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used - * - * @param {integer} pmcLevel player's level - * @param {number} difficulty a reward scaling factor from 0.2 to 1 - * @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader) - * @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest - * @returns {object} object of "Reward"-type that can be given for a repeatable mission + * @param pmcLevel Level of player reward is being generated for + * @param difficulty Reward scaling factor from 0.2 to 1 + * @param traderId Trader reward will be given by + * @param repeatableConfig Config for quest type (daily, weekly) + * @param questConfig + * @param rewardTplBlacklist OPTIONAL: list of tpls to NOT use when picking a reward + * @returns IQuestRewards */ - generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards; + generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig, rewardTplBlacklist?: string[]): IQuestRewards; protected getQuestRewardValues(rewardScaling: IRewardScaling, difficulty: number, pmcLevel: number): IQuestRewardValues; /** * Get an array of items + stack size to give to player as reward that fit inside of a rouble budget @@ -133,7 +137,7 @@ export declare class RepeatableQuestRewardGenerator { * @param preset Optional array of preset items * @returns {object} Object of "Reward"-item-type */ - protected generatePresetReward(tpl: string, count: number, index: number, preset?: Item[]): IQuestReward; + protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward; /** * Picks rewardable items from items.json * This means they must: diff --git a/types/generators/ScavCaseRewardGenerator.d.ts b/types/generators/ScavCaseRewardGenerator.d.ts index 45f2e517..715b84ea 100644 --- a/types/generators/ScavCaseRewardGenerator.d.ts +++ b/types/generators/ScavCaseRewardGenerator.d.ts @@ -1,10 +1,10 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; -import { IHideoutScavCase } from "@spt/models/eft/hideout/IHideoutScavCase"; +import { IScavRecipe } from "@spt/models/eft/hideout/IHideoutProduction"; import { IScavCaseConfig } from "@spt/models/spt/config/IScavCaseConfig"; -import { RewardCountAndPriceDetails, ScavCaseRewardCountsAndPrices } from "@spt/models/spt/hideout/ScavCaseRewardCountsAndPrices"; +import { IRewardCountAndPriceDetails, IScavCaseRewardCountsAndPrices } from "@spt/models/spt/hideout/ScavCaseRewardCountsAndPrices"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { DatabaseService } from "@spt/services/DatabaseService"; @@ -36,7 +36,7 @@ export declare class ScavCaseRewardGenerator { * @param recipeId recipe of the scav case craft * @returns Product array */ - generate(recipeId: string): Item[][]; + generate(recipeId: string): IItem[][]; /** * Get all db items that are not blacklisted in scavcase config or global blacklist * Store in class field @@ -48,7 +48,7 @@ export declare class ScavCaseRewardGenerator { * @param itemFilters how the rewards should be filtered down (by item count) * @returns */ - protected pickRandomRewards(items: ITemplateItem[], itemFilters: RewardCountAndPriceDetails, rarity: string): ITemplateItem[]; + protected pickRandomRewards(items: ITemplateItem[], itemFilters: IRewardCountAndPriceDetails, rarity: string): ITemplateItem[]; /** * Choose if money should be a reward based on the moneyRewardChancePercent config chance in scavCaseConfig * @returns true if reward should be money @@ -75,19 +75,19 @@ export declare class ScavCaseRewardGenerator { * @param rewardItems items to convert * @returns Product array */ - protected randomiseContainerItemRewards(rewardItems: ITemplateItem[], rarity: string): Item[][]; + protected randomiseContainerItemRewards(rewardItems: ITemplateItem[], rarity: string): IItem[][]; /** * @param dbItems all items from the items.json * @param itemFilters controls how the dbItems will be filtered and returned (handbook price) * @returns filtered dbItems array */ - protected getFilteredItemsByPrice(dbItems: ITemplateItem[], itemFilters: RewardCountAndPriceDetails): ITemplateItem[]; + protected getFilteredItemsByPrice(dbItems: ITemplateItem[], itemFilters: IRewardCountAndPriceDetails): ITemplateItem[]; /** * Gathers the reward min and max count params for each reward quality level from config and scavcase.json into a single object - * @param scavCaseDetails scavcase.json values + * @param scavCaseDetails production.json/scavRecipes object * @returns ScavCaseRewardCountsAndPrices object */ - protected getScavCaseRewardCountsAndPrices(scavCaseDetails: IHideoutScavCase): ScavCaseRewardCountsAndPrices; + protected getScavCaseRewardCountsAndPrices(scavCaseDetails: IScavRecipe): IScavCaseRewardCountsAndPrices; /** * Randomises the size of ammo and money stacks * @param itemToCalculate ammo or money item diff --git a/types/generators/WeatherGenerator.d.ts b/types/generators/WeatherGenerator.d.ts index c9ca02a2..71d28262 100644 --- a/types/generators/WeatherGenerator.d.ts +++ b/types/generators/WeatherGenerator.d.ts @@ -1,6 +1,8 @@ import { ApplicationContext } from "@spt/context/ApplicationContext"; +import { WeatherHelper } from "@spt/helpers/WeatherHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { IWeather, IWeatherData } from "@spt/models/eft/weather/IWeatherData"; +import { Season } from "@spt/models/enums/Season"; import { WindDirection } from "@spt/models/enums/WindDirection"; import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -10,6 +12,7 @@ import { RandomUtil } from "@spt/utils/RandomUtil"; import { TimeUtil } from "@spt/utils/TimeUtil"; export declare class WeatherGenerator { protected weightedRandomHelper: WeightedRandomHelper; + protected weatherHelper: WeatherHelper; protected logger: ILogger; protected randomUtil: RandomUtil; protected timeUtil: TimeUtil; @@ -18,7 +21,7 @@ export declare class WeatherGenerator { protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; private serverStartTimestampMS; - constructor(weightedRandomHelper: WeightedRandomHelper, logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, seasonalEventService: SeasonalEventService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(weightedRandomHelper: WeightedRandomHelper, weatherHelper: WeatherHelper, logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, seasonalEventService: SeasonalEventService, applicationContext: ApplicationContext, configServer: ConfigServer); /** * Get current + raid datetime and format into correct BSG format and return * @param data Weather data @@ -32,12 +35,6 @@ export declare class WeatherGenerator { * @returns formatted time */ protected getBsgFormattedInRaidTime(): string; - /** - * Get the current in-raid time - * @param currentDate (new Date()) - * @returns Date object of current in-raid time - */ - getInRaidTime(): Date; /** * Get current time formatted to fit BSGs requirement * @param date date to format into bsg style @@ -46,18 +43,28 @@ export declare class WeatherGenerator { protected getBSGFormattedTime(date: Date): string; /** * Return randomised Weather data with help of config/weather.json + * @param currentSeason the currently active season + * @param timestamp OPTIONAL what timestamp to generate the weather data at, defaults to now when not supplied * @returns Randomised weather data */ - generateWeather(): IWeather; + generateWeather(currentSeason: Season, timestamp?: number): IWeather; + /** + * Choose a temprature for the raid based on time of day and current season + * @param currentSeason What season tarkov is currently in + * @param inRaidTimestamp What time is the raid running at + * @returns Timestamp + */ + protected getRaidTemperature(currentSeason: Season, inRaidTimestamp: number): number; /** * Set IWeather date/time/timestamp values to now * @param weather Object to update + * @param timestamp OPTIONAL, define timestamp used */ - protected setCurrentDateTime(weather: IWeather): void; + protected setCurrentDateTime(weather: IWeather, timestamp?: number): void; protected getWeightedWindDirection(): WindDirection; protected getWeightedClouds(): number; protected getWeightedWindSpeed(): number; protected getWeightedFog(): number; protected getWeightedRain(): number; - protected getRandomFloat(node: string): number; + protected getRandomFloat(node: string, precision?: number): number; } diff --git a/types/generators/weapongen/InventoryMagGen.d.ts b/types/generators/weapongen/InventoryMagGen.d.ts index 1db99158..7e2011dc 100644 --- a/types/generators/weapongen/InventoryMagGen.d.ts +++ b/types/generators/weapongen/InventoryMagGen.d.ts @@ -1,5 +1,5 @@ -import { Inventory } from "@spt/models/eft/common/tables/IBotBase"; -import { GenerationData } from "@spt/models/eft/common/tables/IBotType"; +import { IInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IGenerationData } from "@spt/models/eft/common/tables/IBotType"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; export declare class InventoryMagGen { private magCounts; @@ -7,10 +7,10 @@ export declare class InventoryMagGen { private weaponTemplate; private ammoTemplate; private pmcInventory; - constructor(magCounts: GenerationData, magazineTemplate: ITemplateItem, weaponTemplate: ITemplateItem, ammoTemplate: ITemplateItem, pmcInventory: Inventory); - getMagCount(): GenerationData; + constructor(magCounts: IGenerationData, magazineTemplate: ITemplateItem, weaponTemplate: ITemplateItem, ammoTemplate: ITemplateItem, pmcInventory: IInventory); + getMagCount(): IGenerationData; getMagazineTemplate(): ITemplateItem; getWeaponTemplate(): ITemplateItem; getAmmoTemplate(): ITemplateItem; - getPmcInventory(): Inventory; + getPmcInventory(): IInventory; } diff --git a/types/helpers/BotDifficultyHelper.d.ts b/types/helpers/BotDifficultyHelper.d.ts index 2348bd33..ef30bbc0 100644 --- a/types/helpers/BotDifficultyHelper.d.ts +++ b/types/helpers/BotDifficultyHelper.d.ts @@ -1,5 +1,6 @@ import { BotHelper } from "@spt/helpers/BotHelper"; -import { Difficulty } from "@spt/models/eft/common/tables/IBotType"; +import { IDifficultyCategories } from "@spt/models/eft/common/tables/IBotType"; +import { IBots } from "@spt/models/spt/bots/IBots"; import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -17,42 +18,21 @@ export declare class BotDifficultyHelper { protected cloner: ICloner; protected pmcConfig: IPmcConfig; constructor(logger: ILogger, databaseService: DatabaseService, randomUtil: RandomUtil, localisationService: LocalisationService, botHelper: BotHelper, configServer: ConfigServer, cloner: ICloner); - /** - * Get a difficulty object modified to handle fighting other PMCs - * @param pmcType 'bear or 'usec' - * @param difficulty easy / normal / hard / impossible - * @param usecType pmcUSEC - * @param bearType pmcBEAR - * @returns Difficulty object - */ - getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; - /** - * Add bot types to ENEMY_BOT_TYPES array - * @param difficultySettings Bot settings to alter - * @param typesToAdd Bot types to add to enemy list - * @param typeBeingEdited Bot type to ignore and not add to enemy list - */ - protected addBotToEnemyList(difficultySettings: Difficulty, typesToAdd: string[], typeBeingEdited?: string): void; - /** - * Configure difficulty settings to be hostile to USEC and BEAR - * Look up value in bot.json/chanceSameSideIsHostilePercent - * @param difficultySettings pmc difficulty settings - */ - protected setDifficultyToHostileToBearAndUsec(difficultySettings: Difficulty): void; /** * Get difficulty settings for desired bot type, if not found use assault bot types * @param type bot type to retrieve difficulty of * @param difficulty difficulty to get settings for (easy/normal etc) + * @param botDb bots from database * @returns Difficulty object */ - getBotDifficultySettings(type: string, difficulty: string): Difficulty; + getBotDifficultySettings(type: string, difficulty: string, botDb: IBots): IDifficultyCategories; /** * Get difficulty settings for a PMC * @param type "usec" / "bear" * @param difficulty what difficulty to retrieve * @returns Difficulty object */ - protected getDifficultySettings(type: string, difficulty: string): Difficulty; + protected getDifficultySettings(type: string, difficulty: string): IDifficultyCategories; /** * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value * @param dropDownDifficulty Dropdown difficulty value to convert diff --git a/types/helpers/BotGeneratorHelper.d.ts b/types/helpers/BotGeneratorHelper.d.ts index 00ae8ae7..468d27bb 100644 --- a/types/helpers/BotGeneratorHelper.d.ts +++ b/types/helpers/BotGeneratorHelper.d.ts @@ -3,9 +3,9 @@ import { ContainerHelper } from "@spt/helpers/ContainerHelper"; import { DurabilityLimitsHelper } from "@spt/helpers/DurabilityLimitsHelper"; import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { Inventory } from "@spt/models/eft/common/tables/IBotBase"; -import { Item, Repairable, Upd } from "@spt/models/eft/common/tables/IItem"; -import { Grid, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem, IUpd, IUpdRepairable } from "@spt/models/eft/common/tables/IItem"; +import { IGrid, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { ItemAddedResult } from "@spt/models/enums/ItemAddedResult"; import { IChooseRandomCompatibleModResult } from "@spt/models/spt/bots/IChooseRandomCompatibleModResult"; import { EquipmentFilters, IBotConfig, IRandomisedResourceValues } from "@spt/models/spt/config/IBotConfig"; @@ -37,7 +37,7 @@ export declare class BotGeneratorHelper { * @returns Item Upd object with extra properties */ generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: string): { - upd?: Upd; + upd?: IUpd; }; /** * Randomize the HpResource for bots e.g (245/400 resources) @@ -60,15 +60,14 @@ export declare class BotGeneratorHelper { * @param botRole type of bot being generated for * @returns Repairable object */ - protected generateWeaponRepairableProperties(itemTemplate: ITemplateItem, botRole?: string): Repairable; + protected generateWeaponRepairableProperties(itemTemplate: ITemplateItem, botRole?: string): IUpdRepairable; /** * Create a repairable object for an armor that containers durability + max durability properties * @param itemTemplate weapon object being generated for * @param botRole type of bot being generated for * @returns Repairable object */ - protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole?: string): Repairable; - isWeaponModIncompatibleWithCurrentMods(itemsEquipped: Item[], tplToCheck: string, modSlot: string): IChooseRandomCompatibleModResult; + protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole?: string): IUpdRepairable; /** * Can item be added to another item without conflict * @param itemsEquipped Items to check compatibilities with @@ -76,7 +75,7 @@ export declare class BotGeneratorHelper { * @param equipmentSlot Slot the item will be placed into * @returns false if no incompatibilities, also has incompatibility reason */ - isItemIncompatibleWithCurrentItems(itemsEquipped: Item[], tplToCheck: string, equipmentSlot: string): IChooseRandomCompatibleModResult; + isItemIncompatibleWithCurrentItems(itemsEquipped: IItem[], tplToCheck: string, equipmentSlot: string): IChooseRandomCompatibleModResult; /** * Convert a bots role to the equipment role used in config/bot.json * @param botRole Role to convert @@ -92,12 +91,12 @@ export declare class BotGeneratorHelper { * @param inventory Inventory to add item+children into * @returns ItemAddedResult result object */ - addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], rootItemId: string, rootItemTplId: string, itemWithChildren: Item[], inventory: Inventory, containersIdFull?: Set): ItemAddedResult; + addItemWithChildrenToEquipmentSlot(equipmentSlots: string[], rootItemId: string, rootItemTplId: string, itemWithChildren: IItem[], inventory: IInventory, containersIdFull?: Set): ItemAddedResult; /** * Is the provided item allowed inside a container * @param slotGrid Items sub-grid we want to place item inside * @param itemTpl Item tpl being placed * @returns True if allowed */ - protected itemAllowedInContainer(slotGrid: Grid, itemTpl: string): boolean; + protected itemAllowedInContainer(slotGrid: IGrid, itemTpl: string): boolean; } diff --git a/types/helpers/BotHelper.d.ts b/types/helpers/BotHelper.d.ts index c5871ae7..7dc9b59a 100644 --- a/types/helpers/BotHelper.d.ts +++ b/types/helpers/BotHelper.d.ts @@ -1,6 +1,6 @@ import { MinMax } from "@spt/models/common/MinMax"; -import { Difficulty, IBotType } from "@spt/models/eft/common/tables/IBotType"; -import { EquipmentFilters, IBotConfig, RandomisationDetails } from "@spt/models/spt/config/IBotConfig"; +import { IBotType, IDifficultyCategories } from "@spt/models/eft/common/tables/IBotType"; +import { EquipmentFilters, IBotConfig, IRandomisationDetails } from "@spt/models/spt/config/IBotConfig"; import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,20 +33,15 @@ export declare class BotHelper { * @param difficultySettings bot settings to alter * @param typeToAdd bot type to add to friendly list */ - addBotToFriendlyList(difficultySettings: Difficulty, typeToAdd: string): void; + addBotToFriendlyList(difficultySettings: IDifficultyCategories, typeToAdd: string): void; /** * Add a bot to the REVENGE_BOT_TYPES array * @param difficultySettings bot settings to alter * @param typesToAdd bot type to add to revenge list */ - addBotToRevengeList(difficultySettings: Difficulty, typesToAdd: string[]): void; - /** - * Choose if a bot should become a PMC by checking if bot type is allowed to become a Pmc in botConfig.convertFromChances and doing a random int check - * @param botRole the bot role to check if should be a pmc - * @returns true if should be a pmc - */ - shouldBotBePmc(botRole: string): boolean; - rollChanceToBePmc(role: string, botConvertMinMax: MinMax): boolean; + addBotToRevengeList(difficultySettings: IDifficultyCategories, typesToAdd: string[]): void; + rollChanceToBePmc(botConvertMinMax: MinMax): boolean; + protected getPmcConversionValuesForLocation(location: string): Record; /** * is the provided role a PMC, case-agnostic * @param botRole Role to check @@ -59,7 +54,7 @@ export declare class BotHelper { * @param botEquipConfig bot equipment json * @returns RandomisationDetails */ - getBotRandomizationDetails(botLevel: number, botEquipConfig: EquipmentFilters): RandomisationDetails | undefined; + getBotRandomizationDetails(botLevel: number, botEquipConfig: EquipmentFilters): IRandomisationDetails | undefined; /** * Choose between pmcBEAR and pmcUSEC at random based on the % defined in pmcConfig.isUsec * @returns pmc role @@ -76,5 +71,11 @@ export declare class BotHelper { * @returns pmc side as string */ protected getRandomizedPmcSide(): string; - getPmcNicknameOfMaxLength(userId: string, maxLength: number): string; + /** + * Get a name from a PMC that fits the desired length + * @param maxLength Max length of name, inclusive + * @param side OPTIONAL - what side PMC to get name from (usec/bear) + * @returns name of PMC + */ + getPmcNicknameOfMaxLength(maxLength: number, side?: string): string; } diff --git a/types/helpers/BotWeaponGeneratorHelper.d.ts b/types/helpers/BotWeaponGeneratorHelper.d.ts index 5ab4e59f..8a2d23a0 100644 --- a/types/helpers/BotWeaponGeneratorHelper.d.ts +++ b/types/helpers/BotWeaponGeneratorHelper.d.ts @@ -1,9 +1,9 @@ import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; -import { Inventory } from "@spt/models/eft/common/tables/IBotBase"; -import { GenerationData } from "@spt/models/eft/common/tables/IBotType"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IGenerationData } from "@spt/models/eft/common/tables/IBotType"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { EquipmentSlots } from "@spt/models/enums/EquipmentSlots"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -27,13 +27,13 @@ export declare class BotWeaponGeneratorHelper { * @param magTemplate magazine to generate bullet count for * @returns bullet count number */ - getRandomizedBulletCount(magCounts: GenerationData, magTemplate: ITemplateItem): number; + getRandomizedBulletCount(magCounts: IGenerationData, magTemplate: ITemplateItem): number; /** * Get a randomized count of magazines * @param magCounts min and max value returned value can be between * @returns numerical value of magazine count */ - getRandomizedMagazineCount(magCounts: GenerationData): number; + getRandomizedMagazineCount(magCounts: IGenerationData): number; /** * Is this magazine cylinder related (revolvers and grenade launchers) * @param magazineParentName the name of the magazines parent @@ -47,7 +47,7 @@ export declare class BotWeaponGeneratorHelper { * @param magTemplate template object of magazine * @returns Item array */ - createMagazineWithAmmo(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): Item[]; + createMagazineWithAmmo(magazineTpl: string, ammoTpl: string, magTemplate: ITemplateItem): IItem[]; /** * Add a specific number of cartridges to a bots inventory (defaults to vest and pockets) * @param ammoTpl Ammo tpl to add to vest/pockets @@ -55,7 +55,7 @@ export declare class BotWeaponGeneratorHelper { * @param inventory bot inventory to add cartridges to * @param equipmentSlotsToAddTo what equipment slots should bullets be added into */ - addAmmoIntoEquipmentSlots(ammoTpl: string, cartridgeCount: number, inventory: Inventory, equipmentSlotsToAddTo?: EquipmentSlots[]): void; + addAmmoIntoEquipmentSlots(ammoTpl: string, cartridgeCount: number, inventory: IInventory, equipmentSlotsToAddTo?: EquipmentSlots[]): void; /** * Get a weapons default magazine template id * @param weaponTemplate weapon to get default magazine for diff --git a/types/helpers/Dialogue/SptDialogueChatBot.d.ts b/types/helpers/Dialogue/SptDialogueChatBot.d.ts index 8d3aa979..d2bf5c52 100644 --- a/types/helpers/Dialogue/SptDialogueChatBot.d.ts +++ b/types/helpers/Dialogue/SptDialogueChatBot.d.ts @@ -6,17 +6,21 @@ import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { GiftService } from "@spt/services/GiftService"; +import { LocalisationService } from "@spt/services/LocalisationService"; import { MailSendService } from "@spt/services/MailSendService"; +import { SeasonalEventService } from "@spt/services/SeasonalEventService"; import { RandomUtil } from "@spt/utils/RandomUtil"; export declare class SptDialogueChatBot implements IDialogueChatBot { protected profileHelper: ProfileHelper; protected randomUtil: RandomUtil; protected mailSendService: MailSendService; + protected seasonalEventService: SeasonalEventService; + protected localisationService: LocalisationService; protected giftService: GiftService; protected configServer: ConfigServer; protected coreConfig: ICoreConfig; protected weatherConfig: IWeatherConfig; - constructor(profileHelper: ProfileHelper, randomUtil: RandomUtil, mailSendService: MailSendService, giftService: GiftService, configServer: ConfigServer); + constructor(profileHelper: ProfileHelper, randomUtil: RandomUtil, mailSendService: MailSendService, seasonalEventService: SeasonalEventService, localisationService: LocalisationService, giftService: GiftService, configServer: ConfigServer); getChatBot(): IUserDialogInfo; /** * Send responses back to player when they communicate with SPT friend on friends list diff --git a/types/helpers/DialogueHelper.d.ts b/types/helpers/DialogueHelper.d.ts index febe696c..7e1f9db8 100644 --- a/types/helpers/DialogueHelper.d.ts +++ b/types/helpers/DialogueHelper.d.ts @@ -1,8 +1,8 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper"; import { NotifierHelper } from "@spt/helpers/NotifierHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { Dialogue, MessagePreview } from "@spt/models/eft/profile/ISptProfile"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IDialogue, IMessagePreview } from "@spt/models/eft/profile/ISptProfile"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseServer } from "@spt/servers/DatabaseServer"; import { SaveServer } from "@spt/servers/SaveServer"; @@ -23,7 +23,7 @@ export declare class DialogueHelper { * @param dialogue * @returns MessagePreview */ - getMessagePreview(dialogue: Dialogue): MessagePreview; + getMessagePreview(dialogue: IDialogue): IMessagePreview; /** * Get the item contents for a particular message. * @param messageID @@ -31,11 +31,11 @@ export declare class DialogueHelper { * @param itemId Item being moved to inventory * @returns */ - getMessageItemContents(messageID: string, sessionID: string, itemId: string): Item[]; + getMessageItemContents(messageID: string, sessionID: string, itemId: string): IItem[]; /** * Get the dialogs dictionary for a profile, create if doesnt exist * @param sessionId Session/player id * @returns Dialog dictionary */ - getDialogsForProfile(sessionId: string): Record; + getDialogsForProfile(sessionId: string): Record; } diff --git a/types/helpers/HandbookHelper.d.ts b/types/helpers/HandbookHelper.d.ts index 0ed965ec..d6777345 100644 --- a/types/helpers/HandbookHelper.d.ts +++ b/types/helpers/HandbookHelper.d.ts @@ -1,5 +1,5 @@ -import { Category } from "@spt/models/eft/common/tables/IHandbookBase"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IHandbookCategory } from "@spt/models/eft/common/tables/IHandbookBase"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IItemConfig } from "@spt/models/spt/config/IItemConfig"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { DatabaseService } from "@spt/services/DatabaseService"; @@ -33,7 +33,7 @@ export declare class HandbookHelper { * @returns price in roubles */ getTemplatePrice(tpl: string): number; - getTemplatePriceForItems(items: Item[]): number; + getTemplatePriceForItems(items: IItem[]): number; /** * Get all items in template with the given parent category * @param parentId @@ -66,6 +66,6 @@ export declare class HandbookHelper { * @returns currency count in desired type */ fromRUB(roubleCurrencyCount: number, currencyTypeTo: string): number; - getCategoryById(handbookId: string): Category; + getCategoryById(handbookId: string): IHandbookCategory; } export {}; diff --git a/types/helpers/HealthHelper.d.ts b/types/helpers/HealthHelper.d.ts index a164285e..b05d0089 100644 --- a/types/helpers/HealthHelper.d.ts +++ b/types/helpers/HealthHelper.d.ts @@ -1,6 +1,7 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; +import { IBodyPartsHealth, IHealth } from "@spt/models/eft/common/tables/IBotBase"; import { ISyncHealthRequestData } from "@spt/models/eft/health/ISyncHealthRequestData"; -import { Effects, ISptProfile } from "@spt/models/eft/profile/ISptProfile"; +import { IEffects, ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { IHealthConfig } from "@spt/models/spt/config/IHealthConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -21,6 +22,23 @@ export declare class HealthHelper { * @returns updated profile */ resetVitality(sessionID: string): ISptProfile; + /** + * Update player profile vitality values with changes from client request object + * @param pmcData Player profile + * @param postRaidHealth Post raid data + * @param sessionID Session id + * @param isDead Is player dead + * @param addEffects Should effects be added to profile (default - true) + * @param deleteExistingEffects Should all prior effects be removed before apply new ones (default - true) + */ + updateProfileHealthPostRaid(pmcData: IPmcData, postRaidHealth: IHealth, sessionID: string, isDead: boolean): void; + protected storeHydrationEnergyTempInProfile(fullProfile: ISptProfile, hydration: number, energy: number, temprature: number): void; + /** + * Take body part effects from client profile and apply to server profile + * @param postRaidBodyParts Post-raid body part data + * @param profileData Player profile on server + */ + protected transferPostRaidLimbEffectsToProfile(postRaidBodyParts: IBodyPartsHealth, profileData: IPmcData): void; /** * Update player profile vitality values with changes from client request object * @param pmcData Player profile @@ -45,7 +63,7 @@ export declare class HealthHelper { * @param bodyPartsWithEffects dict of body parts with effects that should be added to profile * @param addEffects Should effects be added back to profile */ - protected saveEffects(pmcData: IPmcData, sessionId: string, bodyPartsWithEffects: Effects, deleteExistingEffects?: boolean): void; + protected saveEffects(pmcData: IPmcData, sessionId: string, bodyPartsWithEffects: IEffects, deleteExistingEffects?: boolean): void; /** * Add effect to body part in profile * @param pmcData Player profile diff --git a/types/helpers/HideoutHelper.d.ts b/types/helpers/HideoutHelper.d.ts index df0376b5..21672c65 100644 --- a/types/helpers/HideoutHelper.d.ts +++ b/types/helpers/HideoutHelper.d.ts @@ -2,14 +2,15 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { HideoutArea, IHideoutImprovement, Production, Productive } from "@spt/models/eft/common/tables/IBotBase"; -import { Item, Upd } from "@spt/models/eft/common/tables/IItem"; -import { StageBonus } from "@spt/models/eft/hideout/IHideoutArea"; +import { IBotHideoutArea, IHideoutImprovement, IProduction, IProductive } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem, IUpd } from "@spt/models/eft/common/tables/IItem"; +import { IHideoutArea, IStageBonus } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutContinuousProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutContinuousProductionStartRequestData"; import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction"; import { IHideoutSingleProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutSingleProductionStartRequestData"; import { IHideoutTakeProductionRequestData } from "@spt/models/eft/hideout/IHideoutTakeProductionRequestData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; +import { HideoutAreas } from "@spt/models/enums/HideoutAreas"; import { SkillTypes } from "@spt/models/enums/SkillTypes"; import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -37,6 +38,7 @@ export declare class HideoutHelper { protected configServer: ConfigServer; protected cloner: ICloner; static bitcoinFarm: string; + static cultistCircleCraftId: string; static bitcoinProductionId: string; static waterCollector: string; static maxSkillPoint: number; @@ -54,19 +56,19 @@ export declare class HideoutHelper { * This convenience function initializes new Production Object * with all the constants. */ - initProduction(recipeId: string, productionTime: number, needFuelForAllProductionTime: boolean): Production; + initProduction(recipeId: string, productionTime: number, needFuelForAllProductionTime: boolean): IProduction; /** * Is the provided object a Production type * @param productive * @returns */ - isProductionType(productive: Productive): productive is Production; + isProductionType(productive: IProductive): productive is IProduction; /** * Apply bonus to player profile given after completing hideout upgrades * @param pmcData Profile to add bonus to * @param bonus Bonus to add to profile */ - applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: StageBonus): void; + applyPlayerUpgradesBonuses(pmcData: IPmcData, bonus: IStageBonus): void; /** * Process a players hideout, update areas that use resources + increment production timers * @param sessionID Session id @@ -82,7 +84,7 @@ export declare class HideoutHelper { isGeneratorOn: boolean; waterCollectorHasFilter: boolean; }; - protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean; + protected doesWaterCollectorHaveFilter(waterCollector: IBotHideoutArea): boolean; /** * Iterate over productions and update their progress timers * @param pmcData Profile to check for productions and update @@ -93,6 +95,21 @@ export declare class HideoutHelper { isGeneratorOn: boolean; waterCollectorHasFilter: boolean; }): void; + /** + * Is a craft from a particular hideout area + * @param craft Craft to check + * @param hideoutType Type to check craft against + * @returns True it is from that area + */ + protected isCraftOfType(craft: IProduction, hideoutType: HideoutAreas): boolean; + /** + * Has the craft completed + * Ignores bitcoin farm/cultist circle as they're continuous crafts + * @param craft Craft to check + + * @returns True when craft is compelte + */ + protected isCraftComplete(craft: IProduction): boolean; /** * Update progress timer for water collector * @param pmcData profile to update @@ -116,6 +133,8 @@ export declare class HideoutHelper { isGeneratorOn: boolean; waterCollectorHasFilter?: boolean; }): void; + protected updateCultistCircleCraftProgress(pmcData: IPmcData, prodId: string): void; + protected flagCultistCircleCraftAsComplete(production: IProductive): void; /** * Check if a productions progress value matches its corresponding recipes production time value * @param pmcData Player profile @@ -147,8 +166,8 @@ export declare class HideoutHelper { * @param pmcData Player profile * @param isGeneratorOn Is the generator turned on since last update */ - protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void; - protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, hideoutProperties: { + protected updateFuel(generatorArea: IBotHideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void; + protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: IBotHideoutArea, hideoutProperties: { btcFarmCGs: number; isGeneratorOn: boolean; waterCollectorHasFilter: boolean; @@ -168,7 +187,7 @@ export declare class HideoutHelper { * @param isGeneratorOn is generator enabled * @param pmcData Player profile */ - protected updateWaterFilters(waterFilterArea: HideoutArea, production: Production, isGeneratorOn: boolean, pmcData: IPmcData): void; + protected updateWaterFilters(waterFilterArea: IBotHideoutArea, production: IProduction, isGeneratorOn: boolean, pmcData: IPmcData): void; /** * Get an adjusted water filter drain rate based on time elapsed since last run, * handle edge case when craft time has gone on longer than total production time @@ -198,15 +217,15 @@ export declare class HideoutHelper { * @param resourceUnitsConsumed * @returns Upd */ - protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number, isFoundInRaid: boolean): Upd; - protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void; - protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production | undefined; + protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number, isFoundInRaid: boolean): IUpd; + protected updateAirFilters(airFilterArea: IBotHideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void; + protected updateBitcoinFarm(pmcData: IPmcData, btcProduction: IProductive, btcFarmCGs: number, isGeneratorOn: boolean): void; /** * Add bitcoin object to btc production products array and set progress time * @param btcProd Bitcoin production object * @param coinCraftTimeSeconds Time to craft a bitcoin */ - protected addBtcToProduction(btcProd: Production, coinCraftTimeSeconds: number): void; + protected addBtcToProduction(btcProd: IProduction, coinCraftTimeSeconds: number): void; /** * Get number of ticks that have passed since hideout areas were last processed, reduced when generator is off * @param pmcData Player profile @@ -248,7 +267,7 @@ export declare class HideoutHelper { * @returns Seconds to reduce craft time by */ getSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number, skill: SkillTypes, amountPerLevel: number): number; - isProduction(productive: Productive): productive is Production; + isProduction(productive: IProductive): productive is IProduction; /** * Gather crafted BTC from hideout area and add to inventory * Reset production start timestamp if hideout area at full coin capacity @@ -286,5 +305,12 @@ export declare class HideoutHelper { * @param activeDogtags Active dogtags in place of fame dogtag slots * @returns combat bonus */ - protected getDogtagCombatSkillBonusPercent(pmcData: IPmcData, activeDogtags: Item[]): number; + protected getDogtagCombatSkillBonusPercent(pmcData: IPmcData, activeDogtags: IItem[]): number; + /** + * The wall pollutes a profile with various temp buffs/debuffs, + * Remove them all + * @param wallAreaDb Hideout area data + * @param pmcData Player profile + */ + removeHideoutWallBuffsAndDebuffs(wallAreaDb: IHideoutArea, pmcData: IPmcData): void; } diff --git a/types/helpers/InRaidHelper.d.ts b/types/helpers/InRaidHelper.d.ts index 987c9ec3..c64077eb 100644 --- a/types/helpers/InRaidHelper.d.ts +++ b/types/helpers/InRaidHelper.d.ts @@ -1,122 +1,35 @@ +import { QuestController } from "@spt/controllers/QuestController"; import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { PaymentHelper } from "@spt/helpers/PaymentHelper"; -import { ProfileHelper } from "@spt/helpers/ProfileHelper"; -import { QuestHelper } from "@spt/helpers/QuestHelper"; -import { IPmcData, IPostRaidPmcData } from "@spt/models/eft/common/IPmcData"; -import { IQuestStatus, TraderInfo } from "@spt/models/eft/common/tables/IBotBase"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { ISaveProgressRequestData } from "@spt/models/eft/inRaid/ISaveProgressRequestData"; +import { IPmcData } from "@spt/models/eft/common/IPmcData"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IInRaidConfig } from "@spt/models/spt/config/IInRaidConfig"; import { ILostOnDeathConfig } from "@spt/models/spt/config/ILostOnDeathConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; -import { SaveServer } from "@spt/servers/SaveServer"; import { DatabaseService } from "@spt/services/DatabaseService"; -import { LocalisationService } from "@spt/services/LocalisationService"; -import { ProfileFixerService } from "@spt/services/ProfileFixerService"; -import { RandomUtil } from "@spt/utils/RandomUtil"; -import { TimeUtil } from "@spt/utils/TimeUtil"; import { ICloner } from "@spt/utils/cloners/ICloner"; +import { ProfileHelper } from "./ProfileHelper"; +import { QuestHelper } from "./QuestHelper"; export declare class InRaidHelper { protected logger: ILogger; - protected timeUtil: TimeUtil; - protected saveServer: SaveServer; + protected inventoryHelper: InventoryHelper; protected itemHelper: ItemHelper; + protected configServer: ConfigServer; + protected cloner: ICloner; protected databaseService: DatabaseService; - protected inventoryHelper: InventoryHelper; + protected questController: QuestController; protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; - protected paymentHelper: PaymentHelper; - protected localisationService: LocalisationService; - protected profileFixerService: ProfileFixerService; - protected configServer: ConfigServer; - protected randomUtil: RandomUtil; - protected cloner: ICloner; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, saveServer: SaveServer, itemHelper: ItemHelper, databaseService: DatabaseService, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer, randomUtil: RandomUtil, cloner: ICloner); - /** - * Lookup quest item loss from lostOnDeath config - * @returns True if items should be removed from inventory - */ - shouldQuestItemsBeRemovedOnDeath(): boolean; - /** - * Check items array and add an upd object to money with a stack count of 1 - * Single stack money items have no upd object and thus no StackObjectsCount, causing issues - * @param items Items array to check - */ - addStackCountToMoneyFromRaid(items: Item[]): void; - /** - * Reset a profile to a baseline, used post-raid - * Reset points earned during session property - * Increment exp - * @param profileData Profile to update - * @param saveProgressRequest post raid save data request data - * @param sessionID Session id - * @returns Reset profile object - */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; + constructor(logger: ILogger, inventoryHelper: InventoryHelper, itemHelper: ItemHelper, configServer: ConfigServer, cloner: ICloner, databaseService: DatabaseService, questController: QuestController, profileHelper: ProfileHelper, questHelper: QuestHelper); /** + * @deprecated * 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 validateTaskConditionCounters(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 a status different from what it began the raid with - * @param sessionId Player id - * @param pmcData Player profile - * @param preRaidQuests Quests prior to starting raid - * @param postRaidProfile Profile sent by client with post-raid quests - */ - protected processAlteredQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; - protected handleFailRestartableQuestStatus(pmcData: IPmcData, postRaidProfile: IPostRaidPmcData, postRaidQuest: IQuestStatus): void; - /** - * Take body part effects from client profile and apply to server profile - * @param saveProgressRequest post-raid request - * @param profileData player profile on server - */ - protected transferPostRaidLimbEffectsToProfile(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; - /** - * Adjust server trader settings if they differ from data sent by client - * @param tradersServerProfile Server - * @param tradersClientProfile Client - */ - protected applyTraderStandingAdjustments(tradersServerProfile: Record, tradersClientProfile: Record): void; - /** - * Transfer client achievements into profile - * @param profile Player pmc profile - * @param clientAchievements Achievements from client - */ - protected updateProfileAchievements(profile: IPmcData, clientAchievements: Record): void; - /** - * Set the SPT inraid location Profile property to 'none' - * @param sessionID Session id - */ - protected setPlayerInRaidLocationStatusToNone(sessionID: string): void; - /** - * Iterate over inventory items and remove the property that defines an item as Found in Raid - * Only removes property if item had FiR when entering raid - * @param postRaidProfile profile to update items for - * @returns Updated profile with SpawnedInSession removed - */ - removeSpawnedInSessionPropertyFromItems(postRaidProfile: IPostRaidPmcData): IPostRaidPmcData; /** * Update a players inventory post-raid * Remove equipped items from pre-raid @@ -126,7 +39,18 @@ export declare class InRaidHelper { * @param serverProfile Profile to update * @param postRaidProfile Profile returned by client after a raid */ - setInventory(sessionID: string, serverProfile: IPmcData, postRaidProfile: IPmcData): void; + setInventory(sessionID: string, serverProfile: IPmcData, postRaidProfile: IPmcData, isSurvived: boolean, isTransfer: boolean): void; + /** + * Remove FiR status from items + * @param items Items to process + */ + protected removeFiRStatusFromCertainItems(items: IItem[]): void; + /** + * Add items from one parameter into another + * @param itemsToAdd Items we want to add + * @param serverInventoryItems Location to add items to + */ + protected addItemsToInventory(itemsToAdd: IItem[], serverInventoryItems: IItem[]): void; /** * Clear PMC inventory of all items except those that are exempt * Used post-raid to remove items after death @@ -134,29 +58,24 @@ export declare class InRaidHelper { * @param sessionId Session id */ deleteInventory(pmcData: IPmcData, sessionId: string): void; + /** + * Remove FiR status from designated container + * @param sessionId Session id + * @param pmcData Player profile + * @param secureContainerSlotId Container slot id to find items for and remove FiR from + */ + removeFiRStatusFromItemsInContainer(sessionId: string, pmcData: IPmcData, secureContainerSlotId: string): void; /** * Get an array of items from a profile that will be lost on death * @param pmcProfile Profile to get items from * @returns Array of items lost on death */ - protected getInventoryItemsLostOnDeath(pmcProfile: IPmcData): Item[]; - /** - * Get items in vest/pocket/backpack inventory containers (excluding children) - * @param pmcData Player profile - * @returns Item array - */ - protected getBaseItemsInRigPocketAndBackpack(pmcData: IPmcData): Item[]; + protected getInventoryItemsLostOnDeath(pmcProfile: IPmcData): IItem[]; /** * Does the provided items slotId mean its kept on the player after death * @pmcData Player profile * @itemToCheck Item to check should be kept * @returns true if item is kept after death */ - protected isItemKeptAfterDeath(pmcData: IPmcData, itemToCheck: Item): boolean; - /** - * Return the equipped items from a players inventory - * @param items Players inventory to search through - * @returns an array of equipped items - */ - getPlayerGear(items: Item[]): Item[]; + protected isItemKeptAfterDeath(pmcData: IPmcData, itemToCheck: IItem): boolean; } diff --git a/types/helpers/InventoryHelper.d.ts b/types/helpers/InventoryHelper.d.ts index 92bb49c6..b082fa95 100644 --- a/types/helpers/InventoryHelper.d.ts +++ b/types/helpers/InventoryHelper.d.ts @@ -6,8 +6,8 @@ import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderAssortHelper } from "@spt/helpers/TraderAssortHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Inventory } from "@spt/models/eft/common/tables/IBotBase"; -import { Item, Upd } from "@spt/models/eft/common/tables/IItem"; +import { IInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem, IItemLocation, IUpd } from "@spt/models/eft/common/tables/IItem"; import { IAddItemDirectRequest } from "@spt/models/eft/inventory/IAddItemDirectRequest"; import { IAddItemsDirectRequest } from "@spt/models/eft/inventory/IAddItemsDirectRequest"; import { IInventoryMergeRequestData } from "@spt/models/eft/inventory/IInventoryMergeRequestData"; @@ -16,7 +16,7 @@ import { IInventoryRemoveRequestData } from "@spt/models/eft/inventory/IInventor import { IInventorySplitRequestData } from "@spt/models/eft/inventory/IInventorySplitRequestData"; import { IInventoryTransferRequestData } from "@spt/models/eft/inventory/IInventoryTransferRequestData"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IInventoryConfig, RewardDetails } from "@spt/models/spt/config/IInventoryConfig"; +import { IInventoryConfig, IRewardDetails } from "@spt/models/spt/config/IInventoryConfig"; import { IOwnerInventoryItems } from "@spt/models/spt/inventory/IOwnerInventoryItems"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -65,33 +65,33 @@ export declare class InventoryHelper { * @param itemWithChildren An item * @param foundInRaid Item was found in raid */ - protected setFindInRaidStatusForItem(itemWithChildren: Item[], foundInRaid: boolean): void; + protected setFindInRaidStatusForItem(itemWithChildren: IItem[], foundInRaid: boolean): void; /** * Remove properties from a Upd object used by a trader/ragfair that are unnecessary to a player * @param upd Object to update */ - protected removeTraderRagfairRelatedUpdProperties(upd: Upd): void; + protected removeTraderRagfairRelatedUpdProperties(upd: IUpd): void; /** - * Can all probided items be added into player inventory + * Can all provided items be added into player inventory * @param sessionId Player id * @param itemsWithChildren array of items with children to try and fit * @returns True all items fit */ - canPlaceItemsInInventory(sessionId: string, itemsWithChildren: Item[][]): boolean; + canPlaceItemsInInventory(sessionId: string, itemsWithChildren: IItem[][]): boolean; /** * Do the provided items all fit into the grid * @param containerFS2D Container grid to fit items into * @param itemsWithChildren items to try and fit into grid * @returns True all fit */ - canPlaceItemsInContainer(containerFS2D: number[][], itemsWithChildren: Item[][]): boolean; + canPlaceItemsInContainer(containerFS2D: number[][], itemsWithChildren: IItem[][]): boolean; /** * Does an item fit into a container grid * @param containerFS2D Container grid * @param itemWithChildren item to check fits * @returns True it fits */ - canPlaceItemInContainer(containerFS2D: number[][], itemWithChildren: Item[]): boolean; + canPlaceItemInContainer(containerFS2D: number[][], itemWithChildren: IItem[]): boolean; /** * Find a free location inside a container to fit the item * @param containerFS2D Container grid to add item to @@ -99,7 +99,7 @@ export declare class InventoryHelper { * @param containerId Id of the container we're fitting item into * @param desiredSlotId slot id value to use, default is "hideout" */ - placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string, desiredSlotId?: string): void; + placeItemInContainer(containerFS2D: number[][], itemWithChildren: IItem[], containerId: string, desiredSlotId?: string): void; /** * Find a location to place an item into inventory and place it * @param stashFS2D 2-dimensional representation of the container slots @@ -109,7 +109,7 @@ export declare class InventoryHelper { * @param useSortingTable Should sorting table to be used if main stash has no space * @param output output to send back to client */ - protected placeItemInInventory(stashFS2D: number[][], sortingTableFS2D: number[][], itemWithChildren: Item[], playerInventory: Inventory, useSortingTable: boolean, output: IItemEventRouterResponse): void; + protected placeItemInInventory(stashFS2D: number[][], sortingTableFS2D: number[][], itemWithChildren: IItem[], playerInventory: IInventory, useSortingTable: boolean, output: IItemEventRouterResponse): void; /** * Handle Remove event * Remove item from player inventory + insured items array @@ -144,7 +144,7 @@ export declare class InventoryHelper { * @param inventoryItems * @returns [width, height] */ - getItemSize(itemTpl: string, itemID: string, inventoryItems: Item[]): number[]; + getItemSize(itemTpl: string, itemID: string, inventoryItems: IItem[]): number[]; /** * Calculates the size of an item including attachements * takes into account if item is folded @@ -162,14 +162,16 @@ export declare class InventoryHelper { */ protected getBlankContainerMap(containerH: number, containerY: number): number[][]; /** + * Get a 2d mapping of a container with what grid slots are filled * @param containerH Horizontal size of container * @param containerV Vertical size of container - * @param itemList + * @param itemList Players inventory items * @param containerId Id of the container * @returns Two-dimensional representation of container */ - getContainerMap(containerH: number, containerV: number, itemList: Item[], containerId: string): number[][]; - protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash; + getContainerMap(containerH: number, containerV: number, itemList: IItem[], containerId: string): number[][]; + protected isVertical(itemLocation: IItemLocation): boolean; + protected getInventoryItemHash(inventoryItem: IItem[]): InventoryHelper.InventoryItemHash; /** * Return the inventory that needs to be modified (scav/pmc etc) * Changes made to result apply to character inventory @@ -217,7 +219,7 @@ export declare class InventoryHelper { * @param toItems Inventory of the destination * @param request Move request */ - moveItemToProfile(sourceItems: Item[], toItems: Item[], request: IInventoryMoveRequestData): void; + moveItemToProfile(sourceItems: IItem[], toItems: IItem[], request: IInventoryMoveRequestData): void; /** * Internal helper function to move item within the same profile_f. * @param pmcData profile to edit @@ -225,7 +227,7 @@ export declare class InventoryHelper { * @param moveRequest client move request * @returns True if move was successful */ - moveItemInternal(pmcData: IPmcData, inventoryItems: Item[], moveRequest: IInventoryMoveRequestData): { + moveItemInternal(pmcData: IPmcData, inventoryItems: IItem[], moveRequest: IInventoryMoveRequestData): { success: boolean; errorMessage?: string; }; @@ -234,17 +236,17 @@ export declare class InventoryHelper { * @param pmcData Player profile * @param itemBeingMoved item being moved */ - protected updateFastPanelBinding(pmcData: IPmcData, itemBeingMoved: Item): void; + protected updateFastPanelBinding(pmcData: IPmcData, itemBeingMoved: IItem): void; /** * Internal helper function to handle cartridges in inventory if any of them exist. */ - protected handleCartridges(items: Item[], request: IInventoryMoveRequestData): void; + protected handleCartridges(items: IItem[], request: IInventoryMoveRequestData): void; /** * Get details for how a random loot container should be handled, max rewards, possible reward tpls * @param itemTpl Container being opened * @returns Reward details */ - getRandomLootContainerRewardDetails(itemTpl: string): RewardDetails; + getRandomLootContainerRewardDetails(itemTpl: string): IRewardDetails; getInventoryConfig(): IInventoryConfig; /** * Recursively checks if the given item is @@ -254,12 +256,21 @@ export declare class InventoryHelper { * @param itemToCheck Item to look for * @returns True if item exists inside stash */ - isItemInStash(pmcData: IPmcData, itemToCheck: Item): boolean; + isItemInStash(pmcData: IPmcData, itemToCheck: IItem): boolean; + validateInventoryUsesMonogoIds(itemsToValidate: IItem[]): void; + /** + * Does the provided item have a root item with the provided id + * @param pmcData Profile with items + * @param item Item to check + * @param rootId Root item id to check for + * @returns True when item has rootId, false when not + */ + doesItemHaveRootId(pmcData: IPmcData, item: IItem, rootId: string): boolean; } declare namespace InventoryHelper { interface InventoryItemHash { - byItemId: Record; - byParentId: Record; + byItemId: Record; + byParentId: Record; } } export {}; diff --git a/types/helpers/ItemHelper.d.ts b/types/helpers/ItemHelper.d.ts index c304ceee..24a6b38f 100644 --- a/types/helpers/ItemHelper.d.ts +++ b/types/helpers/ItemHelper.d.ts @@ -1,8 +1,8 @@ import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { IStaticAmmoDetails } from "@spt/models/eft/common/ILocation"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { InsuredItem } from "@spt/models/eft/common/tables/IBotBase"; -import { Item, Repairable, Upd } from "@spt/models/eft/common/tables/IItem"; +import { IInsuredItem } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem, IUpd, IUpdRepairable } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { ItemTpl } from "@spt/models/enums/ItemTpl"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -42,7 +42,7 @@ export declare class ItemHelper { * @param slotId OPTIONAL - slotid of desired item * @returns True if pool contains item */ - hasItemWithTpl(itemPool: Item[], item: ItemTpl, slotId?: string): boolean; + hasItemWithTpl(itemPool: IItem[], item: ItemTpl, slotId?: string): boolean; /** * Get the first item from provided pool with the desired tpl * @param itemPool Item collection to search @@ -50,7 +50,7 @@ export declare class ItemHelper { * @param slotId OPTIONAL - slotid of desired item * @returns Item or undefined */ - getItemFromPoolByTpl(itemPool: Item[], item: ItemTpl, slotId?: string): Item | undefined; + getItemFromPoolByTpl(itemPool: IItem[], item: ItemTpl, slotId?: string): IItem | undefined; /** * This method will compare two items (with all its children) and see if the are equivalent. * This method will NOT compare IDs on the items @@ -59,7 +59,7 @@ export declare class ItemHelper { * @param compareUpdProperties Upd properties to compare between the items * @returns true if they are the same, false if they arent */ - isSameItems(item1: Item[], item2: Item[], compareUpdProperties?: Set): boolean; + isSameItems(item1: IItem[], item2: IItem[], compareUpdProperties?: Set): boolean; /** * This method will compare two items and see if the are equivalent. * This method will NOT compare IDs on the items @@ -68,15 +68,21 @@ export declare class ItemHelper { * @param compareUpdProperties Upd properties to compare between the items * @returns true if they are the same, false if they arent */ - isSameItem(item1: Item, item2: Item, compareUpdProperties?: Set): boolean; + isSameItem(item1: IItem, item2: IItem, compareUpdProperties?: Set): boolean; /** * Helper method to generate a Upd based on a template * @param itemTemplate the item template to generate a Upd for * @returns A Upd with all the default properties set */ - generateUpdForItem(itemTemplate: ITemplateItem): Upd; + generateUpdForItem(itemTemplate: ITemplateItem): IUpd; /** - * Checks if an id is a valid item. Valid meaning that it's an item that be stored in stash + * Checks if a tpl is a valid item. Valid meaning that it's an item that be stored in stash + * Valid means: + * Not quest item + * 'Item' type + * Not on the invalid base types array + * Price above 0 roubles + * Not on item config blacklist * @param {string} tpl the template id / tpl * @returns boolean; true for items that may be in player possession and not quest items */ @@ -165,7 +171,7 @@ export declare class ItemHelper { * @param item Item to update * @returns Fixed item */ - fixItemStackCount(item: Item): Item; + fixItemStackCount(item: IItem): IItem; /** * Get cloned copy of all item data from items.json * @returns array of ITemplateItem objects @@ -185,7 +191,7 @@ export declare class ItemHelper { * @param skipArmorItemsWithoutDurability Skip over armor items without durability * @returns % quality modifer between 0 and 1 */ - getItemQualityModifierForItems(items: Item[], skipArmorItemsWithoutDurability?: boolean): number; + getItemQualityModifierForItems(items: IItem[], skipArmorItemsWithoutDurability?: boolean): number; /** * get normalized value (0-1) based on item condition * Will return -1 for base armor items with 0 durability @@ -193,7 +199,7 @@ export declare class ItemHelper { * @param skipArmorItemsWithoutDurability return -1 for armor items that have maxdurability of 0 * @returns Number between 0 and 1 */ - getItemQualityModifier(item: Item, skipArmorItemsWithoutDurability?: boolean): number; + getItemQualityModifier(item: IItem, skipArmorItemsWithoutDurability?: boolean): number; /** * Get a quality value based on a repairable items (weapon/armor) current state between current and max durability * @param itemDetails Db details for item we want quality value for @@ -201,14 +207,14 @@ export declare class ItemHelper { * @param item Item quality value is for * @returns A number between 0 and 1 */ - protected getRepairableItemQualityValue(itemDetails: ITemplateItem, repairable: Repairable, item: Item): number; + protected getRepairableItemQualityValue(itemDetails: ITemplateItem, repairable: IUpdRepairable, item: IItem): number; /** * Recursive function that looks at every item from parameter and gets their childrens Ids + includes parent item in results * @param items Array of items (item + possible children) * @param baseItemId Parent items id * @returns an array of strings */ - findAndReturnChildrenByItems(items: Item[], baseItemId: string): string[]; + findAndReturnChildrenByItems(items: IItem[], baseItemId: string): string[]; /** * A variant of findAndReturnChildren where the output is list of item objects instead of their ids. * @param items Array of items (item + possible children) @@ -216,20 +222,20 @@ export declare class ItemHelper { * @param modsOnly Include only mod items, exclude items stored inside root item * @returns An array of Item objects */ - findAndReturnChildrenAsItems(items: Item[], baseItemId: string, modsOnly?: boolean): Item[]; + findAndReturnChildrenAsItems(items: IItem[], baseItemId: string, modsOnly?: boolean): IItem[]; /** * Find children of the item in a given assort (weapons parts for example, need recursive loop function) * @param itemIdToFind Template id of item to check for * @param assort Array of items to check in * @returns Array of children of requested item */ - findAndReturnChildrenByAssort(itemIdToFind: string, assort: Item[]): Item[]; + findAndReturnChildrenByAssort(itemIdToFind: string, assort: IItem[]): IItem[]; /** * Check if the passed in item has buy count restrictions * @param itemToCheck Item to check * @returns true if it has buy restrictions */ - hasBuyRestrictions(itemToCheck: Item): boolean; + hasBuyRestrictions(itemToCheck: IItem): boolean; /** * is the passed in template id a dog tag * @param tpl Template id to check @@ -241,7 +247,7 @@ export declare class ItemHelper { * @param item * @returns "slotId OR slotid,locationX,locationY" */ - getChildId(item: Item): string; + getChildId(item: IItem): string; /** * Can the passed in item be stacked * @param tpl item to check @@ -253,21 +259,28 @@ export declare class ItemHelper { * @param itemToSplit Item to split into smaller stacks * @returns Array of root item + children */ - splitStack(itemToSplit: Item): Item[]; + splitStack(itemToSplit: IItem): IItem[]; /** * Turn items like money into separate stacks that adhere to max stack size * @param itemToSplit Item to split into smaller stacks * @returns */ - splitStackIntoSeparateItems(itemToSplit: Item): Item[][]; + splitStackIntoSeparateItems(itemToSplit: IItem): IItem[][]; /** * Find Barter items from array of items * @param {string} by tpl or id - * @param {Item[]} itemsToSearch Array of items to iterate over + * @param {IItem[]} itemsToSearch Array of items to iterate over * @param {string} desiredBarterItemIds * @returns Array of Item objects */ - findBarterItems(by: "tpl" | "id", itemsToSearch: Item[], desiredBarterItemIds: string | string[]): Item[]; + findBarterItems(by: "tpl" | "id", itemsToSearch: IItem[], desiredBarterItemIds: string | string[]): IItem[]; + /** + * Replace the _id value for base item + all children that are children of it + * REPARENTS ROOT ITEM ID, NOTHING ELSE + * @param itemWithChildren Item with mods to update + * @param newId new id to add on chidren of base item + */ + replaceRootItemID(itemWithChildren: IItem[], newId?: string): void; /** * Regenerate all GUIDs with new IDs, for the exception of special item types (e.g. quest, sorting table, etc.) This * function will not mutate the original items array, but will return a new array with new GUIDs. @@ -278,13 +291,13 @@ export declare class ItemHelper { * @param fastPanel Quick slot panel * @returns Item[] */ - replaceIDs(originalItems: Item[], pmcData?: IPmcData, insuredItems?: InsuredItem[], fastPanel?: any): Item[]; + replaceIDs(originalItems: IItem[], pmcData?: IPmcData, insuredItems?: IInsuredItem[], fastPanel?: any): IItem[]; /** * Mark the passed in array of items as found in raid. * Modifies passed in items * @param items The list of items to mark as FiR */ - setFoundInRaid(items: Item[]): void; + setFoundInRaid(items: IItem[]): void; /** * WARNING, SLOW. Recursively loop down through an items hierarchy to see if any of the ids match the supplied list, return true if any do * @param {string} tpl Items tpl to check parents of @@ -309,7 +322,7 @@ export declare class ItemHelper { * @param parent The parent of the item to be checked * @returns True if the item is actually moddable, false if it is not, and undefined if the check cannot be performed. */ - isRaidModdable(item: Item, parent: Item): boolean | undefined; + isRaidModdable(item: IItem, parent: IItem): boolean | undefined; /** * Retrieves the main parent item for a given attachment item. * @@ -326,14 +339,14 @@ export declare class ItemHelper { * @param itemsMap - A Map containing item IDs mapped to their corresponding Item objects for quick lookup. * @returns The Item object representing the top-most parent of the given item, or `undefined` if no such parent exists. */ - getAttachmentMainParent(itemId: string, itemsMap: Map): Item | undefined; + getAttachmentMainParent(itemId: string, itemsMap: Map): IItem | undefined; /** * Determines if an item is an attachment that is currently attached to it's parent item. * * @param item The item to check. * @returns true if the item is attached attachment, otherwise false. */ - isAttachmentAttached(item: Item): boolean; + isAttachmentAttached(item: IItem): boolean; /** * Retrieves the equipment parent item for a given item. * @@ -349,14 +362,14 @@ export declare class ItemHelper { * @param itemsMap - A Map containing item IDs mapped to their corresponding Item objects for quick lookup. * @returns The Item object representing the equipment parent of the given item, or `undefined` if no such parent exists. */ - getEquipmentParent(itemId: string, itemsMap: Map): Item | undefined; + getEquipmentParent(itemId: string, itemsMap: Map): IItem | undefined; /** * Get the inventory size of an item * @param items Item with children * @param rootItemId * @returns ItemSize object (width and height) */ - getItemSize(items: Item[], rootItemId: string): ItemHelper.ItemSize; + getItemSize(items: IItem[], rootItemId: string): ItemHelper.IItemSize; /** * Get a random cartridge from an items Filter property * @param item Db item template to look up Cartridge filter values from @@ -368,21 +381,21 @@ export declare class ItemHelper { * @param ammoBox Box to add cartridges to * @param ammoBoxDetails Item template from items db */ - addCartridgesToAmmoBox(ammoBox: Item[], ammoBoxDetails: ITemplateItem): void; + addCartridgesToAmmoBox(ammoBox: IItem[], ammoBoxDetails: ITemplateItem): void; /** * Add a single stack of cartridges to the ammo box * @param ammoBox Box to add cartridges to * @param ammoBoxDetails Item template from items db */ - addSingleStackCartridgesToAmmoBox(ammoBox: Item[], ammoBoxDetails: ITemplateItem): void; + addSingleStackCartridgesToAmmoBox(ammoBox: IItem[], ammoBoxDetails: ITemplateItem): void; /** * Check if item is stored inside of a container - * @param item Item to check is inside of container + * @param itemToCheck Item to check is inside of container * @param desiredContainerSlotId Name of slot to check item is in e.g. SecuredContainer/Backpack * @param items Inventory with child parent items to check * @returns True when item is in container */ - itemIsInsideContainer(item: Item, desiredContainerSlotId: string, items: Item[]): boolean; + itemIsInsideContainer(itemToCheck: IItem, desiredContainerSlotId: string, items: IItem[]): boolean; /** * Add child items (cartridges) to a magazine * @param magazine Magazine to add child items to @@ -393,15 +406,15 @@ export declare class ItemHelper { * @param defaultCartridgeTpl Cartridge to use when none found * @param weapon Weapon the magazine will be used for (if passed in uses Chamber as whitelist) */ - fillMagazineWithRandomCartridge(magazine: Item[], magTemplate: ITemplateItem, staticAmmoDist: Record, caliber?: string, minSizePercent?: number, defaultCartridgeTpl?: string, weapon?: ITemplateItem): void; + fillMagazineWithRandomCartridge(magazine: IItem[], magTemplate: ITemplateItem, staticAmmoDist: Record, caliber?: string, minSizePercent?: number, defaultCartridgeTpl?: string, weapon?: ITemplateItem): void; /** * Add child items to a magazine of a specific cartridge * @param magazineWithChildCartridges Magazine to add child items to * @param magTemplate Db template of magazine * @param cartridgeTpl Cartridge to add to magazine - * @param minSizePercent % the magazine must be filled to + * @param minSizeMultiplier % the magazine must be filled to */ - fillMagazineWithCartridge(magazineWithChildCartridges: Item[], magTemplate: ITemplateItem, cartridgeTpl: string, minSizePercent?: number): void; + fillMagazineWithCartridge(magazineWithChildCartridges: IItem[], magTemplate: ITemplateItem, cartridgeTpl: string, minSizeMultiplier?: number): void; /** * Choose a random bullet type from the list of possible a magazine has * @param magTemplate Magazine template from Db @@ -426,13 +439,13 @@ export declare class ItemHelper { * @param foundInRaid OPTIONAL - Are cartridges found in raid (SpawnedInSession) * @returns Item */ - createCartridges(parentId: string, ammoTpl: string, stackCount: number, location: number, foundInRaid?: boolean): Item; + createCartridges(parentId: string, ammoTpl: string, stackCount: number, location: number, foundInRaid?: boolean): IItem; /** * Get the size of a stack, return 1 if no stack object count property found * @param item Item to get stack size of * @returns size of stack */ - getItemStackSize(item: Item): number; + getItemStackSize(item: IItem): number; /** * Get the name of an item from the locale file using the item tpl * @param itemTpl Tpl of item to get name of @@ -453,7 +466,7 @@ export declare class ItemHelper { * @param requiredOnly Only add required mods * @returns Item with children */ - addChildSlotItems(itemToAdd: Item[], itemToAddTemplate: ITemplateItem, modSpawnChanceDict?: Record, requiredOnly?: boolean): Item[]; + addChildSlotItems(itemToAdd: IItem[], itemToAddTemplate: ITemplateItem, modSpawnChanceDict?: Record, requiredOnly?: boolean): IItem[]; /** * Get a compatible tpl from the array provided where it is not found in the provided incompatible mod tpls parameter * @param possibleTpls Tpls to randomly choose from @@ -478,14 +491,14 @@ export declare class ItemHelper { * @param itemWithChildren Primary item + children of primary item * @returns Item array with updated IDs */ - reparentItemAndChildren(rootItem: Item, itemWithChildren: Item[]): Item[]; + reparentItemAndChildren(rootItem: IItem, itemWithChildren: IItem[]): IItem[]; /** * Update a root items _id property value to be unique * @param itemWithChildren Item to update root items _id property * @param newId Optional: new id to use * @returns New root id */ - remapRootItemId(itemWithChildren: Item[], newId?: string): string; + remapRootItemId(itemWithChildren: IItem[], newId?: string): string; /** * Adopts orphaned items by resetting them as root "hideout" items. Helpful in situations where a parent has been * deleted from a group of items and there are children still referencing the missing parent. This method will @@ -495,24 +508,42 @@ export declare class ItemHelper { * @param items Array of Items that should be adjusted. * @returns Array of Items that have been adopted. */ - adoptOrphanedItems(rootId: string, items: Item[]): Item[]; + adoptOrphanedItems(rootId: string, items: IItem[]): IItem[]; /** * Populate a Map object of items for quick lookup using their ID. * * @param items An array of Items that should be added to a Map. * @returns A Map where the keys are the item IDs and the values are the corresponding Item objects. */ - generateItemsMap(items: Item[]): Map; + generateItemsMap(items: IItem[]): Map; /** * Add a blank upd object to passed in item if it does not exist already * @param item item to add upd to * @param warningMessageWhenMissing text to write to log when upd object was not found * @returns True when upd object was added */ - addUpdObjectToItem(item: Item, warningMessageWhenMissing?: string): boolean; + addUpdObjectToItem(item: IItem, warningMessageWhenMissing?: string): boolean; + /** + * Return all tpls from Money enum + * @returns string tpls + */ + getMoneyTpls(): string[]; + /** + * Get a randomsied stack size for the passed in ammo + * @param ammoItemTemplate Ammo to get stack size for + * @param maxLimit default: Limit to 60 to prevent crazy values when players use stack increase mods + * @returns number + */ + getRandomisedAmmoStackSize(ammoItemTemplate: ITemplateItem, maxLimit?: number): number; + getItemBaseType(tpl: string, rootOnly?: boolean): string; + /** + * Remove FiR status from passed in items + * @param items Items to update FiR status of + */ + removeSpawnedInSessionPropertyFromItems(items: IItem[]): void; } declare namespace ItemHelper { - interface ItemSize { + interface IItemSize { width: number; height: number; } diff --git a/types/helpers/NotificationSendHelper.d.ts b/types/helpers/NotificationSendHelper.d.ts index 3a74563e..80beb77f 100644 --- a/types/helpers/NotificationSendHelper.d.ts +++ b/types/helpers/NotificationSendHelper.d.ts @@ -1,4 +1,4 @@ -import { Dialogue, IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; +import { IDialogue, IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent"; import { MessageType } from "@spt/models/enums/MessageType"; import { SaveServer } from "@spt/servers/SaveServer"; @@ -32,5 +32,5 @@ export declare class NotificationSendHelper { * @param senderDetails Who is sending the message * @returns Dialogue */ - protected getDialog(sessionId: string, messageType: MessageType, senderDetails: IUserDialogInfo): Dialogue; + protected getDialog(sessionId: string, messageType: MessageType, senderDetails: IUserDialogInfo): IDialogue; } diff --git a/types/helpers/NotifierHelper.d.ts b/types/helpers/NotifierHelper.d.ts index b947f1be..2732631c 100644 --- a/types/helpers/NotifierHelper.d.ts +++ b/types/helpers/NotifierHelper.d.ts @@ -1,5 +1,5 @@ import { HttpServerHelper } from "@spt/helpers/HttpServerHelper"; -import { Message, MessageContentRagfair } from "@spt/models/eft/profile/ISptProfile"; +import { IMessage, IMessageContentRagfair } from "@spt/models/eft/profile/ISptProfile"; import { IWsChatMessageReceived } from "@spt/models/eft/ws/IWsChatMessageReceived"; import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent"; import { IWsRagfairOfferSold } from "@spt/models/eft/ws/IWsRagfairOfferSold"; @@ -17,12 +17,12 @@ export declare class NotifierHelper { * @param ragfairData Ragfair data to attach to notification * @returns */ - createRagfairOfferSoldNotification(dialogueMessage: Message, ragfairData: MessageContentRagfair): IWsRagfairOfferSold; + createRagfairOfferSoldNotification(dialogueMessage: IMessage, ragfairData: IMessageContentRagfair): IWsRagfairOfferSold; /** * Create a new notification with the specified dialogueMessage object * @param dialogueMessage * @returns */ - createNewMessageNotification(dialogueMessage: Message): IWsChatMessageReceived; + createNewMessageNotification(dialogueMessage: IMessage): IWsChatMessageReceived; getWebSocketServer(sessionID: string): string; } diff --git a/types/helpers/PresetHelper.d.ts b/types/helpers/PresetHelper.d.ts index f16d6ce1..62fda36d 100644 --- a/types/helpers/PresetHelper.d.ts +++ b/types/helpers/PresetHelper.d.ts @@ -40,9 +40,9 @@ export declare class PresetHelper { getAllPresets(): IPreset[]; getPresets(templateId: string): IPreset[]; /** - * Get the default preset for passed in item id - * @param templateId Item id to get preset for - * @returns Null if no default preset, otherwise IPreset + * Get a cloned default preset for passed in item tpl + * @param templateId Item tpl to get preset for + * @returns undefined if no default preset, otherwise IPreset */ getDefaultPreset(templateId: string): IPreset | undefined; getBaseItemTpl(presetId: string): string; diff --git a/types/helpers/ProfileHelper.d.ts b/types/helpers/ProfileHelper.d.ts index cdab870b..ce9af111 100644 --- a/types/helpers/ProfileHelper.d.ts +++ b/types/helpers/ProfileHelper.d.ts @@ -1,8 +1,10 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Common, CounterKeyValue, Stats } from "@spt/models/eft/common/tables/IBotBase"; +import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData"; +import { BonusType } from "@spt/models/enums/BonusType"; import { SkillTypes } from "@spt/models/enums/SkillTypes"; import { IInventoryConfig } from "@spt/models/spt/config/IInventoryConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -10,7 +12,6 @@ import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; import { DatabaseService } from "@spt/services/DatabaseService"; import { LocalisationService } from "@spt/services/LocalisationService"; -import { ProfileSnapshotService } from "@spt/services/ProfileSnapshotService"; import { HashUtil } from "@spt/utils/HashUtil"; import { TimeUtil } from "@spt/utils/TimeUtil"; import { Watermark } from "@spt/utils/Watermark"; @@ -23,12 +24,11 @@ export declare class ProfileHelper { protected saveServer: SaveServer; protected databaseService: DatabaseService; protected itemHelper: ItemHelper; - protected profileSnapshotService: ProfileSnapshotService; protected localisationService: LocalisationService; protected configServer: ConfigServer; protected cloner: ICloner; protected inventoryConfig: IInventoryConfig; - constructor(logger: ILogger, hashUtil: HashUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseService: DatabaseService, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, hashUtil: HashUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseService: DatabaseService, itemHelper: ItemHelper, localisationService: LocalisationService, configServer: ConfigServer, cloner: ICloner); /** * Remove/reset a completed quest condtion from players profile quest data * @param sessionID Session id @@ -47,18 +47,10 @@ export declare class ProfileHelper { */ getCompleteProfile(sessionId: string): IPmcData[]; /** - * Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen - * Server saves the post-raid changes prior to the xp screen getting the profile, this results in the xp screen using - * the now updated profile values as a base, meaning it shows x2 xp gained - * Instead, clone the post-raid profile (so we dont alter its values), apply the pre-raid xp values to the cloned objects and return - * Delete snapshot of pre-raid profile prior to returning profile data - * @param sessionId Session id - * @param output pmc and scav profiles array - * @param pmcProfile post-raid pmc profile - * @param scavProfile post-raid scav profile - * @returns Updated profile array + * Sanitize any information from the profile that the client does not expect to receive + * @param clonedProfile A clone of the full player profile */ - protected postRaidXpWorkaroundFix(sessionId: string, pmcProfile: IPmcData, scavProfile: IPmcData, output: IPmcData[]): IPmcData[]; + protected sanitizeProfileForClient(clonedProfile: ISptProfile): void; /** * Check if a nickname is used by another profile loaded by the server * @param nicknameRequest nickname request object @@ -120,7 +112,7 @@ export declare class ProfileHelper { * Get baseline counter values for a fresh profile * @returns Default profile Stats object */ - getDefaultCounters(): Stats; + getDefaultCounters(): IStats; /** * is this profile flagged for data removal * @param sessionID Profile id @@ -154,7 +146,7 @@ export declare class ProfileHelper { * @param counters Counters to search for key * @param keyToIncrement Key */ - incrementStatCounter(counters: CounterKeyValue[], keyToIncrement: string): void; + incrementStatCounter(counters: ICounterKeyValue[], keyToIncrement: string): void; /** * Check if player has a skill at elite level * @param skillType Skill to check @@ -190,6 +182,13 @@ export declare class ProfileHelper { * @param rowsToAdd How many rows to give profile */ addStashRowsBonusToProfile(sessionId: string, rowsToAdd: number): void; + /** + * Iterate over all bonuses and sum up all bonuses of desired type in provided profile + * @param pmcProfile Player profile + * @param desiredBonus Bonus to sum up + * @returns Summed bonus value or 0 if no bonus found + */ + getBonusValueFromProfile(pmcProfile: IPmcData, desiredBonus: BonusType): number; playerIsFleaBanned(pmcProfile: IPmcData): boolean; /** * Add an achievement to player profile @@ -198,4 +197,16 @@ export declare class ProfileHelper { */ addAchievementToProfile(pmcProfile: IPmcData, achievementId: string): void; hasAccessToRepeatableFreeRefreshSystem(pmcProfile: IPmcData): boolean; + /** + * Find a profiles "Pockets" item and replace its tpl with passed in value + * @param pmcProfile Player profile + * @param newPocketTpl New tpl to set profiles Pockets to + */ + replaceProfilePocketTpl(pmcProfile: IPmcData, newPocketTpl: string): void; + /** + * Return all quest items current in the supplied profile + * @param profile Profile to get quest items from + * @returns Array of item objects + */ + getQuestItemsInProfile(profile: IPmcData): IItem[]; } diff --git a/types/helpers/QuestHelper.d.ts b/types/helpers/QuestHelper.d.ts index 2d5730da..cfb1be48 100644 --- a/types/helpers/QuestHelper.d.ts +++ b/types/helpers/QuestHelper.d.ts @@ -8,10 +8,11 @@ import { RagfairServerHelper } from "@spt/helpers/RagfairServerHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { Common, IQuestStatus } from "@spt/models/eft/common/tables/IBotBase"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IQuest, IQuestCondition, IQuestReward } from "@spt/models/eft/common/tables/IQuest"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { IAcceptQuestRequestData } from "@spt/models/eft/quests/IAcceptQuestRequestData"; +import { ICompleteQuestRequestData } from "@spt/models/eft/quests/ICompleteQuestRequestData"; import { IFailQuestRequestData } from "@spt/models/eft/quests/IFailQuestRequestData"; import { QuestStatus } from "@spt/models/enums/QuestStatus"; import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig"; @@ -22,6 +23,7 @@ import { DatabaseService } from "@spt/services/DatabaseService"; import { LocaleService } from "@spt/services/LocaleService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { MailSendService } from "@spt/services/MailSendService"; +import { PlayerService } from "@spt/services/PlayerService"; import { SeasonalEventService } from "@spt/services/SeasonalEventService"; import { HashUtil } from "@spt/utils/HashUtil"; import { TimeUtil } from "@spt/utils/TimeUtil"; @@ -44,10 +46,11 @@ export declare class QuestHelper { protected traderHelper: TraderHelper; protected presetHelper: PresetHelper; protected mailSendService: MailSendService; + protected playerService: PlayerService; protected configServer: ConfigServer; protected cloner: ICloner; protected questConfig: IQuestConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseService: DatabaseService, questConditionHelper: QuestConditionHelper, eventOutputHolder: EventOutputHolder, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, seasonalEventService: SeasonalEventService, traderHelper: TraderHelper, presetHelper: PresetHelper, mailSendService: MailSendService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, itemHelper: ItemHelper, databaseService: DatabaseService, questConditionHelper: QuestConditionHelper, eventOutputHolder: EventOutputHolder, localeService: LocaleService, ragfairServerHelper: RagfairServerHelper, dialogueHelper: DialogueHelper, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, seasonalEventService: SeasonalEventService, traderHelper: TraderHelper, presetHelper: PresetHelper, mailSendService: MailSendService, playerService: PlayerService, configServer: ConfigServer, cloner: ICloner); /** * Get status of a quest in player profile by its id * @param pmcData Profile to search @@ -102,20 +105,20 @@ export declare class QuestHelper { * @param questReward Reward item to fix * @returns Fixed rewards */ - protected processReward(questReward: IQuestReward): Item[]; + protected processReward(questReward: IQuestReward): IItem[]; /** * Add missing mod items to a quest armor reward * @param originalRewardRootItem Original armor reward item from IQuestReward.items object * @param questReward Armor reward from quest */ - protected generateArmorRewardChildSlots(originalRewardRootItem: Item, questReward: IQuestReward): void; + protected generateArmorRewardChildSlots(originalRewardRootItem: IItem, questReward: IQuestReward): void; /** - * Gets a flat list of reward items for the given quest at a specific state (e.g. Fail/Success) + * Gets a flat list of reward items for the given quest at a specific state for the specified game version (e.g. Fail/Success) * @param quest quest to get rewards for * @param status Quest status that holds the items (Started, Success, Fail) * @returns array of items with the correct maxStack */ - getQuestRewardItems(quest: IQuest, status: QuestStatus): Item[]; + getQuestRewardItems(quest: IQuest, status: QuestStatus, gameVersion: string): IItem[]; /** * Look up quest in db by accepted quest id and construct a profile-ready object ready to store in profile * @param pmcData Player profile @@ -142,6 +145,22 @@ export declare class QuestHelper { * @param questId QuestId to check */ questIsForOtherSide(playerSide: string, questId: string): boolean; + /** + * Is the provided quest prevented from being viewed by the provided game version + * (Inclusive filter) + * @param gameVersion Game version to check against + * @param questId Quest id to check + * @returns True Quest should not be visible to game version + */ + protected questIsProfileBlacklisted(gameVersion: string, questId: string): boolean; + /** + * Is the provided quest able to be seen by the provided game version + * (Exclusive filter) + * @param gameVersion Game version to check against + * @param questId Quest id to check + * @returns True Quest should be visible to game version + */ + protected questIsProfileWhitelisted(gameVersion: string, questId: string): boolean; /** * Get quests that can be shown to player after failing a quest * @param failedQuestId Id of the quest failed by player @@ -152,7 +171,7 @@ export declare class QuestHelper { /** * Adjust quest money rewards by passed in multiplier * @param quest Quest to multiple money rewards - * @param bonusPercent Value to adjust money rewards by + * @param bonusPercent Pecent to adjust money rewards by * @param questStatus Status of quest to apply money boost to rewards of * @returns Updated quest */ @@ -173,7 +192,7 @@ export declare class QuestHelper { * @param sessionId Session id * @param item Item that was adjusted */ - protected addItemStackSizeChangeIntoEventResponse(output: IItemEventRouterResponse, sessionId: string, item: Item): void; + protected addItemStackSizeChangeIntoEventResponse(output: IItemEventRouterResponse, sessionId: string, item: IItem): void; /** * Get quests, strip all requirement conditions except level * @param quests quests to process @@ -243,7 +262,14 @@ export declare class QuestHelper { * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Item[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): IItem[]; + /** + * Does the provided quest reward have a game version requirement to be given and does it match + * @param reward Reward to check + * @param gameVersion Version of game to check reward against + * @returns True if it has requirement, false if it doesnt pass check + */ + protected questRewardIsForGameEdition(reward: IQuestReward, gameVersion: string): boolean; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id @@ -259,7 +285,7 @@ export declare class QuestHelper { * @param pmcData player profile * @returns bonus as a percent */ - protected getQuestMoneyRewardBonus(pmcData: IPmcData): number; + protected getQuestMoneyRewardBonusMultiplier(pmcData: IPmcData): number; /** * Find quest with 'findItem' condition that needs the item tpl be handed in * @param itemTpl item tpl to look for @@ -286,4 +312,72 @@ export declare class QuestHelper { * @returns Hours item will be available for */ getMailItemRedeemTimeHoursForProfile(pmcData: IPmcData): number; + completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle client/quest/list + * Get all quests visible to player + * Exclude quests with incomplete preconditions (level/loyalty) + * @param sessionID session id + * @returns array of IQuest + */ + getClientQuests(sessionID: string): IQuest[]; + /** + * Create a clone of the given quest array with the rewards updated to reflect the + * given game version + * + * @param quests The list of quests to check + * @param gameVersion The game version of the profile + * @returns array of IQuest objects with the rewards filtered correctly for the game version + */ + protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; + /** + * Return a list of quests that would fail when supplied quest is completed + * @param completedQuestId quest completed id + * @returns array of IQuest objects + */ + protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; + /** + * Fail the provided quests + * Update quest in profile, otherwise add fresh quest object with failed status + * @param sessionID session id + * @param pmcData player profile + * @param questsToFail quests to fail + * @param output Client output + */ + protected failQuests(sessionID: string, pmcData: IPmcData, questsToFail: IQuest[], output: IItemEventRouterResponse): void; + /** + * Send a popup to player on successful completion of a quest + * @param sessionID session id + * @param pmcData Player profile + * @param completedQuestId Completed quest id + * @param questRewards Rewards given to player + */ + protected sendSuccessDialogMessageOnQuestComplete(sessionID: string, pmcData: IPmcData, completedQuestId: string, questRewards: IItem[]): void; + /** + * Look for newly available quests after completing a quest with a requirement to wait x minutes (time-locked) before being available and add data to profile + * @param pmcData Player profile to update + * @param quests Quests to look for wait conditions in + * @param completedQuestId Quest just completed + */ + protected addTimeLockedQuestsToProfile(pmcData: IPmcData, quests: IQuest[], completedQuestId: string): void; + /** + * Remove a quest entirely from a profile + * @param sessionId Player id + * @param questIdToRemove Qid of quest to remove + */ + protected removeQuestFromScavProfile(sessionId: string, questIdToRemove: string): void; + /** + * Return quests that have different statuses + * @param preQuestStatusus Quests before + * @param postQuestStatuses Quests after + * @returns QuestStatusChange array + */ + protected getQuestsWithDifferentStatuses(preQuestStatusus: IQuestStatus[], postQuestStatuses: IQuestStatus[]): IQuestStatus[] | undefined; + /** + * Does a provided quest have a level requirement equal to or below defined level + * @param quest Quest to check + * @param playerLevel level of player to test against quest + * @returns true if quest can be seen/accepted by player of defined level + */ + protected playerLevelFulfillsQuestRequirement(quest: IQuest, playerLevel: number): boolean; } diff --git a/types/helpers/RagfairHelper.d.ts b/types/helpers/RagfairHelper.d.ts index 52ca4676..0ec76d63 100644 --- a/types/helpers/RagfairHelper.d.ts +++ b/types/helpers/RagfairHelper.d.ts @@ -2,7 +2,7 @@ import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { TraderAssortHelper } from "@spt/helpers/TraderAssortHelper"; import { UtilityHelper } from "@spt/helpers/UtilityHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITraderAssort } from "@spt/models/eft/common/tables/ITrader"; import { ISearchRequestData } from "@spt/models/eft/ragfair/ISearchRequestData"; import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; @@ -36,7 +36,7 @@ export declare class RagfairHelper { * Iterate over array of identical items and merge stack count * Ragfair allows abnormally large stacks. */ - mergeStackable(items: Item[]): Item[]; + mergeStackable(items: IItem[]): IItem[]; /** * Return the symbol for a currency * e.g. 5449016a4bdc2d6f028b456f return ₽ diff --git a/types/helpers/RagfairOfferHelper.d.ts b/types/helpers/RagfairOfferHelper.d.ts index 2386316e..66a146d1 100644 --- a/types/helpers/RagfairOfferHelper.d.ts +++ b/types/helpers/RagfairOfferHelper.d.ts @@ -9,14 +9,15 @@ import { RagfairServerHelper } from "@spt/helpers/RagfairServerHelper"; import { RagfairSortHelper } from "@spt/helpers/RagfairSortHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITraderAssort } from "@spt/models/eft/common/tables/ITrader"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; import { ISearchRequestData } from "@spt/models/eft/ragfair/ISearchRequestData"; +import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig"; -import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { IRagfairConfig, ITieredFlea } from "@spt/models/spt/config/IRagfairConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -55,6 +56,7 @@ export declare class RagfairOfferHelper { protected static goodSoldTemplate: string; protected ragfairConfig: IRagfairConfig; protected questConfig: IQuestConfig; + protected botConfig: IBotConfig; constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, eventOutputHolder: EventOutputHolder, databaseService: DatabaseService, traderHelper: TraderHelper, saveServer: SaveServer, itemHelper: ItemHelper, botHelper: BotHelper, paymentHelper: PaymentHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, ragfairServerHelper: RagfairServerHelper, ragfairSortHelper: RagfairSortHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, localeService: LocaleService, localisationService: LocalisationService, mailSendService: MailSendService, configServer: ConfigServer); /** * Passthrough to ragfairOfferService.getOffers(), get flea offers a player should see @@ -65,6 +67,7 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level * @param searchRequest Search request from client @@ -125,7 +128,7 @@ export declare class RagfairOfferHelper { * @param itemsInInventoryToList items to sum up * @returns Total count */ - getTotalStackCountSize(itemsInInventoryToList: Item[][]): number; + getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** * Add amount to players ragfair rating * @param sessionId Profile to update @@ -173,7 +176,7 @@ export declare class RagfairOfferHelper { * @param offer The flea offer * @returns True if the given item is functional */ - isItemFunctional(offerRootItem: Item, offer: IRagfairOffer): boolean; + isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; /** * Should a ragfair offer be visible to the player * @param searchRequest Search request @@ -190,7 +193,7 @@ export declare class RagfairOfferHelper { * @param item Item to check * @returns True if has condition */ - protected isConditionItem(item: Item): boolean; + protected isConditionItem(item: IItem): boolean; /** * Is items quality value within desired range * @param item Item to check quality of @@ -198,5 +201,5 @@ export declare class RagfairOfferHelper { * @param max Desired maximum quality * @returns True if in range */ - protected itemQualityInRange(item: Item, min: number, max: number): boolean; + protected itemQualityInRange(item: IItem, min: number, max: number): boolean; } diff --git a/types/helpers/RagfairSellHelper.d.ts b/types/helpers/RagfairSellHelper.d.ts index fc9e4b50..232ec514 100644 --- a/types/helpers/RagfairSellHelper.d.ts +++ b/types/helpers/RagfairSellHelper.d.ts @@ -1,4 +1,4 @@ -import { SellResult } from "@spt/models/eft/ragfair/IRagfairOffer"; +import { ISellResult } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -28,5 +28,5 @@ export declare class RagfairSellHelper { * @param sellInOneGo All items listed get sold at once * @returns Array of purchases of item(s) listed */ - rollForSale(sellChancePercent: number, itemSellCount: number, sellInOneGo?: boolean): SellResult[]; + rollForSale(sellChancePercent: number, itemSellCount: number, sellInOneGo?: boolean): ISellResult[]; } diff --git a/types/helpers/RagfairServerHelper.d.ts b/types/helpers/RagfairServerHelper.d.ts index 3e1fea9b..c7c72a0f 100644 --- a/types/helpers/RagfairServerHelper.d.ts +++ b/types/helpers/RagfairServerHelper.d.ts @@ -1,7 +1,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig"; import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; @@ -65,7 +65,7 @@ export declare class RagfairServerHelper { * @param sessionID Player to send items to * @param returnedItems Items to send to player */ - returnItems(sessionID: string, returnedItems: Item[]): void; + returnItems(sessionID: string, returnedItems: IItem[]): void; calculateDynamicStackCount(tplId: string, isWeaponPreset: boolean): number; /** * Choose a currency at random with bias @@ -77,11 +77,11 @@ export declare class RagfairServerHelper { * @param item Preset item * @returns Array of weapon and its children */ - getPresetItems(item: Item): Item[]; + getPresetItems(item: IItem): IItem[]; /** * Possible bug, returns all items associated with an items tpl, could be multiple presets from globals.json * @param item Preset item * @returns */ - getPresetItemsByTpl(item: Item): Item[]; + getPresetItemsByTpl(item: IItem): IItem[]; } diff --git a/types/helpers/RepairHelper.d.ts b/types/helpers/RepairHelper.d.ts index 63c78c9b..67da4ef9 100644 --- a/types/helpers/RepairHelper.d.ts +++ b/types/helpers/RepairHelper.d.ts @@ -1,5 +1,5 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { ITemplateItem, Props } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IProps, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IRepairConfig } from "@spt/models/spt/config/IRepairConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -24,7 +24,7 @@ export declare class RepairHelper { * @param traderQualityMultipler Trader quality value from traders base json * @param applyMaxDurabilityDegradation should item have max durability reduced */ - updateItemDurability(itemToRepair: Item, itemToRepairDetails: ITemplateItem, isArmor: boolean, amountToRepair: number, useRepairKit: boolean, traderQualityMultipler: number, applyMaxDurabilityDegradation?: boolean): void; + updateItemDurability(itemToRepair: IItem, itemToRepairDetails: ITemplateItem, isArmor: boolean, amountToRepair: number, useRepairKit: boolean, traderQualityMultipler: number, applyMaxDurabilityDegradation?: boolean): void; /** * Repairing armor reduces the total durability value slightly, get a randomised (to 2dp) amount based on armor material * @param armorMaterial What material is the armor being repaired made of @@ -42,5 +42,5 @@ export declare class RepairHelper { * @param traderQualityMultipler Different traders produce different loss values * @returns Amount to reduce max durability by */ - protected getRandomisedWeaponRepairDegradationValue(itemProps: Props, isRepairKit: boolean, weaponMax: number, traderQualityMultipler: number): number; + protected getRandomisedWeaponRepairDegradationValue(itemProps: IProps, isRepairKit: boolean, weaponMax: number, traderQualityMultipler: number): number; } diff --git a/types/helpers/SecureContainerHelper.d.ts b/types/helpers/SecureContainerHelper.d.ts index b6bcffe0..76844860 100644 --- a/types/helpers/SecureContainerHelper.d.ts +++ b/types/helpers/SecureContainerHelper.d.ts @@ -1,8 +1,8 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -export interface OwnerInventoryItems { - from: Item[]; - to: Item[]; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +export interface IOwnerInventoryItems { + from: IItem[]; + to: IItem[]; sameInventory: boolean; isMail: boolean; } @@ -14,5 +14,5 @@ export declare class SecureContainerHelper { * @param items Inventory items to look for secure container in * @returns Array of ids */ - getSecureContainerItems(items: Item[]): string[]; + getSecureContainerItems(items: IItem[]): string[]; } diff --git a/types/helpers/TradeHelper.d.ts b/types/helpers/TradeHelper.d.ts index 6e6f3a25..c7e1e140 100644 --- a/types/helpers/TradeHelper.d.ts +++ b/types/helpers/TradeHelper.d.ts @@ -3,7 +3,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { TraderAssortHelper } from "@spt/helpers/TraderAssortHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { IProcessBuyTradeRequestData } from "@spt/models/eft/trade/IProcessBuyTradeRequestData"; import { IProcessSellTradeRequestData } from "@spt/models/eft/trade/IProcessSellTradeRequestData"; @@ -13,6 +13,7 @@ import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { RagfairServer } from "@spt/servers/RagfairServer"; +import { DatabaseService } from "@spt/services/DatabaseService"; import { FenceService } from "@spt/services/FenceService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { PaymentService } from "@spt/services/PaymentService"; @@ -21,6 +22,7 @@ import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class TradeHelper { protected logger: ILogger; + protected databaseService: DatabaseService; protected eventOutputHolder: EventOutputHolder; protected traderHelper: TraderHelper; protected itemHelper: ItemHelper; @@ -36,7 +38,7 @@ export declare class TradeHelper { protected cloner: ICloner; protected traderConfig: ITraderConfig; protected inventoryConfig: IInventoryConfig; - constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, traderHelper: TraderHelper, itemHelper: ItemHelper, paymentService: PaymentService, fenceService: FenceService, localisationService: LocalisationService, httpResponse: HttpResponseUtil, inventoryHelper: InventoryHelper, ragfairServer: RagfairServer, traderAssortHelper: TraderAssortHelper, traderPurchasePersisterService: TraderPurchasePersisterService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, databaseService: DatabaseService, eventOutputHolder: EventOutputHolder, traderHelper: TraderHelper, itemHelper: ItemHelper, paymentService: PaymentService, fenceService: FenceService, localisationService: LocalisationService, httpResponse: HttpResponseUtil, inventoryHelper: InventoryHelper, ragfairServer: RagfairServer, traderAssortHelper: TraderAssortHelper, traderPurchasePersisterService: TraderPurchasePersisterService, configServer: ConfigServer, cloner: ICloner); /** * Buy item from flea or trader * @param pmcData Player profile @@ -56,6 +58,7 @@ export declare class TradeHelper { * @param output IItemEventRouterResponse */ sellItem(profileWithItemsToSell: IPmcData, profileToReceiveMoney: IPmcData, sellRequest: IProcessSellTradeRequestData, sessionID: string, output: IItemEventRouterResponse): void; + protected incrementCirculateSoldToTraderCounter(profileWithItemsToSell: IPmcData, profileToReceiveMoney: IPmcData, sellRequest: IProcessSellTradeRequestData): void; /** * Traders allow a limited number of purchases per refresh cycle (default 60 mins) * @param sessionId Session id @@ -65,5 +68,5 @@ export declare class TradeHelper { * @param assortId Id of assort being purchased * @param count How many of the item are being bought */ - protected checkPurchaseIsWithinTraderItemLimit(sessionId: string, pmcData: IPmcData, traderId: string, assortBeingPurchased: Item, assortId: string, count: number): void; + protected checkPurchaseIsWithinTraderItemLimit(sessionId: string, pmcData: IPmcData, traderId: string, assortBeingPurchased: IItem, assortId: string, count: number): void; } diff --git a/types/helpers/TraderAssortHelper.d.ts b/types/helpers/TraderAssortHelper.d.ts index f1ecd3b6..a50b5894 100644 --- a/types/helpers/TraderAssortHelper.d.ts +++ b/types/helpers/TraderAssortHelper.d.ts @@ -4,7 +4,7 @@ import { AssortHelper } from "@spt/helpers/AssortHelper"; import { PaymentHelper } from "@spt/helpers/PaymentHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITrader, ITraderAssort } from "@spt/models/eft/common/tables/ITrader"; import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -58,7 +58,7 @@ export declare class TraderAssortHelper { * Reset every traders root item `BuyRestrictionCurrent` property to 0 * @param assortItems Items to adjust */ - protected resetBuyRestrictionCurrentValue(assortItems: Item[]): void; + protected resetBuyRestrictionCurrentValue(assortItems: IItem[]): void; /** * Create a dict of all assort id = quest id mappings used to work out what items should be shown to player based on the quests they've started/completed/failed */ @@ -85,7 +85,7 @@ export declare class TraderAssortHelper { * @param traderId trader id * @returns array of Items */ - protected getPristineTraderAssorts(traderId: string): Item[]; + protected getPristineTraderAssorts(traderId: string): IItem[]; /** * Returns generated ragfair offers in a trader assort format * @returns Trader assort object diff --git a/types/helpers/TraderHelper.d.ts b/types/helpers/TraderHelper.d.ts index 52c0d9b8..1eb3426a 100644 --- a/types/helpers/TraderHelper.d.ts +++ b/types/helpers/TraderHelper.d.ts @@ -2,9 +2,9 @@ import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { ProfileTraderTemplate } from "@spt/models/eft/common/tables/IProfileTemplate"; -import { ITraderAssort, ITraderBase, LoyaltyLevel } from "@spt/models/eft/common/tables/ITrader"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IProfileTraderTemplate } from "@spt/models/eft/common/tables/IProfileTemplate"; +import { ITraderAssort, ITraderBase, ITraderLoyaltyLevel } from "@spt/models/eft/common/tables/ITrader"; import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { Traders } from "@spt/models/enums/Traders"; import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; @@ -39,7 +39,7 @@ export declare class TraderHelper { * @param sessionID Players id * @returns Trader base */ - getTrader(traderID: string, sessionID: string): ITraderBase | undefined; + getTrader(traderID: string, sessionID: string): ITraderBase | any; /** * Get all assort data for a particular trader * @param traderId Trader to get assorts for @@ -52,7 +52,7 @@ export declare class TraderHelper { * @param assortId Id of assort to find * @returns Item object */ - getTraderAssortItemByAssortId(traderId: string, assortId: string): Item | undefined; + getTraderAssortItemByAssortId(traderId: string, assortId: string): IItem | undefined; /** * Reset a profiles trader data back to its initial state as seen by a level 1 player * Does NOT take into account different profile levels @@ -66,7 +66,7 @@ export declare class TraderHelper { * @param rawProfileTemplate Raw profile from profiles.json to look up standing from * @returns Standing value */ - protected getStartingStanding(traderId: string, rawProfileTemplate: ProfileTraderTemplate): number; + protected getStartingStanding(traderId: string, rawProfileTemplate: IProfileTraderTemplate): number; /** * Add an array of suit ids to a profiles suit array, no duplicates * @param fullProfile Profile to add to @@ -118,7 +118,7 @@ export declare class TraderHelper { * @returns Time in seconds */ getTraderUpdateSeconds(traderId: string): number | undefined; - getLoyaltyLevel(traderID: string, pmcData: IPmcData): LoyaltyLevel; + getLoyaltyLevel(traderID: string, pmcData: IPmcData): ITraderLoyaltyLevel; /** * Store the purchase of an assort from a trader in the player profile * @param sessionID Session id @@ -130,7 +130,7 @@ export declare class TraderHelper { count: number; }[]; traderId: string; - }, itemPurchased: Item): void; + }, itemPurchased: IItem): void; /** * EoD and Unheard get a 20% bonus to personal trader limit purchases * @param buyRestrictionMax Existing value from trader item diff --git a/types/helpers/WeatherHelper.d.ts b/types/helpers/WeatherHelper.d.ts new file mode 100644 index 00000000..c82f42b1 --- /dev/null +++ b/types/helpers/WeatherHelper.d.ts @@ -0,0 +1,25 @@ +import { DateTime } from "@spt/models/enums/DateTime"; +import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { TimeUtil } from "@spt/utils/TimeUtil"; +export declare class WeatherHelper { + protected logger: ILogger; + protected timeUtil: TimeUtil; + protected configServer: ConfigServer; + protected weatherConfig: IWeatherConfig; + constructor(logger: ILogger, timeUtil: TimeUtil, configServer: ConfigServer); + /** + * Get the current in-raid time - does not include an accurate date, only time + * @param currentDate (new Date()) + * @returns Date object of current in-raid time + */ + getInRaidTime(timestamp?: number): Date; + /** + * Is the current raid at nighttime + * @param timeVariant PASS OR CURR (from raid settings) + * @returns True when nighttime + */ + isNightTime(timeVariant: DateTime): boolean; + isHourAtNightTime(currentHour: number): boolean; +} diff --git a/types/helpers/WeightedRandomHelper.d.ts b/types/helpers/WeightedRandomHelper.d.ts index f3a34f32..e6e2041d 100644 --- a/types/helpers/WeightedRandomHelper.d.ts +++ b/types/helpers/WeightedRandomHelper.d.ts @@ -1,13 +1,4 @@ export declare class WeightedRandomHelper { - /** - * @deprecated USE getWeightedValue() WHERE POSSIBLE - * Gets a tplId from a weighted dictionary - * @param {tplId: weighting[]} itemArray - * @returns tplId - */ - getWeightedInventoryItem(itemArray: { - [tplId: string]: unknown; - } | ArrayLike): string; /** * Choos an item from the passed in array based on the weightings of each * @param itemArray Items and weights to use diff --git a/types/loaders/BundleLoader.d.ts b/types/loaders/BundleLoader.d.ts index 8c0ed4d2..fcbf97d4 100644 --- a/types/loaders/BundleLoader.d.ts +++ b/types/loaders/BundleLoader.d.ts @@ -8,7 +8,7 @@ export declare class BundleInfo { filename: string; crc: number; dependencies: string[]; - constructor(modpath: string, bundle: BundleManifestEntry, bundleHash: number); + constructor(modpath: string, bundle: IBundleManifestEntry, bundleHash: number); } export declare class BundleLoader { protected httpServerHelper: HttpServerHelper; @@ -26,10 +26,10 @@ export declare class BundleLoader { addBundles(modpath: string): void; addBundle(key: string, b: BundleInfo): void; } -export interface BundleManifest { - manifest: BundleManifestEntry[]; +export interface IBundleManifest { + manifest: IBundleManifestEntry[]; } -export interface BundleManifestEntry { +export interface IBundleManifestEntry { key: string; dependencyKeys: string[]; } diff --git a/types/loaders/PreSptModLoader.d.ts b/types/loaders/PreSptModLoader.d.ts index 88145256..e8166f13 100644 --- a/types/loaders/PreSptModLoader.d.ts +++ b/types/loaders/PreSptModLoader.d.ts @@ -1,6 +1,6 @@ import { ModLoadOrder } from "@spt/loaders/ModLoadOrder"; import { ModTypeCheck } from "@spt/loaders/ModTypeCheck"; -import { ModDetails } from "@spt/models/eft/profile/ISptProfile"; +import { IModDetails } from "@spt/models/eft/profile/ISptProfile"; import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; import { IModLoader } from "@spt/models/spt/mod/IModLoader"; import { IPackageJsonData } from "@spt/models/spt/mod/IPackageJsonData"; @@ -36,7 +36,7 @@ export declare class PreSptModLoader implements IModLoader { */ getImportedModsNames(): string[]; getImportedModDetails(): Record; - getProfileModsGroupedByModName(profileMods: ModDetails[]): ModDetails[]; + getProfileModsGroupedByModName(profileMods: IModDetails[]): IModDetails[]; getModPath(mod: string): string; protected importModsAsync(): Promise; protected sortMods(prev: string, next: string, missingFromOrderJSON: Record): number; diff --git a/types/models/eft/bot/IGenerateBotsRequestData.d.ts b/types/models/eft/bot/IGenerateBotsRequestData.d.ts index f1f70132..f0f7168e 100644 --- a/types/models/eft/bot/IGenerateBotsRequestData.d.ts +++ b/types/models/eft/bot/IGenerateBotsRequestData.d.ts @@ -1,7 +1,7 @@ export interface IGenerateBotsRequestData { - conditions: Condition[]; + conditions: ICondition[]; } -export interface Condition { +export interface ICondition { /** e.g. assault/pmcBot/bossKilla */ Role: string; Limit: number; diff --git a/types/models/eft/common/IGlobals.d.ts b/types/models/eft/common/IGlobals.d.ts index bfcb920d..29f2abff 100644 --- a/types/models/eft/common/IGlobals.d.ts +++ b/types/models/eft/common/IGlobals.d.ts @@ -1,15 +1,101 @@ import { Ixyz } from "@spt/models/eft/common/Ixyz"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IGlobals { time: number; config: IConfig; + LocationInfection: ILocationInfection; bot_presets: IBotPreset[]; AudioSettings: IAudioSettings; EnvironmentSettings: IEnvironmentSettings; BotWeaponScatterings: IBotWeaponScattering[]; ItemPresets: Record; } +export interface ILocationInfection { + Interchange: number; + Lighthouse: number; + RezervBase: number; + Sandbox: number; + Shoreline: number; + TarkovStreets: number; + Woods: number; + bigmap: number; + factory4: number; + laboratory: number; +} +export interface IArtilleryShelling { + ArtilleryMapsConfigs: Record; + ProjectileExplosionParams: IProjectileExplosionParams; + MaxCalledShellingCount: number; +} +export interface IArtilleryMapSettings { + PlanedShellingOn: boolean; + InitShellingTimer: number; + BeforeShellingSignalTime: number; + ShellingCount: number; + ZonesInShelling: number; + NewZonesForEachShelling: boolean; + InitCalledShellingTime: number; + ShellingZones: IShellingZone[]; + Brigades: IBrigade[]; + ArtilleryShellingAirDropSettings: IArtilleryShellingAirDropSettings; + PauseBetweenShellings: Ixyz; +} +export interface IShellingZone { + ID: number; + PointsInShellings: Ixyz; + ShellingRounds: number; + ShotCount: number; + PauseBetweenRounds: Ixyz; + PauseBetweenShots: Ixyz; + Center: Ixyz; + Rotate: number; + GridStep: Ixyz; + Points: Ixyz; + PointRadius: number; + ExplosionDistanceRange: Ixyz; + AlarmStages: IAlarmStage[]; + BeforeShellingSignalTime: number; + UsedInPlanedShelling: boolean; + UseInCalledShelling: boolean; + IsActive: boolean; +} +export interface IAlarmStage { + Value: { + x: number; + y: number; + }; +} +export interface IBrigade { + ID: number; + ArtilleryGuns: IArtilleryGun[]; +} +export interface IArtilleryGun { + Position: Ixyz; +} +export interface IArtilleryShellingAirDropSettings { + UseAirDrop: boolean; + AirDropTime: number; + AirDropPosition: Ixyz; + LootTemplateId: string; +} +export interface IProjectileExplosionParams { + Blindness: Ixyz; + Contusion: Ixyz; + ArmorDistanceDistanceDamage: Ixyz; + MinExplosionDistance: number; + MaxExplosionDistance: number; + FragmentsCount: number; + Strength: number; + ArmorDamage: number; + StaminaBurnRate: number; + PenetrationPower: number; + DirectionalDamageAngle: number; + DirectionalDamageMultiplier: number; + FragmentType: string; + DeadlyDistance: number; +} export interface IConfig { + ArtilleryShelling: IArtilleryShelling; content: IContent; AimPunchMagnitude: number; WeaponSkillProgressRate: number; @@ -23,14 +109,19 @@ export interface IConfig { MaxBotsAliveOnMapPvE: number; SavagePlayCooldown: number; SavagePlayCooldownNdaFree: number; + SeasonActivity: ISeasonActivity; MarksmanAccuracy: number; SavagePlayCooldownDevelop: number; TODSkyDate: string; Mastering: IMastering[]; GlobalItemPriceModifier: number; TradingUnlimitedItems: boolean; + TransitSettings: ITransitSettings; + TripwiresSettings: ITripwiresSettings; MaxLoyaltyLevelForAll: boolean; + MountingSettings: IMountingSettings; GlobalLootChanceModifier: number; + GlobalLootChanceModifierPvE: number; GraphicSettings: IGraphicSettings; TimeBeforeDeploy: number; TimeBeforeDeployLocal: number; @@ -47,8 +138,10 @@ export interface IConfig { UncheckOnShot: boolean; BotsEnabled: boolean; BufferZone: IBufferZone; + Airdrop: IAirdropGlobalSettings; ArmorMaterials: IArmorMaterials; ArenaEftTransferSettings: IArenaEftTransferSettings; + KarmaCalculationSettings: IKarmaCalculationSettings; LegsOverdamage: number; HandsOverdamage: number; StomachOverdamage: number; @@ -103,6 +196,14 @@ export interface IConfig { Ballistic: IBallistic; RepairSettings: IRepairSettings; } +export interface ISeasonActivity { + InfectionHalloween: ISeasonActivityHalloween; +} +export interface ISeasonActivityHalloween { + DisplayUIEnabled: boolean; + Enabled: boolean; + ZombieBleedMul: number; +} export interface IEnvironmentSetting2 { EnvironmentUIData: IEnvironmentUIData; } @@ -173,6 +274,81 @@ export interface IEventWeather { Wind: number; WindDirection: number; } +export interface ITransitSettings { + BearPriceMod: number; + ClearAllPlayerEffectsOnTransit: boolean; + CoefficientDiscountCharisma: number; + DeliveryMinPrice: number; + DeliveryPrice: number; + ModDeliveryCost: number; + PercentageOfMissingEnergyRestore: number; + PercentageOfMissingHealthRestore: number; + PercentageOfMissingWaterRestore: number; + RestoreHealthOnDestroyedParts: boolean; + ScavPriceMod: number; + UsecPriceMod: number; + active: boolean; +} +export interface ITripwiresSettings { + CollisionCapsuleCheckCoef: number; + CollisionCapsuleRadius: number; + DefuseTimeSeconds: number; + DestroyedSeconds: number; + GroundDotProductTolerance: number; + InertSeconds: number; + InteractionSqrDistance: number; + MaxHeightDifference: number; + MaxLength: number; + MaxPreviewLength: number; + MaxTripwireToPlayerDistance: number; + MinLength: number; + MultitoolDefuseTimeSeconds: number; + ShotSqrDistance: number; +} +export interface IMountingSettings { + MovementSettings: IMountingMovementSettings; + PointDetectionSettings: IMountingPointDetectionSettings; +} +export interface IMountingMovementSettings { + ApproachTime: number; + ApproachTimeDeltaAngleModifier: number; + ExitTime: number; + MaxApproachTime: number; + MaxPitchLimitExcess: number; + MaxVerticalMountAngle: number; + MaxYawLimitExcess: number; + MinApproachTime: number; + MountingCameraSpeed: number; + MountingSwayFactorModifier: number; + PitchLimitHorizontal: Ixyz; + PitchLimitHorizontalBipod: Ixyz; + PitchLimitVertical: Ixyz; + RotationSpeedClamp: number; + SensitivityMultiplier: number; +} +export interface IMountingPointDetectionSettings { + CheckHorizontalSecondaryOffset: number; + CheckWallOffset: number; + EdgeDetectionDistance: number; + GridMaxHeight: number; + GridMinHeight: number; + HorizontalGridFromTopOffset: number; + HorizontalGridSize: number; + HorizontalGridStepsAmount: number; + MaxFramesForRaycast: number; + MaxHorizontalMountAngleDotDelta: number; + MaxProneMountAngleDotDelta: number; + MaxVerticalMountAngleDotDelta: number; + PointHorizontalMountOffset: number; + PointVerticalMountOffset: number; + RaycastDistance: number; + SecondCheckVerticalDistance: number; + SecondCheckVerticalGridOffset: number; + SecondCheckVerticalGridSize: number; + SecondCheckVerticalGridSizeStepsAmount: number; + VerticalGridSize: number; + VerticalGridStepsAmount: number; +} export interface IGraphicSettings { ExperimentalFogInCity: boolean; } @@ -229,6 +405,8 @@ export interface IMatchEnd { survivedMult: number; runnerMult: number; killedMult: number; + transit_exp_reward: number; + transit_mult: number[][]; } export interface IKill { combo: ICombo[]; @@ -392,10 +570,30 @@ export interface IBodyParts { Feet: string; Hands: string; } +export interface IAirdropGlobalSettings { + ParachuteEndOpenHeight: number; + ParachuteStartOpenHeight: number; + PlaneAdditionalDistance: number; + PlaneAirdropDuration: number; + PlaneAirdropFlareWait: number; + PlaneAirdropSmoke: number; + PlaneMaxFlightHeight: number; + PlaneMinFlightHeight: number; + PlaneSpeed: number; + SmokeActivateHeight: number; +} +export interface IKarmaCalculationSettings { + defaultPveKarmaValue: number; + enable: boolean; + expireDaysAfterLastRaid: number; + maxKarmaThresholdPercentile: number; + minKarmaThresholdPercentile: number; + minSurvivedRaidCount: number; +} export interface IArenaEftTransferSettings { - ArenaEftTransferSettings: ArenaEftTransferSettings; + ArenaEftTransferSettings: IArenaEftTransferSettings; } -export interface ArenaEftTransferSettings { +export interface IArenaEftTransferSettings { ArenaManagerReputationTaxMultiplier: number; CharismaTaxMultiplier: number; CreditPriceTaxMultiplier: number; @@ -459,6 +657,12 @@ export interface IEffects { HeavyBleeding: IHeavyBleeding; LightBleeding: ILightBleeding; BodyTemperature: IBodyTemperature; + ZombieInfection: IZombieInfection; +} +export interface IZombieInfection { + Dehydration: number; + HearingDebuffPercentage: number; + СumulativeTime: number; } export interface IExistence { EnergyLoopTime: number; @@ -805,6 +1009,7 @@ export interface IRagFair { balancerAveragePriceCoefficient: number; delaySinceOfferAdd: number; uniqueBuyerTimeoutInDays: number; + userRatingChangeFrequencyMultiplayer: number; ratingSumForIncrease: number; ratingIncreaseCount: number; ratingSumForDecrease: number; @@ -813,6 +1018,7 @@ export interface IRagFair { maxSumForDecreaseRatingPerOneSale: number; maxSumForRarity: IMaxSumForRarity; ChangePriceCoef: number; + ItemRestrictions: IItemGlobalRestrictions[]; balancerUserItemSaleCooldownEnabled: boolean; balancerUserItemSaleCooldown: number; youSellOfferMaxStorageTimeInHour: number; @@ -820,11 +1026,15 @@ export interface IRagFair { isOnlyFoundInRaidAllowed: boolean; sellInOnePiece: number; } +export interface IItemGlobalRestrictions { + MaxFlea: number; + MaxFleaStacked: number; + TemplateId: string; +} export interface IMaxActiveOfferCount { from: number; to: number; count: number; - countForSpecialEditions: number; } export interface IMaxSumForRarity { Common: IRarityMaxSum; @@ -842,7 +1052,10 @@ export interface IStamina { Capacity: number; SprintDrainRate: number; BaseRestorationRate: number; + BipodAimDrainRateMultiplier: number; JumpConsumption: number; + MountingHorizontalAimDrainRateMultiplier: number; + MountingVerticalAimDrainRateMultiplier: number; GrenadeHighThrow: number; GrenadeLowThrow: number; AimDrainRate: number; @@ -913,8 +1126,9 @@ export interface IAlpinist { RequirementTip: string; } export interface IRestrictionsInRaid { + MaxInLobby: number; + MaxInRaid: number; TemplateId: string; - Value: number; } export interface IFavoriteItemsSettings { WeaponStandMaxItemsCount: number; @@ -1013,10 +1227,12 @@ export interface ISquadSettings { SendRequestDelaySeconds: number; } export interface IInsurance { + ChangeForReturnItemsInOfflineRaid: number; MaxStorageTimeInHour: number; CoefOfSendingMessageTime: number; CoefOfHavingMarkOfUnknown: number; EditionSendingMessageTime: Record; + OnlyInDeathCase: boolean; } export interface IMessageSendTImeMultipler { multiplier: number; @@ -1028,6 +1244,7 @@ export interface ISkillsSettings { HideoutManagement: IHideoutManagement; Crafting: ICrafting; Metabolism: IMetabolism; + MountingErgonomicsBonusPerLevel: number; Immunity: Immunity; Endurance: IEndurance; Strength: IStrength; @@ -1053,6 +1270,7 @@ export interface ISkillsSettings { BearAksystems: any[]; BearHeavycaliber: any[]; BearRawpower: any[]; + BipodErgonomicsBonusPerLevel: number; UsecArsystems: any[]; UsecDeepweaponmodding_Settings: any[]; UsecLongrangeoptics_Settings: any[]; @@ -1112,6 +1330,7 @@ export interface IArmorCounters { export interface IHideoutManagement { SkillPointsPerAreaUpgrade: number; SkillPointsPerCraft: number; + CircleOfCultistsBonusPercent: number; ConsumptionReductionPerLevel: number; SkillBoostPercent: number; SkillPointsRate: ISkillPointsRate; @@ -1417,6 +1636,7 @@ export interface IFenceLevel { PaidExitCostModifier: number; BotFollowChance: number; ScavEquipmentSpawnChanceModifier: number; + TransitGridSize: Ixyz; PriceModifier: number; HostileBosses: boolean; HostileScavs: boolean; @@ -1435,6 +1655,7 @@ export interface IFenceLevel { ReactOnMarkOnUnknownsPVE: boolean; DeliveryGridSize: Ixyz; CanInteractWithBtr: boolean; + CircleOfCultistsBonusPercent: number; } export interface IInertia { InertiaLimits: Ixyz; @@ -1550,7 +1771,7 @@ export interface IPreset { _changeWeaponName: boolean; _name: string; _parent: string; - _items: Item[]; + _items: IItem[]; /** Default presets have this property */ _encyclopedia?: string; } diff --git a/types/models/eft/common/ILocation.d.ts b/types/models/eft/common/ILocation.d.ts index b8589c99..15a495c7 100644 --- a/types/models/eft/common/ILocation.d.ts +++ b/types/models/eft/common/ILocation.d.ts @@ -1,7 +1,7 @@ -import { Exit, ILocationBase } from "@spt/models/eft/common/ILocationBase"; -import { ILooseLoot } from "@spt/models/eft/common/ILooseLoot"; +import { IExit, ILocationBase } from "@spt/models/eft/common/ILocationBase"; +import { IGroupPostion, ILooseLoot } from "@spt/models/eft/common/ILooseLoot"; import { Ixyz } from "@spt/models/eft/common/Ixyz"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface ILocation { /** Map meta-data */ base: ILocationBase; @@ -15,7 +15,7 @@ export interface ILocation { /** All possible static containers on map + their assign groupings */ statics: IStaticContainer; /** All possible map extracts */ - allExtracts: Exit[]; + allExtracts: IExit[]; } export interface IStaticContainer { containersGroups: Record; @@ -51,12 +51,12 @@ export interface IStaticPropsBase { Rotation: Ixyz; IsGroupPosition: boolean; IsAlwaysSpawn: boolean; - GroupPositions: any[]; + GroupPositions: IGroupPostion[]; Root: string; - Items: any[]; + Items: IItem[]; } export interface IStaticWeaponProps extends IStaticPropsBase { - Items: Item[]; + Items: IItem[]; } export interface IStaticContainerDetails { staticWeapons: IStaticWeaponProps[]; @@ -76,9 +76,9 @@ export interface IStaticForcedProps { itemTpl: string; } export interface IStaticContainerProps extends IStaticPropsBase { - Items: StaticItem[]; + Items: IStaticItem[]; } -export interface StaticItem { +export interface IStaticItem { _id: string; _tpl: string; } diff --git a/types/models/eft/common/ILocationBase.d.ts b/types/models/eft/common/ILocationBase.d.ts index 10f1a57d..75836b67 100644 --- a/types/models/eft/common/ILocationBase.d.ts +++ b/types/models/eft/common/ILocationBase.d.ts @@ -1,18 +1,20 @@ import { MinMax } from "@spt/models/common/MinMax"; import { Ixyz } from "@spt/models/eft/common/Ixyz"; +import { ISpawnpointTemplate } from "./ILooseLoot"; export interface ILocationBase { AccessKeys: string[]; - AirdropParameters: AirdropParameter[]; + AccessKeysPvE: string[]; + AirdropParameters: IAirdropParameter[]; Area: number; AveragePlayTime: number; AveragePlayerLevel: number; - Banners: Banner[]; - BossLocationSpawn: BossLocationSpawn[]; + Banners: IBanner[]; + BossLocationSpawn: IBossLocationSpawn[]; BotAssault: number; BotEasy: number; BotHard: number; BotImpossible: number; - BotLocationModifier: BotLocationModifier; + BotLocationModifier: IBotLocationModifier; BotMarksman: number; BotMax: number; BotMaxPlayer: number; @@ -41,14 +43,14 @@ export interface ILocationBase { Insurance: boolean; IsSecret: boolean; Locked: boolean; - Loot: any[]; - MatchMakerMinPlayersByWaitTime: MinPlayerWaitTime[]; + Loot: ISpawnpointTemplate[]; + MatchMakerMinPlayersByWaitTime: IMinPlayerWaitTime[]; MaxBotPerZone: number; MaxDistToFreePoint: number; MaxPlayers: number; MinDistToExitPoint: number; MinDistToFreePoint: number; - MinMaxBots: MinMaxBot[]; + MinMaxBots: IMinMaxBot[]; MinPlayers: number; MaxCoopGroup: number; Name: string; @@ -57,7 +59,7 @@ export interface ILocationBase { OcculsionCullingEnabled: boolean; OldSpawn: boolean; OpenZones: string; - Preview: Preview; + Preview: IPreview; PlayersRequestCount: number; RequiredPlayerLevel?: number; RequiredPlayerLevelMin?: number; @@ -67,30 +69,44 @@ export interface ILocationBase { ScavMaxPlayersInGroup: number; Rules: string; SafeLocation: boolean; - Scene: Scene; - SpawnPointParams: SpawnPointParam[]; + Scene: IScene; + SpawnPointParams: ISpawnPointParam[]; UnixDateTime: number; _Id: string; doors: any[]; EscapeTimeLimit: number; EscapeTimeLimitCoop: number; EscapeTimeLimitPVE: number; + Events: ILocationEvents; exit_access_time: number; + ForceOnlineRaidInPVE: boolean; exit_count: number; exit_time: number; - exits: Exit[]; + exits: IExit[]; filter_ex: string[]; limits: ILimit[]; matching_min_seconds: number; GenerateLocalLootCache: boolean; - maxItemCountInLocation: MaxItemCountInLocation[]; + maxItemCountInLocation: IMaxItemCountInLocation[]; sav_summon_seconds: number; tmp_location_field_remove_me: number; + transits: ITransit[]; users_gather_seconds: number; users_spawn_seconds_n: number; users_spawn_seconds_n2: number; users_summon_seconds: number; - waves: Wave[]; + waves: IWave[]; +} +export interface ITransit { + activateAfterSec: string; + active: boolean; + name: string; + conditions: string; + description: string; + id: number; + location: string; + target: string; + time: number; } export interface INonWaveGroupScenario { Chance: number; @@ -101,7 +117,7 @@ export interface INonWaveGroupScenario { export interface ILimit extends MinMax { items: any[]; } -export interface AirdropParameter { +export interface IAirdropParameter { AirdropPointDeactivateDistance: number; MinPlayersCountToSpawnAirdrop: number; PlaneAirdropChance: number; @@ -113,15 +129,15 @@ export interface AirdropParameter { PlaneAirdropStartMin: number; UnsuccessfulTryPenalty: number; } -export interface Banner { +export interface IBanner { id: string; - pic: Pic; + pic: IPic; } -export interface Pic { +export interface IPic { path: string; rcid: string; } -export interface BossLocationSpawn { +export interface IBossLocationSpawn { BossChance: number; BossDifficult: string; BossEscortAmount: string; @@ -135,48 +151,73 @@ export interface BossLocationSpawn { TriggerId: string; TriggerName: string; Delay?: number; + DependKarma?: boolean; + DependKarmaPVE?: boolean; ForceSpawn?: boolean; IgnoreMaxBots?: boolean; - Supports?: BossSupport[]; + Supports?: IBossSupport[]; sptId?: string; spawnMode: string[]; } -export interface BossSupport { +export interface IBossSupport { BossEscortAmount: string; BossEscortDifficult: string[]; BossEscortType: string; } -export interface BotLocationModifier { +export interface IBotLocationModifier { AccuracySpeed: number; + AdditionalHostilitySettings: IAdditionalHostilitySettings[]; DistToActivate: number; + DistToActivatePvE: number; DistToPersueAxemanCoef: number; DistToSleep: number; + DistToSleepPvE: number; GainSight: number; KhorovodChance: number; MagnetPower: number; MarksmanAccuratyCoef: number; Scattering: number; VisibleDistance: number; + MaxExfiltrationTime: number; + MinExfiltrationTime: number; +} +export interface IAdditionalHostilitySettings { + AlwaysEnemies: string[]; + AlwaysFriends: string[]; + BearEnemyChance: number; + BearPlayerBehaviour: string; + BotRole: string; + ChancedEnemies: IChancedEnemy[]; + Neutral: string[]; + SavagePlayerBehaviour: string; + SavageEnemyChance?: number; + UsecEnemyChance: number; + UsecPlayerBehaviour: string; + Warn: string[]; +} +export interface IChancedEnemy { + EnemyChance: number; + Role: string; } -export interface MinMaxBot extends MinMax { +export interface IMinMaxBot extends MinMax { WildSpawnType: WildSpawnType | string; } -export interface MinPlayerWaitTime { +export interface IMinPlayerWaitTime { minPlayers: number; time: number; } -export interface Preview { +export interface IPreview { path: string; rcid: string; } -export interface Scene { +export interface IScene { path: string; rcid: string; } -export interface SpawnPointParam { +export interface ISpawnPointParam { BotZoneName: string; Categories: string[]; - ColliderParams: ColliderParams; + ColliderParams: IColliderParams; CorePointId: number; DelayToCanSpawnSec: number; Id: string; @@ -185,15 +226,15 @@ export interface SpawnPointParam { Rotation: number; Sides: string[]; } -export interface ColliderParams { +export interface IColliderParams { _parent: string; - _props: Props; + _props: IProps; } -export interface Props { +export interface IProps { Center: Ixyz; Radius: number; } -export interface Exit { +export interface IExit { /** % Chance out of 100 exit will appear in raid */ Chance: number; ChancePVE: number; @@ -217,11 +258,11 @@ export interface Exit { RequirementTip: string; Side?: string; } -export interface MaxItemCountInLocation { +export interface IMaxItemCountInLocation { TemplateId: string; Value: number; } -export interface Wave { +export interface IWave { BotPreset: string; BotSide: string; SpawnPoints: string; @@ -232,11 +273,40 @@ export interface Wave { slots_min: number; time_max: number; time_min: number; + /** OPTIONAL - Needs to be unique - Used by custom wave service to ensure same wave isnt added multiple times */ sptId?: string; ChanceGroup?: number; + /** 'pve' and/or 'regular' */ + SpawnMode: string[]; +} +export interface ILocationEvents { + Halloween2024: IHalloween2024; +} +export interface IHalloween2024 { + CrowdAttackBlockRadius: number; + CrowdAttackSpawnParams: CrowdAttackSpawnParam[]; + CrowdCooldownPerPlayerSec: number; + CrowdsLimit: number; + InfectedLookCoeff: number; + MaxCrowdAttackSpawnLimit: number; + MinInfectionPercentage: number; + MinSpawnDistToPlayer: number; + TargetPointSearchRadiusLimit: number; + ZombieCallDeltaRadius: number; + ZombieCallPeriodSec: number; + ZombieCallRadiusLimit: number; + ZombieMultiplier: number; + InfectionPercentage: number; +} +export interface CrowdAttackSpawnParam { + Difficulty: string; + Role: string; + Weight: number; } export declare enum WildSpawnType { ASSAULT = "assault", MARKSMAN = "marksman", - PMCBOT = "pmcbot" + PMCBOT = "pmcbot", + BOSSKILLA = "bosskilla", + BOSSKNIGHT = "bossknight" } diff --git a/types/models/eft/common/ILocationsSourceDestinationBase.d.ts b/types/models/eft/common/ILocationsSourceDestinationBase.d.ts index e6bc8ee3..4e455a1a 100644 --- a/types/models/eft/common/ILocationsSourceDestinationBase.d.ts +++ b/types/models/eft/common/ILocationsSourceDestinationBase.d.ts @@ -1,9 +1,9 @@ import { ILocations } from "@spt/models/spt/server/ILocations"; export interface ILocationsGenerateAllResponse { locations: ILocations; - paths: Path[]; + paths: IPath[]; } -export interface Path { +export interface IPath { Source: string; Destination: string; } diff --git a/types/models/eft/common/ILooseLoot.d.ts b/types/models/eft/common/ILooseLoot.d.ts index b5b538c1..392a48cd 100644 --- a/types/models/eft/common/ILooseLoot.d.ts +++ b/types/models/eft/common/ILooseLoot.d.ts @@ -1,20 +1,20 @@ import { Ixyz } from "@spt/models/eft/common/Ixyz"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface ILooseLoot { - spawnpointCount: SpawnpointCount; - spawnpointsForced: SpawnpointsForced[]; - spawnpoints: Spawnpoint[]; + spawnpointCount: ISpawnpointCount; + spawnpointsForced: ISpawnpointsForced[]; + spawnpoints: ISpawnpoint[]; } -export interface SpawnpointCount { +export interface ISpawnpointCount { mean: number; std: number; } -export interface SpawnpointsForced { +export interface ISpawnpointsForced { locationId: string; probability: number; - template: SpawnpointTemplate; + template: ISpawnpointTemplate; } -export interface SpawnpointTemplate { +export interface ISpawnpointTemplate { Id: string; IsContainer: boolean; useGravity: boolean; @@ -23,20 +23,26 @@ export interface SpawnpointTemplate { Rotation: Ixyz; IsAlwaysSpawn: boolean; IsGroupPosition: boolean; - GroupPositions: any[]; + GroupPositions: IGroupPostion[]; Root: string; - Items: Item[]; + Items: IItem[]; } -export interface Spawnpoint { +export interface IGroupPostion { + Name: string; + Weight: number; + Postion: Ixyz; + Rotation: Ixyz; +} +export interface ISpawnpoint { locationId: string; probability: number; - template: SpawnpointTemplate; + template: ISpawnpointTemplate; itemDistribution: ItemDistribution[]; } export interface ItemDistribution { - composedKey: ComposedKey; + composedKey: IComposedKey; relativeProbability: number; } -export interface ComposedKey { +export interface IComposedKey { key: string; } diff --git a/types/models/eft/common/tables/IBotBase.d.ts b/types/models/eft/common/tables/IBotBase.d.ts index be37845f..5becac2c 100644 --- a/types/models/eft/common/tables/IBotBase.d.ts +++ b/types/models/eft/common/tables/IBotBase.d.ts @@ -1,4 +1,4 @@ -import { Item, Upd } from "@spt/models/eft/common/tables/IItem"; +import { IItem, IUpd } from "@spt/models/eft/common/tables/IItem"; import { IPmcDataRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; import { BonusSkillType } from "@spt/models/enums/BonusSkillType"; @@ -12,29 +12,30 @@ export interface IBotBase { /** SPT property - use to store player id - TODO - move to AID ( account id as guid of choice) */ sessionId: string; savage?: string; - Info: Info; - Customization: Customization; - Health: Health; - Inventory: Inventory; - Skills: Skills; - Stats: Stats; + karmaValue: number; + Info: IInfo; + Customization: ICustomization; + Health: IHealth; + Inventory: IInventory; + Skills: ISkills; + Stats: IStats; Encyclopedia: Record; TaskConditionCounters: Record; - InsuredItems: InsuredItem[]; - Hideout: Hideout; + InsuredItems: IInsuredItem[]; + Hideout: IHideout; Quests: IQuestStatus[]; - TradersInfo: Record; + TradersInfo: Record; UnlockedInfo: IUnlockedInfo; - RagfairInfo: RagfairInfo; + RagfairInfo: IRagfairInfo; /** Achievement id and timestamp */ Achievements: Record; RepeatableQuests: IPmcDataRepeatableQuest[]; - Bonuses: Bonus[]; - Notes: Notes; + Bonuses: IBonus[]; + Notes: INotes; CarExtractCounts: Record; CoopExtractCounts: Record; SurvivorClass: SurvivorClass; - WishList: string[]; + WishList: Record; moneyTransferLimitData: IMoneyTransferLimits; /** SPT specific property used during bot generation in raid */ sptIsPmc?: boolean; @@ -56,13 +57,14 @@ export interface ITaskConditionCounter { export interface IUnlockedInfo { unlockedProductionRecipe: string[]; } -export interface Info { +export interface IInfo { EntryPoint: string; Nickname: string; LowerNickname: string; Side: string; SquadInviteRestriction: boolean; HasCoopExtension: boolean; + HasPveGame: boolean; Voice: string; Level: number; Experience: number; @@ -70,27 +72,28 @@ export interface Info { GameVersion: string; AccountType: number; MemberCategory: MemberCategory; + SelectedMemberCategory: MemberCategory; lockedMoveCommands: boolean; SavageLockTime: number; LastTimePlayedAsSavage: number; - Settings: Settings; + Settings: IBotInfoSettings; NicknameChangeDate: number; NeedWipeOptions: any[]; - lastCompletedWipe: LastCompleted; + lastCompletedWipe: ILastCompleted; Bans: IBan[]; BannedState: boolean; BannedUntil: number; IsStreamerModeAvailable: boolean; - lastCompletedEvent?: LastCompleted; - SelectedMemberCategory: number; + lastCompletedEvent?: ILastCompleted; isMigratedSkills: boolean; } -export interface Settings { +export interface IBotInfoSettings { Role: string; BotDifficulty: string; Experience: number; StandingForKill: number; AggressorBonus: number; + UseSimpleAnimator: boolean; } export interface IBan { banType: BanType; @@ -105,42 +108,43 @@ export declare enum BanType { FRIENDS = 5, CHANGE_NICKNAME = 6 } -export interface Customization { +export interface ICustomization { Head: string; Body: string; Feet: string; Hands: string; } -export interface Health { - Hydration: CurrentMax; - Energy: CurrentMax; - Temperature: CurrentMax; - BodyParts: BodyPartsHealth; +export interface IHealth { + Hydration: ICurrentMax; + Energy: ICurrentMax; + Temperature: ICurrentMax; + BodyParts: IBodyPartsHealth; UpdateTime: number; Immortal?: boolean; } -export interface BodyPartsHealth { - Head: BodyPartHealth; - Chest: BodyPartHealth; - Stomach: BodyPartHealth; - LeftArm: BodyPartHealth; - RightArm: BodyPartHealth; - LeftLeg: BodyPartHealth; - RightLeg: BodyPartHealth; -} -export interface BodyPartHealth { - Health: CurrentMax; - Effects?: Record; -} -export interface BodyPartEffectProperties { +export interface IBodyPartsHealth { + Head: IBodyPartHealth; + Chest: IBodyPartHealth; + Stomach: IBodyPartHealth; + LeftArm: IBodyPartHealth; + RightArm: IBodyPartHealth; + LeftLeg: IBodyPartHealth; + RightLeg: IBodyPartHealth; +} +export interface IBodyPartHealth { + Health: ICurrentMax; + Effects?: Record; +} +export interface IBodyPartEffectProperties { + ExtraData?: any; Time: number; } -export interface CurrentMax { +export interface ICurrentMax { Current: number; Maximum: number; } -export interface Inventory { - items: Item[]; +export interface IInventory { + items: IItem[]; equipment: string; stash: string; sortingTable: string; @@ -149,16 +153,16 @@ export interface Inventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: string[]; + favoriteItems: IItem[]; } export interface IBaseJsonSkills { Common: Record; - Mastering: Record; + Mastering: Record; Points: number; } -export interface Skills { +export interface ISkills { Common: Common[]; - Mastering: Mastering[]; + Mastering: IMastering[]; Points: number; } export interface IBaseSkill { @@ -171,26 +175,26 @@ export interface Common extends IBaseSkill { PointsEarnedDuringSession?: number; LastAccess?: number; } -export interface Mastering extends IBaseSkill { +export interface IMastering extends IBaseSkill { } -export interface Stats { +export interface IStats { Eft?: IEftStats; } export interface IEftStats { CarriedQuestItems: string[]; - Victims: Victim[]; + Victims: IVictim[]; TotalSessionExperience: number; LastSessionDate: number; - SessionCounters: SessionCounters; - OverallCounters: OverallCounters; + SessionCounters: ISessionCounters; + OverallCounters: IOverallCounters; SessionExperienceMult?: number; ExperienceBonusMult?: number; - Aggressor?: Aggressor; + Aggressor?: IAggressor; DroppedItems?: IDroppedItem[]; - FoundInRaidItems?: FoundInRaidItem[]; - DamageHistory?: DamageHistory; - DeathCause?: DeathCause; - LastPlayerState?: LastPlayerState; + FoundInRaidItems?: IFoundInRaidItem[]; + DamageHistory?: IDamageHistory; + DeathCause?: IDeathCause; + LastPlayerState?: ILastPlayerState; TotalInGameTime: number; SurvivorClass?: string; sptLastRaidFenceRepChange?: number; @@ -200,11 +204,11 @@ export interface IDroppedItem { ItemId: string; ZoneId: string; } -export interface FoundInRaidItem { +export interface IFoundInRaidItem { QuestId: string; ItemId: string; } -export interface Victim { +export interface IVictim { AccountId: string; ProfileId: string; Name: string; @@ -215,18 +219,19 @@ export interface Victim { Level: number; Weapon: string; Role: string; + Location: string; } -export interface SessionCounters { - Items: CounterKeyValue[]; +export interface ISessionCounters { + Items: ICounterKeyValue[]; } -export interface OverallCounters { - Items: CounterKeyValue[]; +export interface IOverallCounters { + Items: ICounterKeyValue[]; } -export interface CounterKeyValue { +export interface ICounterKeyValue { Key: string[]; Value: number; } -export interface Aggressor { +export interface IAggressor { AccountId: string; ProfileId: string; MainProfileNickname: string; @@ -237,12 +242,12 @@ export interface Aggressor { WeaponName: string; Category: string; } -export interface DamageHistory { +export interface IDamageHistory { LethalDamagePart: string; - LethalDamage: LethalDamage; - BodyParts: BodyPartsDamageHistory; + LethalDamage: ILethalDamage; + BodyParts: IBodyPartsDamageHistory; } -export interface LethalDamage { +export interface ILethalDamage { Amount: number; Type: string; SourceId: string; @@ -250,17 +255,17 @@ export interface LethalDamage { Blunt: boolean; ImpactsCount: number; } -export interface BodyPartsDamageHistory { - Head: DamageStats[]; - Chest: DamageStats[]; - Stomach: DamageStats[]; - LeftArm: DamageStats[]; - RightArm: DamageStats[]; - LeftLeg: DamageStats[]; - RightLeg: DamageStats[]; - Common: DamageStats[]; -} -export interface DamageStats { +export interface IBodyPartsDamageHistory { + Head: IDamageStats[]; + Chest: IDamageStats[]; + Stomach: IDamageStats[]; + LeftArm: IDamageStats[]; + RightArm: IDamageStats[]; + LeftLeg: IDamageStats[]; + RightLeg: IDamageStats[]; + Common: IDamageStats[]; +} +export interface IDamageStats { Amount: number; Type: string; SourceId: string; @@ -268,55 +273,63 @@ export interface DamageStats { Blunt: boolean; ImpactsCount: number; } -export interface DeathCause { +export interface IDeathCause { DamageType: string; Side: string; Role: string; WeaponId: string; } -export interface LastPlayerState { - Info: LastPlayerStateInfo; +export interface ILastPlayerState { + Info: ILastPlayerStateInfo; Customization: Record; Equipment: any; } -export interface LastPlayerStateInfo { +export interface ILastPlayerStateInfo { Nickname: string; Side: string; Level: number; MemberCategory: MemberCategory; } -export interface BackendCounter { +export interface IBackendCounter { id: string; qid?: string; value: number; } -export interface InsuredItem { +export interface IInsuredItem { /** Trader Id item was insured by */ tid: string; itemId: string; } -export interface Hideout { - Production: Record; - Areas: HideoutArea[]; - Improvement: Record; +export interface IHideout { + Production: Record; + Areas: IBotHideoutArea[]; + Improvements: Record; + HideoutCounters: IHideoutCounters; Seed: number; + MannequinPoses: string[]; sptUpdateLastRunTimestamp: number; } +export interface IHideoutCounters { + fuelCounter: number; + airFilterCounter: number; + waterFilterCounter: number; + craftingTimeCounter: number; +} export interface IHideoutImprovement { completed: boolean; improveCompleteTimestamp: number; } -export interface Productive { - Products: Product[]; +export interface IProductive { + Products: IProduct[]; /** Seconds passed of production */ Progress?: number; /** Is craft in some state of being worked on by client (crafting/ready to pick up) */ inProgress?: boolean; - StartTimestamp?: number; + StartTimestamp?: string; SkipTime?: number; /** Seconds needed to fully craft */ ProductionTime?: number; - GivenItemsInStart?: string[]; + GivenItemsInStart?: IItem[]; Interrupted?: boolean; Code?: string; Decoded?: boolean; @@ -331,22 +344,23 @@ export interface Productive { /** Is the craft a Continuous, e.g bitcoins/water collector */ sptIsContinuous?: boolean; /** Stores a list of tools used in this craft and whether they're FiR, to give back once the craft is done */ - sptRequiredTools?: Item[]; + sptRequiredTools?: IItem[]; + sptIsCultistCircle?: boolean; } -export interface Production extends Productive { +export interface IProduction extends IProductive { RecipeId: string; - SkipTime: number; - ProductionTime: number; + SkipTime?: number; + ProductionTime?: number; } -export interface ScavCase extends Productive { +export interface IScavCase extends IProductive { RecipeId: string; } -export interface Product { +export interface IProduct { _id: string; _tpl: string; - upd?: Upd; + upd?: IUpd; } -export interface HideoutArea { +export interface IBotHideoutArea { type: HideoutAreas; level: number; active: boolean; @@ -354,26 +368,25 @@ export interface HideoutArea { /** Must be integer */ completeTime: number; constructing: boolean; - slots: HideoutSlot[]; + slots: IHideoutSlot[]; lastRecipe: string; } -export interface HideoutSlot { +export interface IHideoutSlot { /** SPT specific value to keep track of what index this slot is (0,1,2,3 etc) */ locationIndex: number; - item?: HideoutItem[]; + item?: IHideoutItem[]; } -export interface HideoutItem { +export interface IHideoutItem { _id: string; _tpl: string; - upd?: Upd; + upd?: IUpd; } -export interface LastCompleted { +export interface ILastCompleted { $oid: string; } -export interface Notes { - Notes: Note[]; +export interface INotes { + Notes: INote[]; } -export type CarExtractCounts = {}; export declare enum SurvivorClass { UNKNOWN = 0, NEUTRALIZER = 1, @@ -390,20 +403,20 @@ export interface IQuestStatus { completedConditions?: string[]; availableAfter?: number; } -export interface TraderInfo { - loyaltyLevel: number; +export interface ITraderInfo { + loyaltyLevel?: number; salesSum: number; standing: number; nextResupply: number; unlocked: boolean; disabled: boolean; } -export interface RagfairInfo { +export interface IRagfairInfo { rating: number; isRatingGrowing: boolean; offers: IRagfairOffer[]; } -export interface Bonus { +export interface IBonus { id?: string; type: BonusType; templateId?: string; @@ -415,7 +428,7 @@ export interface Bonus { filter?: string[]; skillType?: BonusSkillType; } -export interface Note { +export interface INote { Time: number; Text: string; } diff --git a/types/models/eft/common/tables/IBotType.d.ts b/types/models/eft/common/tables/IBotType.d.ts index 074a7d6a..75811048 100644 --- a/types/models/eft/common/tables/IBotType.d.ts +++ b/types/models/eft/common/tables/IBotType.d.ts @@ -1,28 +1,28 @@ import { MinMax } from "@spt/models/common/MinMax"; -import { Skills } from "@spt/models/eft/common/tables/IBotBase"; +import { ISkills } from "@spt/models/eft/common/tables/IBotBase"; export interface IBotType { - appearance: Appearance; - chances: Chances; - difficulty: Difficulties; - experience: Experience; + appearance: IAppearance; + chances: IChances; + difficulty: IDifficulties; + experience: IExperience; firstName: string[]; - generation: Generation; - health: Health; - inventory: Inventory; + generation: IGeneration; + health: IHealth; + inventory: IInventory; lastName: string[]; - skills: Skills; + skills: ISkills; } -export interface Appearance { +export interface IAppearance { body: Record; feet: Record; hands: Record; head: Record; voice: Record; } -export interface Chances { +export interface IChances { equipment: EquipmentChances; - weaponMods: ModsChances; - equipmentMods: ModsChances; + weaponMods: IModsChances; + equipmentMods: IModsChances; } export interface EquipmentChances { ArmBand: number; @@ -40,7 +40,7 @@ export interface EquipmentChances { SecuredContainer: number; TacticalVest: number; } -export interface ModsChances { +export interface IModsChances { mod_charge: number; mod_equipment: number; mod_equipment_000: number; @@ -74,13 +74,13 @@ export interface ModsChances { mod_tactical_003: number; mod_handguard: number; } -export interface Difficulties { - easy: Difficulty; - normal: Difficulty; - hard: Difficulty; - impossible: Difficulty; +export interface IDifficulties { + easy: IDifficultyCategories; + normal: IDifficultyCategories; + hard: IDifficultyCategories; + impossible: IDifficultyCategories; } -export interface Difficulty { +export interface IDifficultyCategories { Aiming: Record; Boss: Record; Change: Record; @@ -96,42 +96,46 @@ export interface Difficulty { Scattering: Record; Shoot: Record; } -export interface Experience { - aggressorBonus: number; +export interface IExperience { + /** key = bot difficulty */ + aggressorBonus: Record; level: MinMax; - reward: MinMax; - standingForKill: number; -} -export interface Generation { - items: GenerationWeightingItems; -} -export interface GenerationWeightingItems { - grenades: GenerationData; - healing: GenerationData; - drugs: GenerationData; - food: GenerationData; - drink: GenerationData; - currency: GenerationData; - stims: GenerationData; - backpackLoot: GenerationData; - pocketLoot: GenerationData; - vestLoot: GenerationData; - magazines: GenerationData; - specialItems: GenerationData; -} -export interface GenerationData { + /** key = bot difficulty */ + reward: Record; + /** key = bot difficulty */ + standingForKill: Record; + useSimpleAnimator: boolean; +} +export interface IGeneration { + items: IGenerationWeightingItems; +} +export interface IGenerationWeightingItems { + grenades: IGenerationData; + healing: IGenerationData; + drugs: IGenerationData; + food: IGenerationData; + drink: IGenerationData; + currency: IGenerationData; + stims: IGenerationData; + backpackLoot: IGenerationData; + pocketLoot: IGenerationData; + vestLoot: IGenerationData; + magazines: IGenerationData; + specialItems: IGenerationData; +} +export interface IGenerationData { /** key: number of items, value: weighting */ weights: Record; /** Array of item tpls */ whitelist: Record; } -export interface Health { - BodyParts: BodyPart[]; +export interface IHealth { + BodyParts: IBodyPart[]; Energy: MinMax; Hydration: MinMax; Temperature: MinMax; } -export interface BodyPart { +export interface IBodyPart { Chest: MinMax; Head: MinMax; LeftArm: MinMax; @@ -140,13 +144,13 @@ export interface BodyPart { RightLeg: MinMax; Stomach: MinMax; } -export interface Inventory { - equipment: Equipment; - Ammo: Record>; - items: Items; - mods: Mods; +export interface IInventory { + equipment: IEquipment; + Ammo: IAmmo; + items: IItemPools; + mods: IMods; } -export interface Equipment { +export interface IEquipment { ArmBand: Record; ArmorVest: Record; Backpack: Record; @@ -162,11 +166,12 @@ export interface Equipment { SecuredContainer: Record; TacticalVest: Record; } -export interface Items { +export interface IItemPools { Backpack: Record; Pockets: Record; SecuredContainer: Record; SpecialLoot: Record; TacticalVest: Record; } -export type Mods = Record>; +export type IAmmo = Record>; +export type IMods = Record>; diff --git a/types/models/eft/common/tables/ICustomizationItem.d.ts b/types/models/eft/common/tables/ICustomizationItem.d.ts index 3883765b..721e1e9a 100644 --- a/types/models/eft/common/tables/ICustomizationItem.d.ts +++ b/types/models/eft/common/tables/ICustomizationItem.d.ts @@ -4,26 +4,27 @@ export interface ICustomizationItem { _name: string; _parent: string; _type: string; - _props: Props; + _props: IProps; _proto: string; } -export interface Props { +export interface IProps { Name: string; ShortName: string; Description: string; + Game: string[]; Side: string[]; BodyPart: string; AvailableAsDefault?: boolean; Body: string; Hands: string; Feet: string; - Prefab: Prefab; - WatchPrefab: Prefab; + Prefab: IPrefab; + WatchPrefab: IPrefab; IntegratedArmorVest: boolean; WatchPosition: Ixyz; WatchRotation: Ixyz; } -export interface Prefab { +export interface IPrefab { path: string; rcid: string; } diff --git a/types/models/eft/common/tables/IHandbookBase.d.ts b/types/models/eft/common/tables/IHandbookBase.d.ts index 7d7db07a..697b782c 100644 --- a/types/models/eft/common/tables/IHandbookBase.d.ts +++ b/types/models/eft/common/tables/IHandbookBase.d.ts @@ -1,15 +1,15 @@ export interface IHandbookBase { - Categories: Category[]; - Items: HandbookItem[]; + Categories: IHandbookCategory[]; + Items: IHandbookItem[]; } -export interface Category { +export interface IHandbookCategory { Id: string; ParentId?: string; Icon: string; Color: string; Order: string; } -export interface HandbookItem { +export interface IHandbookItem { Id: string; ParentId: string; Price: number; diff --git a/types/models/eft/common/tables/IItem.d.ts b/types/models/eft/common/tables/IItem.d.ts index 8f60c4fd..60b460f9 100644 --- a/types/models/eft/common/tables/IItem.d.ts +++ b/types/models/eft/common/tables/IItem.d.ts @@ -1,99 +1,113 @@ -export interface Item { +export interface IItem { _id: string; _tpl: string; parentId?: string; slotId?: string; - location?: Location | number; - upd?: Upd; + location?: IItemLocation | number; + upd?: IUpd; } -export interface Upd { - Buff?: Buff; +export interface IItemLocation { + x: number; + y: number; + r: string | number; + isSearched?: boolean; + /** SPT property? */ + rotation?: string | boolean; +} +export interface IUpd { + Buff?: IUpdBuff; OriginalStackObjectsCount?: number; - Togglable?: Togglable; - Map?: Map; - Tag?: Tag; + Togglable?: IUpdTogglable; + Map?: IUpdMap; + Tag?: IUpdTag; /** SPT specific property, not made by BSG */ sptPresetId?: string; - FaceShield?: FaceShield; + FaceShield?: IUpdFaceShield; StackObjectsCount?: number; UnlimitedCount?: boolean; - Repairable?: Repairable; - RecodableComponent?: RecodableComponent; - FireMode?: FireMode; + Repairable?: IUpdRepairable; + RecodableComponent?: IUpdRecodableComponent; + FireMode?: IUpdFireMode; SpawnedInSession?: boolean; - Light?: Light; - Key?: Key; - Resource?: Resource; - Sight?: Sight; - MedKit?: MedKit; - FoodDrink?: FoodDrink; - Dogtag?: Dogtag; + Light?: IUpdLight; + Key?: IUpdKey; + Resource?: IUpdResource; + Sight?: IUpdSight; + MedKit?: IUpdMedKit; + FoodDrink?: IUpdFoodDrink; + Dogtag?: IUpdDogtag; BuyRestrictionMax?: number; BuyRestrictionCurrent?: number; - Foldable?: Foldable; - SideEffect?: SideEffect; - RepairKit?: RepairKit; - CultistAmulet?: ICultistAmulet; -} -export interface Buff { - rarity: string; - buffType: string; - value: number; - thresholdDurability?: number; -} -export interface Togglable { + Foldable?: IUpdFoldable; + SideEffect?: IUpdSideEffect; + RepairKit?: IUpdRepairKit; + CultistAmulet?: IUpdCultistAmulet; + PinLockState?: PinLockState; +} +export declare enum PinLockState { + FREE = "Free", + LOCKED = "Locked", + PINNED = "Pinned" +} +export interface IUpdBuff { + Rarity: string; + BuffType: string; + Value: number; + ThresholdDurability?: number; +} +export interface IUpdTogglable { On: boolean; } -export interface Map { - Markers: MapMarker[]; +export interface IUpdMap { + Markers: IMapMarker[]; } -export interface MapMarker { +export interface IMapMarker { X: number; Y: number; } -export interface Tag { +export interface IUpdTag { Color: number; Name: string; } -export interface FaceShield { +export interface IUpdFaceShield { Hits: number; } -export interface Repairable { +export interface IUpdRepairable { Durability: number; MaxDurability: number; } -export interface RecodableComponent { +export interface IUpdRecodableComponent { IsEncoded: boolean; } -export interface MedKit { +export interface IUpdMedKit { HpResource: number; } -export interface Sight { +export interface IUpdSight { ScopesCurrentCalibPointIndexes: number[]; ScopesSelectedModes: number[]; SelectedScope: number; } -export interface Foldable { +export interface IUpdFoldable { Folded: boolean; } -export interface FireMode { +export interface IUpdFireMode { FireMode: string; } -export interface FoodDrink { +export interface IUpdFoodDrink { HpPercent: number; } -export interface Key { +export interface IUpdKey { NumberOfUsages: number; } -export interface Resource { +export interface IUpdResource { Value: number; UnitsConsumed: number; } -export interface Light { +export interface IUpdLight { IsActive: boolean; SelectedMode: number; } -export interface Dogtag { +export interface IUpdDogtag { AccountId: string; ProfileId: string; Nickname: string; @@ -106,20 +120,12 @@ export interface Dogtag { KillerName: string; WeaponName: string; } -export interface Location { - x: number; - y: number; - r: string | number; - isSearched?: boolean; - /** SPT property? */ - rotation?: string | boolean; -} -export interface SideEffect { +export interface IUpdSideEffect { Value: number; } -export interface RepairKit { +export interface IUpdRepairKit { Resource: number; } -export interface ICultistAmulet { +export interface IUpdCultistAmulet { NumberOfUsages: number; } diff --git a/types/models/eft/common/tables/ILocationServices.d.ts b/types/models/eft/common/tables/ILocationServices.d.ts new file mode 100644 index 00000000..399ae7b0 --- /dev/null +++ b/types/models/eft/common/tables/ILocationServices.d.ts @@ -0,0 +1,71 @@ +import { Ixyz } from "@spt/models/eft/common/Ixyz"; +export interface ILocationServices { + TraderServerSettings: ITraderServerSettings; + BTRServerSettings: IBtrServerSettings; +} +export interface ITraderServerSettings { + TraderServices: ITraderServices; +} +export interface ITraderServices { + ExUsecLoyalty: ITraderService; + ZryachiyAid: ITraderService; + CultistsAid: ITraderService; + PlayerTaxi: ITraderService; + BtrItemsDelivery: ITraderService; + BtrBotCover: ITraderService; + TransitItemsDelivery: ITraderService; +} +export interface ITraderService { + TraderId: string; + TraderServiceType: string; + Requirements: IServiceRequirements; + ServiceItemCost: Record; + UniqueItems: string[]; +} +export interface IServiceRequirements { + CompletedQuests: ICompletedQuest[]; + Standings: Record; +} +export interface ICompletedQuest { + QuestId: string; +} +export interface IStandingRequirement { + Value: number; +} +export interface IServiceItemCostDetails { + Count: number; +} +export interface IBtrServerSettings { + ChanceSpawn: number; + SpawnPeriod: Ixyz; + MoveSpeed: number; + ReadyToDepartureTime: number; + CheckTurnDistanceTime: number; + TurnCheckSensitivity: number; + DecreaseSpeedOnTurnLimit: number; + EndSplineDecelerationDistance: number; + AccelerationSpeed: number; + DecelerationSpeed: number; + PauseDurationRange: Ixyz; + BodySwingReturnSpeed: number; + BodySwingDamping: number; + BodySwingIntensity: number; + ServerMapBTRSettings: Record; +} +export interface IServerMapBtrsettings { + MapID: string; + ChanceSpawn: number; + SpawnPeriod: Ixyz; + MoveSpeed: number; + ReadyToDepartureTime: number; + CheckTurnDistanceTime: number; + TurnCheckSensitivity: number; + DecreaseSpeedOnTurnLimit: number; + EndSplineDecelerationDistance: number; + AccelerationSpeed: number; + DecelerationSpeed: number; + PauseDurationRange: Ixyz; + BodySwingReturnSpeed: number; + BodySwingDamping: number; + BodySwingIntensity: number; +} diff --git a/types/models/eft/common/tables/ILocationsBase.d.ts b/types/models/eft/common/tables/ILocationsBase.d.ts index 16bca247..e7730967 100644 --- a/types/models/eft/common/tables/ILocationsBase.d.ts +++ b/types/models/eft/common/tables/ILocationsBase.d.ts @@ -1,9 +1,9 @@ export interface ILocationsBase { - locations: Locations; - paths: Path[]; + locations: ILocations; + paths: IPath[]; } -export type Locations = {}; -export interface Path { +export type ILocations = {}; +export interface IPath { Source: string; Destination: string; } diff --git a/types/models/eft/common/tables/IMatch.d.ts b/types/models/eft/common/tables/IMatch.d.ts index 042f5bbc..5d18f57a 100644 --- a/types/models/eft/common/tables/IMatch.d.ts +++ b/types/models/eft/common/tables/IMatch.d.ts @@ -1,7 +1,7 @@ export interface IMatch { - metrics: Metrics; + metrics: IMetrics; } -export interface Metrics { +export interface IMetrics { Keys: number[]; NetProcessingBins: number[]; RenderBins: number[]; diff --git a/types/models/eft/common/tables/IProfileTemplate.d.ts b/types/models/eft/common/tables/IProfileTemplate.d.ts index 6ba92217..0eb800a0 100644 --- a/types/models/eft/common/tables/IProfileTemplate.d.ts +++ b/types/models/eft/common/tables/IProfileTemplate.d.ts @@ -1,5 +1,5 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Dialogue, IUserBuilds } from "@spt/models/eft/profile/ISptProfile"; +import { IDialogue, IUserBuilds } from "@spt/models/eft/profile/ISptProfile"; export interface IProfileTemplates { Standard: IProfileSides; "Left Behind": IProfileSides; @@ -19,11 +19,11 @@ export interface IProfileSides { export interface ITemplateSide { character: IPmcData; suits: string[]; - dialogues: Record; + dialogues: Record; userbuilds: IUserBuilds; - trader: ProfileTraderTemplate; + trader: IProfileTraderTemplate; } -export interface ProfileTraderTemplate { +export interface IProfileTraderTemplate { initialLoyaltyLevel: Record; initialStanding: Record; setQuestsAvailableForStart?: boolean; diff --git a/types/models/eft/common/tables/IQuest.d.ts b/types/models/eft/common/tables/IQuest.d.ts index 54ff191e..e9568562 100644 --- a/types/models/eft/common/tables/IQuest.d.ts +++ b/types/models/eft/common/tables/IQuest.d.ts @@ -1,4 +1,4 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { QuestRewardType } from "@spt/models/enums/QuestRewardType"; import { QuestStatus } from "@spt/models/enums/QuestStatus"; import { QuestTypeEnum } from "@spt/models/enums/QuestTypeEnum"; @@ -17,21 +17,19 @@ export interface IQuest { image: string; type: QuestTypeEnum; isKey: boolean; - /** @deprecated - Likely not used, use 'status' instead */ - questStatus: QuestStatus; restartable: boolean; instantComplete: boolean; secretQuest: boolean; startedMessageText: string; successMessageText: string; - acceptPlayerMessage: string; + acceptPlayerMessage?: string; declinePlayerMessage: string; - completePlayerMessage: string; - templateId: string; + completePlayerMessage?: string; + templateId?: string; rewards: IQuestRewards; /** Becomes 'AppearStatus' inside client */ - status: string | number; - KeyQuest: boolean; + status?: string | number; + KeyQuest?: boolean; changeQuestMessageText: string; /** "Pmc" or "Scav" */ side: string; @@ -39,10 +37,10 @@ export interface IQuest { sptStatus?: QuestStatus; } export interface IQuestConditionTypes { - Started: IQuestCondition[]; + Started?: IQuestCondition[]; AvailableForFinish: IQuestCondition[]; AvailableForStart: IQuestCondition[]; - Success: IQuestCondition[]; + Success?: IQuestCondition[]; Fail: IQuestCondition[]; } export interface IQuestCondition { @@ -50,21 +48,24 @@ export interface IQuestCondition { index?: number; compareMethod?: string; dynamicLocale: boolean; - visibilityConditions?: VisibilityCondition[]; + visibilityConditions?: IVisibilityCondition[]; globalQuestCounterId?: string; parentId?: string; - target: string[] | string; + target?: string[] | string; value?: string | number; - type?: boolean; + type?: boolean | string; status?: QuestStatus[]; availableAfter?: number; dispersion?: number; onlyFoundInRaid?: boolean; oneSessionOnly?: boolean; + isResetOnConditionFailed?: boolean; + isNecessary?: boolean; doNotResetIfCounterCompleted?: boolean; - dogtagLevel?: number; - maxDurability?: number; - minDurability?: number; + dogtagLevel?: number | string; + traderId?: string; + maxDurability?: number | string; + minDurability?: number | string; counter?: IQuestConditionCounter; plantTime?: number; zoneId?: string; @@ -79,7 +80,7 @@ export interface IQuestConditionCounter { } export interface IQuestConditionCounterCondition { id: string; - dynamicLocale: boolean; + dynamicLocale?: boolean; target?: string[] | string; completeInSeconds?: number; energy?: IValueCompare; @@ -87,7 +88,7 @@ export interface IQuestConditionCounterCondition { hydration?: IValueCompare; time?: IValueCompare; compareMethod?: string; - value?: number; + value?: number | string; weapon?: string[]; distance?: ICounterConditionDistance; equipmentInclusive?: string[][]; @@ -120,12 +121,12 @@ export interface IDaytimeCounter { from: number; to: number; } -export interface VisibilityCondition { +export interface IVisibilityCondition { id: string; target: string; value?: number; dynamicLocale?: boolean; - oneSessionOnly: boolean; + oneSessionOnly?: boolean; conditionType: string; } export interface IQuestRewards { @@ -143,10 +144,14 @@ export interface IQuestReward { type: QuestRewardType; index: number; target?: string; - items?: Item[]; + items?: IItem[]; loyaltyLevel?: number; /** Hideout area id */ traderId?: string; unknown?: boolean; findInRaid?: boolean; + /** Game editions whitelisted to get reward */ + availableInGameEditions?: string[]; + /** Game editions blacklisted from getting reward */ + notAvailableInGameEditions?: string[]; } diff --git a/types/models/eft/common/tables/IRepeatableQuests.d.ts b/types/models/eft/common/tables/IRepeatableQuests.d.ts index 0753cff9..37e582a6 100644 --- a/types/models/eft/common/tables/IRepeatableQuests.d.ts +++ b/types/models/eft/common/tables/IRepeatableQuests.d.ts @@ -41,14 +41,14 @@ export interface IOptions { Completion: ICompletionFilter; } export interface ICompletionFilter { - itemsBlacklist: ItemsBlacklist[]; - itemsWhitelist: ItemsWhitelist[]; + itemsBlacklist: IItemsBlacklist[]; + itemsWhitelist: IItemsWhitelist[]; } -export interface ItemsBlacklist { +export interface IItemsBlacklist { minPlayerLevel: number; itemIds: string[]; } -export interface ItemsWhitelist { +export interface IItemsWhitelist { minPlayerLevel: number; itemIds: string[]; } diff --git a/types/models/eft/common/tables/ITemplateItem.d.ts b/types/models/eft/common/tables/ITemplateItem.d.ts index c5b2da3c..41b4d1dd 100644 --- a/types/models/eft/common/tables/ITemplateItem.d.ts +++ b/types/models/eft/common/tables/ITemplateItem.d.ts @@ -4,11 +4,11 @@ export interface ITemplateItem { _name: string; _parent: string; _type: ItemType; - _props: Props; + _props: IProps; _proto?: string; } -export interface Props { - AllowSpawnOnLocations?: any[]; +export interface IProps { + AllowSpawnOnLocations?: string[]; BeltMagazineRefreshCount?: number; ChangePriceCoef?: number; FixedPrice?: boolean; @@ -25,8 +25,9 @@ export interface Props { SpawnChance?: number; CreditsPrice?: number; ItemSound?: string; - Prefab?: Prefab; - UsePrefab?: Prefab; + Prefab?: IPrefab; + UsePrefab?: IPrefab; + airDropTemplateId?: string; StackObjectsCount?: number; NotShownInSlot?: boolean; ExaminedByDefault?: boolean; @@ -51,6 +52,7 @@ export interface Props { ExtraSizeLeft?: number; ExtraSizeRight?: number; ExtraSizeUp?: number; + FlareTypes?: string[]; ExtraSizeDown?: number; ExtraSizeForceAdd?: boolean; MergesWithChildren?: boolean; @@ -70,8 +72,8 @@ export interface Props { MaxResource?: number; Resource?: number; DogTagQualities?: boolean; - Grids?: Grid[]; - Slots?: Slot[]; + Grids?: IGrid[]; + Slots?: ISlot[]; CanPutIntoDuringTheRaid?: boolean; CantRemoveFromSlotsDuringRaid?: string[]; KeyIds?: string[]; @@ -93,13 +95,16 @@ export interface Props { IsAnimated?: boolean; HasShoulderContact?: boolean; SightingRange?: number; + ZoomSensitivity?: number; DoubleActionAccuracyPenaltyMult?: number; - ModesCount?: any; + ModesCount?: number | number[]; DurabilityBurnModificator?: number; HeatFactor?: number; CoolFactor?: number; muzzleModType?: string; CustomAimPlane?: string; + IsAdjustableOptic?: boolean; + MinMaxFov?: Ixyz; sightModType?: string; aimingSensitivity?: number; SightModesCount?: number; @@ -135,7 +140,7 @@ export interface Props { PixelationBlockCount?: number; ShiftsAimCamera?: number; magAnimationIndex?: number; - Cartridges?: Slot[]; + Cartridges?: ISlot[]; CanFast?: boolean; CanHit?: boolean; CanAdmin?: boolean; @@ -170,7 +175,7 @@ export interface Props { spawnRarity?: string; minCountSpawn?: number; maxCountSpawn?: number; - openedByKeyID?: any[]; + openedByKeyID?: string[]; RigLayoutName?: string; MaxDurability?: number; armorZone?: string[]; @@ -213,7 +218,7 @@ export interface Props { defAmmo?: string; AdjustCollimatorsToTrajectory?: boolean; shotgunDispersion?: number; - Chambers?: Slot[]; + Chambers?: ISlot[]; CameraSnap?: number; CameraToWeaponAngleSpeedRange?: Ixyz; CameraToWeaponAngleStep?: number; @@ -226,6 +231,8 @@ export interface Props { RotationCenterNoStock?: Ixyz; ShotsGroupSettings?: IShotsGroupSettings[]; FoldedSlot?: string; + ForbidMissingVitalParts?: boolean; + ForbidNonEmptyContainers?: boolean; CompactHandling?: boolean; MinRepairDegradation?: number; MaxRepairDegradation?: number; @@ -263,6 +270,13 @@ export interface Props { RecoilStableIndexShot?: number; MinRepairKitDegradation?: number; MaxRepairKitDegradation?: number; + MountCameraSnapMultiplier?: number; + MountHorizontalRecoilMultiplier?: number; + MountReturnSpeedHandMultiplier?: number; + MountVerticalRecoilMultiplier?: number; + MountingHorizontalOutOfBreathMultiplier?: number; + MountingPosition?: Ixyz; + MountingVerticalOutOfBreathMultiplier?: Ixyz; BlocksEarpiece?: boolean; BlocksEyewear?: boolean; BlocksHeadwear?: boolean; @@ -379,6 +393,7 @@ export interface Props { ShowHitEffectOnExplode?: boolean; ExplosionType?: string; AmmoLifeTimeSec?: number; + AmmoTooltipClass?: string; Contusion?: Ixyz; ArmorDistanceDistanceDamage?: Ixyz; Blindness?: Ixyz; @@ -388,7 +403,7 @@ export interface Props { LightAndSoundShotSelfContusionStrength?: number; MalfMisfireChance?: number; MalfFeedChance?: number; - StackSlots?: StackSlot[]; + StackSlots?: IStackSlot[]; type?: string; eqMin?: number; eqMax?: number; @@ -401,6 +416,7 @@ export interface Props { explDelay?: number; EmitTime?: number; CanBeHiddenDuringThrow?: boolean; + CanPlantOnGround?: boolean; MinTimeToContactExplode?: number; ExplosionEffectType?: string; LinkedWeapon?: string; @@ -413,7 +429,7 @@ export interface Props { RepairStrategyTypes?: string[]; IsEncoded?: boolean; LayoutName?: string; - Lower75Prefab?: Prefab; + Lower75Prefab?: IPrefab; MaxUsages?: number; ScavKillExpPenalty?: number; ScavKillExpPenaltyPVE?: number; @@ -426,19 +442,19 @@ export interface IHealthEffect { type: string; value: number; } -export interface Prefab { +export interface IPrefab { path: string; rcid: string; } -export interface Grid { +export interface IGrid { _name: string; _id: string; _parent: string; - _props: GridProps; + _props: IGridProps; _proto: string; } -export interface GridProps { - filters: GridFilter[]; +export interface IGridProps { + filters: IGridFilter[]; cellsH: number; cellsV: number; minCount: number; @@ -446,25 +462,26 @@ export interface GridProps { maxWeight: number; isSortingTable: boolean; } -export interface GridFilter { +export interface IGridFilter { Filter: string[]; ExcludedFilter: string[]; + locked?: boolean; } -export interface Slot { +export interface ISlot { _name: string; _id: string; _parent: string; - _props: SlotProps; + _props: ISlotProps; _max_count?: number; _required?: boolean; _mergeSlotWithChildren?: boolean; _proto: string; } -export interface SlotProps { - filters: SlotFilter[]; +export interface ISlotProps { + filters: ISlotFilter[]; MaxStackCount?: number; } -export interface SlotFilter { +export interface ISlotFilter { Shift?: number; locked?: boolean; Plate?: string; @@ -473,17 +490,17 @@ export interface SlotFilter { Filter: string[]; AnimationIndex?: number; } -export interface StackSlot { +export interface IStackSlot { _name?: string; _id: string; _parent: string; _max_count: number; - _props: StackSlotProps; + _props: IStackSlotProps; _proto: string; upd?: any; } -export interface StackSlotProps { - filters: SlotFilter[]; +export interface IStackSlotProps { + filters: ISlotFilter[]; } export interface IRandomLootSettings { allowToSpawnIdenticalItems: boolean; @@ -500,14 +517,14 @@ export interface IRandomLootExcluded { rarity: string[]; templates: any[]; } -export interface EffectsHealth { - Energy: EffectsHealthProps; - Hydration: EffectsHealthProps; +export interface IEffectsHealth { + Energy: IEffectsHealthProps; + Hydration: IEffectsHealthProps; } -export interface EffectsHealthProps { +export interface IEffectsHealthProps { value: number; } -export interface EffectsDamage { +export interface IEffectsDamage { Pain: IEffectDamageProps; LightBleeding: IEffectDamageProps; HeavyBleeding: IEffectDamageProps; diff --git a/types/models/eft/common/tables/ITrader.d.ts b/types/models/eft/common/tables/ITrader.d.ts index 40cf0047..6dd54c10 100644 --- a/types/models/eft/common/tables/ITrader.d.ts +++ b/types/models/eft/common/tables/ITrader.d.ts @@ -1,4 +1,4 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { DogtagExchangeSide } from "@spt/models/enums/DogtagExchangeSide"; import { ITraderServiceModel } from "@spt/models/spt/services/ITraderServiceModel"; export interface ITrader { @@ -23,16 +23,20 @@ export interface ITraderBase { discount: number; discount_end: number; gridHeight: number; - insurance: Insurance; + sell_modifier_for_prohibited_items?: number; + insurance: ITraderInsurance; items_buy: IItemBuyData; items_buy_prohibited: IItemBuyData; + isCanTransferItems?: boolean; + transferableItems?: IItemBuyData; + prohibitedTransferableItems?: IItemBuyData; location: string; - loyaltyLevels: LoyaltyLevel[]; + loyaltyLevels: ITraderLoyaltyLevel[]; medic: boolean; name: string; nextResupply: number; nickname: string; - repair: Repair; + repair: ITraderRepair; sell_category: string[]; surname: string; unlockedByDefault: boolean; @@ -41,7 +45,7 @@ export interface IItemBuyData { category: string[]; id_list: string[]; } -export interface Insurance { +export interface ITraderInsurance { availability: boolean; excluded_category: string[]; max_return_hour: number; @@ -49,7 +53,7 @@ export interface Insurance { min_payment: number; min_return_hour: number; } -export interface LoyaltyLevel { +export interface ITraderLoyaltyLevel { buy_price_coef: number; exchange_price_coef: number; heal_price_coef: number; @@ -59,18 +63,18 @@ export interface LoyaltyLevel { minStanding: number; repair_price_coef: number; } -export interface Repair { +export interface ITraderRepair { availability: boolean; currency: string; currency_coefficient: number; excluded_category: string[]; /** Doesn't exist in client object */ - excluded_id_list: any[]; + excluded_id_list: string[]; quality: number; } export interface ITraderAssort { nextResupply: number; - items: Item[]; + items: IItem[]; barter_scheme: Record; loyal_level_items: Record; } @@ -84,18 +88,23 @@ export interface IBarterScheme { } export interface ISuit { _id: string; + externalObtain: boolean; + internalObtain: boolean; + isHiddenInPVE: boolean; tid: string; suiteId: string; isActive: boolean; requirements: ISuitRequirements; } export interface ISuitRequirements { + achievementRequirements: string[]; loyaltyLevel: number; profileLevel: number; standing: number; skillRequirements: string[]; questRequirements: string[]; itemRequirements: ItemRequirement[]; + requiredTid: string; } export interface ItemRequirement { count: number; diff --git a/types/models/eft/customization/IBuyClothingRequestData.d.ts b/types/models/eft/customization/IBuyClothingRequestData.d.ts index d19b70d1..3fea5126 100644 --- a/types/models/eft/customization/IBuyClothingRequestData.d.ts +++ b/types/models/eft/customization/IBuyClothingRequestData.d.ts @@ -1,9 +1,9 @@ export interface IBuyClothingRequestData { Action: "CustomizationBuy"; offer: string; - items: ClothingItem[]; + items: IPaymentItemForClothing[]; } -export interface ClothingItem { +export interface IPaymentItemForClothing { del: boolean; id: string; count: number; diff --git a/types/models/eft/dialog/IGetAllAttachmentsResponse.d.ts b/types/models/eft/dialog/IGetAllAttachmentsResponse.d.ts index 9bcfead6..845d92cf 100644 --- a/types/models/eft/dialog/IGetAllAttachmentsResponse.d.ts +++ b/types/models/eft/dialog/IGetAllAttachmentsResponse.d.ts @@ -1,6 +1,6 @@ -import { Message } from "@spt/models/eft/profile/ISptProfile"; +import { IMessage } from "@spt/models/eft/profile/ISptProfile"; export interface IGetAllAttachmentsResponse { - messages: Message[]; + messages: IMessage[]; profiles: any[]; hasMessagesWithRewards: boolean; } diff --git a/types/models/eft/dialog/IGetMailDialogViewResponseData.d.ts b/types/models/eft/dialog/IGetMailDialogViewResponseData.d.ts index ba289104..0eaacf80 100644 --- a/types/models/eft/dialog/IGetMailDialogViewResponseData.d.ts +++ b/types/models/eft/dialog/IGetMailDialogViewResponseData.d.ts @@ -1,6 +1,6 @@ -import { IUserDialogInfo, Message } from "@spt/models/eft/profile/ISptProfile"; +import { IMessage, IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; export interface IGetMailDialogViewResponseData { - messages: Message[]; + messages: IMessage[]; profiles: IUserDialogInfo[]; hasMessagesWithRewards: boolean; } diff --git a/types/models/eft/game/IGameConfigResponse.d.ts b/types/models/eft/game/IGameConfigResponse.d.ts index 2bff352d..c44867e5 100644 --- a/types/models/eft/game/IGameConfigResponse.d.ts +++ b/types/models/eft/game/IGameConfigResponse.d.ts @@ -5,7 +5,7 @@ export interface IGameConfigResponse { ndaFree: boolean; taxonomy: number; activeProfileId: string; - backend: Backend; + backend: IBackend; useProtobuf: boolean; utc_time: number; /** Total in game time */ @@ -13,7 +13,7 @@ export interface IGameConfigResponse { reportAvailable: boolean; twitchEventMember: boolean; } -export interface Backend { +export interface IBackend { Lobby: string; Trading: string; Messaging: string; diff --git a/types/models/eft/game/ISendSurveyOpinionRequest.d.ts b/types/models/eft/game/ISendSurveyOpinionRequest.d.ts new file mode 100644 index 00000000..70683e87 --- /dev/null +++ b/types/models/eft/game/ISendSurveyOpinionRequest.d.ts @@ -0,0 +1,9 @@ +export interface ISendSurveyOpinionRequest { + surveyId: number; + answers: ISurveyOpinionAnswer[]; +} +export interface ISurveyOpinionAnswer { + questionId: number; + answerType: string; + answers: any; +} diff --git a/types/models/eft/game/ISurveyResponseData.d.ts b/types/models/eft/game/ISurveyResponseData.d.ts new file mode 100644 index 00000000..7de9f509 --- /dev/null +++ b/types/models/eft/game/ISurveyResponseData.d.ts @@ -0,0 +1,35 @@ +export interface ISurveyResponseData { + locale: Record>; + survey: ISurvey; +} +export interface ISurvey { + id: number; + welcomePageData: IWelcomePageData; + farewellPageData: IFarewellPageData; + pages: number[][]; + questions: ISurveyQuestion[]; + isNew: boolean; +} +export interface IWelcomePageData { + titleLocaleKey: string; + timeLocaleKey: string; + descriptionLocaleKey: string; +} +export interface IFarewellPageData { + textLocaleKey: string; +} +export interface ISurveyQuestion { + id: number; + sortIndex: number; + titleLocaleKey: string; + hintLocaleKey: string; + answerLimit: number; + answerType: string; + answers: ISurveyAnswer[]; +} +export interface ISurveyAnswer { + id: number; + questionId: number; + sortIndex: number; + localeKey: string; +} diff --git a/types/models/eft/game/IVersionValidateRequestData.d.ts b/types/models/eft/game/IVersionValidateRequestData.d.ts index 0aa0fed3..18213d9f 100644 --- a/types/models/eft/game/IVersionValidateRequestData.d.ts +++ b/types/models/eft/game/IVersionValidateRequestData.d.ts @@ -1,8 +1,8 @@ export interface IVersionValidateRequestData { - version: Version; + version: IVersion; develop: boolean; } -export interface Version { +export interface IVersion { major: string; minor: string; game: string; diff --git a/types/models/eft/health/IHealthTreatmentRequestData.d.ts b/types/models/eft/health/IHealthTreatmentRequestData.d.ts index 598e60c6..e544bf9f 100644 --- a/types/models/eft/health/IHealthTreatmentRequestData.d.ts +++ b/types/models/eft/health/IHealthTreatmentRequestData.d.ts @@ -1,31 +1,31 @@ export interface IHealthTreatmentRequestData { Action: "RestoreHealth"; trader: string; - items: Cost[]; - difference: Difference; + items: IItemCost[]; + difference: IDifference; timestamp: number; } -export interface Cost { +export interface IItemCost { /** Id of stack to take money from */ id: string; /** Amount of money to take off player for treatment */ count: number; } -export interface Difference { - BodyParts: BodyParts; +export interface IDifference { + BodyParts: IBodyParts; Energy: number; Hydration: number; } -export interface BodyParts { - Head: BodyPart; - Chest: BodyPart; - Stomach: BodyPart; - LeftArm: BodyPart; - RightArm: BodyPart; - LeftLeg: BodyPart; - RightLeg: BodyPart; +export interface IBodyParts { + Head: IBodyPart; + Chest: IBodyPart; + Stomach: IBodyPart; + LeftArm: IBodyPart; + RightArm: IBodyPart; + LeftLeg: IBodyPart; + RightLeg: IBodyPart; } -export interface BodyPart { +export interface IBodyPart { Health: number; /** Effects in array are to be removed */ Effects: string[]; diff --git a/types/models/eft/health/ISyncHealthRequestData.d.ts b/types/models/eft/health/ISyncHealthRequestData.d.ts index 20e32f6d..7c7d05ca 100644 --- a/types/models/eft/health/ISyncHealthRequestData.d.ts +++ b/types/models/eft/health/ISyncHealthRequestData.d.ts @@ -1,20 +1,20 @@ export interface ISyncHealthRequestData { - Health: Health; + Health: IBodyPartCollection; IsAlive: boolean; Hydration?: number; Energy?: number; Temperature?: number; } -export interface Health { - Head?: BodyPartHealth; - Chest?: BodyPartHealth; - Stomach?: BodyPartHealth; - LeftArm?: BodyPartHealth; - RightArm?: BodyPartHealth; - LeftLeg?: BodyPartHealth; - RightLeg?: BodyPartHealth; +export interface IBodyPartCollection { + Head?: IBodyPartHealth; + Chest?: IBodyPartHealth; + Stomach?: IBodyPartHealth; + LeftArm?: IBodyPartHealth; + RightArm?: IBodyPartHealth; + LeftLeg?: IBodyPartHealth; + RightLeg?: IBodyPartHealth; } -export interface BodyPartHealth { +export interface IBodyPartHealth { Maximum: number; Current: number; Effects: Record; diff --git a/types/models/eft/health/IWorkoutData.d.ts b/types/models/eft/health/IWorkoutData.d.ts index ba629d2f..d958b743 100644 --- a/types/models/eft/health/IWorkoutData.d.ts +++ b/types/models/eft/health/IWorkoutData.d.ts @@ -1,4 +1,36 @@ export interface IWorkoutData extends Record { - skills: any; - effects: any; + skills: IWorkoutSkills; + effects: IWorkoutEffects; +} +export interface IWorkoutSkills { + Common: IWorkoutSkillCommon[]; + Mastering: any[]; + Bonuses: any; + Points: number; +} +export interface IWorkoutSkillCommon { + Id: string; + Progress: number; + PointsEarnedDuringSession: number; + LastAccess: number; +} +export interface IWorkoutEffects { + Effects: IWorkoutEffectsParts; + Hydration: number; + Energy: number; +} +export interface IWorkoutEffectsParts { + Head: IWorkoutBodyPart; + Chest: IWorkoutBodyPart; + Stomach: IWorkoutBodyPart; + LeftArm: IWorkoutBodyPart; + RightArm: IWorkoutBodyPart; + LeftLeg: IWorkoutBodyPart; + RightLeg: IWorkoutBodyPart; + Common: IWorkoutBodyPart; +} +export interface IWorkoutBodyPart { + Regeneration: number; + Fracture: number; + MildMusclePain: number; } diff --git a/types/models/eft/hideout/HideoutUpgradeCompleteRequestData.d.ts b/types/models/eft/hideout/HideoutUpgradeCompleteRequestData.d.ts deleted file mode 100644 index 8583e8d9..00000000 --- a/types/models/eft/hideout/HideoutUpgradeCompleteRequestData.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface HideoutUpgradeCompleteRequestData { - Action: string; - areaType: number; - timestamp: number; -} diff --git a/types/models/eft/hideout/IHideoutArea.d.ts b/types/models/eft/hideout/IHideoutArea.d.ts index ca0eb07f..ce4d7794 100644 --- a/types/models/eft/hideout/IHideoutArea.d.ts +++ b/types/models/eft/hideout/IHideoutArea.d.ts @@ -1,3 +1,4 @@ +import { IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { BonusSkillType } from "@spt/models/enums/BonusSkillType"; import { BonusType } from "@spt/models/enums/BonusType"; export interface IHideoutArea { @@ -11,16 +12,16 @@ export interface IHideoutArea { displayLevel: boolean; enableAreaRequirements: boolean; parentArea?: string; - stages: Record; + stages: Record; } export interface IAreaRequirement { areaType: number; requiredlevel: number; type: string; } -export interface Stage { +export interface IStage { autoUpgrade: boolean; - bonuses: StageBonus[]; + bonuses: IStageBonus[]; constructionTime: number; /** Containers inventory tpl */ container?: string; @@ -50,20 +51,19 @@ export interface IStageImprovementRequirement { templateId: string; type: string; } -export interface IStageRequirement { +export interface IStageRequirement extends IRequirementBase { areaType?: number; requiredLevel?: number; - type: string; templateId?: string; count?: number; - isEncoded: false; + isEncoded?: false; isFunctional?: boolean; traderId?: string; loyaltyLevel?: number; skillName?: string; skillLevel?: number; } -export interface StageBonus { +export interface IStageBonus { value: number; passive: boolean; production: boolean; diff --git a/types/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData.d.ts b/types/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData.d.ts new file mode 100644 index 00000000..6f7c9b72 --- /dev/null +++ b/types/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData.d.ts @@ -0,0 +1,4 @@ +export interface IHideoutCircleOfCultistProductionStartRequestData { + Action: "HideoutCircleOfCultistProductionStart"; + timestamp: number; +} diff --git a/types/models/eft/hideout/IHideoutDeleteProductionRequestData.d.ts b/types/models/eft/hideout/IHideoutDeleteProductionRequestData.d.ts new file mode 100644 index 00000000..97714ded --- /dev/null +++ b/types/models/eft/hideout/IHideoutDeleteProductionRequestData.d.ts @@ -0,0 +1,5 @@ +export interface IHideoutDeleteProductionRequestData { + Action: "HideoutDeleteProductionCommand"; + recipeId: string; + timestamp: number; +} diff --git a/types/models/eft/hideout/IHideoutImproveAreaRequestData.d.ts b/types/models/eft/hideout/IHideoutImproveAreaRequestData.d.ts index 7e927bf3..f963c13c 100644 --- a/types/models/eft/hideout/IHideoutImproveAreaRequestData.d.ts +++ b/types/models/eft/hideout/IHideoutImproveAreaRequestData.d.ts @@ -3,10 +3,10 @@ export interface IHideoutImproveAreaRequestData { /** Hideout area id from areas.json */ id: string; areaType: number; - items: HideoutItem[]; + items: IHideoutItem[]; timestamp: number; } -export interface HideoutItem { +export interface IHideoutItem { /** Hideout inventory id that was used by improvement action */ id: string; count: number; diff --git a/types/models/eft/hideout/IHideoutProduction.d.ts b/types/models/eft/hideout/IHideoutProduction.d.ts index 7373a4fd..8f2af05c 100644 --- a/types/models/eft/hideout/IHideoutProduction.d.ts +++ b/types/models/eft/hideout/IHideoutProduction.d.ts @@ -1,7 +1,13 @@ +import { MinMax } from "@spt/models/common/MinMax"; +export interface IHideoutProductionData { + recipes: IHideoutProduction[]; + scavRecipes: IScavRecipe[]; + cultistRecipes: ICultistRecipe[]; +} export interface IHideoutProduction { _id: string; areaType: number; - requirements: Requirement[]; + requirements: IRequirement[]; productionTime: number; /** Tpl of item being crafted */ endProduct: string; @@ -11,15 +17,32 @@ export interface IHideoutProduction { continuous: boolean; count: number; productionLimitCount: number; + isCodeProduction: boolean; } -export interface Requirement { +export interface IRequirement extends IRequirementBase { templateId?: string; count?: number; isEncoded?: boolean; isFunctional?: boolean; - type: string; areaType?: number; requiredLevel?: number; resource?: number; questId?: string; } +export interface IRequirementBase { + type: string; +} +export type IScavRecipe = { + _id: string; + requirements: IRequirement[]; + productionTime: number; + endProducts: IEndProducts; +}; +export interface IEndProducts { + Common: MinMax; + Rare: MinMax; + Superrare: MinMax; +} +export type ICultistRecipe = { + _id: string; +}; diff --git a/types/models/eft/hideout/IHideoutScavCase.d.ts b/types/models/eft/hideout/IHideoutScavCase.d.ts deleted file mode 100644 index d081d422..00000000 --- a/types/models/eft/hideout/IHideoutScavCase.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { MinMax } from "@spt/models/common/MinMax"; -export interface IHideoutScavCase { - _id: string; - ProductionTime: number; - Requirements: Requirement[]; - EndProducts: EndProducts; -} -export interface Requirement { - templateId: string; - count: number; - isFunctional: boolean; - type: string; -} -export interface EndProducts { - Common: MinMax; - Rare: MinMax; - Superrare: MinMax; -} diff --git a/types/models/eft/hideout/IHideoutScavCaseStartRequestData.d.ts b/types/models/eft/hideout/IHideoutScavCaseStartRequestData.d.ts index 72fda86f..198d7786 100644 --- a/types/models/eft/hideout/IHideoutScavCaseStartRequestData.d.ts +++ b/types/models/eft/hideout/IHideoutScavCaseStartRequestData.d.ts @@ -1,15 +1,15 @@ export interface IHideoutScavCaseStartRequestData { Action: "HideoutScavCaseProductionStart"; recipeId: string; - items: HideoutItem[]; - tools: Tool[]; + items: IHideoutItem[]; + tools: ITool[]; timestamp: number; } -export interface HideoutItem { +export interface IHideoutItem { id: string; count: number; } -export interface Tool { +export interface ITool { id: string; count: number; } diff --git a/types/models/eft/hideout/IHideoutSettingsBase.d.ts b/types/models/eft/hideout/IHideoutSettingsBase.d.ts index 8e459391..513d3c71 100644 --- a/types/models/eft/hideout/IHideoutSettingsBase.d.ts +++ b/types/models/eft/hideout/IHideoutSettingsBase.d.ts @@ -2,5 +2,6 @@ export interface IHideoutSettingsBase { generatorSpeedWithoutFuel: number; generatorFuelFlowRate: number; airFilterUnitFlowRate: number; + cultistAmuletBonusPercent: number; gpuBoostRate: number; } diff --git a/types/models/eft/hideout/IHideoutSingleProductionStartRequestData.d.ts b/types/models/eft/hideout/IHideoutSingleProductionStartRequestData.d.ts index dfb92e25..1c97b221 100644 --- a/types/models/eft/hideout/IHideoutSingleProductionStartRequestData.d.ts +++ b/types/models/eft/hideout/IHideoutSingleProductionStartRequestData.d.ts @@ -1,11 +1,11 @@ export interface IHideoutSingleProductionStartRequestData { Action: "HideoutSingleProductionStart"; recipeId: string; - items: Item[]; - tools: Item[]; + items: IHandoverItem[]; + tools: IHandoverItem[]; timestamp: number; } -export interface Item { +export interface IHandoverItem { id: string; count: number; } diff --git a/types/models/eft/hideout/IHideoutUpgradeRequestData.d.ts b/types/models/eft/hideout/IHideoutUpgradeRequestData.d.ts index dfbfdcab..59b61419 100644 --- a/types/models/eft/hideout/IHideoutUpgradeRequestData.d.ts +++ b/types/models/eft/hideout/IHideoutUpgradeRequestData.d.ts @@ -1,10 +1,10 @@ export interface IHideoutUpgradeRequestData { Action: "HideoutUpgrade"; areaType: number; - items: HideoutItem[]; + items: IHideoutItem[]; timestamp: number; } -export interface HideoutItem { +export interface IHideoutItem { count: number; id: string; } diff --git a/types/models/eft/inRaid/IItemDeliveryRequestData.d.ts b/types/models/eft/inRaid/IItemDeliveryRequestData.d.ts index a27bfbbb..7e0fe983 100644 --- a/types/models/eft/inRaid/IItemDeliveryRequestData.d.ts +++ b/types/models/eft/inRaid/IItemDeliveryRequestData.d.ts @@ -1,5 +1,5 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IItemDeliveryRequestData { - items: Item[]; + items: IItem[]; traderId: string; } diff --git a/types/models/eft/inRaid/ISaveProgressRequestData.d.ts b/types/models/eft/inRaid/ISaveProgressRequestData.d.ts deleted file mode 100644 index b6540887..00000000 --- a/types/models/eft/inRaid/ISaveProgressRequestData.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { IPostRaidPmcData } from "@spt/models/eft/common/IPmcData"; -import { ISyncHealthRequestData } from "@spt/models/eft/health/ISyncHealthRequestData"; -import { IInsuredItemsData } from "@spt/models/eft/inRaid/IInsuredItemsData"; -import { PlayerRaidEndState } from "@spt/models/enums/PlayerRaidEndState"; -export interface ISaveProgressRequestData { - exit: PlayerRaidEndState; - profile: IPostRaidPmcData; - isPlayerScav: boolean; - health: ISyncHealthRequestData; - insurance: IInsuredItemsData[]; -} diff --git a/types/models/eft/inRaid/IScavSaveRequestData.d.ts b/types/models/eft/inRaid/IScavSaveRequestData.d.ts new file mode 100644 index 00000000..3f26e263 --- /dev/null +++ b/types/models/eft/inRaid/IScavSaveRequestData.d.ts @@ -0,0 +1,3 @@ +import { IPostRaidPmcData } from "@spt/models/eft/common/IPmcData"; +export interface IScavSaveRequestData extends IPostRaidPmcData { +} diff --git a/types/models/eft/inventory/IAddItemDirectRequest.d.ts b/types/models/eft/inventory/IAddItemDirectRequest.d.ts index 16169015..7f58d002 100644 --- a/types/models/eft/inventory/IAddItemDirectRequest.d.ts +++ b/types/models/eft/inventory/IAddItemDirectRequest.d.ts @@ -1,7 +1,7 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IAddItemDirectRequest { /** Item and child mods to add to player inventory */ - itemWithModsToAdd: Item[]; + itemWithModsToAdd: IItem[]; foundInRaid: boolean; callback: (buyCount: number) => void; useSortingTable: boolean; diff --git a/types/models/eft/inventory/IAddItemRequestData.d.ts b/types/models/eft/inventory/IAddItemRequestData.d.ts index 3fa86dcc..70241bcd 100644 --- a/types/models/eft/inventory/IAddItemRequestData.d.ts +++ b/types/models/eft/inventory/IAddItemRequestData.d.ts @@ -1,9 +1,9 @@ export interface IAddItemRequestData { /** Trader id */ tid: string; - items: AddItem[]; + items: IItemToAdd[]; } -export interface AddItem { +export interface IItemToAdd { count: number; sptIsPreset?: boolean; item_id: string; diff --git a/types/models/eft/inventory/IAddItemTempObject.d.ts b/types/models/eft/inventory/IAddItemTempObject.d.ts index 7b3a6ea3..a822d56a 100644 --- a/types/models/eft/inventory/IAddItemTempObject.d.ts +++ b/types/models/eft/inventory/IAddItemTempObject.d.ts @@ -1,8 +1,8 @@ -import { Item, Location } from "@spt/models/eft/common/tables/IItem"; +import { IItem, IItemLocation } from "@spt/models/eft/common/tables/IItem"; export interface IAddItemTempObject { - itemRef: Item; + itemRef: IItem; count: number; isPreset: boolean; - location?: Location; + location?: IItemLocation; containerId?: string; } diff --git a/types/models/eft/inventory/IAddItemsDirectRequest.d.ts b/types/models/eft/inventory/IAddItemsDirectRequest.d.ts index 386359ee..a7444872 100644 --- a/types/models/eft/inventory/IAddItemsDirectRequest.d.ts +++ b/types/models/eft/inventory/IAddItemsDirectRequest.d.ts @@ -1,7 +1,7 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IAddItemsDirectRequest { /** Item and child mods to add to player inventory */ - itemsWithModsToAdd: Item[][]; + itemsWithModsToAdd: IItem[][]; foundInRaid: boolean; /** Runs after EACH item with children is added */ callback?: (buyCount: number) => void; diff --git a/types/models/eft/inventory/IInventoryAddRequestData.d.ts b/types/models/eft/inventory/IInventoryAddRequestData.d.ts index 63c53894..e1ac7ece 100644 --- a/types/models/eft/inventory/IInventoryAddRequestData.d.ts +++ b/types/models/eft/inventory/IInventoryAddRequestData.d.ts @@ -1,6 +1,6 @@ -import { Container, IInventoryBaseActionRequestData } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; +import { IContainer, IInventoryBaseActionRequestData } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; export interface IInventoryAddRequestData extends IInventoryBaseActionRequestData { Action: "Add"; item: string; - container: Container; + container: IContainer; } diff --git a/types/models/eft/inventory/IInventoryBaseActionRequestData.d.ts b/types/models/eft/inventory/IInventoryBaseActionRequestData.d.ts index cc7269cf..64b1a3ed 100644 --- a/types/models/eft/inventory/IInventoryBaseActionRequestData.d.ts +++ b/types/models/eft/inventory/IInventoryBaseActionRequestData.d.ts @@ -1,25 +1,19 @@ import { IBaseInteractionRequestData } from "@spt/models/eft/common/request/IBaseInteractionRequestData"; +import { IItemLocation } from "@spt/models/eft/common/tables/IItem"; export interface IInventoryBaseActionRequestData extends IBaseInteractionRequestData { } -export interface To { +export interface ITo { id: string; container: string; - location?: ToLocation | number; + location?: IItemLocation | number; isSearched?: boolean; } -export interface ToLocation { - x: number; - y: number; - r: string; - rotation?: string; - isSearched: boolean; -} -export interface Container { +export interface IContainer { id: string; container: string; - location?: Location | number; + location?: ILocation | number; } -export interface Location { +export interface ILocation { x: number; y: number; r: string; diff --git a/types/models/eft/inventory/IInventoryCreateMarkerRequestData.d.ts b/types/models/eft/inventory/IInventoryCreateMarkerRequestData.d.ts index 14691364..11d6ebde 100644 --- a/types/models/eft/inventory/IInventoryCreateMarkerRequestData.d.ts +++ b/types/models/eft/inventory/IInventoryCreateMarkerRequestData.d.ts @@ -2,9 +2,9 @@ import { IInventoryBaseActionRequestData } from "@spt/models/eft/inventory/IInve export interface IInventoryCreateMarkerRequestData extends IInventoryBaseActionRequestData { Action: "CreateMapMarker"; item: string; - mapMarker: MapMarker; + mapMarker: IMapMarker; } -export interface MapMarker { +export interface IMapMarker { Type: string; X: number; Y: number; diff --git a/types/models/eft/inventory/IInventoryEditMarkerRequestData.d.ts b/types/models/eft/inventory/IInventoryEditMarkerRequestData.d.ts index 87dcf861..9d7c6754 100644 --- a/types/models/eft/inventory/IInventoryEditMarkerRequestData.d.ts +++ b/types/models/eft/inventory/IInventoryEditMarkerRequestData.d.ts @@ -4,9 +4,9 @@ export interface IInventoryEditMarkerRequestData extends IInventoryBaseActionReq item: string; X: number; Y: number; - mapMarker: MapMarker; + mapMarker: IMapMarker; } -export interface MapMarker { +export interface IMapMarker { Type: string; X: number; Y: number; diff --git a/types/models/eft/inventory/IInventoryMoveRequestData.d.ts b/types/models/eft/inventory/IInventoryMoveRequestData.d.ts index afb6fd02..e5c2a8b9 100644 --- a/types/models/eft/inventory/IInventoryMoveRequestData.d.ts +++ b/types/models/eft/inventory/IInventoryMoveRequestData.d.ts @@ -1,6 +1,6 @@ -import { IInventoryBaseActionRequestData, To } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; +import { IInventoryBaseActionRequestData, ITo } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; export interface IInventoryMoveRequestData extends IInventoryBaseActionRequestData { Action: "Move"; item: string; - to: To; + to: ITo; } diff --git a/types/models/eft/inventory/IInventorySortRequestData.d.ts b/types/models/eft/inventory/IInventorySortRequestData.d.ts index d784c776..10ee2715 100644 --- a/types/models/eft/inventory/IInventorySortRequestData.d.ts +++ b/types/models/eft/inventory/IInventorySortRequestData.d.ts @@ -1,20 +1,6 @@ -import { Upd } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IInventoryBaseActionRequestData } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; export interface IInventorySortRequestData extends IInventoryBaseActionRequestData { Action: "ApplyInventoryChanges"; - changedItems: ChangedItem[]; -} -export interface ChangedItem { - _id: string; - _tpl: string; - parentId: string; - slotId: string; - location: Location; - upd: Upd; -} -export interface Location { - x: number; - y: number; - r: string; - isSearched: boolean; + changedItems: IItem[]; } diff --git a/types/models/eft/inventory/IInventorySplitRequestData.d.ts b/types/models/eft/inventory/IInventorySplitRequestData.d.ts index a4bb8a40..5667f0a9 100644 --- a/types/models/eft/inventory/IInventorySplitRequestData.d.ts +++ b/types/models/eft/inventory/IInventorySplitRequestData.d.ts @@ -1,4 +1,4 @@ -import { Container, IInventoryBaseActionRequestData } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; +import { IContainer, IInventoryBaseActionRequestData } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; export interface IInventorySplitRequestData extends IInventoryBaseActionRequestData { Action: "Split"; /** Id of item to split */ @@ -6,6 +6,6 @@ export interface IInventorySplitRequestData extends IInventoryBaseActionRequestD /** Id of new item stack */ newItem: string; /** Destination new item will be placed in */ - container: Container; + container: IContainer; count: number; } diff --git a/types/models/eft/inventory/IInventorySwapRequestData.d.ts b/types/models/eft/inventory/IInventorySwapRequestData.d.ts index ccf47966..abd3adb0 100644 --- a/types/models/eft/inventory/IInventorySwapRequestData.d.ts +++ b/types/models/eft/inventory/IInventorySwapRequestData.d.ts @@ -1,11 +1,11 @@ import { OwnerInfo } from "@spt/models/eft/common/request/IBaseInteractionRequestData"; -import { IInventoryBaseActionRequestData, To } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; +import { IInventoryBaseActionRequestData, ITo } from "@spt/models/eft/inventory/IInventoryBaseActionRequestData"; export interface IInventorySwapRequestData extends IInventoryBaseActionRequestData { Action: "Swap"; item: string; - to: To; + to: ITo; item2: string; - to2: To; + to2: ITo; fromOwner2: OwnerInfo; toOwner2: OwnerInfo; } diff --git a/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts b/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts index c9b97e0b..f9bc284b 100644 --- a/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts +++ b/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts @@ -3,9 +3,9 @@ export interface IOpenRandomLootContainerRequestData extends IInventoryBaseActio Action: "OpenRandomLootContainer"; /** Container item id being opened */ item: string; - to: To[]; + to: ITo[]; } -export interface To { +export interface ITo { /** Player character (pmc/scav) id items will be sent to */ id: string; } diff --git a/types/models/eft/inventory/IPinOrLockItemRequest.d.ts b/types/models/eft/inventory/IPinOrLockItemRequest.d.ts new file mode 100644 index 00000000..c39b4047 --- /dev/null +++ b/types/models/eft/inventory/IPinOrLockItemRequest.d.ts @@ -0,0 +1,8 @@ +import { PinLockState } from "../common/tables/IItem"; +export interface IPinOrLockItemRequest { + Action: "PinLock"; + /** Id of item being pinned */ + Item: string; + /** "Pinned"/"Locked"/"Free" */ + State: PinLockState; +} diff --git a/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index 0c480141..b66fc03b 100644 --- a/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,5 +1,5 @@ -import { Health, IQuestStatus, Productive, Skills } from "@spt/models/eft/common/tables/IBotBase"; -import { Item, Upd } from "@spt/models/eft/common/tables/IItem"; +import { IHealth, IHideoutImprovement, IMoneyTransferLimits, IProductive, IQuestStatus, ISkills } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem, IItemLocation, IUpd } from "@spt/models/eft/common/tables/IItem"; import { IQuest } from "@spt/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; @@ -8,79 +8,70 @@ export interface IItemEventRouterBase { warnings: Warning[]; profileChanges: TProfileChanges | ""; } -export type TProfileChanges = Record; +export type TProfileChanges = Record; export interface Warning { index: number; errmsg: string; code?: string; data?: any; } -export interface ProfileChange { +export interface IProfileChange { _id: string; experience: number; quests: IQuest[]; ragFairOffers: IRagfairOffer[]; weaponBuilds: IWeaponBuildChange[]; equipmentBuilds: IEquipmentBuildChange[]; - items: ItemChanges; - production: Record; + items: IItemChanges; + production: Record; /** Hideout area improvement id */ - improvements: Record; - skills: Skills; - health: Health; - traderRelations: Record; + improvements: Record; + skills: ISkills; + health: IHealth; + traderRelations: Record; + moneyTransferLimitData: IMoneyTransferLimits; repeatableQuests?: IPmcDataRepeatableQuest[]; recipeUnlocked: Record; changedHideoutStashes?: Record; questsStatus: IQuestStatus[]; } export interface IHideoutStashItem { - Id: string; - Tpl: string; + id: string; + tpl: string; } export interface IWeaponBuildChange { id: string; name: string; root: string; - items: Item[]; + items: IItem[]; } export interface IEquipmentBuildChange { id: string; name: string; root: string; - items: Item[]; + items: IItem[]; type: string; fastpanel: any[]; buildType: EquipmentBuildType; } -export interface ItemChanges { - new: Product[]; - change: Product[]; - del: Product[]; -} -export interface Improvement { - completed: boolean; - improveCompleteTimestamp: number; +export interface IItemChanges { + new: IProduct[]; + change: IProduct[]; + del: IProduct[]; } /** Related to TraderInfo */ -export interface TraderData { +export interface ITraderData { salesSum: number; standing: number; loyalty: number; unlocked: boolean; disabled: boolean; } -export interface Product { +export interface IProduct { _id: string; _tpl?: string; parentId?: string; slotId?: string; - location?: ItemChangeLocation; - upd?: Upd; -} -export interface ItemChangeLocation { - x: number; - y: number; - r: number; - isSearched?: boolean; + location?: IItemLocation; + upd?: IUpd; } diff --git a/types/models/eft/itemEvent/IItemEventRouterRequest.d.ts b/types/models/eft/itemEvent/IItemEventRouterRequest.d.ts index 515b49a8..5b39fb4e 100644 --- a/types/models/eft/itemEvent/IItemEventRouterRequest.d.ts +++ b/types/models/eft/itemEvent/IItemEventRouterRequest.d.ts @@ -1,19 +1,19 @@ export interface IItemEventRouterRequest { - data: Daum[]; + data: IDaum[]; tm: number; reload: number; } -export interface Daum { +export interface IDaum { Action: string; item: string; - to: To; + to: ITo; } -export interface To { +export interface ITo { id: string; container: string; - location?: Location; + location?: ILocation; } -export interface Location { +export interface ILocation { x: number; y: number; r: string; diff --git a/types/models/eft/launcher/IMiniProfile.d.ts b/types/models/eft/launcher/IMiniProfile.d.ts index b25a1e7d..856920f1 100644 --- a/types/models/eft/launcher/IMiniProfile.d.ts +++ b/types/models/eft/launcher/IMiniProfile.d.ts @@ -1,3 +1,4 @@ +import { ISpt } from "../profile/ISptProfile"; export interface IMiniProfile { username: string; nickname: string; @@ -7,8 +8,7 @@ export interface IMiniProfile { prevexp: number; nextlvl: number; maxlvl: number; - sptData: SPTData; -} -export interface SPTData { - version: string; + edition: string; + profileId: string; + sptData: ISpt; } diff --git a/types/models/eft/location/IAirdropLootResult.d.ts b/types/models/eft/location/IAirdropLootResult.d.ts index cacc805e..963e43cc 100644 --- a/types/models/eft/location/IAirdropLootResult.d.ts +++ b/types/models/eft/location/IAirdropLootResult.d.ts @@ -1,5 +1,5 @@ -import { LootItem } from "@spt/models/spt/services/LootItem"; +import { ILootItem } from "@spt/models/spt/services/LootItem"; export interface IAirdropLootResult { dropType: string; - loot: LootItem[]; + loot: ILootItem[]; } diff --git a/types/models/eft/location/IGetAirdropLootRequest.d.ts b/types/models/eft/location/IGetAirdropLootRequest.d.ts new file mode 100644 index 00000000..c8a9cc9b --- /dev/null +++ b/types/models/eft/location/IGetAirdropLootRequest.d.ts @@ -0,0 +1,3 @@ +export interface IGetAirdropLootRequest { + containerId: string; +} diff --git a/types/models/eft/location/IGetAirdropLootResponse.d.ts b/types/models/eft/location/IGetAirdropLootResponse.d.ts new file mode 100644 index 00000000..93950db1 --- /dev/null +++ b/types/models/eft/location/IGetAirdropLootResponse.d.ts @@ -0,0 +1,6 @@ +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { AirdropTypeEnum } from "@spt/models/enums/AirdropType"; +export interface IGetAirdropLootResponse { + icon: AirdropTypeEnum; + container: IItem[]; +} diff --git a/types/models/eft/match/IEndLocalRaidRequestData.d.ts b/types/models/eft/match/IEndLocalRaidRequestData.d.ts new file mode 100644 index 00000000..cc5b0c53 --- /dev/null +++ b/types/models/eft/match/IEndLocalRaidRequestData.d.ts @@ -0,0 +1,44 @@ +import { ExitStatus } from "@spt/models/enums/ExitStatis"; +import { IPmcData } from "../common/IPmcData"; +import { IItem } from "../common/tables/IItem"; +export interface IEndLocalRaidRequestData { + /** ID of server player just left */ + serverId: string; + results: IEndRaidResult; + /** Insured items left in raid by player */ + lostInsuredItems: IItem[]; + /** Items sent via traders to player, keyed to service e.g. BTRTransferStash */ + transferItems: Record; + locationTransit: ILocationTransit; +} +export interface IEndRaidResult { + profile: IPmcData; + /** "Survived/Transit" etc */ + result: ExitStatus; + killerId: string; + killerAid: string; + /** "Gate 3" etc */ + exitName: string; + inSession: boolean; + favorite: boolean; + /** Seconds in raid */ + playTime: number; +} +export interface ILocationTransit { + hash: string; + playersCount: number; + ip: string; + location: string; + profiles: Record; + transitionRaidId: string; + raidMode: string; + side: string; + dayTime: string; + /** The location player last visited */ + sptLastVisitedLocation: string; +} +export interface ITransitProfile { + _id: string; + keyId: string; + isSolo: boolean; +} diff --git a/types/models/eft/match/IGetRaidConfigurationRequestData.d.ts b/types/models/eft/match/IGetRaidConfigurationRequestData.d.ts index 959986c1..ad65e88f 100644 --- a/types/models/eft/match/IGetRaidConfigurationRequestData.d.ts +++ b/types/models/eft/match/IGetRaidConfigurationRequestData.d.ts @@ -1,6 +1,5 @@ import { IRaidSettings } from "@spt/models/eft/match/IRaidSettings"; export interface IGetRaidConfigurationRequestData extends IRaidSettings { keyId: string; - CanShowGroupPreview: boolean; MaxGroupCount: number; } diff --git a/types/models/eft/match/IGroupCharacter.d.ts b/types/models/eft/match/IGroupCharacter.d.ts index 013930a1..dbb8c876 100644 --- a/types/models/eft/match/IGroupCharacter.d.ts +++ b/types/models/eft/match/IGroupCharacter.d.ts @@ -1,4 +1,4 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { MemberCategory } from "@spt/models/enums/MemberCategory"; export interface IGroupCharacter { _id: string; @@ -29,7 +29,7 @@ export interface IGroupCharacter { }; Equipment: { Id: string; - Items: Item[]; + Items: IItem[]; }; }; isLeader: boolean; diff --git a/types/models/eft/match/IPutMetricsRequestData.d.ts b/types/models/eft/match/IPutMetricsRequestData.d.ts index d9ed2141..ab62acf3 100644 --- a/types/models/eft/match/IPutMetricsRequestData.d.ts +++ b/types/models/eft/match/IPutMetricsRequestData.d.ts @@ -1,10 +1,57 @@ export interface IPutMetricsRequestData { sid: string; settings: any; - SharedSettings: any; - HardwareDescription: any; + SharedSettings: ISharedSettings; + HardwareDescription: IHardwareDescription; Location: string; Metrics: any; - ClientEvents: any; + ClientEvents: IClientEvents; SpikeSamples: any[]; + mode: string; +} +export interface ISharedSettings { + StatedFieldOfView: number; +} +export interface IHardwareDescription { + deviceUniqueIdentifier: string; + systemMemorySize: number; + graphicsDeviceID: number; + graphicsDeviceName: string; + graphicsDeviceType: string; + graphicsDeviceVendor: string; + graphicsDeviceVendorID: number; + graphicsDeviceVersion: string; + graphicsMemorySize: number; + graphicsMultiThreaded: boolean; + graphicsShaderLevel: number; + operatingSystem: string; + processorCount: number; + processorFrequency: number; + processorType: string; + driveType: string; + swapDriveType: string; +} +export interface IClientEvents { + MatchingCompleted: number; + MatchingCompletedReal: number; + LocationLoaded: number; + LocationLoadedReal: number; + GamePrepared: number; + GamePreparedReal: number; + GameCreated: number; + GameCreatedReal: number; + GamePooled: number; + GamePooledReal: number; + GameRunned: number; + GameRunnedReal: number; + GameSpawn: number; + GameSpawnReal: number; + PlayerSpawnEvent: number; + PlayerSpawnEventReal: number; + GameSpawned: number; + GameSpawnedReal: number; + GameStarting: number; + GameStartingReal: number; + GameStarted: number; + GameStartedReal: number; } diff --git a/types/models/eft/match/IRaidSettings.d.ts b/types/models/eft/match/IRaidSettings.d.ts index 78a0c19a..a4b74501 100644 --- a/types/models/eft/match/IRaidSettings.d.ts +++ b/types/models/eft/match/IRaidSettings.d.ts @@ -10,17 +10,20 @@ import { TimeFlowType } from "@spt/models/enums/RaidSettings/TimeAndWeather/Time import { WindSpeed } from "@spt/models/enums/RaidSettings/TimeAndWeather/WindSpeed"; import { SideType } from "@spt/models/enums/SideType"; export interface IRaidSettings { + keyId: string; location: string; + isLocationTransition: boolean; timeVariant: DateTime; - raidMode: RaidMode; metabolismDisabled: boolean; - playersSpawnPlace: PlayersSpawnPlace; - timeAndWeatherSettings: TimeAndWeatherSettings; - botSettings: BotSettings; - wavesSettings: WavesSettings; + timeAndWeatherSettings: ITimeAndWeatherSettings; + botSettings: IBotSettings; + wavesSettings: IWavesSettings; side: SideType; + raidMode: RaidMode; + playersSpawnPlace: PlayersSpawnPlace; + CanShowGroupPreview: boolean; } -export interface TimeAndWeatherSettings { +export interface ITimeAndWeatherSettings { isRandomTime: boolean; isRandomWeather: boolean; cloudinessType: CloudinessType; @@ -30,11 +33,11 @@ export interface TimeAndWeatherSettings { timeFlowType: TimeFlowType; hourOfDay: number; } -export interface BotSettings { +export interface IBotSettings { isScavWars: boolean; botAmount: BotAmount; } -export interface WavesSettings { +export interface IWavesSettings { botAmount: BotAmount; botDifficulty: BotDifficulty; isBosses: boolean; diff --git a/types/models/eft/match/IStartLocalRaidRequestData.d.ts b/types/models/eft/match/IStartLocalRaidRequestData.d.ts new file mode 100644 index 00000000..8477df54 --- /dev/null +++ b/types/models/eft/match/IStartLocalRaidRequestData.d.ts @@ -0,0 +1,17 @@ +export interface IStartLocalRaidRequestData { + serverId: string; + location: string; + timeVariant: string; + mode: string; + playerSide: string; + isLocationTransition: boolean; + transition: IStartLocalRaidTransition; + /** Should loot generation be skipped, default false */ + sptSkipLootGeneration?: boolean; +} +export interface IStartLocalRaidTransition { + isLocationTransition: boolean; + transitionRaidId: string; + transitionCount: number; + visitedLocations: string[]; +} diff --git a/types/models/eft/match/IStartLocalRaidResponseData.d.ts b/types/models/eft/match/IStartLocalRaidResponseData.d.ts new file mode 100644 index 00000000..50b35842 --- /dev/null +++ b/types/models/eft/match/IStartLocalRaidResponseData.d.ts @@ -0,0 +1,19 @@ +import { ILocationBase } from "@spt/models/eft/common/ILocationBase"; +import { IInsuredItem } from "@spt/models/eft/common/tables/IBotBase"; +import { ILocationServices } from "@spt/models/eft/common/tables/ILocationServices"; +export interface IStartLocalRaidResponseData { + serverId: string; + serverSettings: ILocationServices; + profile: IProfileInsuredItems; + locationLoot: ILocationBase; + transition: ITransition; +} +export interface IProfileInsuredItems { + insuredItems: IInsuredItem[]; +} +export interface ITransition { + isLocationTransition: boolean; + transitionRaidId: string; + transitionCount: number; + visitedLocations: string[]; +} diff --git a/types/models/eft/player/IPlayerIncrementSkillLevelRequestData.d.ts b/types/models/eft/player/IPlayerIncrementSkillLevelRequestData.d.ts index 59713722..b59fe107 100644 --- a/types/models/eft/player/IPlayerIncrementSkillLevelRequestData.d.ts +++ b/types/models/eft/player/IPlayerIncrementSkillLevelRequestData.d.ts @@ -1,4 +1,4 @@ -import { Skills } from "@spt/models/eft/common/tables/IBotBase"; +import { ISkills } from "@spt/models/eft/common/tables/IBotBase"; export interface IPlayerIncrementSkillLevelRequestData { _id: string; experience: number; @@ -7,7 +7,7 @@ export interface IPlayerIncrementSkillLevelRequestData { builds: any[]; items: Items; production: Production; - skills: Skills; + skills: ISkills; traderRelations: TraderRelations; } export interface Items { diff --git a/types/models/eft/presetBuild/IPresetBuildActionRequestData.d.ts b/types/models/eft/presetBuild/IPresetBuildActionRequestData.d.ts index 3cb85339..9852ccbc 100644 --- a/types/models/eft/presetBuild/IPresetBuildActionRequestData.d.ts +++ b/types/models/eft/presetBuild/IPresetBuildActionRequestData.d.ts @@ -1,9 +1,9 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IPresetBuildActionRequestData { Action: string; Id: string; /** name of preset given by player */ Name: string; Root: string; - Items: Item[]; + Items: IItem[]; } diff --git a/types/models/eft/profile/GetProfileStatusResponseData.d.ts b/types/models/eft/profile/GetProfileStatusResponseData.d.ts index 1228c2e2..2f3a6a86 100644 --- a/types/models/eft/profile/GetProfileStatusResponseData.d.ts +++ b/types/models/eft/profile/GetProfileStatusResponseData.d.ts @@ -1,8 +1,8 @@ -export interface GetProfileStatusResponseData { +export interface IGetProfileStatusResponseData { maxPveCountExceeded: false; - profiles: ProfileData[]; + profiles: IProfileStatusData[]; } -export interface ProfileData { +export interface IProfileStatusData { profileid: string; profileToken: string; status: string; diff --git a/types/models/eft/profile/IGetOtherProfileResponse.d.ts b/types/models/eft/profile/IGetOtherProfileResponse.d.ts index 7df4ebac..0b4683a1 100644 --- a/types/models/eft/profile/IGetOtherProfileResponse.d.ts +++ b/types/models/eft/profile/IGetOtherProfileResponse.d.ts @@ -1,14 +1,14 @@ -import { OverallCounters, Skills } from "@spt/models/eft/common/tables/IBotBase"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IOverallCounters, ISkills } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IGetOtherProfileResponse { id: string; aid: number; info: IOtherProfileInfo; customization: IOtherProfileCustomization; - skills: Skills; + skills: ISkills; equipment: IOtherProfileEquipment; achievements: Record; - favoriteItems: string[]; + favoriteItems: IItem[]; pmcStats: IOtherProfileStats; scavStats: IOtherProfileStats; } @@ -29,12 +29,12 @@ export interface IOtherProfileCustomization { } export interface IOtherProfileEquipment { Id: string; - Items: Item[]; + Items: IItem[]; } export interface IOtherProfileStats { eft: IOtherProfileSubStats; } export interface IOtherProfileSubStats { totalInGameTime: number; - overAllCounters: OverallCounters; + overAllCounters: IOverallCounters; } diff --git a/types/models/eft/profile/ISptProfile.d.ts b/types/models/eft/profile/ISptProfile.d.ts index dd7aea6e..8290b1c4 100644 --- a/types/models/eft/profile/ISptProfile.d.ts +++ b/types/models/eft/profile/ISptProfile.d.ts @@ -1,26 +1,26 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { EquipmentBuildType } from "@spt/models/enums/EquipmentBuildType"; import { MemberCategory } from "@spt/models/enums/MemberCategory"; import { MessageType } from "@spt/models/enums/MessageType"; import { IProfileChangeEvent } from "@spt/models/spt/dialog/ISendMessageDetails"; export interface ISptProfile { info: Info; - characters: Characters; + characters: ICharacters; /** Clothing purchases */ suits: string[]; userbuilds: IUserBuilds; - dialogues: Record; - spt: Spt; - vitality: Vitality; - inraid: Inraid; - insurance: Insurance[]; + dialogues: Record; + spt: ISpt; + vitality: IVitality; + inraid: IInraid; + insurance: IInsurance[]; /** Assort purchases made by player since last trader refresh */ - traderPurchases?: Record>; + traderPurchases?: Record>; /** Achievements earned by player */ achievements: Record; } -export declare class TraderPurchaseData { +export declare class ITraderPurchaseData { count: number; purchaseTimestamp: number; } @@ -34,7 +34,7 @@ export interface Info { wipe: boolean; edition: string; } -export interface Characters { +export interface ICharacters { pmc: IPmcData; scav: IPmcData; } @@ -50,11 +50,11 @@ export interface IUserBuild { } export interface IWeaponBuild extends IUserBuild { Root: string; - Items: Item[]; + Items: IItem[]; } export interface IEquipmentBuild extends IUserBuild { Root: string; - Items: Item[]; + Items: IItem[]; BuildType: EquipmentBuildType; } export interface IMagazineBuild extends IUserBuild { @@ -69,18 +69,18 @@ export interface IMagazineTemplateAmmoItem { } /** Used by defaultEquipmentPresets.json */ export interface IDefaultEquipmentPreset extends IUserBuild { - Items: Item[]; + Items: IItem[]; Root: string; BuildType: EquipmentBuildType; type: string; } -export interface Dialogue { +export interface IDialogue { attachmentsNew: number; new: number; type: MessageType; Users?: IUserDialogInfo[]; pinned: boolean; - messages: Message[]; + messages: IMessage[]; _id: string; } export interface IUserDialogInfo { @@ -95,16 +95,16 @@ export interface IUserDialogDetails { MemberCategory: MemberCategory; SelectedMemberCategory: MemberCategory; } -export interface DialogueInfo { +export interface IDialogueInfo { attachmentsNew: number; new: number; _id: string; type: MessageType; pinned: boolean; Users?: IUserDialogInfo[]; - message: MessagePreview; + message: IMessagePreview; } -export interface Message { +export interface IMessage { _id: string; uid: string; type: MessageType; @@ -116,7 +116,7 @@ export interface Message { replyTo?: IReplyTo; hasRewards?: boolean; rewardCollected: boolean; - items?: MessageItems; + items?: IMessageItems; maxStorageTime?: number; systemData?: ISystemData; profileChangeEvents?: IProfileChangeEvent[]; @@ -128,7 +128,7 @@ export interface IReplyTo { dt: number; text?: string; } -export interface MessagePreview { +export interface IMessagePreview { uid: string; type: MessageType; dt: number; @@ -136,9 +136,9 @@ export interface MessagePreview { text?: string; systemData?: ISystemData; } -export interface MessageItems { +export interface IMessageItems { stash?: string; - data?: Item[]; + data?: IItem[]; } export interface ISystemData { date?: string; @@ -156,39 +156,37 @@ export interface IUpdatableChatMember { Ignored: boolean; Banned: boolean; } -export interface DateTime { - date: string; - time: string; -} -export interface Spt { +export interface ISpt { /** What version of SPT was this profile made with */ version: string; /** What mods has this profile loaded at any point in time */ - mods?: ModDetails[]; + mods?: IModDetails[]; /** What gifts has this profile received and how many */ - receivedGifts: ReceivedGift[]; + receivedGifts?: IReceivedGift[]; /** item TPLs blacklisted from being sold on flea for this profile */ blacklistedItemTpls?: string[]; /** key: daily type */ - freeRepeatableRefreshUsedCount: Record; + freeRepeatableRefreshUsedCount?: Record; + /** When was a profile migrated, value is timestamp */ + migrations?: Record; } -export interface ModDetails { +export interface IModDetails { name: string; version: string; author: string; dateAdded: number; url: string; } -export interface ReceivedGift { +export interface IReceivedGift { giftId: string; timestampLastAccepted: number; current: number; } -export interface Vitality { - health: Health; - effects: Effects; +export interface IVitality { + health: IHealth; + effects: IEffects; } -export interface Health { +export interface IHealth { Hydration: number; Energy: number; Temperature: number; @@ -200,44 +198,44 @@ export interface Health { LeftLeg: number; RightLeg: number; } -export interface Effects { - Head: Head; - Chest: Chest; - Stomach: Stomach; - LeftArm: LeftArm; - RightArm: RightArm; - LeftLeg: LeftLeg; - RightLeg: RightLeg; -} -export type Head = {}; -export type Chest = {}; -export type Stomach = {}; -export interface LeftArm { +export interface IEffects { + Head: IHead; + Chest: IChest; + Stomach: IStomach; + LeftArm: ILeftArm; + RightArm: IRightArm; + LeftLeg: ILeftLeg; + RightLeg: IRightLeg; +} +export type IHead = {}; +export type IChest = {}; +export type IStomach = {}; +export interface ILeftArm { Fracture?: number; } -export interface RightArm { +export interface IRightArm { Fracture?: number; } -export interface LeftLeg { +export interface ILeftLeg { Fracture?: number; } -export interface RightLeg { +export interface IRightLeg { Fracture?: number; } -export interface Inraid { +export interface IInraid { location: string; character: string; } -export interface Insurance { +export interface IInsurance { scheduledTime: number; traderId: string; maxStorageTime: number; systemData: ISystemData; messageType: MessageType; messageTemplateId: string; - items: Item[]; + items: IItem[]; } -export interface MessageContentRagfair { +export interface IMessageContentRagfair { offerId: string; count: number; handbookId: string; diff --git a/types/models/eft/quests/IHandoverQuestRequestData.d.ts b/types/models/eft/quests/IHandoverQuestRequestData.d.ts index 63f10a8b..39604d5e 100644 --- a/types/models/eft/quests/IHandoverQuestRequestData.d.ts +++ b/types/models/eft/quests/IHandoverQuestRequestData.d.ts @@ -2,9 +2,9 @@ export interface IHandoverQuestRequestData { Action: "QuestHandover"; qid: string; conditionId: string; - items: Item[]; + items: IHandoverItem[]; } -export interface Item { +export interface IHandoverItem { id: string; count: number; } diff --git a/types/models/eft/ragfair/IAddOfferRequestData.d.ts b/types/models/eft/ragfair/IAddOfferRequestData.d.ts index 465ee029..b87040a7 100644 --- a/types/models/eft/ragfair/IAddOfferRequestData.d.ts +++ b/types/models/eft/ragfair/IAddOfferRequestData.d.ts @@ -2,9 +2,9 @@ export interface IAddOfferRequestData { Action: string; sellInOnePiece: boolean; items: string[]; - requirements: Requirement[]; + requirements: IRequirement[]; } -export interface Requirement { +export interface IRequirement { _tpl: string; count: number; level: number; diff --git a/types/models/eft/ragfair/IRagfairOffer.d.ts b/types/models/eft/ragfair/IRagfairOffer.d.ts index f6c07fcd..77c56056 100644 --- a/types/models/eft/ragfair/IRagfairOffer.d.ts +++ b/types/models/eft/ragfair/IRagfairOffer.d.ts @@ -1,11 +1,11 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { DogtagExchangeSide } from "@spt/models/enums/DogtagExchangeSide"; import { MemberCategory } from "@spt/models/enums/MemberCategory"; export interface IRagfairOffer { - sellResult?: SellResult[]; + sellResult?: ISellResult[]; _id: string; - items: Item[]; - requirements: OfferRequirement[]; + items: IItem[]; + requirements: IOfferRequirement[]; root: string; intId: number; /** Handbook price */ @@ -14,6 +14,7 @@ export interface IRagfairOffer { requirementsCost: number; startTime: number; endTime: number; + /** True when offer is sold as pack */ sellInOnePiece: boolean; /** Rouble price - same as requirementsCost */ summaryCost: number; @@ -25,7 +26,7 @@ export interface IRagfairOffer { buyRestrictionCurrent?: number; locked?: boolean; } -export interface OfferRequirement { +export interface IOfferRequirement { _tpl: string; count: number; onlyFunctional: boolean; @@ -42,7 +43,7 @@ export interface IRagfairOfferUser { isRatingGrowing?: boolean; aid?: number; } -export interface SellResult { +export interface ISellResult { sellTime: number; amount: number; } diff --git a/types/models/eft/repair/IRepairActionDataRequest.d.ts b/types/models/eft/repair/IRepairActionDataRequest.d.ts index d51c1b9c..58773dff 100644 --- a/types/models/eft/repair/IRepairActionDataRequest.d.ts +++ b/types/models/eft/repair/IRepairActionDataRequest.d.ts @@ -1,10 +1,10 @@ import { IBaseRepairActionDataRequest } from "@spt/models/eft/repair/IBaseRepairActionDataRequest"; export interface IRepairActionDataRequest extends IBaseRepairActionDataRequest { Action: "Repair"; - repairKitsInfo: RepairKitsInfo[]; + repairKitsInfo: IRepairKitsInfo[]; target: string; } -export interface RepairKitsInfo { +export interface IRepairKitsInfo { _id: string; count: number; } diff --git a/types/models/eft/repair/ITraderRepairActionDataRequest.d.ts b/types/models/eft/repair/ITraderRepairActionDataRequest.d.ts index 50f308e1..c55a1d92 100644 --- a/types/models/eft/repair/ITraderRepairActionDataRequest.d.ts +++ b/types/models/eft/repair/ITraderRepairActionDataRequest.d.ts @@ -2,9 +2,9 @@ import { IBaseRepairActionDataRequest } from "@spt/models/eft/repair/IBaseRepair export interface ITraderRepairActionDataRequest extends IBaseRepairActionDataRequest { Action: "TraderRepair"; tid: string; - repairItems: RepairItem[]; + repairItems: IRepairItem[]; } -export interface RepairItem { +export interface IRepairItem { _id: string; count: number; } diff --git a/types/models/eft/trade/IProcessBuyTradeRequestData.d.ts b/types/models/eft/trade/IProcessBuyTradeRequestData.d.ts index d64b2c92..d72a1316 100644 --- a/types/models/eft/trade/IProcessBuyTradeRequestData.d.ts +++ b/types/models/eft/trade/IProcessBuyTradeRequestData.d.ts @@ -6,9 +6,9 @@ export interface IProcessBuyTradeRequestData extends IProcessBaseTradeRequestDat item_id: string; count: number; scheme_id: number; - scheme_items: SchemeItem[]; + scheme_items: ISchemeItem[]; } -export interface SchemeItem { +export interface ISchemeItem { /** Id of stack to take money from, is money tpl when Action is `SptInsure` */ id: string; count: number; diff --git a/types/models/eft/trade/IProcessSellTradeRequestData.d.ts b/types/models/eft/trade/IProcessSellTradeRequestData.d.ts index 459bd288..b345c3e4 100644 --- a/types/models/eft/trade/IProcessSellTradeRequestData.d.ts +++ b/types/models/eft/trade/IProcessSellTradeRequestData.d.ts @@ -4,9 +4,9 @@ export interface IProcessSellTradeRequestData extends IProcessBaseTradeRequestDa type: string; tid: string; price: number; - items: Item[]; + items: ISoldItem[]; } -export interface Item { +export interface ISoldItem { id: string; count: number; scheme_id: number; diff --git a/types/models/eft/weather/IWeatherData.d.ts b/types/models/eft/weather/IWeatherData.d.ts index 81bc7463..2246b86e 100644 --- a/types/models/eft/weather/IWeatherData.d.ts +++ b/types/models/eft/weather/IWeatherData.d.ts @@ -12,12 +12,15 @@ export interface IWeather { temp: number; fog: number; rain_intensity: number; + /** 1 - 3 light rain, 3+ 'rain' */ rain: number; wind_gustiness: number; wind_direction: WindDirection; wind_speed: number; + /** < -0.4 = clear day */ cloud: number; time: string; date: string; timestamp: number; + sptInRaidTimestamp: number; } diff --git a/types/models/eft/wishlist/IAddToWishlistRequest.d.ts b/types/models/eft/wishlist/IAddToWishlistRequest.d.ts new file mode 100644 index 00000000..656f77bc --- /dev/null +++ b/types/models/eft/wishlist/IAddToWishlistRequest.d.ts @@ -0,0 +1,4 @@ +export interface IAddToWishlistRequest { + Action: string; + items: Record; +} diff --git a/types/models/eft/wishlist/IChangeWishlistItemCategoryRequest.d.ts b/types/models/eft/wishlist/IChangeWishlistItemCategoryRequest.d.ts new file mode 100644 index 00000000..7ce88e0d --- /dev/null +++ b/types/models/eft/wishlist/IChangeWishlistItemCategoryRequest.d.ts @@ -0,0 +1,5 @@ +export interface IChangeWishlistItemCategoryRequest { + Action: string; + item: string; + category: number; +} diff --git a/types/models/eft/wishlist/IRemoveFromWishlistRequest.d.ts b/types/models/eft/wishlist/IRemoveFromWishlistRequest.d.ts new file mode 100644 index 00000000..6a13b1f7 --- /dev/null +++ b/types/models/eft/wishlist/IRemoveFromWishlistRequest.d.ts @@ -0,0 +1,4 @@ +export interface IRemoveFromWishlistRequest { + Action: string; + items: string[]; +} diff --git a/types/models/eft/wishlist/IWishlistActionData.d.ts b/types/models/eft/wishlist/IWishlistActionData.d.ts deleted file mode 100644 index 92178648..00000000 --- a/types/models/eft/wishlist/IWishlistActionData.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IWishlistActionData { - Action: string; - templateId: string; -} diff --git a/types/models/eft/ws/IWsChatMessageReceived.d.ts b/types/models/eft/ws/IWsChatMessageReceived.d.ts index 302d8f19..cc73cf3c 100644 --- a/types/models/eft/ws/IWsChatMessageReceived.d.ts +++ b/types/models/eft/ws/IWsChatMessageReceived.d.ts @@ -1,8 +1,8 @@ import { IGroupCharacter } from "@spt/models/eft/match/IGroupCharacter"; -import { Message } from "@spt/models/eft/profile/ISptProfile"; +import { IMessage } from "@spt/models/eft/profile/ISptProfile"; import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent"; export interface IWsChatMessageReceived extends IWsNotificationEvent { dialogId: string; - message: Message; + message: IMessage; profiles?: IGroupCharacter[]; } diff --git a/types/models/enums/AirdropType.d.ts b/types/models/enums/AirdropType.d.ts index a6f6e3a6..103c204b 100644 --- a/types/models/enums/AirdropType.d.ts +++ b/types/models/enums/AirdropType.d.ts @@ -1,6 +1,13 @@ export declare enum AirdropTypeEnum { - MIXED = "mixed", - WEAPONARMOR = "weaponarmor", - FOODMEDICAL = "foodmedical", - BARTER = "barter" + COMMON = "Common", + SUPPLY = "Supply", + MEDICAL = "Medical", + WEAPON_ARMOR = "Weapon" +} +export declare enum SptAirdropTypeEnum { + COMMON = "mixed", + SUPPLY = "barter", + FOOD_MEDICAL = "foodMedical", + WEAPON_ARMOR = "weaponArmor", + RADAR = "radar" } diff --git a/types/models/enums/BaseClasses.d.ts b/types/models/enums/BaseClasses.d.ts index 32ebf7c9..65fc95e6 100644 --- a/types/models/enums/BaseClasses.d.ts +++ b/types/models/enums/BaseClasses.d.ts @@ -107,6 +107,6 @@ export declare enum BaseClasses { RECEIVER = "55818a304bdc2db5418b457d", BARREL = "555ef6e44bdc2de9068b457e", CHARGING_HANDLE = "55818a6f4bdc2db9688b456b", - COMB_MUZZLE_DEVICE = "550aa4dd4bdc2dc9348b4569", + COMB_MUZZLE_DEVICE = "550aa4dd4bdc2dc9348b4569 ", HIDEOUT_AREA_CONTAINER = "63da6da4784a55176c018dba" } diff --git a/types/models/enums/ConfigTypes.d.ts b/types/models/enums/ConfigTypes.d.ts index 646fd550..2c4483a9 100644 --- a/types/models/enums/ConfigTypes.d.ts +++ b/types/models/enums/ConfigTypes.d.ts @@ -24,6 +24,5 @@ export declare enum ConfigTypes { WEATHER = "spt-weather", SEASONAL_EVENT = "spt-seasonalevents", LOST_ON_DEATH = "spt-lostondeath", - GIFTS = "spt-gifts", - BTR = "spt-btr" + GIFTS = "spt-gifts" } diff --git a/types/models/enums/ExitStatis.d.ts b/types/models/enums/ExitStatis.d.ts index 78d97335..25330767 100644 --- a/types/models/enums/ExitStatis.d.ts +++ b/types/models/enums/ExitStatis.d.ts @@ -1,7 +1,8 @@ export declare enum ExitStatus { - SURVIVED = 0, - KILLED = 1, - LEFT = 2, - RUNNER = 3, - MISSINGINACTION = 4 + SURVIVED = "Survived", + KILLED = "Killed", + LEFT = "Left", + RUNNER = "Runner", + MISSINGINACTION = "MissingInAction", + TRANSIT = "Transit" } diff --git a/types/models/enums/HideoutAreas.d.ts b/types/models/enums/HideoutAreas.d.ts index 1af487ab..6211f269 100644 --- a/types/models/enums/HideoutAreas.d.ts +++ b/types/models/enums/HideoutAreas.d.ts @@ -25,5 +25,7 @@ export declare enum HideoutAreas { EMERGENCY_WALL = 22, GYM = 23, WEAPON_STAND = 24, - WEAPON_STAND_SECONDARY = 25 + WEAPON_STAND_SECONDARY = 25, + EQUIPMENT_PRESETS_STAND = 26, + CIRCLE_OF_CULTISTS = 27 } diff --git a/types/models/enums/HideoutEventActions.d.ts b/types/models/enums/HideoutEventActions.d.ts index 556c799c..a495db9d 100644 --- a/types/models/enums/HideoutEventActions.d.ts +++ b/types/models/enums/HideoutEventActions.d.ts @@ -10,5 +10,7 @@ export declare enum HideoutEventActions { HIDEOUT_TAKE_PRODUCTION = "HideoutTakeProduction", HIDEOUT_RECORD_SHOOTING_RANGE_POINTS = "RecordShootingRangePoints", HIDEOUT_IMPROVE_AREA = "HideoutImproveArea", - HIDEOUT_CANCEL_PRODUCTION_COMMAND = "HideoutCancelProductionCommand" + HIDEOUT_CANCEL_PRODUCTION_COMMAND = "HideoutCancelProductionCommand", + HIDEOUT_CIRCLE_OF_CULTIST_PRODUCTION_START = "HideoutCircleOfCultistProductionStart", + HIDEOUT_DELETE_PRODUCTION_COMMAND = "HideoutDeleteProductionCommand" } diff --git a/types/models/enums/ItemEventActions.d.ts b/types/models/enums/ItemEventActions.d.ts index f8a8b5a2..3541ae86 100644 --- a/types/models/enums/ItemEventActions.d.ts +++ b/types/models/enums/ItemEventActions.d.ts @@ -25,5 +25,6 @@ export declare enum ItemEventActions { REMOVE_EQUIPMENT_BUILD = "RemoveEquipmentBuild", REDEEM_PROFILE_REWARD = "RedeemProfileReward", SET_FAVORITE_ITEMS = "SetFavoriteItems", - QUEST_FAIL = "QuestFail" + QUEST_FAIL = "QuestFail", + PIN_LOCK = "PinLock" } diff --git a/types/models/enums/ItemTpl.d.ts b/types/models/enums/ItemTpl.d.ts index 8512ea87..2493578f 100644 --- a/types/models/enums/ItemTpl.d.ts +++ b/types/models/enums/ItemTpl.d.ts @@ -37,8 +37,8 @@ export declare enum ItemTpl { AMMOBOX_366TKM_GEKSA_20RND = "657023fcbfc87b3a34093213", AMMOBOX_45ACP_AP_50RND = "6489879db5a2df1c815a04ef", AMMOBOX_45ACP_FMJ_50RND = "6570240ecfc010a0f50069f2", - AMMOBOX_45ACP_HSHOCK_50RND = "65702406bfc87b3a34093216", - AMMOBOX_45ACP_LASERFMJ_50RND = "6570240a1419851aef03e6f7", + AMMOBOX_45ACP_HYDRASHOK_50RND = "65702406bfc87b3a34093216", + AMMOBOX_45ACP_LASERMATCH_50RND = "6570240a1419851aef03e6f7", AMMOBOX_45ACP_RIP_50RND = "65702414c5d7d4cb4d078555", AMMOBOX_46X30_ACTION_SX_40RND = "657024c81419851aef03e712", AMMOBOX_46X30_AP_SX_40RND = "6489870774a806211e4fb685", @@ -204,6 +204,10 @@ export declare enum ItemTpl { AMMOBOX_9X39_SPP_8RND = "5c12619186f7743f871c8a32", AMMO_127X108_B32 = "5cde8864d7f00c0010373be1", AMMO_127X108_BZT44M = "5d2f2ab648f03550091993ca", + AMMO_127X33_COPPER = "66a0d1e0ed648d72fe064d06", + AMMO_127X33_FMJ = "668fe62ac62660a5d8071446", + AMMO_127X33_HAWK_JSP = "66a0d1f88486c69fce00fdf6", + AMMO_127X33_JHP = "66a0d1c87d0d369e270bb9de", AMMO_127X55_PS12 = "5cadf6ddae9215051e1c23b2", AMMO_127X55_PS12A = "5cadf6e5ae921500113bb973", AMMO_127X55_PS12B = "5cadf6eeae921500134b2799", @@ -237,12 +241,14 @@ export declare enum ItemTpl { AMMO_23X75_SHRAP10 = "5e85a9a6eacf8c039e4e2ac1", AMMO_23X75_SHRAP25 = "5f647f31b6238e5dd066e196", AMMO_23X75_ZVEZDA = "5e85a9f4add9fe03027d9bf1", + AMMO_26X75_AG = "635267f063651329f75a4ee8", AMMO_26X75_FLARE = "62389bc9423ed1685422dc57", AMMO_26X75_GREEN = "62389aaba63f32501b1b444f", AMMO_26X75_RED = "62389ba9a63f32501b1b4451", - AMMO_26X75_SIGNAL = "635267f063651329f75a4ee8", + AMMO_26X75_SIGNAL_FLARE_BLUE = "66d97834d2985e11480d5c1e", AMMO_26X75_SIGNAL_FLARE_GREEN = "624c0570c9b794431568f5d5", AMMO_26X75_SIGNAL_FLARE_RED = "624c09cfbc2e27219346d955", + AMMO_26X75_SIGNAL_FLARE_SPECIAL_YELLOW = "66d9f3047b82b9a9aa055d81", AMMO_26X75_SIGNAL_FLARE_WHITE = "624c09da2cec124eb67c1046", AMMO_26X75_SIGNAL_FLARE_YELLOW = "624c09e49b98e019a3315b66", AMMO_26X75_YELLOW = "62389be94d5d474bf712e709", @@ -510,6 +516,7 @@ export declare enum ItemTpl { ASSAULTCARBINE_KBP_VSK94_9X39_RIFLE = "645e0c6b3b381ede770e1cc9", ASSAULTCARBINE_MOLOT_ARMS_SIMONOV_OPSKS_762X39_CARBINE = "587e02ff24597743df3deaeb", ASSAULTCARBINE_MOLOT_ARMS_VPO101_VEPRHUNTER_762X51_CARBINE = "5c501a4d2e221602b412b540", + ASSAULTCARBINE_SR3M_9X39_COMPACT_ASSAULT_RIFLE = "651450ce0e00edc794068371", ASSAULTCARBINE_TOKAREV_AVT40_762X54R_AUTOMATIC_RIFLE = "6410733d5dd49d77bd07847e", ASSAULTCARBINE_TOKAREV_SVT40_762X54R_RIFLE = "643ea5b23db6f9f57107d9fd", ASSAULTCARBINE_TOZ_SIMONOV_SKS_762X39_CARBINE = "574d967124597745970e7c94", @@ -551,10 +558,11 @@ export declare enum ItemTpl { ASSAULTRIFLE_RIFLE_DYNAMICS_RD704_762X39_ASSAULT_RIFLE = "628a60ae6b1d481ff772e9c8", ASSAULTRIFLE_SAG_AK545_545X39_CARBINE = "628b5638ad252a16da6dd245", ASSAULTRIFLE_SAG_AK545_SHORT_545X39_CARBINE = "628b9c37a733087d0d7fe84b", + ASSAULTRIFLE_SIG_MCXSPEAR_68X51_ASSAULT_RIFLE = "65290f395ae2ae97b80fdf2d", ASSAULTRIFLE_SIG_MCX_300_BLACKOUT_ASSAULT_RIFLE = "5fbcc1d9016cce60e8341ab3", - ASSAULTRIFLE_SIG_MCX_SPEAR_68X51_ASSAULT_RIFLE = "65290f395ae2ae97b80fdf2d", ASSAULTRIFLE_STEYR_AUG_A1_556X45_ASSAULT_RIFLE = "62e7c4fba689e8c9c50dfc38", ASSAULTRIFLE_STEYR_AUG_A3_556X45_ASSAULT_RIFLE = "63171672192e68c5460cebc5", + ASSAULTRIFLE_STEYR_AUG_A3_556X45_ASSAULT_RIFLE_BLACK = "6718817435e3cfd9550d2c27", ASSAULTSCOPE_ELCAN_SPECTERDR_1X4X_SCOPE = "57ac965c24597706be5f975c", ASSAULTSCOPE_ELCAN_SPECTERDR_1X4X_SCOPE_FDE = "57aca93d2459771f2c7e26db", ASSAULTSCOPE_ELCAN_SPECTER_OS4X_ASSAULT_SCOPE = "544a3f024bdc2d1d388b4568", @@ -615,6 +623,7 @@ export declare enum ItemTpl { BACKPACK_6SH118_RAID_BACKPACK_DIGITAL_FLORA = "5df8a4d786f77412672a1e3b", BACKPACK_ANA_TACTICAL_BETA_2_BATTLE_BACKPACK_OLIVE_DRAB = "5b44c6ae86f7742d1627baea", BACKPACK_CAMELBAK_TRIZIP_ASSAULT_BACKPACK_FOLIAGE = "545cdae64bdc2d39198b4568", + BACKPACK_CAMELBAK_TRIZIP_ASSAULT_BACKPACK_MULTICAM = "66b5f22b78bbc0200425f904", BACKPACK_DIRECT_ACTION_DRAGON_EGG_MARK_II_BACKPACK_BLACK = "656f198fb27298d6fd005466", BACKPACK_DUFFLE_BAG = "56e33634d2720bd8058b456b", BACKPACK_EBERLESTOCK_F4_TERMINATOR_LOAD_BEARING_BACKPACK_TIGER_STRIPE = "5f5e46b96bdad616ad46d613", @@ -636,7 +645,9 @@ export declare enum ItemTpl { BACKPACK_MYSTERY_RANCH_BLACKJACK_50_BACKPACK_MULTICAM = "5c0e774286f77468413cc5b2", BACKPACK_MYSTERY_RANCH_NICE_COMM_3_BVS_FRAME_SYSTEM_COYOTE = "628bc7fb408e2b2e9c0801b1", BACKPACK_MYSTERY_RANCH_SATL_BRIDGER_ASSAULT_PACK_FOLIAGE = "656e0436d44a1bb4220303a0", + BACKPACK_MYSTERY_RANCH_TERRAPLANE = "56e294cdd2720b603a8b4575", BACKPACK_OAKLEY_MECHANISM_HEAVY_DUTY_BACKPACK_BLACK = "5d5d940f86f7742797262046", + BACKPACK_PARTISANS_BAG = "66a9f98f3bd5a41b162030f4", BACKPACK_PILGRIM_TOURIST = "59e763f286f7742ee57895da", BACKPACK_SANITARS_BAG = "5e997f0b86f7741ac73993e2", BACKPACK_SANTAS_BAG = "61b9e1aaef9a1b5d6a79899a", @@ -646,9 +657,14 @@ export declare enum ItemTpl { BACKPACK_TASMANIAN_TIGER_TROOPER_35_BACKPACK_KHAKI = "639346cc1c8f182ad90c8972", BACKPACK_TEHINKOM_RKPT25_PATROL_BACKPACK_DIGITAL_FLORA = "656ddcf0f02d7bcea90bf395", BACKPACK_TRANSFORMER_BAG = "56e33680d2720be2748b4576", + BACKPACK_VERTX_READY_PACK_BACKPACK_RED = "66b5f247af44ca0014063c02", BACKPACK_VKBO_ARMY_BAG = "5ab8ee7786f7742d8f33f0b9", BACKPACK_WARTECH_BERKUT_BB102_BACKPACK_ATACS_FG = "5ca20d5986f774331e7c9602", BARREL_9A91_9X39 = "645122f6d4928d46d30be3ff", + BARREL_AA12_12GA_330MM = "66ffac601f7492c901027bbb", + BARREL_AA12_12GA_342MM_THREADED = "670fd03dc424cf758f006946", + BARREL_AA12_12GA_417MM_THREADED = "670fd0a8d8d4eae4790c8187", + BARREL_AA12_12GA_457MM = "670fced86a7e274b1a0964e8", BARREL_AI_AXMC_338_LM_28_INCH = "628121434fa03b6b6c35dc6a", BARREL_AR10_762X51_18_INCH = "5a34f7f1c4a2826c6e06d75d", BARREL_AR10_762X51_22_INCH = "5a34fae7c4a2826c6e06d760", @@ -660,6 +676,11 @@ export declare enum ItemTpl { BARREL_AR15_HANSON_CARBINE_556X45_137_INCH = "63d3ce0446bd475bcb50f55f", BARREL_AR15_HANSON_CARBINE_556X45_16_INCH = "63d3d44a2a49307baf09386d", BARREL_BENELLI_M3_SUPER_90_12GA_500MM = "6259c2c1d714855d182bad85", + BARREL_DESERT_EAGLE_L5_357_127MM = "669fa4c61bd4416eaa09b3ca", + BARREL_DESERT_EAGLE_L5_50_AE_127MM = "669fa4ba1bd4416eaa09b3c6", + BARREL_DESERT_EAGLE_L6_50_AE_152MM = "669fa47da0bab4e8510d9526", + BARREL_DESERT_EAGLE_L6_50_AE_152MM_BARREL_WTS = "669fa48fa0bab4e8510d952a", + BARREL_DESERT_EAGLE_MK_XIX_50_AE_152MM = "668fe5f62a0f85eea407cc18", BARREL_DVL10_762X51_500MM = "5888945a2459774bf43ba385", BARREL_DVL10_M2_762X51_660MM = "5888956924597752983e182d", BARREL_FN_FIVESEVEN_57X28 = "5d3eb5b6a4b9361eab311902", @@ -706,6 +727,10 @@ export declare enum ItemTpl { BARREL_M1911A1_45_ACP_THREADED = "5f3e77f59103d430b93f94c1", BARREL_M1A_762X51_16_INCH = "5aaf9d53e5b5b00015042a52", BARREL_M1A_762X51_22_INCH = "5addbac75acfc400194dbc56", + BARREL_M60E3_762X51_584MM = "6601279cc752a02bbe05e692", + BARREL_M60E4_762X51_458MM = "660126f7c752a02bbe05e688", + BARREL_M60E4_762X51_475MM_HEAVY = "66012788c752a02bbe05e68e", + BARREL_M60E6_762X51_458MM = "66225d88a1c7e3b81600c76f", BARREL_M700_762X51_20_INCH_STAINLESS_STEEL_THREADED = "5d2703038abbc3105103d94c", BARREL_M700_762X51_20_INCH_THREADED = "5bfebc320db8340019668d79", BARREL_M700_762X51_26_INCH = "5bfebc250db834001a6694e1", @@ -716,9 +741,9 @@ export declare enum ItemTpl { BARREL_M870_12GA_660MM_VENT_RIB = "5a787fadc5856700155a6ca1", BARREL_M870_12GA_SAWEDOFF_325MM = "5a787fdfc5856700142fdd9a", BARREL_M9A3_9X19_THREADED = "5cadc1c6ae9215000f2775a4", + BARREL_MCXSPEAR_68X51_330MM = "652910565ae2ae97b80fdf35", BARREL_MCX_300_BLK_171MM = "5fbbfabed5cb881a7363194e", BARREL_MCX_300_BLK_229MM = "5fbbfacda56d053a3543f799", - BARREL_MCX_SPEAR_68X51_330MM = "652910565ae2ae97b80fdf35", BARREL_MDR_556X45_16_INCH = "5c48a2852e221602b21d5923", BARREL_MDR_762X51_16_INCH = "5dcbe9431e1f4616d354987e", BARREL_MK18_338_LM_24_INCH = "5fc23678ab884124df0cd590", @@ -790,7 +815,15 @@ export declare enum ItemTpl { BARREL_TT_762X25_116MM = "571a26d524597720680fbe8a", BARREL_TT_762X25_116MM_GILDED = "5b3baf8f5acfc40dc5296692", BARREL_TT_762X25_121MM_HOMESPUN_THREADED = "571a279b24597720b4066566", - BARREL_VPO215_GORNOSTAY_366TKM_23_INCH = "5de65547883dde217541644b", + BARREL_UZI_238MM_THREADED_3LUG = "6698c89bfbc8142e60024b0e", + BARREL_UZI_9X19_259MM = "6698c8ab29e062525d0ad8ab", + BARREL_UZI_9X19_409MM = "6698c8b7710a4525fe0e9e55", + BARREL_UZI_PRO_9X19_114MM = "66866fe776d1a87cd80fd388", + BARREL_UZI_PRO_9X19_170MM = "6686700a2b934a68630a7fe6", + BARREL_UZI_PRO_9X19_210MM = "66867023c3d473265104f384", + BARREL_UZI_PRO_9X19_240MM = "668670432b934a68630a7fe8", + BARREL_UZI_PRO_9X19_PIKE_ARMS_114MM_THREADED = "668031705014e211b4078046", + BARREL_VPO21502_366TKM_600MM = "5de65547883dde217541644b", BARREL_VSK94_9X39 = "645123013d52156624001fd1", BARTER_42_SIGNATURE_BLEND_ENGLISH_TEA = "5bc9be8fd4351e00334cae6e", BARTER_6STEN140M_MILITARY_BATTERY = "5d03794386f77420415576f5", @@ -868,6 +901,7 @@ export declare enum ItemTpl { BARTER_FLEECE_FABRIC = "5e2af47786f7746d404f3aaa", BARTER_FP100_FILTER_ABSORBER = "5d1b2f3f86f774252167a52c", BARTER_FUEL_CONDITIONER = "5b43575a86f77424f443fe62", + BARTER_GARY_ZONT_PORTABLE_ELECTRONIC_WARFARE_DEVICE = "66d9f8744827a77e870ecaf1", BARTER_GAS_ANALYZER = "590a3efd86f77437d351a25b", BARTER_GAS_MASK_AIR_FILTER = "590c595c86f7747884343ad7", BARTER_GEIGERMULLER_COUNTER = "5672cb724bdc2dc2088b456b", @@ -884,25 +918,27 @@ export declare enum ItemTpl { BARTER_HAND_DRILL = "5d1b317c86f7742523398392", BARTER_HORSE_FIGURINE = "573478bc24597738002c6175", BARTER_HUNTING_MATCHES = "5e2af2bc86f7746d3f3c33fc", + BARTER_INSEQ_GAS_PIPE_WRENCH = "66b37f114410565a8f6789e2", BARTER_INSULATING_TAPE = "5734795124597738002c6176", BARTER_IRIDIUM_MILITARY_THERMAL_VISION_MODULE = "5d0377ce86f774186372f689", BARTER_KEKTAPE_DUCT_TAPE = "5e2af29386f7746d4159f077", BARTER_KILLA_FIGURINE = "66572c82ad599021091c6118", + BARTER_KOSA_UAV_ELECTRONIC_JAMMING_DEVICE = "66d9f7e7099cf6adcc07a369", BARTER_LEDX_SKIN_TRANSILLUMINATOR = "5c0530ee86f774697952d952", BARTER_LEGA_MEDAL = "6656560053eaaa7a23349c86", BARTER_LIGHT_BULB = "5d1b392c86f77425243e98fe", - BARTER_LOCKED_EQUIPMENT_RATE_COMMON = "66588b514de4820934746dc6", - BARTER_LOCKED_EQUIPMENT_RATE_EPIC = "6658285190486915542256c4", - BARTER_LOCKED_EQUIPMENT_RATE_RARE = "66571bf06a723f7f005a0619", - BARTER_LOCKED_SUPPLY_RATE_COMMON = "66588ba291f6e93c4c06efef", - BARTER_LOCKED_SUPPLY_RATE_EPIC = "665828c44de4820934746ce4", - BARTER_LOCKED_SUPPLY_RATE_RARE = "66572b88ac60f009f270d1dc", - BARTER_LOCKED_VALUABLES_RATE_COMMON = "66588bb047fbd536a674240e", - BARTER_LOCKED_VALUABLES_RATE_EPIC = "665828f490486915542256c6", - BARTER_LOCKED_VALUABLES_RATE_RARE = "66572bb3ac60f009f270d1df", - BARTER_LOCKED_WEAPON_RATE_COMMON = "66588b6dcb48a73e674b2649", - BARTER_LOCKED_WEAPON_RATE_EPIC = "66582889efd94e2d665b14a2", - BARTER_LOCKED_WEAPON_RATE_RARE = "66572b3f6a723f7f005a066c", + BARTER_LOCKED_EQUIPMENT_CRATE_COMMON = "66588b514de4820934746dc6", + BARTER_LOCKED_EQUIPMENT_CRATE_EPIC = "6658285190486915542256c4", + BARTER_LOCKED_EQUIPMENT_CRATE_RARE = "66571bf06a723f7f005a0619", + BARTER_LOCKED_SUPPLY_CRATE_COMMON = "66588ba291f6e93c4c06efef", + BARTER_LOCKED_SUPPLY_CRATE_EPIC = "665828c44de4820934746ce4", + BARTER_LOCKED_SUPPLY_CRATE_RARE = "66572b88ac60f009f270d1dc", + BARTER_LOCKED_VALUABLES_CRATE_COMMON = "66588bb047fbd536a674240e", + BARTER_LOCKED_VALUABLES_CRATE_EPIC = "665828f490486915542256c6", + BARTER_LOCKED_VALUABLES_CRATE_RARE = "66572bb3ac60f009f270d1df", + BARTER_LOCKED_WEAPON_CRATE_COMMON = "66588b6dcb48a73e674b2649", + BARTER_LOCKED_WEAPON_CRATE_EPIC = "66582889efd94e2d665b14a2", + BARTER_LOCKED_WEAPON_CRATE_RARE = "66572b3f6a723f7f005a066c", BARTER_LOOT_LORD_PLUSHIE = "60b0f7057897d47c5b04ab94", BARTER_LVNDMARKS_RAT_POISON = "60b0f561c4449e4cb624c1d7", BARTER_MAGNET = "590a391c86f774385a33c404", @@ -953,8 +989,9 @@ export declare enum ItemTpl { BARTER_PRINTED_CIRCUIT_BOARD = "590a3b0486f7743954552bdb", BARTER_PRINTER_PAPER = "577e1c9d2459773cd707c525", BARTER_PROPANE_TANK_5L = "59fafb5d86f774067a6f2084", + BARTER_RADAR_STATION_SPARE_PARTS = "66d9f7256916142b3b02276e", BARTER_RADIATOR_HELIX = "5d1c774f86f7746d6620f8db", - BARTER_RAM = "57347baf24597738002c6178", + BARTER_RAM_STICK = "57347baf24597738002c6178", BARTER_RATCHET_WRENCH = "60391afc25aff57af81f7085", BARTER_RAVEN_FIGURINE = "5e54f62086f774219b0f1937", BARTER_RECHARGEABLE_BATTERY = "590a358486f77429692b2790", @@ -979,6 +1016,7 @@ export declare enum ItemTpl { BARTER_STRIKE_CIGARETTES = "5734770f24597738025ee254", BARTER_SURVL_SURVIVOR_LIGHTER = "5e2af37686f774755a234b65", BARTER_TAGILLA_FIGURINE = "66572cbdad599021091c611a", + BARTER_TAMATTHI_KUNAI_KNIFE_REPLICA = "66b37ea4c5d72b0277488439", BARTER_TETRIZ_PORTABLE_GAME_CONSOLE = "5c12620d86f7743f8b198b72", BARTER_TOILET_PAPER = "5c13cef886f774072e618e82", BARTER_TOOLSET = "590c2e1186f77425357b6124", @@ -993,6 +1031,7 @@ export declare enum ItemTpl { BARTER_USEC_OPERATIVE_FIGURINE = "655c663a6689c676ce57af85", BARTER_UZRGM_GRENADE_FUZE = "5e2af51086f7746d3f3c3402", BARTER_VERITAS_GUITAR_PICK = "5f745ee30acaeb0d490d8c5b", + BARTER_VIIBIIN_SNEAKER = "66b37eb4acff495a29492407", BARTER_VIRTEX_PROGRAMMABLE_PROCESSOR = "5c05308086f7746b2101e90b", BARTER_VPX_FLASH_STORAGE_MODULE = "5c05300686f7746dce784e5d", BARTER_WATER_FILTER = "5d1b385e86f774252167b98a", @@ -1005,8 +1044,11 @@ export declare enum ItemTpl { BARTER_WRENCH = "590c311186f77424d1667482", BARTER_XENOMORPH_SEALING_FOAM = "590c346786f77423e50ed342", BARTER_ZIBBO_LIGHTER = "56742c2e4bdc2d95058b456d", + BIPOD_ALL_TEST = "665745c8a3c672c7b00bb355", + BIPOD_BT10_V8_ATLAS = "6644920d49817dc7d505ca71", BIPOD_HARRIS_HBR = "5888961624597754281f93f3", BIPOD_HK_G36 = "622b397c9a3d4327e41843b6", + BIPOD_M60 = "66012d9a3dff5074ed002e33", BIPOD_PK = "6464d870bb2c580352070cc4", BIPOD_RPD = "6513f037e06849f06c0957d7", BIPOD_SV98 = "56ea8222d2720b69698b4567", @@ -1058,8 +1100,8 @@ export declare enum ItemTpl { BUILTININSERTS_6B516_LEVEL2_SOFT_ARMOR_COLLAR = "65764c39526e320fbe035777", BUILTININSERTS_6B516_LEVEL3_SOFT_ARMOR_FRONT = "65764a4cd8537eb26a0355ee", BUILTININSERTS_6B516_LEVEL3_SOFT_ARMOR_GROIN = "65764c6b526e320fbe03577b", - BUILTININSERTS_ADEPT_NEOSTEEL_LEVEL3_HELMET_ARMOR_NAPE = "657f9ef6c6679fefb3051e1f", - BUILTININSERTS_ADEPT_NEOSTEEL_LEVEL3_HELMET_ARMOR_TOP = "657f9eb7e9433140ad0baf86", + BUILTININSERTS_ADEPT_NEOSTEEL_LEVEL4_HELMET_ARMOR_NAPE = "657f9ef6c6679fefb3051e1f", + BUILTININSERTS_ADEPT_NEOSTEEL_LEVEL4_HELMET_ARMOR_TOP = "657f9eb7e9433140ad0baf86", BUILTININSERTS_ALTIN_LEVEL5_HELMET_ARMOR_EARS = "657bc107aab96fccee08be9f", BUILTININSERTS_ALTIN_LEVEL5_HELMET_ARMOR_NAPE = "657bc0d8a1c61ee0c303632f", BUILTININSERTS_ALTIN_LEVEL5_HELMET_ARMOR_TOP = "657bc06daab96fccee08be9b", @@ -1085,6 +1127,8 @@ export declare enum ItemTpl { BUILTININSERTS_BAGARII_LEVEL3_SOFT_ARMOR_FRONT = "657322988c1cc6dcd9098b2d", BUILTININSERTS_BAGARII_LEVEL3_SOFT_ARMOR_LEFT_SIDE = "657322acd9d89ff7ac0d961b", BUILTININSERTS_BAGARII_LEVEL3_SOFT_ARMOR_RIGHT_SIDE = "657322b7d9d89ff7ac0d961f", + BUILTININSERTS_BALLISTICARMORCO_BASTION_LEVEL4_HELMET_ARMOR_NAPE = "66b61ce0c5d72b027748867e", + BUILTININSERTS_BALLISTICARMORCO_BASTION_LEVEL4_HELMET_ARMOR_TOP = "66b61cfae98be930d701c029", BUILTININSERTS_BANSHEE_LEVEL2_SOFT_ARMOR_BACK = "6573102b292ecadbfa09b38d", BUILTININSERTS_BANSHEE_LEVEL2_SOFT_ARMOR_FRONT = "6573101e292ecadbfa09b389", BUILTININSERTS_BANSHEE_LEVEL2_SOFT_ARMOR_LEFT_SIDE = "65731038292ecadbfa09b391", @@ -1264,11 +1308,16 @@ export declare enum ItemTpl { BUILTININSERTS_REDUT_T_LEVEL3_SOFT_ARMOR_LEFT_SIDE = "6575d9c40546f8b1de093dee", BUILTININSERTS_REDUT_T_LEVEL3_SOFT_ARMOR_RIGHT_ARM = "6575da159e27f4a85e081131", BUILTININSERTS_REDUT_T_LEVEL3_SOFT_ARMOR_RIGHT_SIDE = "6575d9cf0546f8b1de093df2", - BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_EARS = "65711b706d197c216005b31c", - BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_EYES = "65711b9b65daf6aa960c9b1b", - BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_JAW = "65711bc79eb8c145180dbba1", - BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_NAPE = "65711b489eb8c145180dbb9d", - BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_TOP = "65711b07a330b8c9060f7b01", + BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_EARS = "66bdc2c90b603c26902b2018", + BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_EYES = "66bdc2d051aa8c345646d03f", + BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_JAW = "66bdc2d9408f1e66eb4fd957", + BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_NAPE = "66bdc2e25f17154509115d1e", + BUILTININSERTS_RONIN_LEVEL3_HELMET_ARMOR_TOP = "66bdc2ea8cbd597c9c2f9360", + BUILTININSERTS_RONIN_LEVEL4_HELMET_ARMOR_EARS = "65711b706d197c216005b31c", + BUILTININSERTS_RONIN_LEVEL4_HELMET_ARMOR_EYES = "65711b9b65daf6aa960c9b1b", + BUILTININSERTS_RONIN_LEVEL4_HELMET_ARMOR_JAW = "65711bc79eb8c145180dbba1", + BUILTININSERTS_RONIN_LEVEL4_HELMET_ARMOR_NAPE = "65711b489eb8c145180dbb9d", + BUILTININSERTS_RONIN_LEVEL4_HELMET_ARMOR_TOP = "65711b07a330b8c9060f7b01", BUILTININSERTS_RYS_T_LEVEL5_HELMET_ARMOR_EARS = "657bc2e7b30eca976305118d", BUILTININSERTS_RYS_T_LEVEL5_HELMET_ARMOR_NAPE = "657bc2c5a1c61ee0c3036333", BUILTININSERTS_RYS_T_LEVEL5_HELMET_ARMOR_TOP = "657bc285aab96fccee08bea3", @@ -1283,6 +1332,15 @@ export declare enum ItemTpl { BUILTININSERTS_SSH68_LEVEL3_HELMET_ARMOR_EARS = "657119fea330b8c9060f7afc", BUILTININSERTS_SSH68_LEVEL3_HELMET_ARMOR_NAPE = "657119d49eb8c145180dbb95", BUILTININSERTS_SSH68_LEVEL3_HELMET_ARMOR_TOP = "6571199565daf6aa960c9b10", + BUILTININSERTS_STICHPROFI_PCV2_LEVEL2_SOFT_ARMOR_BACK = "66b884eaacff495a29492849", + BUILTININSERTS_STICHPROFI_PCV2_LEVEL2_SOFT_ARMOR_FRONT = "66b884f4c5d72b02774886eb", + BUILTININSERTS_STICHPROFI_PCV2_LEVEL2_SOFT_ARMOR_GROIN_FRONT = "66b884fd7994640992013b37", + BUILTININSERTS_STICHPROFI_PCV2_LEVEL2_SOFT_ARMOR_LEFT_SIDE = "66b8851678bbc0200425fa03", + BUILTININSERTS_STICHPROFI_PCV2_LEVEL2_SOFT_ARMOR_RIGHT_SIDE = "66b88521a7f72d197e70be3b", + BUILTININSERTS_STICH_DEFENSE_M2_LEVEL3_SOFT_ARMOR_BACK = "66b8b20c5891c84aab75cb96", + BUILTININSERTS_STICH_DEFENSE_M2_LEVEL3_SOFT_ARMOR_FRONT = "66b8b217c5d72b02774887b4", + BUILTININSERTS_STICH_DEFENSE_M2_LEVEL3_SOFT_ARMOR_LEFT_SIDE = "66b8b223a7f72d197e70bed3", + BUILTININSERTS_STICH_DEFENSE_M2_LEVEL3_SOFT_ARMOR_RIGHT_SIDE = "66b8b22b78bbc0200425fb20", BUILTININSERTS_STRANDHOGG_LEVEL2_SOFT_ARMOR_BACK = "6572eb1b04ee6483ef039882", BUILTININSERTS_STRANDHOGG_LEVEL2_SOFT_ARMOR_FRONT = "6572eb0e55beba16bc04079f", BUILTININSERTS_STRANDHOGG_LEVEL2_SOFT_ARMOR_GROIN_FRONT = "6572eb865b5eac12f10a03ee", @@ -1345,8 +1403,8 @@ export declare enum ItemTpl { CHARGE_AR15_GEISSELE_ACH_CHARGING_HANDLE_DDC = "5ea16d4d5aad6446a939753d", CHARGE_AR15_HK_EXTENDED_LATCH_CHARGING_HANDLE = "5bb20dbcd4351e44f824c04e", CHARGE_AR15_MASP_INDUSTRIES_AMBIDEXTROUS_BATTLE_CHARGING_HANDLE = "6033749e88382f4fab3fd2c5", - CHARGE_AR15_RADIAN_WEAPONS_RAPTOR_CHARGING_HANDLE = "5b2240bf5acfc40dc528af69", - CHARGE_AR15_RADIAN_WEAPONS_RAPTOR_CHARGING_HANDLE_GREY = "5d44334ba4b9362b346d1948", + CHARGE_AR15_RADIAN_WEAPONS_RAPTOR_CHARGING_HANDLE_FDE = "5b2240bf5acfc40dc528af69", + CHARGE_AR15_RADIAN_WEAPONS_RAPTOR_CHARGING_HANDLE_TUNGSTEN_GREY = "5d44334ba4b9362b346d1948", CHARGE_AR15_RAINIER_ARMS_AVALANCHE_MOD2_CHARGING_HANDLE = "5f633ff5c444ce7e3c30a006", CHARGE_BENELLI_M3_SUPER_90_CHARGING_HANDLE = "625ec45bb14d7326ac20f572", CHARGE_FN_P90_CHARGING_HANDLE = "5cc6ea78e4a949000e1ea3c1", @@ -1355,8 +1413,8 @@ export declare enum ItemTpl { CHARGE_HK417_E1_EXTENDED_CHARGING_HANDLE = "61702d8a67085e45ef140b24", CHARGE_HK_MP5K_COCKING_HANDLE = "5d2f2d5748f03572ec0c0139", CHARGE_HK_MP5_COCKING_HANDLE = "5926c32286f774616e42de99", + CHARGE_MCXSPEAR_CHARGING_HANDLE = "6529109524cbe3c74a05e5b7", CHARGE_MCX_CHARGING_HANDLE = "5fbcc640016cce60e8341acc", - CHARGE_MCX_SPEAR_CHARGING_HANDLE = "6529109524cbe3c74a05e5b7", CHARGE_MK47_AMBIDEXTROUS_CHARGING_HANDLE = "606587bd6d0bd7580617bacc", CHARGE_MP9_CHARGING_HANDLE = "5de922d4b11454561e39239f", CHARGE_MPX_DOUBLE_LATCH_CHARGING_HANDLE = "58949edd86f77409483e16a9", @@ -1380,6 +1438,7 @@ export declare enum ItemTpl { COLLIMATOR_FN_P90_RING_SIGHT_REFLEX_SIGHT = "5cebec38d7f00c00110a652a", COLLIMATOR_HENSOLDT_RV_RED_DOT_SIGHT = "622efbcb99f4ea1a4d6c9a15", COLLIMATOR_HOLOSUN_HS401G5_REFLEX_SIGHT = "5b30b0dc5acfc400153b7124", + COLLIMATOR_KOMZ_RUSAK_REFLEX_SIGHT = "65f05b9d39dab9e9ec049cfd", COLLIMATOR_LEAPERS_UTG_REFLEX_SIGHT = "6165ac8c290d254f5e6b2f6c", COLLIMATOR_MILKOR_M2A1_GRENADE_LAUNCHER_REFLEX_SIGHT = "6284bd5f95250a29bc628a30", COLLIMATOR_NPZ_PK1_OBZOR_DOVETAIL_REFLEX_SIGHT = "618a5d5852ecee1505530b2a", @@ -1421,6 +1480,7 @@ export declare enum ItemTpl { CONTAINER_MR_HOLODILNICK_THERMAL_BAG = "5c093db286f7740a1b2617e3", CONTAINER_SICC = "5d235bb686f77443f4331278", CONTAINER_SIMPLE_WALLET = "5783c43d2459774bbe137486", + CONTAINER_STREAMER_ITEM_CASE = "66bc98a01a47be227a5e956e", CONTAINER_THICC_ITEM_CASE = "5c0a840b86f7742ffa4f2482", CONTAINER_THICC_WEAPON_CASE = "5b6d9ce188a4501afc1b2b25", CONTAINER_WEAPON_CASE = "59fb023c86f7746d0d4b423c", @@ -1429,7 +1489,7 @@ export declare enum ItemTpl { DRINK_AQUAMARI_WATER_BOTTLE_WITH_FILTER = "5c0fa877d174af02a012e1cf", DRINK_BOTTLE_OF_DAN_JACKIEL_WHISKEY = "5d403f9186f7743cac3f229b", DRINK_BOTTLE_OF_FIERCE_HATCHLING_MOONSHINE = "5d1b376e86f774252519444e", - DRINK_BOTTLE_OF_NORVINSKIY_YADRENIY_PREMIUM_KVASS_06L = "5e8f3423fd7471236e6e3b64", + DRINK_BOTTLE_OF_NORVINSKY_YADRENIY_PREMIUM_KVASS_06L = "5e8f3423fd7471236e6e3b64", DRINK_BOTTLE_OF_PEVKO_LIGHT_BEER = "62a09f32621468534a797acb", DRINK_BOTTLE_OF_TARKOVSKAYA_VODKA = "5d40407c86f774318526545a", DRINK_BOTTLE_OF_TARKOVSKAYA_VODKA_BAD = "614451b71e5874611e2c7ae5", @@ -1495,26 +1555,28 @@ export declare enum ItemTpl { FACECOVER_VENGEFUL_ZRYACHIYS_BALACLAVA = "6530e8587cbfc1e309011e37", FACECOVER_ZRYACHIYS_BALACLAVA = "63626d904aa74b8fe30ab426", FLARE_ROP30_REACTIVE_FLARE_CARTRIDGE_WHITE = "62178be9d0050232da3485d9", + FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_BLUE = "66d98233302686954b0c6f81", FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_GREEN = "6217726288ed9f0845317459", FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_RED = "62178c4d4ecf221597654e3d", + FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_SPECIAL_YELLOW = "66d9f1abb16d9aacf5068468", FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_YELLOW = "624c0b3340357b5f566e8766", FLASHHIDER_AAC_SCARSD_51T_762X51_FLASH_HIDER = "618178aa1cb55961fa0fdc80", FLASHHIDER_AI_338_LM_TACTICAL_MUZZLE_BRAKE = "62812081d23f207deb0ab216", FLASHHIDER_AK101_556X45_MUZZLE_BRAKECOMPENSATOR = "5ac72e615acfc43f67248aa0", - FLASHHIDER_AK102_556X45_MUZZLE_BRAKECOMPENSATOR_6P44_020 = "5ac72e725acfc400180ae701", + FLASHHIDER_AK102_556X45_MUZZLE_BRAKECOMPENSATOR = "5ac72e725acfc400180ae701", FLASHHIDER_AK103_762X39_MUZZLE_BRAKECOMPENSATOR = "5ac72e7d5acfc40016339a02", - FLASHHIDER_AK104_762X39_MUZZLE_BRAKECOMPENSATOR_6P46_020 = "5ac72e895acfc43b321d4bd5", - FLASHHIDER_AK105_545X39_MUZZLE_BRAKECOMPENSATOR_6P44_020 = "5ac72e945acfc43f3b691116", + FLASHHIDER_AK104_762X39_MUZZLE_BRAKECOMPENSATOR = "5ac72e895acfc43b321d4bd5", + FLASHHIDER_AK105_545X39_MUZZLE_BRAKECOMPENSATOR = "5ac72e945acfc43f3b691116", FLASHHIDER_AK12_545X39_MUZZLE_BRAKE = "649ec2af961514b22506b10f", - FLASHHIDER_AK74M_545X39_MUZZLE_BRAKECOMPENSATOR_6P20_020 = "5ac7655e5acfc40016339a19", - FLASHHIDER_AK74_545X39_MUZZLE_BRAKECOMPENSATOR_6P20_020 = "5649aa744bdc2ded0b8b457e", + FLASHHIDER_AK74M_545X39_MUZZLE_BRAKECOMPENSATOR = "5ac7655e5acfc40016339a19", + FLASHHIDER_AK74_545X39_MUZZLE_BRAKECOMPENSATOR = "5649aa744bdc2ded0b8b457e", FLASHHIDER_AK74_PWS_CQB_74_545X39_MUZZLE_BRAKE = "5943eeeb86f77412d6384f6b", FLASHHIDER_AK74_SRVV_MBR_JET_545X39_MUZZLE_BRAKE = "5cc9a96cd7f00c011c04e04a", FLASHHIDER_AK74_THREAD_TYPE_JMAC_CUSTOMS_RRD4C_MULTICALIBER_MUZZLE_BRAKE = "5f633f791b231926f2329f13", FLASHHIDER_AKML_SYSTEM_762X39_FLASH_HIDER = "5a0d716f1526d8000d26b1e2", - FLASHHIDER_AKM_762X39_MUZZLE_BRAKECOMPENSATOR_6P1_014 = "59d64fc686f774171b243fe2", + FLASHHIDER_AKM_762X39_MUZZLE_BRAKECOMPENSATOR = "59d64fc686f774171b243fe2", FLASHHIDER_AKM_THREAD_TYPE_JMAC_CUSTOMS_RRD4C_762X39_MUZZLE_BRAKE = "5f633f68f5750b524b45f112", - FLASHHIDER_AKS74U_545X39_MUZZLE_BRAKE_6P26_020 = "57dc324a24597759501edc20", + FLASHHIDER_AKS74U_545X39_MUZZLE_BRAKE = "57dc324a24597759501edc20", FLASHHIDER_AK_HEXAGON_REACTOR_545X39_MUZZLE_BRAKE = "615d8f5dd92c473c770212ef", FLASHHIDER_AK_LANTAC_DRAKON_762X39_MUZZLE_BRAKE = "5c878ebb2e2216001219d48a", FLASHHIDER_AK_SPIKES_TACTICAL_DYNACOMP_762X39_MUZZLE_BRAKECOMPENSATOR = "5a9ea27ca2750c00137fa672", @@ -1527,6 +1589,7 @@ export declare enum ItemTpl { FLASHHIDER_AR10_CMMG_SV_BRAKE_762X51_MUZZLE_BRAKE = "6065c6e7132d4d12c81fd8e1", FLASHHIDER_AR10_DANIEL_DEFENSE_WAVE_762X51_MUZZLE_BRAKE = "5d1f819086f7744b355c219b", FLASHHIDER_AR10_DEAD_AIR_KEYMOUNT_762X51_MUZZLE_BRAKE = "628a66b41d5e41750e314f34", + FLASHHIDER_AR10_DELTATEK_DTKAR10_762X51_MUZZLE_BRAKE = "6642f63667f5cb56a00662eb", FLASHHIDER_AR10_FORTIS_RED_BRAKE_762X51_MUZZLE_BRAKE = "5d026791d7ad1a04a067ea63", FLASHHIDER_AR10_KAC_QDC_762X51_FLASH_SUPPRESSOR_KIT = "5dfa3cd1b33c0951220c079b", FLASHHIDER_AR10_KAC_QDC_762X51_MUZZLE_BRAKE_KIT = "6130c43c67085e45ef1405a1", @@ -1547,6 +1610,8 @@ export declare enum ItemTpl { FLASHHIDER_AR15_BULLETEC_ST6012_556X45_MUZZLE_BRAKE = "5cf6937cd7f00c056c53fb39", FLASHHIDER_AR15_COLT_USGI_A2_556X45_FLASH_HIDER = "544a38634bdc2d58388b4568", FLASHHIDER_AR15_DANIEL_DEFENSE_WAVE_556X45_MUZZLE_BRAKE = "5cff9e5ed7ad1a09407397d4", + FLASHHIDER_AR15_DELTATEK_DTKM16_556X45_MUZZLE_BRAKE = "664301213dd83ddae20dda18", + FLASHHIDER_AR15_DOUBLESTAR_CARLSON_TAC_COMP_556X45_COMPENSATOR = "6621455e3aceea9e2b0b01e7", FLASHHIDER_AR15_FERFRANS_CQB_556X45_MUZZLE_BRAKE = "5f6372e2865db925d54f3869", FLASHHIDER_AR15_GRIFFIN_ARMAMENT_GATELOK_HAMMER_556X45_FLASH_HIDER = "6386120cd6baa055ad1e201c", FLASHHIDER_AR15_HK_BLITZ_556X45_FLASH_HIDER = "615d8e2f1cb55961fa0fd9a4", @@ -1601,7 +1666,9 @@ export declare enum ItemTpl { FLASHHIDER_M1A_NATIONAL_MATCH_762X51_FLASH_SUPPRESSOR = "5addbb6e5acfc408fb1393fd", FLASHHIDER_M1A_SMITH_ENTERPRISE_SOCOM_16_762X51_THREADED_MUZZLE_BRAKE_GAS_BLOCK = "5ab3afb2d8ce87001660304d", FLASHHIDER_M1A_SOCOM_16_762X51_MUZZLE_BRAKECOMPENSATOR = "5aafa1c2e5b5b00015042a56", - FLASHHIDER_MCX_SPEAR_CLUTCHLOK_QD_68X51_SHOULDERED_FLASH_HIDER = "6529113b5ae2ae97b80fdf39", + FLASHHIDER_M60E3_762X51_FLASH_HIDER = "6601281fc752a02bbe05e696", + FLASHHIDER_M60E6_762X51_FLASH_HIDER = "66012a1d3dff5074ed002e2a", + FLASHHIDER_MCXSPEAR_CLUTCHLOK_QD_68X51_SHOULDERED_FLASH_HIDER = "6529113b5ae2ae97b80fdf39", FLASHHIDER_MOSIN_RIFLE_TACFIRE_TANKER_STYLE_762X54R_MUZZLE_BRAKE = "5bbdb83fd4351e44f824c44b", FLASHHIDER_MOSIN_RIFLE_TEXAS_PRECISION_PRODUCTS_762X54R_MUZZLE_BRAKE = "5bc5a351d4351e003477a414", FLASHHIDER_MOSIN_RIFLE_WITT_MACHINE_762X54R_MUZZLE_BRAKE = "5bc5a35cd4351e450201232f", @@ -1630,8 +1697,9 @@ export declare enum ItemTpl { FLASHHIDER_SV98_SRVV_MK20_762X54R_MUZZLE_BRAKECOMPENSATOR = "5c4ee3d62e2216152006f302", FLASHHIDER_SVDS_762X54R_MUZZLE_BRAKECOMPENSATOR = "5c471bfc2e221602b21d4e17", FLASHHIDER_SVT40_762X54R_MUZZLE_BRAKE = "64119d1f2c6d6f921a0929f8", - FLASHHIDER_TACCOM_CARBINE_BRAKE_MULTICALIBER_MUZZLE_BRAKE = "5cf6935bd7f00c06585fb791", + FLASHHIDER_TACCOM_CARBINE_BRAKE_9X19_MUZZLE_BRAKE = "5cf6935bd7f00c06585fb791", FLASHHIDER_TT_PMLASER_DTKTT_MUZZLE_BRAKECOMPENSATOR = "5bffd7ed0db834001d23ebf9", + FLASHHIDER_UZI_VENTED_BARREL_SHROUD = "6699370c57df3e2b4e0a0dab", FLASHHIDER_VPO136_VEPRKM_762X39_MUZZLE_BRAKECOMPENSATOR = "59e61eb386f77440d64f5daf", FLASHHIDER_VPO209_THREAD_PROTECTOR = "59e8a00d86f7742ad93b569c", FLASHHIDER_YANKEE_HILL_ANNIHILATOR_MULTICALIBER_FLASH_HIDER = "5b3a16655acfc40016387a2a", @@ -1663,6 +1731,8 @@ export declare enum ItemTpl { FOREGRIP_A3_TACTICAL_MVF001_KEYMOD_VERTICAL_FOREGRIP_BLACK = "5fc0f9b5d724d907e2077d82", FOREGRIP_AI_AXMC_PADDED_HANDGUARD_GRIP = "6281212a09427b40ab14e770", FOREGRIP_ASH12_VERTICAL = "5cda9bcfd7f00c0c0b53e900", + FOREGRIP_BCM_GUNFIGHTER_MOD_3_MLOK_FOREGRIP_BLACK = "665d5d9e338229cfd6078da1", + FOREGRIP_BCM_GUNFIGHTER_MOD_3_MLOK_FOREGRIP_FDE = "665edce564fb556f940ab32a", FOREGRIP_BCM_GUNFIGHTER_MOD_3_VERTICAL = "5c7fc87d2e221644f31c0298", FOREGRIP_DANIEL_DEFENSE_ENHANCED_MLOK_VERTICAL_FOREGRIP_BLACK = "651a8bf3a8520e48047bf708", FOREGRIP_DANIEL_DEFENSE_ENHANCED_MLOK_VERTICAL_FOREGRIP_COYOTE_BROWN = "651a8e529829226ceb67c319", @@ -1689,15 +1759,22 @@ export declare enum ItemTpl { FOREGRIP_RTM_PILLAU_TACTICAL = "5cf4fb76d7f00c065703d3ac", FOREGRIP_RTM_PILLAU_TACTICAL_FOREGRIP_SAND = "648067db042be0705c0b3009", FOREGRIP_SIG_SAUER_VERTICAL_FOREGRIP_KEYMOD_BLACK = "5fc0f9cbd6fa9c00c571bb90", + FOREGRIP_SR3M_POLYMER_FOREGRIP_BLACK = "65329ebcc0d50d0c9204ace1", + FOREGRIP_SR3M_POLYMER_FOREGRIP_PLUM = "6565c0c2ff7eb7070409084c", FOREGRIP_STARK_SE5_EXPRESS_FORWARD = "5b057b4f5acfc4771e1bd3e9", FOREGRIP_STARK_SE5_EXPRESS_FORWARD_FOREGRIP_FDE = "655df24fdf80b12750626d0a", FOREGRIP_STEYR_AUG_VERTICAL = "634e61b0767cb15c4601a877", + FOREGRIP_STEYR_AUG_VERTICAL_FOREGRIP_BLACK = "671883292e2eeb98d406f3b8", FOREGRIP_STRIKE_INDUSTRIES_COBRA_TACTICAL = "5c791e872e2216001219c40a", FOREGRIP_STRIKE_INDUSTRIES_COBRA_TACTICAL_FOREGRIP_FDE = "655dccfdbdcc6b5df71382b6", FOREGRIP_TACTICAL_DYNAMICS_SKELETONIZED = "5f6340d3ca442212f4047eb2", + FOREGRIP_TANGODOWN_BGVQDITI_FOREGRIP_BLACK = "661e52e29c8b4dadef008577", + FOREGRIP_TANGODOWN_BGVQDITI_FOREGRIP_FDE = "661e53149c8b4dadef008579", FOREGRIP_TANGODOWN_STUBBY_BGVMK46K_FOREGRIP_BLACK = "558032614bdc2de7118b4585", FOREGRIP_TANGODOWN_STUBBY_BGVMK46K_FOREGRIP_FDE = "58c157be86f77403c74b2bb6", FOREGRIP_TANGODOWN_STUBBY_BGVMK46K_FOREGRIP_STEALTH_GREY = "58c157c886f774032749fb06", + FOREGRIP_TANGODOWN_STUBBY_BGVQDK_FOREGRIP_BLACK = "661e52415be02310ed07a07a", + FOREGRIP_TANGODOWN_STUBBY_BGVQDK_FOREGRIP_FDE = "661e52b5b099f32c28003586", FOREGRIP_VIKING_TACTICS_UVG_TACTICAL = "591af28e86f77414a27a9e1d", FOREGRIP_ZENIT_RK0_TACTICAL = "5c1bc4812e22164bef5cfde7", FOREGRIP_ZENIT_RK1_TACTICAL = "5c1bc5612e221602b5429350", @@ -1707,10 +1784,10 @@ export declare enum ItemTpl { FOREGRIP_ZENIT_RK5_TACTICAL = "5c1bc7432e221602b412949d", FOREGRIP_ZENIT_RK6_TACTICAL = "5c1bc7752e221602b1779b34", GASBLOCK_AK12_GAS_TUBE = "649ec107961514b22506b10c", - GASBLOCK_AK545_SAG_MK_21_GAS_TUBE = "628b8d83717774443b15e248", - GASBLOCK_AK74_GAS_TUBE_6P20_SB12 = "59c6633186f7740cf0493bb9", - GASBLOCK_AKM_GAS_TUBE_6P1_SB12 = "59d64ec286f774171d1e0a42", - GASBLOCK_AKS74U_GAS_TUBE_6P26_SB12 = "59d36a0086f7747e673f3946", + GASBLOCK_AK545_MK_21_GAS_TUBE = "628b8d83717774443b15e248", + GASBLOCK_AK74_GAS_TUBE = "59c6633186f7740cf0493bb9", + GASBLOCK_AKM_GAS_TUBE = "59d64ec286f774171d1e0a42", + GASBLOCK_AKS74U_GAS_TUBE = "59d36a0086f7747e673f3946", GASBLOCK_AK_KIBA_ARMS_VDM_CS_GAS_TUBE = "5a01ad4786f77450561fda02", GASBLOCK_AK_TROY_FULL_LENGTH_RAIL_HANDGUARD_GAS_TUBE_COMBO = "5b237e425acfc4771e1be0b6", GASBLOCK_AK_ULTIMAK_M1B_GAS_TUBE_HANDGUARD = "59ccfdba86f7747f2109a587", @@ -1727,8 +1804,8 @@ export declare enum ItemTpl { GASBLOCK_HK_416A5_LOW_PROFILE_GAS_BLOCK = "5bb20dcad4351e3bac1212da", GASBLOCK_HK_G36_GAS_BLOCK = "622b327b267a1b13a44abea3", GASBLOCK_M4A1_FRONT_SIGHT_WITH_GAS_BLOCK = "5ae30e795acfc408fb139a0b", + GASBLOCK_MCXSPEAR_ADJUSTABLE_GAS_PISTON = "652910bc24cbe3c74a05e5b9", GASBLOCK_MCX_GAS_BLOCK = "5fbc210bf24b94483f726481", - GASBLOCK_MCX_SPEAR_ADJUSTABLE_GAS_PISTON = "652910bc24cbe3c74a05e5b9", GASBLOCK_MK18_GAS_BLOCK = "5fc2360f900b1d5091531e19", GASBLOCK_MOLOT_ARMS_AKMTYPE_GAS_TUBE = "59e649f986f77411d949b246", GASBLOCK_OPSKS_GAS_TUBE = "634f036a517ccc8a960fc746", @@ -1736,7 +1813,7 @@ export declare enum ItemTpl { GASBLOCK_RD704_SLR_ION_LITE_RAILED_GAS_TUBE_HANDGUARD_GAS_TUBE_COMBO = "628a83c29179c324ed269508", GASBLOCK_SKS_GAS_TUBE = "634f02d7517ccc8a960fc744", GASBLOCK_SVDS_GAS_TUBE = "5c471c842e221615214259b5", - GASBLOCK_VPO101_VEPRHUNTER_GAS_TUBE = "5c5039be2e221602b177c9ff", + GASBLOCK_VPO101_GAS_TUBE = "5c5039be2e221602b177c9ff", GRENADELAUNCHER_FN40GL_01 = "5e81ebcd8e146c7080625e15", GRENADELAUNCHER_FN40GL_02 = "639c3fbbd0446708ee622ee9", GRENADELAUNCHER_FN40GL_03 = "639af924d0446708ee62294e", @@ -1754,15 +1831,15 @@ export declare enum ItemTpl { HANDGUARD_9A91 = "644675573d52156624001fc9", HANDGUARD_AI_AXMC_AX_KEYSLOT_16_INCH = "6281209662cba23f6c4d7a19", HANDGUARD_AK12 = "649ec127c93611967b034957", - HANDGUARD_AK545_SAG_MK3 = "628b916469015a4e1711ed8d", - HANDGUARD_AK74_PLUM_POLYMER_HANDGUARD_6P20_SB9 = "5cbda9f4ae9215000e5b9bfc", - HANDGUARD_AK74_POLYMER_HANDGUARD_6P20_SB9 = "5648b1504bdc2d9d488b4584", - HANDGUARD_AK74_WOODEN_HANDGUARD_6P20_SB6 = "5648b0744bdc2d363b8b4578", - HANDGUARD_AKM_WOODEN_HANDGUARD_6P1_SB61 = "59d64f2f86f77417193ef8b3", + HANDGUARD_AK545_MK3 = "628b916469015a4e1711ed8d", + HANDGUARD_AK74M_POLYMER = "5648b1504bdc2d9d488b4584", + HANDGUARD_AK74_POLYMER_HANDGUARD_PLUM = "5cbda9f4ae9215000e5b9bfc", + HANDGUARD_AK74_WOODEN = "5648b0744bdc2d363b8b4578", + HANDGUARD_AKM_WOODEN = "59d64f2f86f77417193ef8b3", HANDGUARD_AKS74U_ALFA_ARMS_GOLIAF = "5d15ce51d7ad1a1eff619092", HANDGUARD_AKS74U_ALFA_ARMS_GOLIAF_MLOK = "647db1eca8d3399c380d195c", HANDGUARD_AKS74U_CAA_XRSU47SU_TACTICAL = "5a957c3fa2750c00137fa5f7", - HANDGUARD_AKS74U_WOODEN_HANDGUARD_6P26_SB6 = "57dc32dc245977596d4ef3d3", + HANDGUARD_AKS74U_WOODEN = "57dc32dc245977596d4ef3d3", HANDGUARD_AKS74U_ZENIT_B11 = "57ffa9f4245977728561e844", HANDGUARD_AK_100SERIES_POLYMER = "5cbda392ae92155f3c17c39f", HANDGUARD_AK_545_DESIGN_AGGRESSOR = "5cf4e3f3d7f00c06595bc7f0", @@ -1855,6 +1932,8 @@ export declare enum ItemTpl { HANDGUARD_HK_G36_2VENT = "62386b2adf47d66e835094b2", HANDGUARD_HK_G36_4VENT = "62386b7153757417e93a4e9f", HANDGUARD_HK_G36_6VENT = "6231654c71b5bc3baa1078e5", + HANDGUARD_HK_G36_KAC_QUAD_RAIL = "67069d66af4890b09f0006ec", + HANDGUARD_HK_G36_SLIM_LINE_HKEY = "67069d8dad91f3a63c0bc2b4", HANDGUARD_HK_MP5K_POLYMER = "5d2f259b48f0355a844acd74", HANDGUARD_HK_MP5SD_POLYMER = "5926f34786f77469195bfe92", HANDGUARD_HK_MP5_BT_TL99_ALUMINUM = "5a9548c9159bd400133e97b3", @@ -1862,13 +1941,16 @@ export declare enum ItemTpl { HANDGUARD_HK_MP5_PTR_TRIRAIL = "5d19cd96d7ad1a4a992c9f52", HANDGUARD_HK_MP5_WIDE_TROPICAL_POLYMER = "5926c36d86f77467a92a8629", HANDGUARD_KS23M_FORESTOCK = "5e848d51e4dbc5266a4ec63b", + HANDGUARD_M60E4_MOD_1 = "66012d64c752a02bbe05e69b", + HANDGUARD_M60E4_MOD_1_HANDGUARD_FDE = "661fbe066751ee51930b01f2", + HANDGUARD_M60E6 = "66012d003dff5074ed002e2c", HANDGUARD_M700_AB_ARMS_MODX_GEN_3_KEYMOD = "5cde7afdd7f00c000d36b89d", HANDGUARD_M870_FAB_DEFENSE_PR870_FORESTOCK = "5a788031c585673f2b5c1c79", HANDGUARD_M870_MAGPUL_MOE = "5a788068c5856700137e4c8f", HANDGUARD_M870_SPEEDFEED_SHORT = "5a788089c5856700142fdd9c", + HANDGUARD_MCXSPEAR_11_INCH_MLOK = "652910ef50dc782999054b97", HANDGUARD_MCX_GEN1_KEYMOD_12_INCH = "5fbc227aa56d053a3543f79e", HANDGUARD_MCX_GEN1_KEYMOD_8_INCH = "5fbc226eca32ed67276c155d", - HANDGUARD_MCX_SPEAR_11_INCH_MLOK = "652910ef50dc782999054b97", HANDGUARD_MDR_HANDGUARD_BLACK = "5dcbd6b46ec07c0c4347a564", HANDGUARD_MDR_HANDGUARD_FDE = "5c48a14f2e2216152006edd7", HANDGUARD_MK18_18_INCH = "5fc235db2770a0045c59c683", @@ -1911,25 +1993,39 @@ export declare enum ItemTpl { HANDGUARD_SOK12_CUSTOM_GUNS_TYPE340 = "6086b5731246154cad35d6c7", HANDGUARD_SOK12_LEAPERS_UTG_PRO_MTU002_LONG_TOP_ALUMINUM = "5827272a24597748c74bdeea", HANDGUARD_SOK12_LEAPERS_UTG_PRO_MTU002_SHORT_TOP_ALUMINUM = "58272b392459774b4c7b3ccd", - HANDGUARD_SOK12_POLYMER_HANDGUARD_SB71 = "576169e62459773c69055191", - HANDGUARD_SR2M_POLYMER = "62e15547db1a5c41971c1b5e", + HANDGUARD_SOK12_POLYMER = "576169e62459773c69055191", HANDGUARD_SR2M_POLYMER_HANDGUARD_BLACK = "637ba19df7ca6372bf2613d7", + HANDGUARD_SR2M_POLYMER_HANDGUARD_PLUM = "62e15547db1a5c41971c1b5e", + HANDGUARD_SR3M_POLYMER_HANDGUARD_BLACK = "65144f546ddb773afa0e35e1", + HANDGUARD_SR3M_POLYMER_HANDGUARD_PLUM = "6565c3ab977bcc2dbb01c2e7", + HANDGUARD_SR3M_RAILED_POLYMER_HANDGUARD_BLACK = "6568a6bf2c5fb7afc70bc424", HANDGUARD_SV98_CNC_GUNS_OVSV98_KEYMOD = "623c3c1f37b4b31470357737", HANDGUARD_SVDS_POLYMER = "5c471c6c2e221602b66cd9ae", HANDGUARD_SVD_CAA_XRSDRG = "5e5699df2161e06ac158df6f", HANDGUARD_SVD_MODERNIZATION_KIT = "5e56991336989c75ab4f03f6", HANDGUARD_SVD_SAG_MK1_CHASSIS = "5dfcd0e547101c39625f66f9", + HANDGUARD_UZI_HANDGUARD_WITH_FOREGRIP = "66993149558c59581e03c028", + HANDGUARD_UZI_KGRIP = "6699313af74fef4dfd0b04f6", + HANDGUARD_UZI_POLYMER = "6698c8c736ba38d29101770b", + HANDGUARD_UZI_PRO_A3_TACTICAL_MLOK = "668031bde3e7eb26e8004cd7", HANDGUARD_VPO136_VEPRKM_WOODEN = "59e6284f86f77440d569536f", HANDGUARD_VPO209_WOODEN = "59e898ee86f77427614bd225", HANDGUARD_VSK94 = "6448f2f6d4928d46d30be3f6", + HANDGUARD_VSSVAL_POLYMER_HANDGUARD_BLACK = "6565bb7eb4b12a56eb04b084", + HANDGUARD_VSSVAL_POLYMER_HANDGUARD_PLUM = "651178336cad06c37c049eb4", HANDGUARD_WASR1063_CAF_WOODEN_FOREGRIP = "5d2c829448f0353a5c7d6674", HEADPHONES_GSSH01_ACTIVE_HEADSET = "5b432b965acfc47a8774094e", HEADPHONES_MSA_SORDIN_SUPREME_PROXL_HEADSET = "5aa2ba71e5b5b000137b758f", HEADPHONES_OPSCORE_FAST_RAC_HEADSET = "5a16b9fffcdbcb0176308b34", HEADPHONES_OPSMEN_EARMOR_M32_HEADSET = "6033fa48ffd42c541047f728", - HEADPHONES_PELTOR_COMTAC_2_HEADSET_OD_GREEN = "5645bcc04bdc2d363b8b4572", - HEADPHONES_PELTOR_COMTAC_4_HYBRID_HEADSET_COYOTE_BROWN = "628e4e576d783146b124c64d", + HEADPHONES_PELTOR_COMTAC_II_HEADSET_OD_GREEN = "5645bcc04bdc2d363b8b4572", + HEADPHONES_PELTOR_COMTAC_IV_HYBRID_HEADSET_COYOTE_BROWN = "628e4e576d783146b124c64d", + HEADPHONES_PELTOR_COMTAC_VI_HEADSET_COYOTE_BROWN = "66b5f6985891c84aab75ca76", + HEADPHONES_PELTOR_COMTAC_V_HEADSET_OD_GREEN = "66b5f693acff495a294927e3", HEADPHONES_PELTOR_TACTICAL_SPORT_HEADSET = "5c165d832e2216398b5a7e36", + HEADPHONES_SAFARILAND_LIBERATOR_HP_20_HEARING_PROTECTION_HEADSET_FDE = "66b5f68de98be930d701c00e", + HEADPHONES_TW_EXFIL_PELTOR_COMTAC_VI_HEADSET_COYOTE_BROWN = "66b5f6a28ca68c6461709ed8", + HEADPHONES_TW_EXFIL_PELTOR_COMTAC_V_HEADSET_OD_GREEN = "66b5f69ea7f72d197e70bcdb", HEADPHONES_WALKERS_RAZOR_DIGITAL_HEADSET = "5e4d34ca86f774264f758330", HEADPHONES_WALKERS_XCEL_500BT_DIGITAL_HEADSET = "5f60cd6cf2bcbb675b00dac6", HEADWEAR_6B47_RATNIKBSH_HELMET_DIGITAL_FLORA_COVER = "5aa7cfc0e5b5b00015693143", @@ -1943,6 +2039,9 @@ export declare enum ItemTpl { HEADWEAR_ARMY_CAP_DESERT = "60361b0b5a45383c122086a1", HEADWEAR_ARMY_CAP_FLORA = "60361a7497633951dc245eb4", HEADWEAR_ARMY_CAP_UCP = "60361b5a9a15b10d96792291", + HEADWEAR_BALLISTIC_ARMOR_CO_BASTION_HELMET_ARMOR_BLACK = "66b5f65ca7f72d197e70bcd6", + HEADWEAR_BALLISTIC_ARMOR_CO_BASTION_HELMET_MULTICAM = "66b5f666cad6f002ab7214c2", + HEADWEAR_BALLISTIC_ARMOR_CO_BASTION_HELMET_OD_GREEN = "66b5f661af44ca0014063c05", HEADWEAR_BANDANA = "5b43271c5acfc432ff4dce65", HEADWEAR_BASEBALL_CAP = "572b7d8524597762b472f9d1", HEADWEAR_BASMACH_LEATHER_CAP = "65749ccf33fdc9c0cf06d3ca", @@ -1958,7 +2057,8 @@ export declare enum ItemTpl { HEADWEAR_BOSS_CAP = "60a7acf20c5cb24b01346648", HEADWEAR_CRYE_PRECISION_AIRFRAME_HELMET_TAN = "5c17a7ed2e2216152142459c", HEADWEAR_DED_MOROZ_HAT = "5a43943586f77416ad2f06e2", - HEADWEAR_DEVTAC_RONIN_BALLISTIC_HELMET = "5b4329f05acfc47a86086aa1", + HEADWEAR_DEVTAC_RONIN_BALLISTIC_HELMET = "66bdc28a0b603c26902b2011", + HEADWEAR_DEVTAC_RONIN_RESPIRATOR = "5b4329f05acfc47a86086aa1", HEADWEAR_DIAMOND_AGE_BASTION_HELMET_BLACK = "5ea17ca01412a1425304d1c0", HEADWEAR_DIAMOND_AGE_NEOSTEEL_HIGH_CUT_HELMET_BLACK = "65709d2d21b9f815e208ff95", HEADWEAR_DOOR_KICKER_BOONIE_HAT = "5d96141523f0ea1b7f2aacab", @@ -2015,6 +2115,10 @@ export declare enum ItemTpl { HEADWEAR_ZRYACHIYS_BALACLAVA_FOLDED = "636270263f2495c26f00b007", HEADWEAR_ZSH12M_HELMET_BLACK_COVER = "5aa7e4a4e5b5b000137b76f2", HEADWEAR_ZSH12M_HELMET_OLIVE_DRAB = "5aa7e454e5b5b0214e506fa2", + HIDEOUTAREACONTAINER_CIRCLEOFCULTISTS_STASH_1 = "66740c3739b9da6ce402ee65", + HIDEOUTAREACONTAINER_EQUIPMENTPRESETSTAND_STASH_1 = "65e5957613227bb7690ce9f6", + HIDEOUTAREACONTAINER_EQUIPMENTPRESETSTAND_STASH_2 = "65e597266017f07a3204b775", + HIDEOUTAREACONTAINER_EQUIPMENTPRESETSTAND_STASH_3 = "65e5972a13227bb7690cea07", HIDEOUTAREACONTAINER_PLACEOFFAME_STASH_1 = "63dbd45917fff4dee40fe16e", HIDEOUTAREACONTAINER_PLACEOFFAME_STASH_2 = "65424185a57eea37ed6562e9", HIDEOUTAREACONTAINER_PLACEOFFAME_STASH_3 = "6542435ea57eea37ed6562f0", @@ -2027,6 +2131,7 @@ export declare enum ItemTpl { INFO_DIARY = "590c645c86f77412b01304d9", INFO_DOCUMENTS_WITH_DECRYPTED_DATA = "660bc341c38b837877075e4c", INFO_ENCRYPTED_FLASH_DRIVE = "660bbc47c38b837877075e47", + INFO_FLASH_DRIVE_WITH_SPECIAL_SOFTWARE = "6707d13e4e617ec94f0e5631", INFO_INTELLIGENCE_FOLDER = "5c12613b86f7743bbe2c3f76", INFO_MILITARY_FLASH_DRIVE = "62a0a16d0b9d3c46de5b6e97", INFO_SAS_DRIVE = "590c37d286f77443be3d7827", @@ -2038,19 +2143,21 @@ export declare enum ItemTpl { INFO_SSD_DRIVE = "590c392f86f77444754deb29", INFO_TECH_MANUAL = "590c639286f774151567fa95", INFO_TERRAGROUP_BLUE_FOLDERS_MATERIALS = "6389c8c5dbfd5e4b95197e6b", + INFO_TGVI24_LETHAL_VACCINE = "6707d0804e617ec94f0e562f", + INFO_TGVI24_TRUE_VACCINE = "6707d0bdaab679420007e01a", INFO_TOPOGRAPHIC_SURVEY_MAPS = "62a0a124de7ac81993580542", INFO_VIDEO_CASSETTE_WITH_THE_CYBORG_KILLER_MOVIE = "62a09e974f842e1bd12da3f0", INVENTORY_DEFAULT = "55d7217a4bdc2d86028b456d", - IRONSIGHT_AK105_REAR_SIGHT_6P44_SB130 = "5ac733a45acfc400192630e2", + IRONSIGHT_AK105_REAR_SIGHT = "5ac733a45acfc400192630e2", IRONSIGHT_AK12_REAR_SIGHT = "649ec2cec93611967b03495e", - IRONSIGHT_AK12_REAR_SIGHT_BASE = "649ec2da59cbb3c813042dca", - IRONSIGHT_AK545_SAG_REAR_SIGHT = "628b9471078f94059a4b9bfb", - IRONSIGHT_AK74M_REAR_SIGHT_6P20_SB2 = "5ac72e475acfc400180ae6fe", - IRONSIGHT_AK74_REAR_SIGHT_6P20_SB2 = "5649b0544bdc2d1b2b8b458a", + IRONSIGHT_AK12_REAR_SIGHT_MOUNT = "649ec2da59cbb3c813042dca", + IRONSIGHT_AK545_REAR_SIGHT = "628b9471078f94059a4b9bfb", + IRONSIGHT_AK74M_REAR_SIGHT = "5ac72e475acfc400180ae6fe", + IRONSIGHT_AK74_REAR_SIGHT = "5649b0544bdc2d1b2b8b458a", IRONSIGHT_AKMB_SYSTEM_REAR_SIGHT = "5a0eb980fcdbcb001a3b00a6", IRONSIGHT_AKMP_SYSTEM_FRONT_SIGHT_DEVICE = "5a0f096dfcdbcb0176308b15", IRONSIGHT_AKMP_SYSTEM_REAR_SIGHT_DEVICE = "5a0ed824fcdbcb0176308b0d", - IRONSIGHT_AKM_REAR_SIGHT_6P1_SB21 = "59d650cf86f7741b846413a4", + IRONSIGHT_AKM_REAR_SIGHT = "59d650cf86f7741b846413a4", IRONSIGHT_AK_RD_ENHANCED_V2_REAR_SIGHT = "628a7b23b0f75035732dd565", IRONSIGHT_AK_TAKTIKA_TULA_TT01_REAR_SIGHT_RAIL = "5649d9a14bdc2d79388b4580", IRONSIGHT_APB_REAR_SIGHT = "5aba639ed8ce8700182ece67", @@ -2067,6 +2174,8 @@ export declare enum ItemTpl { IRONSIGHT_CHIAPPA_RHINO_REAR_SIGHT = "619f4cee4c58466fe1228435", IRONSIGHT_CHIAPPA_RHINO_RED_FIBER_OPTIC_FRONT_SIGHT = "619f52454c58466fe122843b", IRONSIGHT_CHIAPPA_RHINO_RED_FIBER_OPTIC_REAR_SIGHT = "619f4f8c4c58466fe1228439", + IRONSIGHT_DESERT_EAGLE_FRONT_SIGHT = "668fe5ec4315934ba10c6f96", + IRONSIGHT_DESERT_EAGLE_REAR_SIGHT = "668fe5e1800f0244f9036e46", IRONSIGHT_FN_FIVESEVEN_MK2_FRONT_SIGHT = "5d3eb536a4b9363b1f22f8e2", IRONSIGHT_FN_FIVESEVEN_MK2_REAR_SIGHT = "5d3eb4aba4b93650d64e497d", IRONSIGHT_FN_SCAR_FLIPUP_FRONT_SIGHT = "61816fcad92c473c770215cc", @@ -2105,6 +2214,9 @@ export declare enum ItemTpl { IRONSIGHT_M1A_SA_XS_POST_125_BLADE_FRONT_SIGHT = "5aafa49ae5b5b00015042a58", IRONSIGHT_M45A1_NOVAK_LOMOUNT_FRONT_SIGHT = "5f3e78a7fbf956000b716b8e", IRONSIGHT_M45A1_NOVAK_LOMOUNT_REAR_SIGHT = "5f3e7897ddc4f03b010e204a", + IRONSIGHT_M60E4_FRONT_SIGHT = "6601268bc752a02bbe05e686", + IRONSIGHT_M60E6_FRONT_SIGHT_RAIL = "660126a98f2b23af220b27e7", + IRONSIGHT_M60_REAR_SIGHT = "6601265f98a610c1aa0ea637", IRONSIGHT_M9A3_FRONT_SIGHT = "5cadd919ae921500126a77f3", IRONSIGHT_M9A3_REAR_SIGHT = "5cadd940ae9215051e1c2316", IRONSIGHT_M9A3_SIGHT_MOUNT_REAR_SIGHT_RAIL = "5cadd954ae921500103bb3c2", @@ -2147,7 +2259,7 @@ export declare enum ItemTpl { IRONSIGHT_SVT40_FRONT_SIGHT = "64119d672c6d6f921a0929fb", IRONSIGHT_SVT40_REAR_SIGHT = "64119d90dcf48d656f0aa275", IRONSIGHT_TRIJICON_ACOG_BACKUP_REAR_SIGHT = "5c05295e0db834001a66acbb", - IRONSIGHT_VPO101_VEPRHUNTER_REAR_SIGHT = "5c503b1c2e221602b21d6e9d", + IRONSIGHT_VPO101_REAR_SIGHT = "5c503b1c2e221602b21d6e9d", IRONSIGHT_VPO209_REAR_SIGHT = "59e8977386f77415a553c453", IRONSIGHT_VSS_REAR_SIGHT = "57838e1b2459774a256959b1", KEYCARD_OBJECT_11SR = "5e42c81886f7742a01529f57", @@ -2159,6 +2271,8 @@ export declare enum ItemTpl { KEYCARD_TERRAGROUP_LABS_KEYCARD_RED = "5c1d0efb86f7744baf2e7b7b", KEYCARD_TERRAGROUP_LABS_KEYCARD_VIOLET = "5c1e495a86f7743109743dfb", KEYCARD_TERRAGROUP_LABS_KEYCARD_YELLOW = "5c1d0d6d86f7744bb2683e1f", + KEYCARD_TERRAGROUP_LABS_RESIDENTIAL_UNIT = "6711039f9e648049e50b3307", + KEYCARD_TERRAGROUP_STORAGE_ROOM = "66acd6702b17692df20144c0", KEYCARD_WITH_A_BLUE_MARKING = "5efde6b4f5448336730dbd61", KEY_ABANDONED_FACTORY_MARKED = "63a3a93f8a56922e82001f5d", KEY_ARCHIVE_ROOM = "63a39e49cd6db0635c1975fc", @@ -2365,6 +2479,7 @@ export declare enum ItemTpl { KNIFE_CULTIST = "5fc64ea372b0dd78d51159dc", KNIFE_ER_FULCRUM_BAYONET = "54491bb74bdc2d09088b4567", KNIFE_FREEMAN_CROWBAR = "5c07df7f0db834001b73588a", + KNIFE_INFECTIOUS_STRIKE = "670ad7f1ad195290cd00da7a", KNIFE_KIBA_ARMS_TACTICAL_TOMAHAWK = "57cd379a24597778e7682ecf", KNIFE_MILLER_BROS_BLADES_M2_TACTICAL_SWORD = "5bffdd7e0db834001b734a1a", KNIFE_MPL50_ENTRENCHING_TOOL = "5bead2e00db834001c062938", @@ -2383,14 +2498,17 @@ export declare enum ItemTpl { LOOTCONTAINER_AIRDROP_COMMON_SUPPLY_CRATE = "6223349b3136504a544d1608", LOOTCONTAINER_AIRDROP_MEDICAL_CRATE = "622334c873090231d904a9fc", LOOTCONTAINER_AIRDROP_SUPPLY_CRATE = "622334fa3136504a544d160c", + LOOTCONTAINER_AIRDROP_TECHNICAL_SUPPLY_CRATE_EVENT_1 = "66da1b49099cf6adcc07a36b", + LOOTCONTAINER_AIRDROP_TECHNICAL_SUPPLY_CRATE_EVENT_2 = "66da1b546916142b3b022777", LOOTCONTAINER_AIRDROP_WEAPON_CRATE = "6223351bb5d97a7b2c635ca7", LOOTCONTAINER_BANK_CASH_REGISTER = "64d116f41a9c6143a956127d", - LOOTCONTAINER_BANK_SAFE = "64d11702dd0cd96ab82c3280", + LOOTCONTAINER_BANK_SAFE_3X3 = "66acff0a1d8e1083b303f5af", + LOOTCONTAINER_BANK_SAFE_4X4 = "64d11702dd0cd96ab82c3280", LOOTCONTAINER_BURIED_BARREL_CACHE = "5d6d2bb386f774785b07a77a", LOOTCONTAINER_CASH_REGISTER = "578f879c24597735401e6bc6", LOOTCONTAINER_CASH_REGISTER_TAR22 = "5ad74cf586f774391278f6f0", + LOOTCONTAINER_CIVILIAN_BODY = "658420d8085fea07e674cdb6", LOOTCONTAINER_COMMON_FUND_STASH = "5d07b91b86f7745a077a9432", - LOOTCONTAINER_DEAD_CIVILIAN = "658420d8085fea07e674cdb6", LOOTCONTAINER_DEAD_SCAV = "5909e4b686f7747f5b744fa4", LOOTCONTAINER_DRAWER = "578f87b7245977356274f2cd", LOOTCONTAINER_DUFFLE_BAG = "578f87a3245977356274f2cb", @@ -2428,12 +2546,18 @@ export declare enum ItemTpl { MACHINEGUN_KALASHNIKOV_PKTM_762X54R_MODERNIZED_TANK_MACHINE_GUN = "657857faeff4c850222dff1b", MACHINEGUN_NSV_UTYOS_127X108_HEAVY_MACHINE_GUN = "5cdeb229d7f00c000e7ce174", MACHINEGUN_RPK16_545X39_LIGHT_MACHINE_GUN = "5beed0f50db834001c062b12", + MACHINEGUN_US_ORDNANCE_M60E4_762X51_LIGHT_MACHINE_GUN = "65fb023261d5829b2d090755", + MACHINEGUN_US_ORDNANCE_M60E6_762X51_LIGHT_MACHINE_GUN = "661ceb1b9311543c7104149b", + MACHINEGUN_US_ORDNANCE_M60E6_762X51_LIGHT_MACHINE_GUN_FDE = "661cec09b2c6356b4d0c7a36", MAGAZINE_127X108_100_100RND = "5cffa483d7ad1a049e54ef1c", + MAGAZINE_127X33_DE_7RND = "668fe5c5f35310705d02b696", MAGAZINE_127X55_ASH12_10RND = "5caf1041ae92157c28402e3f", MAGAZINE_127X55_ASH12_20RND = "5caf1109ae9215753c44119f", MAGAZINE_127X55_RSH12_CYL_5RND = "633ec6ee025b096d320a3b15", MAGAZINE_12G_255_CYL_5RND = "60dc519adf4c47305f6d410d", MAGAZINE_12G_590A1X8_8RND = "5e87080c81c4ed43e83cefda", + MAGAZINE_12G_AA12_20RND = "6709133fa532466d5403fb7c", + MAGAZINE_12G_AA12_8RND = "66ffaab91f7492c901027bb8", MAGAZINE_12G_M3X11_11RND = "625ff3046d721f05d93bf2ee", MAGAZINE_12G_M3X13_13RND = "625ff31daaaa8c1130599f64", MAGAZINE_12G_M3X5_5RND = "625ff2ccb8c587128c1a01dd", @@ -2461,8 +2585,8 @@ export declare enum ItemTpl { MAGAZINE_30X29_AGS30_99RND = "5d52d479a4b936793d58c76b", MAGAZINE_366TKM_6610_20RND = "587df583245977373c4f1129", MAGAZINE_366TKM_6L10_30RND = "5a01c29586f77474660c694c", + MAGAZINE_366TKM_6P2SB11_40RND = "59e5f5a486f7746c530b3ce2", MAGAZINE_366TKM_6P2_BAK_40RND = "5b1fb3e15acfc4001637f068", - MAGAZINE_366TKM_6P2_SB11_40RND = "59e5f5a486f7746c530b3ce2", MAGAZINE_366TKM_AK103_30RND = "5ac66bea5acfc43b321d4aec", MAGAZINE_366TKM_AK30_30RND = "59fafc5086f7740dbe19f6c3", MAGAZINE_366TKM_AK30_FDE_30RND = "59fafc9386f774067d462453", @@ -2488,8 +2612,10 @@ export declare enum ItemTpl { MAGAZINE_45ACP_MECGAR_11RND = "5ef3448ab37dfd6af863525c", MAGAZINE_45ACP_UMP_45_25RND = "5fc3e466187fea44d52eda90", MAGAZINE_45ACP_USP45T_12RND = "6193d3149fb0c665d5490e32", + MAGAZINE_45ACP_USP45T_999RND = "671d8b8c0959c721a50ca838", MAGAZINE_45ACP_USP45_12RND = "6193d338de3cdf1d2614a6fc", MAGAZINE_45ACP_WILSON_7RND = "5f3e77b26cda304dcc634057", + MAGAZINE_45ACP_WILSON_999RND = "671d8b38b769f0d88c0950f8", MAGAZINE_46X30_MP7_20RND = "5ba264f6d4351e0034777d52", MAGAZINE_46X30_MP7_30RND = "5ba2657ed4351e0035628ff2", MAGAZINE_46X30_MP7_40RND = "5ba26586d4351e44f824b340", @@ -2515,8 +2641,8 @@ export declare enum ItemTpl { MAGAZINE_556X45_GEN_M3_10RND = "5aaa5e60e5b5b000140293d6", MAGAZINE_556X45_GEN_M3_20RND = "5448c1d04bdc2dff2f8b4569", MAGAZINE_556X45_GEN_M3_30RND = "5aaa5dfee5b5b000140293d3", - MAGAZINE_556X45_GEN_M3_30RND_FDE = "6241c2c2117ad530666a5108", MAGAZINE_556X45_GEN_M3_40RND = "544a378f4bdc2d30388b4567", + MAGAZINE_556X45_GEN_M3_AIRSOFT_30RND = "6241c2c2117ad530666a5108", MAGAZINE_556X45_GEN_M3_FDE_30RND = "5d1340b3d7ad1a0b52682ed7", MAGAZINE_556X45_GEN_M3_FDE_40RND = "5d1340bdd7ad1a0e8d245aab", MAGAZINE_556X45_GEN_M3_WINDOW_30RND = "55802d5f4bdc2dac148b458e", @@ -2535,6 +2661,7 @@ export declare enum ItemTpl { MAGAZINE_762X25TT_PPSH_35RND = "5ea034eb5aad6446a939737b", MAGAZINE_762X25TT_PPSH_71RND = "5ea034f65aad6446a939737e", MAGAZINE_762X25TT_TT105_8RND = "571a29dc2459771fb2755a6a", + MAGAZINE_762X25TT_TT105_999RND = "671d85439ae8365d69117ba6", MAGAZINE_762X39_BUBEN_100RND = "6513f0a194c72326990a3868", MAGAZINE_762X51_417_762_10RND = "617130016c780c1e710c9a24", MAGAZINE_762X51_417_762_20RND = "617131a4568c120fdd29482d", @@ -2542,6 +2669,7 @@ export declare enum ItemTpl { MAGAZINE_762X51_AA70_20RND = "5cf12a15d7f00c05464b293f", MAGAZINE_762X51_AICS_10RND = "5d25a6538abbc306c62e630d", MAGAZINE_762X51_AICS_5RND = "5d25a4a98abbc30b917421a4", + MAGAZINE_762X51_ASSAULT_BOX_100RND = "660ea4453786cc0af808a1be", MAGAZINE_762X51_AXMC_308_10RND = "628120f210e26c1f344e6558", MAGAZINE_762X51_DVL10_10RND = "5888988e24597752fe43a6fa", MAGAZINE_762X51_KAC_762_10RND = "5df8f535bb49d91fb446d6b0", @@ -2582,6 +2710,7 @@ export declare enum ItemTpl { MAGAZINE_86X70_MK18_10RND = "5fc23426900b1d5091531e15", MAGAZINE_9X18PM_APS_20RND = "5a17fb03fcdbcbcae668728f", MAGAZINE_9X18PM_PM_8RND = "5448c12b4bdc2d02308b456f", + MAGAZINE_9X18PM_PM_999RND = "670e8eab8c1bb0e5a7075acf", MAGAZINE_9X18PM_PM_DRUM_84RND = "55d485be4bdc2d962f8b456f", MAGAZINE_9X18PM_PP91_20RND = "57d14e1724597714010c3f4b", MAGAZINE_9X18PM_PP91_30RND = "57d1519e24597714373db79d", @@ -2590,11 +2719,13 @@ export declare enum ItemTpl { MAGAZINE_9X19_BIG_STICK_33RND = "5a7ad2e851dfba0016153692", MAGAZINE_9X19_CR_CYL_6RND = "624c3074dbbd335e8e6becf3", MAGAZINE_9X19_G19X_19RND = "63076701a987397c0816d21b", + MAGAZINE_9X19_G19X_999RND = "671d8ac8a3e45c1f59082799", MAGAZINE_9X19_GL9_21RND = "5a718da68dc32e000d46d264", MAGAZINE_9X19_GLOCK_9X19_17RND = "5a718b548dc32e000d46d262", MAGAZINE_9X19_G_SGMT_50RND = "5a718f958dc32e00094b97e7", MAGAZINE_9X19_M9A3_17RND = "5cadc2e0ae9215051e1c21e7", MAGAZINE_9X19_MP443_18RND = "576a5ed62459771e9c2096cb", + MAGAZINE_9X19_MP443_999RND = "671d8617a3e45c1f5908278c", MAGAZINE_9X19_MP5_20RND = "5d2f213448f0355009199284", MAGAZINE_9X19_MP5_30RND = "5926c3b286f774640d189b6b", MAGAZINE_9X19_MP9_15RND = "5de8e8dafd6b4e6e2276dc32", @@ -2612,15 +2743,25 @@ export declare enum ItemTpl { MAGAZINE_9X19_SB7_10RND = "5998529a86f774647f44f421", MAGAZINE_9X19_SG919_20RND = "5c0673fb0db8340023300271", MAGAZINE_9X19_SG919_30RND = "5c0672ed0db834001b7353f3", + MAGAZINE_9X19_UZI_20RND = "66992713ae08c5c29e0c4f97", + MAGAZINE_9X19_UZI_25RND = "6699271b9950f5f4cd060299", + MAGAZINE_9X19_UZI_32RND = "669927203c4fda6471005cbe", + MAGAZINE_9X19_UZI_40RND = "66992725ae08c5c29e0c4f9a", + MAGAZINE_9X19_UZI_50RND = "6699272a3c4fda6471005cc1", + MAGAZINE_9X19_UZI_PRO_20RND = "668031ffe3e7eb26e8004cdd", + MAGAZINE_9X19_UZI_PRO_25RND = "66866f4ec3d473265104f381", + MAGAZINE_9X19_UZI_PRO_32RND = "66866f622a2296a8d9099639", MAGAZINE_9X19_X5_MP5_50RND = "5a351711c4a282000b1521a4", MAGAZINE_9X21_SR1MP_18RND = "59f99a7d86f7745b134aa97b", MAGAZINE_9X21_SR2M_20RND = "633a98eab8b0506e48497c1a", MAGAZINE_9X21_SR2M_30RND = "62e153bcdb1a5c41971c1b5b", MAGAZINE_9X33R_CR_CYL_6RND = "619f54a1d25cbd424731fb99", + MAGAZINE_9X33R_DE_9RND = "669fa435803b94fb5d0e3a76", MAGAZINE_9X39_6L24_10RND = "57838f0b2459774a256959b2", MAGAZINE_9X39_6L25_20RND = "57838f9f2459774a150289a0", MAGAZINE_9X39_9A91_20RND = "6450ec2e7da7133e5a09ca96", MAGAZINE_9X39_SR3M130_30RND = "5a9e81fba2750c00164f6b11", + MAGAZINE_9X39_VSSVAL_30RND = "65118f531b90b4fc77015083", MAP_CUSTOMS_PLAN = "5798a2832459774b53341029", MAP_FACTORY_PLAN = "574eb85c245977648157eec3", MAP_INTERCHANGE_PLAN = "5be4038986f774527d3fae60", @@ -2657,16 +2798,17 @@ export declare enum ItemTpl { MONEY_EUROS = "569668774bdc2da2298b4568", MONEY_GP_COIN = "5d235b4d86f7742e017bc88a", MONEY_ROUBLES = "5449016a4bdc2d6f028b456f", - MOUNT_AIMPOINT_LRP_MOUNT_FOR_COMPM4_SIGHTS = "5c7d55f52e221644f31bff6a", + MOUNT_AIMPOINT_COMPM4PRO_LRP = "5c7d55f52e221644f31bff6a", + MOUNT_AIMPOINT_COMPM4PRO_QRP2 = "616584766ef05c2ce828ef57", MOUNT_AIMPOINT_MICRO_H2_STANDARD = "616554fe50224f204c1da2aa", MOUNT_AIMPOINT_MICRO_SPACER_HIGH = "58d39b0386f77443380bf13c", MOUNT_AIMPOINT_MICRO_STANDARD = "58d39d3d86f77445bb794ae7", - MOUNT_AIMPOINT_QRP2_MOUNT_FOR_COMPM4PRO_SIGHTS = "616584766ef05c2ce828ef57", MOUNT_AIMPOINT_STANDARD_SPACER = "5c7d560b2e22160bc12c6139", MOUNT_AI_AX50_34MM_SCOPE = "62811f461d5df4475f46a332", MOUNT_AI_AXMC_ADAPTER_KIT_MEDIUM_LENGTH_RAIL = "628120dd308cb521f87a8fa1", MOUNT_AI_AXMC_ADAPTER_KIT_SHORT_LENGTH_RAIL = "628120d309427b40ab14e76d", MOUNT_AI_AXMC_AT_X_TOP_RAIL = "628120c21d5df4475f46a337", + MOUNT_AI_AXMC_KEYSLOT_HARRIS_BIPOD = "671126a210d67adb5b08e925", MOUNT_AKS74U_ZENIT_B18 = "57ffb0062459777a045af529", MOUNT_AK_ZENIT_B12 = "57ffaea724597779f52b3a4d", MOUNT_ALEXANDER_ARMS_10_INCH_RAIL = "5b30bc285acfc47a8608615d", @@ -2681,6 +2823,8 @@ export declare enum ItemTpl { MOUNT_BURRIS_FASTFIRE_WEAVER_BASE = "577d128124597739d65d0e56", MOUNT_CNC_GUNS_KEYMOD_2_INCH_RAIL = "623c2f652febb22c2777d8d7", MOUNT_CNC_GUNS_KEYMOD_4_INCH_RAIL = "623c2f4242aee3103f1c44b7", + MOUNT_CORVUS_DEFENSIO_KEYMOD_18_INCH_RAIL_SECTION = "67111094d1758189fc0bd223", + MOUNT_CORVUS_DEFENSIO_KEYMOD_68_INCH_RAIL_SECTION = "6711109e723c2733410161eb", MOUNT_CUSTOM_GUNS_HANDGUARD_RAIL = "6086b5392535c57a13424d70", MOUNT_DANIEL_DEFENSE_25MM_ACCESSORY_RING = "6267c6396b642f77f56f5c1c", MOUNT_DELTAPOINT_CROSS_SLOT_MOUNT_BASE = "58d2664f86f7747fec5834f6", @@ -2692,8 +2836,21 @@ export declare enum ItemTpl { MOUNT_FN_P90_UPPER_RECEIVER_TOP_RAIL = "5cc7015ae4a949001152b4c6", MOUNT_FN_SCAR_BOTTOM_RAIL = "61816df1d3a39d50044c139e", MOUNT_FN_SCAR_KINETIC_MREX_65_MLOK_RAIL = "619666f4af1f5202c57a952d", + MOUNT_FN_SCAR_KINETIC_MREX_65_MLOK_RAIL_FDE = "66ffc6ceb7ff397142017c3a", + MOUNT_FN_SCAR_PMM_MLOK_LOWER_RAIL = "66ffc72082d36dec82030c1f", + MOUNT_FN_SCAR_PMM_MLOK_LOWER_RAIL_FDE = "66ffc903fe9b382596065304", + MOUNT_FN_SCAR_PMM_MLOK_SIDE_RAILS = "66ffe6c36f11538c7d0581e3", + MOUNT_FN_SCAR_PMM_MLOK_SIDE_RAILS_FDE = "66ffe7bab8da88805e07a03e", + MOUNT_FN_SCAR_PMM_MRE_XL_RAIL_EXTENSION = "66ffe2fbab3336cc0106382b", + MOUNT_FN_SCAR_PMM_MRE_XL_RAIL_EXTENSION_FDE = "66ffe5edfe9b38259606530d", + MOUNT_FN_SCAR_PMM_RAIL_ELIMINATION_PANELS = "66ffe66a20771d839f0fb4a9", + MOUNT_FN_SCAR_PMM_RAIL_ELIMINATION_PANELS_FDE = "66ffe6916f11538c7d0581e1", MOUNT_FN_SCAR_PWS_SRX_RAIL_EXTENSION = "61965d9058ef8c428c287e0d", - MOUNT_FN_SCAR_SIDE_RAIL = "61816dfa6ef05c2ce828f1ad", + MOUNT_FN_SCAR_SIDE_RAILS = "61816dfa6ef05c2ce828f1ad", + MOUNT_FN_SCAR_VLTOR_CASVSCAR_HANDGUARD = "66ffe811f5d758d71101e89a", + MOUNT_FN_SCAR_VLTOR_CASVSCAR_HANDGUARD_EXTENDER = "66ffea456be19fd81e0ef742", + MOUNT_FN_SCAR_VLTOR_CASVSCAR_HANDGUARD_EXTENDER_PATRIOT_BROWN = "66ffeab4ab3336cc01063833", + MOUNT_FN_SCAR_VLTOR_CASVSCAR_HANDGUARD_PATRIOT_BROWN = "66ffea06132225f0fe061394", MOUNT_GBRS_AIMPOINT_HYDRA_MOUNT_KIT_BLACK = "65392f611406374f82152ba5", MOUNT_GBRS_AIMPOINT_HYDRA_MOUNT_KIT_FDE = "653931da5db71d30ab1d6296", MOUNT_GEISSELE_SUPER_PRECISION_30MM_RING_SCOPE = "618b9643526131765025ab35", @@ -2715,6 +2872,7 @@ export declare enum ItemTpl { MOUNT_HK_G36_SIDE_HANDGUARD_RAIL = "62444cd3674028188b052799", MOUNT_HK_G36_SIGHT = "622b3c081b89c677a33bcda6", MOUNT_HK_G36_STANAG_MAGWELL = "622f039199f4ea1a4d6c9a17", + MOUNT_HK_HKEY_3_INCH_RAIL = "67069d3bb29a2cd338033390", MOUNT_HK_MP5SD_BT_TRIRAIL_RING = "59c63b4486f7747afb151c1c", MOUNT_HK_MP5_BT_TRIRAIL_RECEIVER = "5a966ec8a2750c00171b3f36", MOUNT_HK_MP5_MFI_HK_UNIVERSAL_LOW_PROFILE_SCOPE = "5926dad986f7741f82604363", @@ -2736,6 +2894,7 @@ export declare enum ItemTpl { MOUNT_KRISS_VECTOR_SIDE_RAIL = "5fce0f9b55375d18a253eff2", MOUNT_LARUE_LT101_QD_TACTICAL_PICATINNY_RISER = "5c064c400db834001d23f468", MOUNT_LEAPERS_UTG_25MM_RING_SCOPE = "5dff77c759400025ea5150cf", + MOUNT_LEAPERS_UTG_UNIVERSAL_SHOTGUN_BARREL = "6710cea62bb09af72f0e6bf8", MOUNT_LOBAEV_ARMS_30MM_SCOPE = "57c69dd424597774c03b7bbc", MOUNT_M14_AMEGA_MINI_SCOUT_MOUNT_SYSTEM = "5addbfd15acfc40015621bde", MOUNT_M14_ARMS_18_SCOPE = "5addbfe15acfc4001a5fc58b", @@ -2748,13 +2907,16 @@ export declare enum ItemTpl { MOUNT_M1A_SOCOM_16_UPPER_PART = "5ab24ef9e5b5b00fe93c9209", MOUNT_M700_30MM_INTEGRAL_RING_SCOPE = "5bfebc5e0db834001a6694e5", MOUNT_M700_AB_ARMS_MODX_RAIL = "5cde7b43d7f00c000d36b93e", + MOUNT_M700_BADGER_ORDNANCE_SCOPE_RAIL = "65f064eec4da400cbb0dc1fe", MOUNT_M700_EXTENDED_MULTISLOT_WEAVER_RAIL_BASE = "5bfebc530db834001d23eb65", MOUNT_M700_MAGPUL_PRO_700_CHASSIS_INLINE = "5cdeaca5d7f00c00b61c4b70", MOUNT_M870_LEAPERS_UTG_PRO_MTU028SG_RAIL = "5a7893c1c585673f2b5c374d", MOUNT_M870_MESA_TACTICAL_MAGAZINE_CLAMP = "5a789261c5856700186c65d3", MOUNT_M870_XS_SHOTRAIL_RAIL_WITH_GHOST_RING_REAR_SIGHT = "5a78948ec5856700177b1124", + MOUNT_MAGPUL_MLOK_093_INCH_RAIL = "669a6a4a525be1d2d004b8eb", MOUNT_MAGPUL_MLOK_25_INCH_RAIL = "5b7be47f5acfc400170e2dd2", MOUNT_MAGPUL_MLOK_41_INCH_RAIL = "5b7be4895acfc400170e2dd5", + MOUNT_MAGPUL_MLOK_BIPOD = "671126b049e181972e0681fa", MOUNT_MAGPUL_MLOK_CANTILEVER = "6269220d70b6c02e665f2635", MOUNT_MAGPUL_MLOK_OFFSET_LIGHT = "6269545d0e57f218e4548ca2", MOUNT_MOSIN_RIFLE_AIM_SPORTS_MNG_RAIL = "5bc5a372d4351e44f824d17f", @@ -2777,6 +2939,7 @@ export declare enum ItemTpl { MOUNT_NIGHTFORCE_MAGMOUNT_34MM_RING_SCOPE_MOUNT_WITH_RUGGEDIZED_ACCESSORY_PLATFORM = "5aa66c72e5b5b00016327c93", MOUNT_NOROTOS_TITANIUM_ADVANCED_TACTICAL = "5a16b8a9fcdbcb00165aa6ca", MOUNT_NPZ_1P781_DOVETAIL = "618a75c9a3884f56c957ca1b", + MOUNT_ODIN_WORKS_KPOD_KEYMOD_BIPOD_ADAPTER = "67112695fe5c8bf33f02476d", MOUNT_OPSCORE_PICATINNY_RAIL_ADAPTER = "5a398b75c4a282000a51a266", MOUNT_OPSCORE_SINGLE_CLAMP_RAIL_ADAPTER = "5a398ab9c4a282000c5a9842", MOUNT_OPSKS_DOVETAIL = "587e08ee245977446b4410cf", @@ -2805,6 +2968,8 @@ export declare enum ItemTpl { MOUNT_RFB_HANDGUARD_RAIL = "5f2aa493cd375f14e15eea72", MOUNT_RFB_SCOPE_RAIL = "5f2aa49f9b44de6b1b4e68d4", MOUNT_RPK16_HANDGUARD_RAIL = "5beecbb80db834001d2c465e", + MOUNT_RS_REGULATE_AK303M_FULL_LENGTH_LOWER_DOVETAIL = "65f1b1176dbd6c5ba2082eed", + MOUNT_RS_REGULATE_AKR_TOP = "65f1b2a5c14a07890801fc70", MOUNT_SAG_AK_DOVETAIL_SIDE = "63d114019e35b334d82302f7", MOUNT_SAG_BIT_LOW_PROFILE_DOVETAIL_SIDE = "638db77630c4240f9e06f8b6", MOUNT_SIG_ALPHA4_30MM_RING_SCOPE = "6567e751a715f85433025998", @@ -2819,8 +2984,14 @@ export declare enum ItemTpl { MOUNT_SR2M_SHORT_SIDE_RAIL = "62ed189fb3608410ef5a2bfc", MOUNT_SR2M_SIDE_RAIL = "62ed1921b3608410ef5a2c04", MOUNT_SR2M_ZENIT_B17 = "62e281349ecd3f493f6df954", + MOUNT_SR3MP_DOVETAIL_SIDE_RAIL_BLACK = "67069c8cee8138ed2f05ad34", + MOUNT_SR3MP_DOVETAIL_SIDE_RAIL_PLUM = "67069cbbb29a2cd33803338c", + MOUNT_SR3MP_SIDE_RAILS_BLACK = "67069cf1af4890b09f0006e8", + MOUNT_SR3MP_SIDE_RAILS_PLUM = "67069d02ad91f3a63c0bc2b0", + MOUNT_STEYR_AUG_A3_CORVUS_DEFENSIO_RECEIVER_RAIL_MOI_30_SLOTS = "67110dd41ad01bb88705347b", MOUNT_STEYR_AUG_A3_M1_HIGH_SIGHT = "62e7c8f91cd3fde4d503d690", MOUNT_STEYR_AUG_A3_M1_LOW_SIGHT = "62ebba1fb658e07ef9082b5a", + MOUNT_STEYR_AUG_CORVUS_DEFENSIO_KEYMOD_FORWARD_ACCESSORY_RAIL = "6711107e1ad01bb88705347e", MOUNT_STRIKE_INDUSTRIES_KEYMOD_4_INCH_RAIL = "5a9d6d00a2750c5c985b5305", MOUNT_STRIKE_INDUSTRIES_KEYMOD_6_INCH_RAIL = "5a9d6d13a2750c00164f6b03", MOUNT_STRIKE_INDUSTRIES_TRAX_BRIDGE_RAIL = "5a9d6d21a2750c00137fa649", @@ -2840,6 +3011,10 @@ export declare enum ItemTpl { MOUNT_TROY_QARS_42_INCH_RAIL = "5b4736b986f77405cb415c10", MOUNT_UM_TACTICAL_UM3_PISTOL_SIGHT = "5a7b4900e899ef197b331a2a", MOUNT_UNV_DLOCIRD_SIGHT = "5a1ead28fcdbcb001912fa9f", + MOUNT_UZI_HANDGUARD_RAIL = "6698c8f4710a4525fe0e9e57", + MOUNT_UZI_PRO_SMG_RAIL_ADAPTER = "668ea3f68117e4968b0cff4a", + MOUNT_UZI_STORMWERKZ_LOWER_HANDGUARD_RAIL = "66992f7d9950f5f4cd0602a8", + MOUNT_UZI_STORMWERKZ_SCOPE = "6698c90829e062525d0ad8ad", MOUNT_VLTOR_CASV_2_INCH_RAIL = "5b7be4575acfc400161d0832", MOUNT_VLTOR_CASV_4_INCH_RAIL = "5b7be4645acfc400170e2dcc", MOUNT_VLTOR_CASV_5_INCH_RAIL = "5b7be46e5acfc400170e2dcf", @@ -2848,14 +3023,17 @@ export declare enum ItemTpl { MOUNT_VLTOR_CASV_KEYMOD_6_INCH_RAIL = "59e0bed186f774156f04ce84", MOUNT_VOMZ_PILAD_04302_DOVETAIL = "57acb6222459771ec34b5cb0", MOUNT_VPO102_ARBALET = "609a4b4fe2ff132951242d04", - MOUNT_VPO215_GORNOSTAY_SCOPE_RAIL = "5de6558e9f98ac2bc65950fc", + MOUNT_VPO215_SCOPE_RAIL = "5de6558e9f98ac2bc65950fc", MOUNT_VSSVAL_TOZ_6P29M = "59eb7ebe86f7740b373438ce", MOUNT_VSSVAL_ZENIT_B3_MOUNT_COMBO = "5a9fc7e6a2750c0032157184", MOUNT_VSSVAL_ZENIT_B3_RING = "57a3459f245977764a01f703", MOUNT_ZENIT_B13V_KLASSIKA_DOVETAIL_RAIL_PLATFORM = "5c90c3622e221601da359851", MOUNT_ZENIT_B13_KLASSIKA_DOVETAIL_RAIL_PLATFORM = "5c61a40d2e2216001403158d", MOUNT_ZENIT_KR2_OLD_GEN = "646f6322f43d0c5d62063715", + MULTITOOLS_LEATHERMAN_MULTITOOL = "544fb5454bdc2df8738b456a", MUZZLECOMBO_9A91_HANDGUARD_RETAINER = "64527a263d52156624001fd7", + MUZZLECOMBO_AA12_12GA_CHOKE = "670fd1cc95c92bfc8e0bea39", + MUZZLECOMBO_AA12_THREAD_PROTECTOR = "670fd0eed8d4eae4790c818a", MUZZLECOMBO_AI_AXMC_THREAD_PROTECTION_CAP = "628120621d5df4475f46a335", MUZZLECOMBO_AKM_762X39_KIBA_ARMS_308_MUZZLE_DEVICE_ADAPTER = "615d8e9867085e45ef1409c6", MUZZLECOMBO_AK_762X39_TAKTIKA_TULA_MUZZLE_ADAPTER = "5a0abb6e1526d8000a025282", @@ -2900,10 +3078,15 @@ export declare enum ItemTpl { MUZZLECOMBO_STEYR_AUG_RAT_WORX_556X45_MUZZLE_DEVICE_ADAPTER = "630f27f04f3f6281050b94d7", MUZZLECOMBO_SVDS_ROTOR_43_THREAD_ADAPTER = "5e01e9e273d8eb11426f5bc3", MUZZLECOMBO_TROMIX_MONSTER_CLAW_12GA_MUZZLE_BRAKE = "59fb137a86f7740adb646af1", - MUZZLECOMBO_VPO215_GORNOSTAY_THREAD_PROTECTION_CAP = "5de6556a205ddc616a6bc4f7", - NIGHTVISION_ANPVS14_NIGHT_VISION_MONOCULAR = "57235b6f24597759bf5a30f1", + MUZZLECOMBO_UZI_9X19_3LUG_BARREL_RETAINING_NUT = "6698c9ba29e062525d0ad8b1", + MUZZLECOMBO_UZI_9X19_3LUG_BARREL_THREAD_PROTECTOR = "6698c9c636ba38d291017711", + MUZZLECOMBO_UZI_9X19_BARREL_RETAINING_NUT = "6698c9aa36ba38d29101770f", + MUZZLECOMBO_UZI_PRO_9X19_BARREL_RETAINING_NUT = "668670e3fb75ee4a5e02eb16", + MUZZLECOMBO_UZI_PRO_9X19_MASADA_THREAD_PROTECTOR = "668670f52a2296a8d909963c", + MUZZLECOMBO_VPO215_THREAD_PROTECTOR = "5de6556a205ddc616a6bc4f7", NIGHTVISION_ARMASIGHT_N15_NIGHT_VISION_GOGGLES = "5c066e3a0db834001b7353f0", - NIGHTVISION_GPNVG18_NIGHT_VISION_GOGGLES = "5c0558060db834001b735271", + NIGHTVISION_L3HARRIS_ANPVS14_NIGHT_VISION_MONOCULAR = "57235b6f24597759bf5a30f1", + NIGHTVISION_L3HARRIS_GPNVG18_NIGHT_VISION_GOGGLES = "5c0558060db834001b735271", NIGHTVISION_PNV10T_NIGHT_VISION_GOGGLES = "5c0696830db834001d23f5da", OPTICSCOPE_BELOMO_PSO1M21_4X24_SCOPE = "576fd4ec2459777f0b518431", OPTICSCOPE_BELOMO_PSO1M2_4X24_SCOPE = "5c82343a2e221644f31c0611", @@ -2923,27 +3106,27 @@ export declare enum ItemTpl { OPTICSCOPE_PAG17_SCOPE = "5d53f4b7a4b936793d58c780", OPTICSCOPE_PU_35X_RIFLESCOPE = "5b3f7c1c5acfc40dc5296b1d", OPTICSCOPE_SCHMIDT_BENDER_PM_II_18X24_30MM_RIFLESCOPE = "617151c1d92c473c770214ab", - OPTICSCOPE_SCHMIDT_BENDER_PM_II_312X50_34MM_RIFLESCOPE = "61714eec290d254f5e6b2ffc", + OPTICSCOPE_SCHMIDT_BENDER_PM_II_320X50_34MM_RIFLESCOPE = "61714eec290d254f5e6b2ffc", OPTICSCOPE_SCHMIDT_BENDER_PM_II_525X56_34MM_RIFLESCOPE = "62850c28da09541f43158cca", OPTICSCOPE_SIG_TANGO6T_16X24_30MM_RIFLESCOPE = "6567e7681265c8a131069b0f", OPTICSCOPE_VOMZ_PILAD_4X32_254MM_RIFLESCOPE = "5dff772da3651922b360bf91", OPTICSCOPE_VORTEX_RAZOR_HD_GEN2_16X24_30MM_RIFLESCOPE = "618ba27d9008e4636a67f61d", PISTOLGRIP_9A91_PISTOL_GRIP = "6450f21a3d52156624001fcf", PISTOLGRIP_AK12_PISTOL_GRIP = "5beec8ea0db834001a6f9dbf", + PISTOLGRIP_AK74_BAKELITE_PISTOL_GRIP = "5649ad3f4bdc2df8348b4585", + PISTOLGRIP_AK74_POLYMER_PISTOL_GRIP = "5649ade84bdc2d1b2b8b4587", PISTOLGRIP_AKM_BAKELITE_PISTOL_GRIP = "59e62cc886f77440d40b52a1", PISTOLGRIP_AKM_WOODEN_PISTOL_GRIP = "5a0071d486f77404e23a12b2", + PISTOLGRIP_AKS74U_BAKELITE_PISTOL_GRIP = "57e3dba62459770f0c32322b", PISTOLGRIP_AK_AEROKNOX_SCORPIUS_PISTOL_GRIP = "5f6341043ada5942720e2dc5", - PISTOLGRIP_AK_BAKELITE_PISTOL_GRIP = "59e6318286f77444dd62c4cc", - PISTOLGRIP_AK_BAKELITE_PISTOL_GRIP_6P1_SB8V = "5649ad3f4bdc2df8348b4585", - PISTOLGRIP_AK_BAKELITE_PISTOL_GRIP_6P4_SB9 = "57e3dba62459770f0c32322b", - PISTOLGRIP_AK_CG101_ARTYPE_PISTOL_GRIP_ADAPTER = "648ae3e356c6310a830fc291", PISTOLGRIP_AK_CUSTOM_ARMS_AGS74_PRO_SNIPER_KIT_PISTOL_GRIP = "6087e663132d4d12c81fd96b", - PISTOLGRIP_AK_FAB_DEFENSE_AGR47_PISTOL_GRIP = "623c3be0484b5003161840dc", + PISTOLGRIP_AK_CUSTOM_GUNS_CG101_ARTYPE_PISTOL_GRIP_ADAPTER = "648ae3e356c6310a830fc291", + PISTOLGRIP_AK_FAB_DEFENSE_AGR47_PISTOL_GRIP_FDE = "623c3be0484b5003161840dc", PISTOLGRIP_AK_KGB_MG47_PISTOL_GRIP = "5cf54404d7f00c108840b2ef", PISTOLGRIP_AK_KGB_MG47_PISTOL_GRIP_ANODIZED_RED = "5e2192a498a36665e8337386", PISTOLGRIP_AK_MAGPUL_MOE_PISTOL_GRIP_BLACK = "5b30ac585acfc433000eb79c", PISTOLGRIP_AK_MISSION_FIRST_TACTICAL_ENGAGE_AK47_PISTOL_GRIP = "63f4da90f31d4a33b87bd054", - PISTOLGRIP_AK_POLYMER_PISTOL_GRIP_6P1_SB8 = "5649ade84bdc2d1b2b8b4587", + PISTOLGRIP_AK_MOLOT_BAKELITE_PISTOL_GRIP = "59e6318286f77444dd62c4cc", PISTOLGRIP_AK_PUFGUN_SGM2_PISTOL_GRIP = "651580dc71a4f10aec4b6056", PISTOLGRIP_AK_STRIKE_INDUSTRIES_ENHANCED_PISTOL_GRIP_BLACK = "5cf50850d7f00c056e24104c", PISTOLGRIP_AK_STRIKE_INDUSTRIES_ENHANCED_PISTOL_GRIP_FDE = "5cf508bfd7f00c056e24104e", @@ -2971,16 +3154,19 @@ export declare enum ItemTpl { PISTOLGRIP_AR15_MAGPUL_MOE_PISTOL_GRIP_BLACK = "55802f5d4bdc2dac148b458f", PISTOLGRIP_AR15_MAGPUL_MOE_PISTOL_GRIP_FDE = "5d15cf3bd7ad1a67e71518b2", PISTOLGRIP_AR15_NAROH_ARMS_GRALS_PISTOL_GRIP = "59db3a1d86f77429e05b4e92", - PISTOLGRIP_AR15_SIG_M400_REDUCED_ANGLE_PISTOL_GRIP_COYOTE_TAN = "652911675ae2ae97b80fdf3c", + PISTOLGRIP_AR15_SIG_REDUCED_ANGLE_PISTOL_GRIP_COYOTE_TAN = "652911675ae2ae97b80fdf3c", PISTOLGRIP_AR15_STARK_AR_RIFLE_GRIP_BLACK = "59db3acc86f7742a2c4ab912", PISTOLGRIP_AR15_STARK_AR_RIFLE_GRIP_FDE = "59db3b0886f77429d72fb895", PISTOLGRIP_AR15_TACTICAL_DYNAMICS_HEXGRIP_PISTOL_GRIP = "615d8faecabb9b7ad90f4d5d", PISTOLGRIP_AR15_TACTICAL_DYNAMICS_SKELETONIZED_PISTOL_GRIP = "5b07db875acfc40dc528a5f6", - PISTOLGRIP_AS_VAL_PISTOL_GRIP = "57c44fa82459772d2d75e415", - PISTOLGRIP_AS_VAL_ROTOR_43_PISTOL_GRIP_BUFFER_TUBE = "5a69a2ed8dc32e000d46d1f1", + PISTOLGRIP_AS_VAL_PISTOL_GRIP_BLACK = "6565b91666492762f5029c0b", + PISTOLGRIP_AS_VAL_PISTOL_GRIP_PLUM = "57c44fa82459772d2d75e415", + PISTOLGRIP_AS_VAL_ROTOR_43_PISTOL_GRIP_WITH_BUFFER_TUBE = "5a69a2ed8dc32e000d46d1f1", PISTOLGRIP_BENELLI_M3_TELESCOPIC_STOCK_PISTOL_GRIP = "6259c3d8012d6678ec38eeb8", PISTOLGRIP_CHIAPPA_RHINO_PLASTIC_PISTOL_GRIP = "619f4ab2d25cbd424731fb95", PISTOLGRIP_CHIAPPA_RHINO_WOODEN_PISTOL_GRIP = "619f4bffd25cbd424731fb97", + PISTOLGRIP_DESERT_EAGLE_HOGUE_RUBBER_GRIP = "668fe5d42a0f85eea407cc16", + PISTOLGRIP_DESERT_EAGLE_HOGUE_RUBBER_GRIP_WITH_FINGER_GROOVES = "66a0da76b6f47fcfeb025e96", PISTOLGRIP_GLOCK_PACHMAYR_TACTICAL_GRIP_GLOVE = "5a7b4960e899ef197b331a2d", PISTOLGRIP_HOGUE_OVERMOLDED_RUBBER_GRIP_BLACK = "57c55efc2459772d2c6271e7", PISTOLGRIP_HOGUE_OVERMOLDED_RUBBER_GRIP_FDE = "57af48872459771f0b2ebf11", @@ -2993,6 +3179,12 @@ export declare enum ItemTpl { PISTOLGRIP_M1911_KIBA_ARMS_GENEBURN_CUSTOM_SIDE_GRIPS = "626a9cb151cb5849f6002890", PISTOLGRIP_M1911_PACHMAYR_AMERICAN_LEGEND_GRIP_423 = "5ef366938cef260c0642acad", PISTOLGRIP_M45A1_MILTAC_GVT_G10_SIDE_GRIPS = "5f3e778efcd9b651187d7201", + PISTOLGRIP_M60E4_PISTOL_GRIP = "660125bf1d087a96c60a54db", + PISTOLGRIP_M60E4_TRIGGER_GROUP = "6601257f1347bc1a5f0f4db6", + PISTOLGRIP_M60E6_PISTOL_GRIP = "66152060a031cbb5570e3466", + PISTOLGRIP_M60E6_PISTOL_GRIP_FDE = "6615211ca031cbb5570e346d", + PISTOLGRIP_M60E6_TRIGGER_GROUP = "6615208aa031cbb5570e346a", + PISTOLGRIP_M60E6_TRIGGER_GROUP_FDE = "66152153a031cbb5570e346f", PISTOLGRIP_M700_MAGPUL_PRO_700_PISTOL_GRIP = "5cdeac5cd7f00c000f261694", PISTOLGRIP_M870_FAB_DEFENSE_AGR870_PISTOL_GRIP = "5bfe86a20db834001d23e8f7", PISTOLGRIP_M9A3_POLYMER_SIDE_GRIPS = "5cadc431ae921500113bb8d5", @@ -3014,9 +3206,10 @@ export declare enum ItemTpl { PISTOLGRIP_PB_BAKELITE_SIDE_GRIPS = "56e05a6ed2720bd0748b4567", PISTOLGRIP_PK_PISTOL_GRIP = "646371779f5f0ea59a04c204", PISTOLGRIP_PK_PISTOL_GRIP_BLACK = "64cbad529f7cf7f75c077fd5", - PISTOLGRIP_PM_BAKELITE_SIDE_GRIPS = "6374a7e7417239a7bf00f042", + PISTOLGRIP_PM_BAKELITE_GRIP = "6374a7e7417239a7bf00f042", PISTOLGRIP_PM_FAB_DEFENSE_PMG_PISTOL_GRIP = "637784c5f7b3f4ac1a0d1a9a", PISTOLGRIP_PM_FAB_DEFENSE_PMG_PISTOL_GRIP_OLIVE_DRAB = "648afce7ec6bb25b2608defb", + PISTOLGRIP_PM_PMLASER_GRIP_WITH_LASER_SIGHT = "661f8995c341ea101e0d33e8", PISTOLGRIP_PM_TACTIC_KIT_PISTOL_GRIP = "637b6d610aef6cfc5e02dd14", PISTOLGRIP_PP1901_VITYAZ_PISTOL_GRIP = "5998517986f7746017232f7e", PISTOLGRIP_PP91_KEDR_POLYMER_PISTOL_GRIP = "57d152ec245977144076ccdf", @@ -3027,8 +3220,8 @@ export declare enum ItemTpl { PISTOLGRIP_SA58_SAWSTYLE_PISTOL_GRIP_BLACK = "5b099b965acfc400186331e6", PISTOLGRIP_SKSVZ58_FAB_DEFENSE_AG58_PISTOL_GRIP = "5d023784d7ad1a049d4aa7f2", PISTOLGRIP_SKS_TAPCO_INTRAFUSE_SAWSTYLE_PISTOL_GRIP = "5afd7e445acfc4001637e35a", - PISTOLGRIP_SR2M_PISTOL_GRIP = "637b9c37b7e3bc41b21ce71a", PISTOLGRIP_SR2M_PISTOL_GRIP_BLACK = "637ba29bf7ca6372bf2613db", + PISTOLGRIP_SR2M_PISTOL_GRIP_PLUM = "637b9c37b7e3bc41b21ce71a", PISTOLGRIP_SVDS_LYNX_ARMS_AKSERIES_PISTOL_GRIP_ADAPTER = "6516b129609aaf354b34b3a8", PISTOLGRIP_SVDS_PISTOL_GRIP = "5c471be12e221602b66cd9ac", PISTOLGRIP_TOZ106_002_PISTOL_GRIP = "5a38eecdc4a282329a73b512", @@ -3037,6 +3230,7 @@ export declare enum ItemTpl { PISTOLGRIP_TT_PMLASER_TT206_SIDE_GRIPS_WITH_LASER_SIGHT = "5bffcf7a0db83400232fea79", PISTOLGRIP_TT_RAZOR_ARMS_RUBBER_GRIP = "5c079ec50db834001966a706", PISTOLGRIP_TT_SIDE_GRIPS = "571a282c2459771fb2755a69", + PISTOLGRIP_UZI_PISTOL_GRIP_COVER = "669946c157df3e2b4e0a0dc5", PISTOL_20X1MM_TOY_GUN = "66015072e9f84d5680039678", PISTOL_APB_9X18PM_SILENCED_MACHINE = "5abccb7dd8ce87001773e277", PISTOL_BERETTA_M9A3_9X19 = "5cadc190ae921500103bb3b6", @@ -3049,6 +3243,11 @@ export declare enum ItemTpl { PISTOL_GLOCK_19X_9X19 = "63088377b5cd696784087147", PISTOL_HK_USP_45_ACP = "6193a720f8ee7e52e42109ed", PISTOL_LEBEDEV_PL15_9X19 = "602a9740da11d6478d5a06dc", + PISTOL_MAGNUM_RESEARCH_DESERT_EAGLE_L5_357 = "669fa409933e898cce0c2166", + PISTOL_MAGNUM_RESEARCH_DESERT_EAGLE_L5_50_AE = "669fa3f88abd2662d80eee77", + PISTOL_MAGNUM_RESEARCH_DESERT_EAGLE_L6_50_AE = "669fa39b48fc9f8db6035a0c", + PISTOL_MAGNUM_RESEARCH_DESERT_EAGLE_L6_50_AE_PISTOL_WTS = "669fa3d876116c89840b1217", + PISTOL_MAGNUM_RESEARCH_DESERT_EAGLE_MK_XIX_50_AE = "668fe5a998b5ad715703ddd6", PISTOL_MAKAROV_PM_9X18PM = "5448bd6b4bdc2dfc2f8b4569", PISTOL_MAKAROV_PM_T_9X18PM = "579204f224597773d619e051", PISTOL_PB_9X18PM_SILENCED = "56e0598dd2720bb5668b45a6", @@ -3058,6 +3257,7 @@ export declare enum ItemTpl { PISTOL_TT33_762X25_TT = "571a12c42459771f627b58a0", PISTOL_TT33_762X25_TT_PISTOL_GOLDEN = "5b3b713c5acfc4330140bd8d", PISTOL_YARYGIN_MP443_GRACH_9X19 = "576a581d2459771e7b1bc4f1", + PLANTINGKITS_TRIPWIRE_INSTALLATION_KIT = "666b11055a706400b717cfa5", POCKETS_1X3 = "60c7272c204bc17802313365", POCKETS_1X4 = "557ffd194bdc2d28148b457f", POCKETS_1X4_SPECIAL = "627a4e6b255f7527fb05a0f6", @@ -3071,37 +3271,46 @@ export declare enum ItemTpl { QUEST_ARENA_POSTER_EASY_MONEY = "664b69e8e1238e506d3630af", QUEST_ARENA_POSTER_KILLA = "664b69c5a082271bc46c4e11", QUEST_BANK_CASE = "590dde5786f77405e71908b2", + QUEST_BATTERED_DIARY = "666073159916667083033cb9", QUEST_BLOOD_SAMPLE = "5a687e7886f7740c4a5133fb", + QUEST_BLOOD_SAMPLE_NF2024 = "66a0f0926fee20fa70036da6", QUEST_BOTTLE_OF_LE_JEAN_WINE = "6582bd252b50c61c565828e2", QUEST_CADASTRAL_REGISTRY_RECORDS = "657acb2ac900be5902191ac9", QUEST_CARBON_CASE = "5910922b86f7747d96753483", + QUEST_CASE_WITH_PRECISION_TOOLS = "66b22630a6b4e5ec7c02cdb7", QUEST_CHEFS_DIARY = "64f69b4267e11a7c6206e010", QUEST_CHEMCONT_SAMPLES = "63927b29c115f907b14700b9", + QUEST_CHEMICAL_CONTAINER = "66a0e523e749756c920d02d0", QUEST_CHEMICAL_CONTAINER_1 = "5b43237186f7742f3a4ab252", QUEST_CHEMICAL_CONTAINER_2 = "5b4c81a086f77417d26be63f", QUEST_CHEMICAL_CONTAINER_3 = "5b4c81bd86f77418a75ae159", + QUEST_CHEMICAL_SAMPLE = "669fac549b0ce3feae01a137", QUEST_CLOTHES_DESIGN_HANDBOOK_PART_1 = "5ae9a3f586f7740aab00e4e6", QUEST_CLOTHES_DESIGN_HANDBOOK_PART_2 = "5ae9a4fc86f7746e381e1753", - QUEST_COMPROMISING_INFORMATION_ON_REF = "664fce7a90294949fe2d81cb", + QUEST_EASY_MONEY_POSTER_PACK = "664b69f3a082271bc46c4e13", QUEST_ENCRYPTED_MESSAGE = "5d3ec50586f774183a607442", QUEST_FLASHDRIVE_CAR_SERVICE = "638cbb3ba63f1b49be6a300e", QUEST_FLASHDRIVE_TERRAGROUP_EMPLOYEE = "5eff135be0d3331e9d282b7b", QUEST_FLASHDRIVE_WATCHING_YOU = "638e9d5536b3b72c944e2fc7", QUEST_FLASHDRIVE_WET_JOB_PT_4 = "5a29357286f77409c705e025", QUEST_FLASH_DRIVE_WITH_FAKE_INFO = "5c12301c86f77419522ba7e4", - QUEST_FLYERS4 = "664b69f3a082271bc46c4e13", + QUEST_GAMING_MAGAZINE = "667a8ef464eea5fdef0db135", QUEST_GOLDEN_ZIBBO_LIGHTER = "5939a00786f7742fe8132936", QUEST_GOSHAN_CARGO_MANIFESTS = "5ae9a0dd86f7742e5f454a05", QUEST_HARD_DRIVE = "661666458c2aa9cb1602503b", QUEST_HARD_DRIVE_TERRAGROUP_SCIENTIST = "6575a6ca8778e96ded05a802", QUEST_HDD_SURVEILLANCE = "638dfc803083a019d447768e", QUEST_HDD_TOP_SECRET = "628393620d8524273e7eb028", + QUEST_HDD_UNUSED = "66760b3deb51b08bd40c2b08", QUEST_HDD_WET_JOB = "5a29276886f77435ed1b117c", QUEST_HOUSING_JOURNAL = "638e0057ab150a5f56238960", QUEST_IDEA_CARGO_MANIFESTS = "5ae9a1b886f77404c8537c62", + QUEST_INFECTED_BLOOD_SAMPLE = "6707cc67cc1667e49e0f7232", QUEST_INFORMANT_JOURNAL = "63989ced706b793c7d60cfef", QUEST_JOURNAL = "64f07f7726cfa02c506f8ac0", QUEST_KEY_TO_THE_CLOSED_PREMISES_OF_THE_HEALTH_RESORT = "5a0448bc86f774736f14efa8", + QUEST_LAB_JOURNAL = "66c0b39ca1f68fcc1d0c0cc3", + QUEST_LEDX_SKIN_TRANSILLUMINATOR_US_VERSION = "666879d498b97e3a8f09f1ae", QUEST_LETTER_GOT_MAIL = "638cbc68a63f1b49be6a3010", QUEST_LETTER_HERMIT = "61904c9df62c89219a56e034", QUEST_LETTER_POSTMAN_PAT = "591093bb86f7747caa7bb2ee", @@ -3139,8 +3348,10 @@ export declare enum ItemTpl { QUEST_PICTURE_7 = "64e74a3d4d49d23b2c39d319", QUEST_PICTURE_8 = "64e74a44c2b4f829615ec334", QUEST_PICTURE_9 = "64e74a4baac4cd0a7264ecdd", + QUEST_PILOT_LOGBOOK = "66c0b90c8398582e4b0c2e27", QUEST_PUMPING_STATION_OPERATION_REPORT = "619268ad78f4fa33f173dbe5", QUEST_RADIO_TRANSMITTER_BODY = "6399f54b0a36db13c823ad21", + QUEST_REF_DIRT = "664fce7a90294949fe2d81cb", QUEST_SECRET_COMPONENT = "64f5b4f71a5f313cb144c06c", QUEST_SECURED_TAPE = "6398a4cfb5992f573c6562b3", QUEST_SECURE_FLASH_DRIVE = "59f9ddae86f77407ab46e047", @@ -3156,17 +3367,23 @@ export declare enum ItemTpl { QUEST_SKIER_AND_PEACEKEEPER_CORRESPONDENCE = "6614238e0d240a5f5d0f679d", QUEST_SLIDERKEY_SECURE_FLASH_DRIVE = "590c62a386f77412b0130255", QUEST_STOLEN_MILITARY_DOCUMENTS = "61a00bcb177fb945751bbe6a", + QUEST_STOLEN_WEAPON_CASE = "671a406a6d315b526708f103", QUEST_SURGERY_KIT_MARKED_WITH_A_BLUE_SYMBOL = "5efdafc1e70b5e33f86de058", QUEST_SYRINGE_WITH_A_CHEMICAL = "593a87af86f774122f54a951", QUEST_T90M_COMMANDER_CONTROL_PANEL = "609267a2bb3f46069c3e6c7d", + QUEST_TARKOV_CITY_SOUVENIR_KEY = "66687bc89111279d600b5062", + QUEST_TGVI24_SAMPLE = "6707cd70aab679420007e018", QUEST_TOUGHBOOK_CARGO = "5a29284f86f77463ef3db363", QUEST_TOUGHBOOK_SEASIDE_VACATION = "619252352be33f26043400a7", + QUEST_TRUE_VACCINE_RECIPE = "6707d1f9571b50abc703b651", QUEST_UAV_SAS_DISK_1 = "5a294d7c86f7740651337cf9", QUEST_UAV_SAS_DISK_2 = "5a294d8486f774068638cd93", QUEST_UNHEARD_LAPTOP = "661421c7c1f2f548c50ee649", QUEST_UNHEARD_LAPTOP_2 = "661423200d240a5f5d0f679b", QUEST_UNHEARD_PHONE = "6614217b6d9d5abcad0ff098", QUEST_UNHEARD_PHONE_2 = "6614230055afee107f05e998", + QUEST_VACCINE_SAMPLE_IV = "6707cf827d279daad80fa95f", + QUEST_VO_SIGNED_DIARY = "6707cef3571b50abc703b64f", QUEST_WATCH_BRONZE = "5937fd0086f7742bf33fc198", QUEST_WATCH_GOLD = "590de92486f77423d9312a33", QUEST_WATCH_SILVER = "5937fc6786f7742cab753590", @@ -3234,23 +3451,35 @@ export declare enum ItemTpl { RANDOMLOOTCONTAINER_EVENT_CONTAINER_AIRDROP_48 = "6489cca131a2135f0d7d0fdd", RANDOMLOOTCONTAINER_EVENT_CONTAINER_AIRDROP_49 = "6489d812cf0cd80b7e749071", RANDOMLOOTCONTAINER_EVENT_CONTAINER_AIRDROP_50 = "6489d89debac5a4a1b73caf7", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_COMMON = "6694f4101ae1778e310f4f8e", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_COMMON_PLUS_1 = "66a3896972c8e72507028806", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_COMMON_PLUS_2 = "66a3896de45f71bf1009e45a", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_EPIC = "6694f423909d2322a8073151", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_EPIC_PLUS_1 = "66a389c0705adefa710cdeaa", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_EPIC_PLUS_2 = "66a389c60982fc7e4c091c51", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_RARE = "6694f418c74d8a180f0f78c0", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_RARE_PLUS_1 = "66a3898c1df2a447cc0d3c35", + RANDOMLOOTCONTAINER_ITEM_CONTAINER_EVENT_TWITCH_SUMMER_DROPS_2024_RARE_PLUS_2 = "66a3898f0982fc7e4c091c4d", RANDOMLOOTCONTAINER_NEW_YEAR_GIFT_BIG = "63a897c6b1ff6e29734fcc95", RANDOMLOOTCONTAINER_NEW_YEAR_GIFT_MEDIUM = "63a898a328e385334e0640a5", RANDOMLOOTCONTAINER_NEW_YEAR_GIFT_SMALL = "63a8970d7108f713591149f5", RANDOMLOOTCONTAINER_PUMPKIN_RAND_LOOT_CONTAINER = "634959225289190e5e773b3b", RANDOMLOOTCONTAINER_RANDOM_LOOT_CONTAINER = "62f10b79e7ee985f386b2f47", RANDOMLOOTCONTAINER_RANDOM_LOOT_QUEST_CONTAINER = "633ffb5d419dbf4bea7004c6", + RANDOMLOOTCONTAINER_RAND_LOOT_CONTAINER_TWITCH_EVENT = "66aa3a180d6ecb50a21a4e1a", + RANDOMLOOTCONTAINER_RAND_LOOT_CONTAINER_TWITCH_EVENT_PLUS_1 = "66aa3a31efb1b8119f0196c7", + RANDOMLOOTCONTAINER_RAND_LOOT_CONTAINER_TWITCH_EVENT_PLUS_2 = "66aa3a3800b2c42adb07d13e", RANGEFINDER_VORTEX_RANGER_1500 = "61605e13ffa6e502ac5e7eef", RECEIVER_AI_AXMC_338_LM_CHASSIS = "6281204f308cb521f87a8f9b", RECEIVER_AI_AXMC_UPPER = "62811fbf09427b40ab14e767", - RECEIVER_AK12_DUST_COVER = "649ec2f3961514b22506b111", - RECEIVER_AK545_SAG_RAILED_DUST_COVER = "628b9be6cff66b70c002b14c", - RECEIVER_AK74M_DUST_COVER_6P34_01 = "5ac50da15acfc4001718d287", - RECEIVER_AK74_DUST_COVER_6P20_01 = "5649af094bdc2df8348b4586", - RECEIVER_AKM_DUST_COVER_6P1_01 = "59d6507c86f7741b846413a2", + RECEIVER_AK12_RAILED_DUST_COVER = "649ec2f3961514b22506b111", + RECEIVER_AK545_RAILED_DUST_COVER = "628b9be6cff66b70c002b14c", + RECEIVER_AK74M_DUST_COVER = "5ac50da15acfc4001718d287", + RECEIVER_AK74_DUST_COVER = "5649af094bdc2df8348b4586", + RECEIVER_AKM_DUST_COVER = "59d6507c86f7741b846413a2", RECEIVER_AKS74UB_DUST_COVER = "5839a7742459773cf9693481", - RECEIVER_AKS74U_DUST_COVER_6P26_SB7 = "57dc334d245977597164366f", - RECEIVER_AKS74U_LEGAL_ARSENAL_PILIGRIM_RAILED_DUST_COVER = "655cb6b5d680a544f30607fa", + RECEIVER_AKS74U_DUST_COVER = "57dc334d245977597164366f", + RECEIVER_AKS74U_LEGAL_ARSENAL_PILGRIM_RAILED_DUST_COVER = "655cb6b5d680a544f30607fa", RECEIVER_AK_AKADEMIA_BASTION_DUST_COVER = "5d2c76ed48f03532f2136169", RECEIVER_AK_FAB_DEFENSE_PDC_DUST_COVER = "5d2c770c48f0354b4a07c100", RECEIVER_AK_TWS_DOG_LEG_RAIL_DUST_COVER = "5d2c772c48f0355d95672c25", @@ -3260,6 +3489,11 @@ export declare enum ItemTpl { RECEIVER_AR15_NOVESKE_GEN3_556X45_UPPER = "5c07a8770db8340023300450", RECEIVER_AR15_VLTOR_MUR1S_556X45_UPPER = "59bfe68886f7746004266202", RECEIVER_AS_VAL_DUST_COVER = "57c44f4f2459772d2c627113", + RECEIVER_DESERT_EAGLE_L5_357_PISTOL_SLIDE = "669fa5127a09bc295603b499", + RECEIVER_DESERT_EAGLE_L5_50_AE_PISTOL_SLIDE = "669fa5019aa2a422600442f6", + RECEIVER_DESERT_EAGLE_L6_PISTOL_SLIDE = "669fa4d97a09bc295603b496", + RECEIVER_DESERT_EAGLE_L6_PISTOL_SLIDE_WTS = "669fa5271bd4416eaa09b3ce", + RECEIVER_DESERT_EAGLE_MK_XIX_PISTOL_SLIDE = "668fe60b56984d93550462c6", RECEIVER_FAL_STANDARD_DUST_COVER = "5b7d6c105acfc40015109a5f", RECEIVER_FN_FIVESEVEN_MK2_PISTOL_SLIDE = "5d3eb44aa4b93650d64e4979", RECEIVER_FN_P90_57X28_UPPER = "5cc70102e4a949035e43ba74", @@ -3294,8 +3528,8 @@ export declare enum ItemTpl { RECEIVER_M45A1_PISTOL_SLIDE = "5f3e7823ddc4f03b010e2045", RECEIVER_M4A1_556X45_UPPER = "55d355e64bdc2d962f8b4569", RECEIVER_M9A3_PISTOL_SLIDE = "5cadc55cae921500103bb3be", + RECEIVER_MCXSPEAR_68X51_UPPER = "6529119424cbe3c74a05e5bb", RECEIVER_MCX_GEN1_300_BLK_UPPER = "5fbcc3e4d6fa9c00c571bb58", - RECEIVER_MCX_SPEAR_68X51_UPPER = "6529119424cbe3c74a05e5bb", RECEIVER_MK18_338_LM_UPPER = "5fc278107283c4046c581489", RECEIVER_MK47_RESOLUTE_762X39_UPPER = "606587a88900dc2d9a55b659", RECEIVER_MOLOT_ARMS_AKMTYPE_DUST_COVER = "59e6449086f7746c9f75e822", @@ -3318,16 +3552,18 @@ export declare enum ItemTpl { RECEIVER_SA58_EXTREME_DUTY_DUST_COVER = "5b099bb25acfc400186331e8", RECEIVER_SKS_DUST_COVER = "634f05ca517ccc8a960fc748", RECEIVER_SKS_LEAPERS_UTG_PRO_MTU017_RECEIVER_COVER_MOUNT = "6415c694da439c6a97048b56", - RECEIVER_SOK12_DUST_COVER_SB02 = "57616c112459773cce774d66", + RECEIVER_SOK12_DUST_COVER = "57616c112459773cce774d66", RECEIVER_SR25_762X51_UPPER = "5df8e4080b92095fd441e594", RECEIVER_SR2M_DUST_COVER = "62e27a7865f0b1592a49e17b", RECEIVER_STEYR_AUG_A3_556X45 = "62e7c72df68e7a0676050c77", + RECEIVER_STEYR_AUG_A3_VLTOR_556X45 = "67110d8d388bded67304ceb4", RECEIVER_STM9_9X19_UPPER = "602e63fb6335467b0c5ac94d", RECEIVER_SVDS_CUSTOM_CUT_DUST_COVER = "5dfce88fe9dc277128008b2e", RECEIVER_SVDS_DUST_COVER = "5c471bd12e221602b4129c3a", RECEIVER_SVT_DUST_COVER = "64119cdbdcf48d656f0aa272", RECEIVER_TX15_556X45_LIGHTWEIGHT_UPPER = "5d4405aaa4b9361e6a4e6bd3", - RECEIVER_VPO101_VEPRHUNTER_DUST_COVER = "5c503d0a2e221602b542b7ef", + RECEIVER_UZI_PRO_DUST_COVER = "6680326874b8f2050c0b9178", + RECEIVER_VPO101_DUST_COVER = "5c503d0a2e221602b542b7ef", RECEIVER_VSS_DUST_COVER = "578395402459774a256959b5", REPAIRKITS_BODY_ARMOR_REPAIR_KIT = "591094e086f7747caa7bb2ef", REPAIRKITS_WEAPON_REPAIR_KIT = "5910968f86f77425cf569c32", @@ -3343,7 +3579,7 @@ export declare enum ItemTpl { SECURE_CONTAINER_GAMMA = "5857a8bc2459772bad15db29", SECURE_CONTAINER_GAMMA_TUE = "665ee77ccf2d642e98220bca", SECURE_CONTAINER_KAPPA = "5c093ca986f7740a1867ab12", - SECURE_THETA_SECURE_CONTAINER = "664a55d84a90fc2c8a6305c9", + SECURE_CONTAINER_THETA = "664a55d84a90fc2c8a6305c9", SECURE_TOURNAMENT_SECURED_CONTAINER = "64f6f4c5911bcdfe8b03b0dc", SECURE_WAIST_POUCH = "5732ee6a24597719ae0c0281", SHOTGUN_BENELLI_M3_SUPER_90_12GA_DUALMODE = "6259b864ebedf17603599e88", @@ -3354,6 +3590,8 @@ export declare enum ItemTpl { SHOTGUN_MP18_762X54R_SINGLESHOT_RIFLE = "61f7c9e189e6fb1a5e3ea78d", SHOTGUN_MP431C_12GA_DOUBLEBARREL = "5580223e4bdc2d1c128b457f", SHOTGUN_MP43_12GA_SAWEDOFF_DOUBLEBARREL = "64748cb8de82c85eaf0a273a", + SHOTGUN_MPS_AUTO_ASSAULT12_GEN_1_12GA_AUTOMATIC = "66ffa9b66e19cc902401c5e8", + SHOTGUN_MPS_AUTO_ASSAULT12_GEN_2_12GA_AUTOMATIC = "67124dcfa3541f2a1f0e788b", SHOTGUN_REMINGTON_MODEL_870_12GA_PUMPACTION = "5a7828548dc32e5a9c28b516", SHOTGUN_SAIGA12K_VER10_12GA_SEMIAUTOMATIC = "576165642459773c7a400233", SHOTGUN_TOZ106_20GA_BOLTACTION = "5a38e6bac4a2826c6e06d79b", @@ -3399,7 +3637,7 @@ export declare enum ItemTpl { SILENCER_KAC_QDC_65X35_SOUND_SUPPRESSOR = "55d617094bdc2d89028b4568", SILENCER_KAC_QDSS_NT4_556X45_SOUND_SUPPRESSOR_BLACK = "57da93632459771cb65bf83f", SILENCER_KAC_QDSS_NT4_556X45_SOUND_SUPPRESSOR_FDE = "57dbb57e2459774673234890", - SILENCER_MCX_SPEAR_SLX68MGQD_68X51_SOUND_SUPPRESSOR = "652911e650dc782999054b9d", + SILENCER_MCXSPEAR_SLX68MGQD_68X51_SOUND_SUPPRESSOR = "652911e650dc782999054b9d", SILENCER_MOSIN_RIFLE_BRAMIT_762X54R_SOUND_SUPPRESSOR = "5b86a0e586f7745b600ccb23", SILENCER_MP9_9X19_SOUND_SUPPRESSOR = "5de8f2d5b74cd90030650c72", SILENCER_MPXSD_9X19_INTEGRATED_SOUND_SUPPRESSOR = "58aeac1b86f77457c419f475", @@ -3407,17 +3645,18 @@ export declare enum ItemTpl { SILENCER_PL15_9X19_SOUND_SUPPRESSOR = "602a97060ddce744014caf6f", SILENCER_PP1901_VITYAZ_9X19_SOUND_SUPPRESSOR = "59bfc5c886f7743bf6794e62", SILENCER_PP9101_KEDRB_9X18PM_SOUND_SUPPRESSOR = "57f3c8cc2459773ec4480328", - SILENCER_ROTOR_43_366_TKM_MUZZLE_BRAKECOMPENSATOR = "5a9fbb74a2750c0032157181", - SILENCER_ROTOR_43_556X45_MUZZLE_BRAKECOMPENSATOR = "5a9fbb84a2750c00137fa685", - SILENCER_ROTOR_43_762X39_MUZZLE_BRAKECOMPENSATOR = "5a9fbacda2750c00141e080f", - SILENCER_ROTOR_43_762X54R_MUZZLE_BRAKECOMPENSATOR = "5e01ea19e9dc277128008c0b", - SILENCER_ROTOR_43_9X19_MUZZLE_BRAKECOMPENSATOR = "5a9fb739a2750c003215717f", + SILENCER_ROTOR_43_366_TKM_SOUND_SUPPRESSOR = "5a9fbb74a2750c0032157181", + SILENCER_ROTOR_43_556X45_SOUND_SUPPRESSOR = "5a9fbb84a2750c00137fa685", + SILENCER_ROTOR_43_762X39_SOUND_SUPPRESSOR = "5a9fbacda2750c00141e080f", + SILENCER_ROTOR_43_762X54R_SOUND_SUPPRESSOR = "5e01ea19e9dc277128008c0b", + SILENCER_ROTOR_43_9X19_SOUND_SUPPRESSOR = "5a9fb739a2750c003215717f", SILENCER_SIG_SAUER_SRD762QD_762X51_SOUND_SUPPRESSOR = "5fbe760793164a5b6278efc8", SILENCER_SIG_SAUER_SRD762TI_762X51_SOUND_SUPPRESSOR = "5fbe7618d6fa9c00c571bb6c", SILENCER_SIG_SAUER_SRD9_9X19_SOUND_SUPPRESSOR = "5c6165902e22160010261b28", SILENCER_SKS_HEXAGON_762X39_SOUND_SUPPRESSOR = "593d490386f7745ee97a1555", SILENCER_SR1MP_9X21_SOUND_SUPPRESSOR = "5a27b6bec4a282000e496f78", - SILENCER_SR2M_9X21_SOUND_SUPPRESSOR_SV1381 = "62e2a7138e1ac9380579c122", + SILENCER_SR2M_9X21_SV1381_SOUND_SUPPRESSOR = "62e2a7138e1ac9380579c122", + SILENCER_SR3M_9X39_SOUND_SUPPRESSOR = "65144ff50e00edc79406836f", SILENCER_STEYR_AUG_ASE_UTRA_S_SERIES_SL7I_556X45_SOUND_SUPPRESSOR = "634eba08f69c710e0108d386", SILENCER_STEYR_AUG_RELFEX_T4AUG_RANGER_556X45_SOUND_SUPPRESSOR = "630f2982cdb9e392db0cbcc7", SILENCER_SUREFIRE_SOCOM556MINI_MONSTER_556X45_SOUND_SUPPRESSOR = "55d6190f4bdc2d87028b4567", @@ -3426,7 +3665,8 @@ export declare enum ItemTpl { SILENCER_SV98_762X54R_SOUND_SUPPRESSOR = "5c4eecc32e221602b412b440", SILENCER_THUNDER_BEAST_ARMS_ULTRA_5_SOUND_SUPPRESSOR = "5d44064fa4b9361e4f6eb8b5", SILENCER_TT_762X25_MAKESHIFT_SOUND_SUPPRESSOR = "571a28e524597720b4066567", - SILENCER_VPO101_VEPRHUNTER_ROTOR_43_762X51_MUZZLE_BRAKECOMPENSATOR = "5f63407e1b231926f2329f15", + SILENCER_UZI_9X19_SOUND_SUPPRESSOR = "66993733f74fef4dfd0b04ff", + SILENCER_VPO101_ROTOR_43_762X51_SOUND_SUPPRESSOR = "5f63407e1b231926f2329f15", SILENCER_VSS_9X39_INTEGRAL_BARRELSUPPRESSOR = "57838c962459774a1651ec63", SMG_BT_MP9N_9X19_SUBMACHINE_GUN = "5de7bd7bfd6b4e6e2276dc25", SMG_BT_MP9_9X19_SUBMACHINE_GUN = "5e00903ae9dc277128008b87", @@ -3436,6 +3676,9 @@ export declare enum ItemTpl { SMG_HK_MP7A1_46X30_SUBMACHINE_GUN = "5ba26383d4351e00334c93d9", SMG_HK_MP7A2_46X30_SUBMACHINE_GUN = "5bd70322209c4d00d7167b8f", SMG_HK_UMP_45_ACP_SUBMACHINE_GUN = "5fc3e272f8b6a877a729eac5", + SMG_IWI_UZI_9X19_SUBMACHINE_GUN = "66992b349950f5f4cd06029f", + SMG_IWI_UZI_PRO_PISTOL_9X19_SUBMACHINE_GUN = "6680304edadb7aa61d00cef0", + SMG_IWI_UZI_PRO_SMG_9X19_SUBMACHINE_GUN = "668e71a8dadf42204c032ce1", SMG_PP1901_VITYAZ_9X19_SUBMACHINE_GUN = "59984ab886f7743e98271174", SMG_PP9101_KEDRB_9X18PM_SUBMACHINE_GUN = "57f3c6bd24597738e730fa2f", SMG_PP91_KEDR_9X18PM_SUBMACHINE_GUN = "57d14d2524597714373db789", @@ -3464,10 +3707,10 @@ export declare enum ItemTpl { SPECIALSCOPE_SIG_SAUER_ECHO1_12X30MM_30HZ_THERMAL_REFLEX_SCOPE = "6478641c19d732620e045e17", SPECIALSCOPE_TORREY_PINES_LOGIC_T12W_30HZ_THERMAL_REFLEX_SIGHT = "609bab8b455afd752b2e6138", SPECIALSCOPE_TRIJICON_REAPIR_THERMAL_SCOPE = "5a1eaa87fcdbcb001865f75e", - SPECITEM_LEATHERMAN_MULTITOOL = "544fb5454bdc2df8738b456a", SPECITEM_MS2000_MARKER = "5991b51486f77447b112d44f", SPECITEM_RADIO_REPEATER = "63a0b2eabea67a6d93009e52", SPECITEM_SIGNAL_JAMMER = "5ac78a9b86f7741cca0bbd8d", + SPECITEM_THE_EYE_MORTAR_STRIKE_SIGNALING_DEVICE = "6655e35b6bc645cb7b059912", SPECITEM_WIFI_CAMERA = "5b4391a586f7745321235ab2", STASH_EDGE_OF_DARKNESS_STASH_10X68 = "5811ce772459770e9e5f9532", STASH_LEFT_BEHIND_STASH_10X40 = "5811ce572459770cba1a34ea", @@ -3499,18 +3742,21 @@ export declare enum ItemTpl { STIM_XTG12_ANTIDOTE_INJECTOR = "5fca138c2a7b221b2852a5c6", STIM_ZAGUSTIN_HEMOSTATIC_DRUG_INJECTOR = "5c0e533786f7747fa23f4d47", STOCK_9A91_TOPFOLDING = "6451167ad4928d46d30be3fd", + STOCK_AA12_STOCK_ASSEMBLY = "66ffac9e316b08f6840a73e6", + STOCK_AA12_STOCK_ASSEMBLY_FDE = "670fd23798663bc4b10e911a", + STOCK_AA12_STOCK_ASSEMBLY_TERRAGROUP = "6719023b612cc94b9008e78c", STOCK_AI_AXMC_AX_BUTT = "62811f828193841aca4a45c3", STOCK_AI_AXMC_GTAC_ARTYPE_PISTOL_GRIP_ADAPTER = "62811e335631d45211793c95", STOCK_AI_AXMC_PISTOL_GRIP = "62811e2510e26c1f344e6554", STOCK_AK12 = "5beec8c20db834001d2c465c", STOCK_AK12_BUFFER_TUBE = "649ec87d8007560a9001ab36", - STOCK_AK545_SAG_BUFFER_TUBE = "628b9a40717774443b15e9f2", + STOCK_AK545_BUFFER_TUBE = "628b9a40717774443b15e9f2", STOCK_AK74MAK100_ZENIT_PT_LOCK = "5ac78eaf5acfc4001926317a", STOCK_AK74M_CAA_AKTS_AK74_BUFFER_TUBE = "5cf50fc5d7f00c056c53f83c", - STOCK_AK74M_POLYMER_STOCK_6P34_SB15 = "5ac50c185acfc400163398d4", - STOCK_AK74_PLUM_POLYMER_STOCK_6P20_SB7 = "5cbdb1b0ae9215000d50e105", - STOCK_AK74_POLYMER_STOCK_6P20_SB7 = "5649b0fc4bdc2d17108b4588", - STOCK_AK74_WOODEN_STOCK_6P20_SB5 = "5649b1c04bdc2d16268b457c", + STOCK_AK74M_POLYMER = "5ac50c185acfc400163398d4", + STOCK_AK74_POLYMER = "5649b0fc4bdc2d17108b4588", + STOCK_AK74_POLYMER_STOCK_PLUM = "5cbdb1b0ae9215000d50e105", + STOCK_AK74_WOODEN = "5649b1c04bdc2d16268b457c", STOCK_AKMAK74_CAA_AKTS_BUFFER_TUBE = "5cf518cfd7f00c065b422214", STOCK_AKMAK74_FAB_DEFENSE_UAS = "5b04473a5acfc40018632f70", STOCK_AKMAK74_HERA_ARMS_CQR47_PISTOL_GRIPBUTT = "619b69037b9de8162902673e", @@ -3520,15 +3766,16 @@ export declare enum ItemTpl { STOCK_AKMAK74_PROMAG_ARCHANGEL_OPFOR_AA47_BUTT = "6087e2a5232e5a31c233d552", STOCK_AKMAK74_RD_AK_TO_M4_BUFFER_TUBE_ADAPTER = "628a6678ccaab13006640e49", STOCK_AKMAK74_ZENIT_PT_LOCK = "5b222d335acfc4771e1be099", - STOCK_AKMSN_SHOULDER_PIECE_6P4N_SB119 = "5abcd472d8ce8700166032ae", - STOCK_AKMS_SHOULDER_PIECE_6P4_SB119 = "59ff3b6a86f77477562ff5ed", - STOCK_AKM_WOODEN_STOCK_6P1_SB5 = "59d6514b86f774171a068a08", + STOCK_AKMSN_FOLDING = "5abcd472d8ce8700166032ae", + STOCK_AKMS_FOLDING = "59ff3b6a86f77477562ff5ed", + STOCK_AKM_WOODEN = "59d6514b86f774171a068a08", STOCK_AKS74AKS74U_ZENIT_PT_LOCK = "59ecc28286f7746d7a68aa8c", - STOCK_AKS74U_METAL_SKELETON_STOCK_6P26_SB5 = "57dc347d245977596754e7a1", - STOCK_AKS74_METAL_SKELETONIZED_STOCK_6P21_SB5 = "5ab626e4d8ce87272e4c6e43", + STOCK_AKS74U_SKELETONIZED = "57dc347d245977596754e7a1", + STOCK_AKS74_SKELETONIZED = "5ab626e4d8ce87272e4c6e43", STOCK_AK_100SERIES_METAL_SKELETONIZED = "6386300124a1dc425c00577a", STOCK_AK_CUSTOM_ARMS_STEF_74_SKELETON_STOCK_EXTENSION = "6494094948796d891603e59f", STOCK_AK_GP25_ACCESSORY_KIT_RECOIL_PAD = "5a0c59791526d8dba737bba7", + STOCK_AK_SKELETONIZED_STOCK_CUSTOMIZED = "66ac9d9740e27931602042d4", STOCK_AK_ZENIT_PT1_KLASSIKA = "5b222d405acfc400153af4fe", STOCK_AK_ZENIT_PT3_KLASSIKA = "59ecc3dd86f7746dc827481c", STOCK_APB_DETACHABLE_WIRE = "5a17fb9dfcdbcbcae6687291", @@ -3596,17 +3843,26 @@ export declare enum ItemTpl { STOCK_FN_SCAR_CHEEK_REST_FDE = "61825d24d3a39d50044c13af", STOCK_FN_SCAR_FOLDING_POLYMER = "61816734d8e3106d9806c1f3", STOCK_FN_SCAR_FOLDING_POLYMER_STOCK_FDE = "61825d06d92c473c770215de", + STOCK_FN_SCAR_JMAC_CUSTOMS_RSASCAR_1913_ADAPTER = "66ffc246a81a4f85e70d4d06", STOCK_FN_SCAR_RETRACTABLE_POLYMER = "618167528004cc50514c34f9", STOCK_FN_SCAR_RETRACTABLE_POLYMER_STOCK_FDE = "61825d136ef05c2ce828f1cc", STOCK_FN_SCAR_RUBBER_BUTTPAD = "618167616ef05c2ce828f1a8", + STOCK_FN_SCAR_VLTOR_RESCAR_STOCK_ADAPTER = "66ffbfb1a73a7bce3d0b45a8", + STOCK_FN_SCAR_VLTOR_RESCAR_STOCK_ADAPTER_PATRIOT_BROWN = "66ffc20ba73a7bce3d0b45ab", + STOCK_FN_SCAR_VLTOR_VSS11_POLYMER = "66ffc2bd132225f0fe0611d8", + STOCK_FN_SCAR_VLTOR_VSS11_POLYMER_STOCK_PATRIOT_BROWN = "66ffc2ecfe9b3825960652f7", STOCK_GLOCK_FAB_DEFENSE_GLR17 = "5d1c702ad7ad1a632267f429", STOCK_HK417_ADJUSTABLE_BUTT = "617155ee50224f204c1da3cd", STOCK_HK417_E2_BUTT = "617154aa1cb55961fa0fdb3b", STOCK_HK_ADJUSTABLE_BUTTSTOCK_CHEEK_REST = "61715e7e67085e45ef140b33", STOCK_HK_ENHANCED_TUBE_BUFFER_TUBE = "5bb20e58d4351e00320205d7", STOCK_HK_G28_BUFFER_TUBE = "617153016c780c1e710c9a2f", + STOCK_HK_G36_IDZ_ADJUSTABLE = "67110d06723c2733410161e8", + STOCK_HK_G36_IDZ_CONCAVE_BUTTPAD = "67110d6fa71d1f123d021cd3", + STOCK_HK_G36_IDZ_CONVEX_BUTTPAD = "67110d5ed1758189fc0bd221", STOCK_HK_G36_KV_ADJUSTABLE = "622f14e899892a7f9e08f6c5", STOCK_HK_G36_POLYMER = "622f140da5958f63c67f1735", + STOCK_HK_G36_TOMMY_BUILT_AR_STOCK_ADAPTER = "6706a159c67236b2f703bb95", STOCK_HK_MP5K_END_CAP = "5d2f25bc48f03502573e5d85", STOCK_HK_MP5_A2 = "5926d3c686f77410de68ebc8", STOCK_HK_MP5_A3_OLD_MODEL = "5926d40686f7740f152b6b7e", @@ -3624,6 +3880,9 @@ export declare enum ItemTpl { STOCK_M14_TROY_SASS_CHASSIS = "5ab372a310e891001717f0d8", STOCK_M1A_PROMAG_ARCHANGEL_CHASSIS = "5addbf175acfc408fb13965b", STOCK_M1A_SOCOM_16 = "5aaf8e43e5b5b00015693246", + STOCK_M60E4_BUTT = "660126161347bc1a5f0f4dba", + STOCK_M60E6_BUTT = "6615202b96461aa8360271eb", + STOCK_M60E6_BUTTSTOCK_FDE = "661520fb6f8e1a96340afaa6", STOCK_M700_AB_ARMS_MODX_BUFFER_TUBE_SIDE_FOLDER_ADAPTER = "5cde77a9d7f00c000f261009", STOCK_M700_AB_ARMS_MODX_GEN_3_CHASSIS = "5cde739cd7f00c0010373bd3", STOCK_M700_AI_AT_AICS_POLYMER_CHASSIS = "5d25d0ac8abbc3054f3e61f7", @@ -3636,11 +3895,9 @@ export declare enum ItemTpl { STOCK_M870_SHOCKWAVE_RAPTOR_GRIP = "5a788169c5856700142fdd9e", STOCK_M870_SPS_POLYMER = "5a7880d0c5856700142fdd9d", STOCK_MAGPUL_MOE_CARBINE_RUBBER_BUTTPAD = "58d2912286f7744e27117493", - STOCK_MCXMPX_FOLDING_STOCK_ADAPTER_BUFFER_TUBE_COYOTE_TAN = "6529366450dc782999054ba0", - STOCK_MCXMPX_STOCK_LOCKING_HINGE_ASSEMBLY = "6529348224cbe3c74a05e5c4", STOCK_MESA_TACTICAL_CROSSHAIR_HYDRAULIC_BUFFER_TUBE = "5ef1ba28c64c5d0dfc0571a5", STOCK_MOSIN_RIFLE_AIM_SPORTS_RECOIL_PAD = "5bbde409d4351e003562b036", - STOCK_MOSIN_RIFLE_ATI_MONTE_CARLO_CHASSIS = "5bbdb870d4351e00367fb67d", + STOCK_MOSIN_RIFLE_ATI_MONTE_CARLO = "5bbdb870d4351e00367fb67d", STOCK_MOSIN_RIFLE_CARBINE = "5bfd384c0db834001a6691d3", STOCK_MOSIN_RIFLE_INFANTRY = "5bfd35380db83400232fe5cc", STOCK_MOSIN_RIFLE_PROMAG_ARCHANGEL_OPFOR_PRS_CHASSIS = "5bae13bad4351e00320204af", @@ -3664,11 +3921,13 @@ export declare enum ItemTpl { STOCK_MP431C_BUTTPAD = "611a31ce5b7ffe001b4649d1", STOCK_MP9 = "5de910da8b6c4240ba2651b5", STOCK_MPXMCX_COLLAPSINGTELESCOPING = "5894a13e86f7742405482982", - STOCK_MPXMCX_LIGHTWEIGHT = "5fbcc437d724d907e2077d5c", - STOCK_MPXMCX_MAXIM_DEFENSE_CQB_TELESCOPING = "5c5db6ee2e221600113fba54", + STOCK_MPXMCX_FOLDING_KNUCKLE_STOCK_ADAPTER = "58ac1bf086f77420ed183f9f", + STOCK_MPXMCX_MAXIM_DEFENSE_CQB = "5c5db6ee2e221600113fba54", STOCK_MPXMCX_PMM_ULSS_FOLDABLE = "5c5db6f82e2216003a0fe914", - STOCK_MPXMCX_RETRACTABLE_STOCK_ADAPTER = "58ac1bf086f77420ed183f9f", - STOCK_MPXMCX_TELESCOPING = "5fbcc429900b1d5091531dd7", + STOCK_MPXMCX_STOCK_ADAPTER_LOW_PROFILE_TUBE_COYOTE_TAN = "6529366450dc782999054ba0", + STOCK_MPXMCX_STOCK_LOCKING_HINGE_ASSEMBLY = "6529348224cbe3c74a05e5c4", + STOCK_MPXMCX_TELESCOPINGFOLDING = "5fbcc429900b1d5091531dd7", + STOCK_MPXMCX_THIN_SIDEFOLDING = "5fbcc437d724d907e2077d5c", STOCK_MTS25512_WOODEN = "612781056f3d944a17348d60", STOCK_MTS_2001 = "5adf23995acfc400185c2aeb", STOCK_OPSKS_WOODEN = "587e0531245977466077a0f7", @@ -3687,7 +3946,7 @@ export declare enum ItemTpl { STOCK_SA58_FOLDING = "5b7d63cf5acfc4001876c8df", STOCK_SA58_HUMPBACK_POLYMER = "5b7d645e5acfc400170e2f90", STOCK_SA58_SPR = "5b7d63de5acfc400170e2f8d", - STOCK_SKS_ATI_MONTE_CARLO_CHASSIS = "653ecef836fae5a82f02b869", + STOCK_SKS_ATI_MONTE_CARLO = "653ecef836fae5a82f02b869", STOCK_SKS_FAB_DEFENSE_UAS_BUTT = "653ed132896b99b40a0292e6", STOCK_SKS_FAB_DEFENSE_UAS_CHASSIS = "5d0236dad7ad1a0940739d29", STOCK_SKS_TAPCO_INTRAFUSE_BUFFER_TUBE = "5afd7e095acfc40017541f61", @@ -3703,28 +3962,39 @@ export declare enum ItemTpl { STOCK_TOZ106 = "5a38ef1fc4a282000b1521f6", STOCK_TOZ106_CUSTOM_CUT_MOSIN = "5c99f3592e221644fc633070", STOCK_TOZ106_FAB_DEFENSE_GPCP_CHEEK_REST = "626a8ae89e664a2e2a75f409", - STOCK_VPO101_VEPRHUNTER = "5c503af12e221602b177ca02", - STOCK_VPO101_VEPRHUNTER_SVDSTYLE = "5f63405df5750b524b45f114", + STOCK_UZI_PRO_A3_TACTICAL_MODULAR_FOLDING_BRACE = "6686717ffb75ee4a5e02eb19", + STOCK_UZI_PRO_A3_TACTICAL_REAR_STOCK_ADAPTER = "668672b8c99550c6fd0f0b29", + STOCK_UZI_PRO_BACKPLATE = "66881008f23233ee9a0742e7", + STOCK_UZI_PRO_CSM_STOCK_ADAPTER = "669cf78806768ff39504fc1c", + STOCK_UZI_PRO_SBR_BUTT = "66867310f3734a938b077f79", + STOCK_UZI_PRO_STABILIZING_BRACE = "668032ba74b8f2050c0b917d", + STOCK_UZI_STORMWERKZ_STOCK_ADAPTER = "66992f4db9f31ddda10dd1c8", + STOCK_UZI_TYPE_3_BUTT = "6698c9ed36ba38d291017713", + STOCK_UZI_TYPE_5_BUTT = "6699249f3c4fda6471005cba", + STOCK_UZI_TYPE_6_BUTT = "669924a69950f5f4cd060295", + STOCK_UZI_TYPE_7_BUTT = "6698c9e07356874dfe0a0b88", + STOCK_VPO101_SVDSTYLE_WALNUT = "5f63405df5750b524b45f114", + STOCK_VPO101_WOODEN = "5c503af12e221602b177ca02", STOCK_VPO136_VEPRKM_WOODEN = "59e6227d86f77440d64f5dc2", STOCK_VPO209_WOODEN = "59e89d0986f77427600d226e", - STOCK_VPO215_GORNOSTAY = "5de655be4a9f347bc92edb88", + STOCK_VPO215_WOODEN = "5de655be4a9f347bc92edb88", STOCK_VSK94 = "6452519e3d52156624001fd5", STOCK_VSS_WOODEN = "578395e82459774a0e553c7b", - TACTICALCOMBO_ANPEQ15_TACTICAL_DEVICE = "544909bb4bdc2d6f028b4577", - TACTICALCOMBO_ANPEQ2_TACTICAL_DEVICE = "5d10b49bd7ad1a1a560708b0", + TACTICALCOMBO_BE_MEYERS_MAWLC1_TACTICAL_DEVICE = "644a3df63b0b6f03e101e065", TACTICALCOMBO_GLOCK_GTL_21_TACTICAL_FLASHLIGHT_WITH_LASER = "5a800961159bd4315e3a1657", TACTICALCOMBO_HOLOSUN_LS321_TACTICAL_DEVICE = "57fd23e32459772d0805bcf1", + TACTICALCOMBO_INSIGHT_ANPEQ2_TACTICAL_DEVICE = "5d10b49bd7ad1a1a560708b0", TACTICALCOMBO_INSIGHT_WMX200_TACTICAL_FLASHLIGHT = "626becf9582c3e319310b837", - TACTICALCOMBO_LA5BPEQ_TACTICAL_DEVICE = "5c06595c0db834001a66af6c", - TACTICALCOMBO_MAWLC1_TACTICAL_DEVICE = "644a3df63b0b6f03e101e065", - TACTICALCOMBO_NCSTAR_TACTICAL_BLUE_LASER_LAMMODULE = "5cc9c20cd7f00c001336c65d", + TACTICALCOMBO_L3HARRIS_ANPEQ15_TACTICAL_DEVICE = "544909bb4bdc2d6f028b4577", + TACTICALCOMBO_L3HARRIS_LA5BPEQ_TACTICAL_DEVICE = "5c06595c0db834001a66af6c", + TACTICALCOMBO_NCSTAR_TACTICAL_BLUE_LASER = "5cc9c20cd7f00c001336c65d", TACTICALCOMBO_OLIGHT_BALDR_PRO_TACTICAL_FLASHLIGHT_WITH_LASER = "6272370ee4013c5d7e31f418", TACTICALCOMBO_OLIGHT_BALDR_PRO_TACTICAL_FLASHLIGHT_WITH_LASER_TAN = "6272379924e29f06af4d5ecb", TACTICALCOMBO_STEINER_DBALPL_TACTICAL_DEVICE = "5d2369418abbc306c62e0c80", TACTICALCOMBO_STEINER_LASTAC_2_TACTICAL_FLASHLIGHT = "5b07dd285acfc4001754240d", TACTICALCOMBO_SUREFIRE_X400_ULTRA_TACTICAL_FLASHLIGHT_WITH_LASER = "56def37dd2720bec348b456a", TACTICALCOMBO_SUREFIRE_XC1_TACTICAL_FLASHLIGHT = "5a7b483fe899ef0016170d15", - TACTICALCOMBO_TT_DLP_TACTICAL_PRECISION_LAMMODULE = "5c079ed60db834001a66b372", + TACTICALCOMBO_TT_DLP_TACTICAL_PRECISION_LASER_SIGHT = "5c079ed60db834001a66b372", TACTICALCOMBO_WILCOX_RAPTAR_ES_TACTICAL_RANGEFINDER = "61605d88ffa6e502ac5e7eeb", TACTICALCOMBO_ZENIT_KLESCH2IKS_IR_ILLUMINATOR_WITH_LASER = "5a5f1ce64f39f90b401987bc", TACTICALCOMBO_ZENIT_KLESCH2P_FLASHLIGHT_WITH_LASER = "560d657b4bdc2da74d8b4572", @@ -3774,6 +4044,9 @@ export declare enum ItemTpl { VEST_SS_PRECISION_PLATEFRAME_PLATE_CARRIER_GOONS_EDITION = "628b9784bcf6e2659e09b8a2", VEST_STICH_PROFI_CHEST_RIG_MK2_ASSAULT_ATACS_FG = "60a621c49c197e4e8c4455e6", VEST_STICH_PROFI_CHEST_RIG_MK2_RECON_ATACS_FG = "60a6220e953894617404b00a", + VEST_STICH_PROFI_PLATE_CARRIER_V2_BLACK = "66b6296d7994640992013b17", + VEST_STICH_PROFI_STICH_DEFENSE_MOD2_PLATE_CARRIER_MULTICAM = "66b6295178bbc0200425f995", + VEST_TASMANIAN_TIGER_PLATE_CARRIER_MKIII_COYOTE_BROWN = "66b6295a8ca68c6461709efa", VEST_TASMANIAN_TIGER_SK_PLATE_CARRIER_MULTICAM_BLACK = "628cd624459354321c4b7fa2", VEST_TYPE_56_CHICOM_CHEST_HARNESS = "64be7110bf597ba84a0a41ea", VEST_UMKA_M33SET1_HUNTER_VEST_OLIVE_DRAB = "6034cf5fffd42c541047f72e", @@ -3786,8 +4059,8 @@ export declare enum ItemTpl { VEST_ZULU_NYLON_GEAR_M4_REDUCED_SIGNATURE_CHEST_RIG_RANGER_GREEN = "64be7095047e826eae02b0c1", VISORS_6B34_ANTIFRAGMENTATION_GLASSES = "5b432be65acfc433000ed01f", VISORS_ANTIFRAGMENTATION_GLASSES = "59e770b986f7742cbd762754", - VISORS_CROSSBOW_TACTICAL_GLASSES = "5d5fca1ea4b93635fd598c07", VISORS_DUNDUKK_SPORT_SUNGLASSES = "5aa2b986e5b5b00014028f4c", + VISORS_ESS_CROSSBOW_TACTICAL_GLASSES = "5d5fca1ea4b93635fd598c07", VISORS_GAS_WELDER_SAFETY_GOGGLES = "61c18d83b00456371a66814b", VISORS_JOHNB_LIQUID_DNB_GLASSES = "62a09e410b9d3c46de5b6e78", VISORS_NPP_KLASS_CONDOR_GLASSES = "603409c80ca681766b6a0fb2", diff --git a/types/models/enums/QuestRewardType.d.ts b/types/models/enums/QuestRewardType.d.ts index 3f010408..e09f71d3 100644 --- a/types/models/enums/QuestRewardType.d.ts +++ b/types/models/enums/QuestRewardType.d.ts @@ -9,5 +9,6 @@ export declare enum QuestRewardType { TRADER_STANDING_RESET = "TraderStandingReset", TRADER_STANDING_RESTORE = "TraderStandingRestore", STASH_ROWS = "StashRows", - ACHIEVEMENT = "Achievement" + ACHIEVEMENT = "Achievement", + POCKETS = "Pockets" } diff --git a/types/models/enums/Season.d.ts b/types/models/enums/Season.d.ts index b1d3662e..aae50b9c 100644 --- a/types/models/enums/Season.d.ts +++ b/types/models/enums/Season.d.ts @@ -3,5 +3,7 @@ export declare enum Season { AUTUMN = 1, WINTER = 2, SPRING = 3, - STORM = 4 + AUTUMN_LATE = 4, + SPRING_EARLY = 5, + STORM = 6 } diff --git a/types/models/enums/SeasonalEventType.d.ts b/types/models/enums/SeasonalEventType.d.ts index cfea1f5b..5e67118f 100644 --- a/types/models/enums/SeasonalEventType.d.ts +++ b/types/models/enums/SeasonalEventType.d.ts @@ -4,5 +4,5 @@ export declare enum SeasonalEventType { HALLOWEEN = "Halloween", NEW_YEARS = "NewYears", PROMO = "Promo", - SNOW = "Snow" + APRIL_FOOLS = "AprilFools" } diff --git a/types/models/enums/TraderServiceType.d.ts b/types/models/enums/TraderServiceType.d.ts index f3586dc9..f0ca76dd 100644 --- a/types/models/enums/TraderServiceType.d.ts +++ b/types/models/enums/TraderServiceType.d.ts @@ -4,5 +4,6 @@ export declare enum TraderServiceType { CULTISTS_AID = "CultistsAid", BTR_ITEMS_DELIVERY = "BtrItemsDelivery", PLAYER_TAXI = "PlayerTaxi", - BTR_BOT_COVER = "BtrBotCover" + BTR_BOT_COVER = "BtrBotCover", + TRANSIT_ITEMS_DELIVERY = "TransitItemsDelivery" } diff --git a/types/models/enums/Weapons.d.ts b/types/models/enums/Weapons.d.ts index 178bc68a..d88d7426 100644 --- a/types/models/enums/Weapons.d.ts +++ b/types/models/enums/Weapons.d.ts @@ -6,6 +6,7 @@ export declare enum Weapons { ASSAULTCARBINE_762X54R_SVT_40 = "643ea5b23db6f9f57107d9fd", ASSAULTCARBINE_9X39_9A_91 = "644674a13d52156624001fbc", ASSAULTCARBINE_9X39_AS_VAL = "57c44b372459772d2b39b8ce", + ASSAULTCARBINE_9X39_SR_3M = "651450ce0e00edc794068371", ASSAULTCARBINE_9X39_VSK_94 = "645e0c6b3b381ede770e1cc9", ASSAULTRIFLE_127X55_ASH_12 = "5cadfbf7ae92152ac412eeef", ASSAULTRIFLE_366TKM_VPO_209 = "59e6687d86f77411d949b251", @@ -26,6 +27,7 @@ export declare enum Weapons { ASSAULTRIFLE_556X45_AK_102 = "5ac66d015acfc400180ae6e4", ASSAULTRIFLE_556X45_AUG_A1 = "62e7c4fba689e8c9c50dfc38", ASSAULTRIFLE_556X45_AUG_A3 = "63171672192e68c5460cebc5", + ASSAULTRIFLE_556X45_AUG_A3_BLACK = "6718817435e3cfd9550d2c27", ASSAULTRIFLE_556X45_G36 = "623063e994fc3f7b302a9696", ASSAULTRIFLE_556X45_HK_416A5 = "5bb2475ed4351e00853264e3", ASSAULTRIFLE_556X45_M4A1 = "5447a9cd4bdc2dbd208b4567", @@ -49,9 +51,11 @@ export declare enum Weapons { ASSAULTRIFLE_762X51_MK_17_FDE = "6165ac306ef05c2ce828ef74", ASSAULTRIFLE_762X51_SA_58 = "5b0bbe4e5acfc40dc528a72d", ASSAULTRIFLE_9X18PM_MASTER_HAND = "5ae083b25acfc4001a5fc702", + FLARE_26X75_BLUE = "66d98233302686954b0c6f81", FLARE_26X75_FLARE_WHITE = "62178be9d0050232da3485d9", FLARE_26X75_GREEN = "6217726288ed9f0845317459", FLARE_26X75_RED = "62178c4d4ecf221597654e3d", + FLARE_26X75_S_YELLOW_SPECIAL_YELLOW = "66d9f1abb16d9aacf5068468", FLARE_26X75_YELLOW = "624c0b3340357b5f566e8766", GRENADELAUNCHER_40MMRU_FN40GL = "639af924d0446708ee62294e", GRENADELAUNCHER_40X46_FN40GL = "5e81ebcd8e146c7080625e15", @@ -61,6 +65,9 @@ export declare enum Weapons { MACHINEGUN_545X39_RPK_16 = "5beed0f50db834001c062b12", MACHINEGUN_762X39_RPD = "6513ef33e06849f06c0957ca", MACHINEGUN_762X39_RPDN = "65268d8ecb944ff1e90ea385", + MACHINEGUN_762X51_M60E6 = "661ceb1b9311543c7104149b", + MACHINEGUN_762X51_M60E6_FDE = "661cec09b2c6356b4d0c7a36", + MACHINEGUN_762X51_MK_43_MOD_1 = "65fb023261d5829b2d090755", MACHINEGUN_762X54R_PKM = "64637076203536ad5600c990", MACHINEGUN_762X54R_PKP = "64ca3d3954fc657e230529cc", MACHINEGUN_762X54R_PKTM = "657857faeff4c850222dff1b", @@ -72,6 +79,10 @@ export declare enum Weapons { MARKSMANRIFLE_762X54R_SVDS = "5c46fbd72e2216398b5a8c9c", MARKSMANRIFLE_86X70_MK_18_MJLNIR = "5fc22d7c187fea44d52eda44", MARKSMANRIFLE_9X39_VSS_VINTOREZ = "57838ad32459774a17445cd2", + PISTOL_127X33_DESERT_EAGLE_L5 = "669fa3f88abd2662d80eee77", + PISTOL_127X33_DESERT_EAGLE_L6 = "669fa39b48fc9f8db6035a0c", + PISTOL_127X33_DESERT_EAGLE_L6_WTS = "669fa3d876116c89840b1217", + PISTOL_127X33_DESERT_EAGLE_MK_XIX = "668fe5a998b5ad715703ddd6", PISTOL_20X1MM_BLICKY = "66015072e9f84d5680039678", PISTOL_45ACP_M1911A1 = "5e81c3cbac2bb513793cdc75", PISTOL_45ACP_M45A1 = "5f36a0e5fbf956000b716b65", @@ -93,12 +104,15 @@ export declare enum Weapons { PISTOL_9X19_P226R = "56d59856d2720bd8418b456a", PISTOL_9X19_PL_15 = "602a9740da11d6478d5a06dc", PISTOL_9X21_SR_1MP = "59f98b4986f7746f546d2cef", + PISTOL_9X33R_DESERT_EAGLE_L5 = "669fa409933e898cce0c2166", REVOLVER_127X55_RSH_12 = "633ec7c2a6918cb895019c6c", REVOLVER_12G_MTS_255_12 = "60db29ce99594040e04c4a27", REVOLVER_40X46_MSGL = "6275303a9f372d6ea97f9ec7", REVOLVER_9X19_CR_200DS = "624c2e8614da335f1e034d8c", REVOLVER_9X33R_CR_50DS = "61a4c8884f95bc3b2c5dc96f", SHOTGUN_12G_590A1 = "5e870397991fd70db46995c8", + SHOTGUN_12G_AA_12_GEN_1 = "66ffa9b66e19cc902401c5e8", + SHOTGUN_12G_AA_12_GEN_2 = "67124dcfa3541f2a1f0e788b", SHOTGUN_12G_M3_SUPER_90 = "6259b864ebedf17603599e88", SHOTGUN_12G_M870 = "5a7828548dc32e5a9c28b516", SHOTGUN_12G_MP_133 = "54491c4f4bdc2db1078b4568", @@ -128,6 +142,9 @@ export declare enum Weapons { SMG_9X19_PP_19_01 = "59984ab886f7743e98271174", SMG_9X19_SAIGA_9 = "59f9cabd86f7743a10721f46", SMG_9X19_STM_9 = "60339954d62c9b14ed777c06", + SMG_9X19_UZI = "66992b349950f5f4cd06029f", + SMG_9X19_UZI_PRO_PISTOL = "6680304edadb7aa61d00cef0", + SMG_9X19_UZI_PRO_SMG = "668e71a8dadf42204c032ce1", SMG_9X19_VECTOR_9X19 = "5fc3f2d5900b1d5091531e57", SMG_9X21_SR_2M = "62e14904c2699c0ec93adc47", SNIPERRIFLE_366TKM_VPO_215_GORNOSTAY = "5de652c31b7e3716273428be", diff --git a/types/models/enums/WildSpawnTypeNumber.d.ts b/types/models/enums/WildSpawnTypeNumber.d.ts index 19d00629..d93c13b4 100644 --- a/types/models/enums/WildSpawnTypeNumber.d.ts +++ b/types/models/enums/WildSpawnTypeNumber.d.ts @@ -45,12 +45,19 @@ export declare enum WildSpawnTypeNumber { FOLLOWERKOLONTAYASSAULT = 44, FOLLOWERKOLONTAYSECURITY = 45, SHOOTERBTR = 46, - SPIRITWINTER = 47, - SPIRITSPRING = 48, - PMCBEAR = 49, - PMCUSEC = 50, - SKIER = 51, - PEACEMAKER = 52, - SPTUSEC = 100, - SPTBEAR = 101 + BOSSPARTISAN = 47, + SPIRITWINTER = 48, + SPIRITSPRING = 49, + PEACEMAKER = 50, + PMCBEAR = 51, + PMCUSEC = 52, + SKIER = 53, + SECTANTPREDVESTNIK = 57, + SECTANTPRIZRAK = 58, + SECTANTONI = 59, + INFECTEDASSAULT = 60, + INFECTEDPMC = 61, + INFECTEDCIVIL = 62, + INFECTEDLABORANT = 63, + INFECTEDTAGILLA = 64 } diff --git a/types/models/enums/hideout/QteEffectType.d.ts b/types/models/enums/hideout/QteEffectType.d.ts index 9ecd1a2e..08aa9c6a 100644 --- a/types/models/enums/hideout/QteEffectType.d.ts +++ b/types/models/enums/hideout/QteEffectType.d.ts @@ -1,5 +1,5 @@ export declare enum QteEffectType { - FINISH_EFFECT = "FinishEffect", - SINGLE_SUCCESS_EFFECT = "SingleSuccessEffect", - SINGLE_FAIL_EFFECT = "SingleFailEffect" + FINISH_EFFECT = "finishEffect", + SINGLE_SUCCESS_EFFECT = "singleSuccessEffect", + SINGLE_FAIL_EFFECT = "singleFailEffect" } diff --git a/types/models/external/HttpFramework.d.ts b/types/models/external/HttpFramework.d.ts index fda87328..96fb4ed8 100644 --- a/types/models/external/HttpFramework.d.ts +++ b/types/models/external/HttpFramework.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; export type HandleFn = (_: string, req: IncomingMessage, resp: ServerResponse) => void; /** @@ -6,7 +5,9 @@ export type HandleFn = (_: string, req: IncomingMessage, resp: ServerResponse) = * @param basePath The base path * @returns The decorator that create the listener proxy */ -export declare const Listen: (basePath: string) => any>(Base: T) => T; +export declare const Listen: (basePath: string) => (Base: T) => T; /** * HTTP DELETE decorator */ diff --git a/types/models/spt/bots/BotGenerationDetails.d.ts b/types/models/spt/bots/BotGenerationDetails.d.ts index 3977ee57..81acc7df 100644 --- a/types/models/spt/bots/BotGenerationDetails.d.ts +++ b/types/models/spt/bots/BotGenerationDetails.d.ts @@ -1,5 +1,5 @@ import { MinMax } from "@spt/models/common/MinMax"; -export interface BotGenerationDetails { +export interface IBotGenerationDetails { /** Should the bot be generated as a PMC */ isPmc: boolean; /** assault/pmcBot etc */ diff --git a/types/models/spt/bots/GenerateWeaponResult.d.ts b/types/models/spt/bots/GenerateWeaponResult.d.ts deleted file mode 100644 index d4a25267..00000000 --- a/types/models/spt/bots/GenerateWeaponResult.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Mods } from "@spt/models/eft/common/tables/IBotType"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; -export declare class GenerateWeaponResult { - weapon: Item[]; - chosenAmmoTpl: string; - chosenUbglAmmoTpl: string; - weaponMods: Mods; - weaponTemplate: ITemplateItem; -} diff --git a/types/models/spt/bots/IGenerateEquipmentProperties.d.ts b/types/models/spt/bots/IGenerateEquipmentProperties.d.ts index 9cf76855..e19a9e07 100644 --- a/types/models/spt/bots/IGenerateEquipmentProperties.d.ts +++ b/types/models/spt/bots/IGenerateEquipmentProperties.d.ts @@ -1,22 +1,22 @@ -import { Inventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; -import { Chances, Mods } from "@spt/models/eft/common/tables/IBotType"; -import { EquipmentFilters, RandomisationDetails } from "@spt/models/spt/config/IBotConfig"; +import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IChances, IMods } from "@spt/models/eft/common/tables/IBotType"; +import { EquipmentFilters, IRandomisationDetails } from "@spt/models/spt/config/IBotConfig"; +import { IBotData } from "./IGenerateWeaponRequest"; export interface IGenerateEquipmentProperties { /** Root Slot being generated */ rootEquipmentSlot: string; /** Equipment pool for root slot being generated */ rootEquipmentPool: Record; - modPool: Mods; + modPool: IMods; /** Dictionary of mod items and their chance to spawn for this bot type */ - spawnChances: Chances; - /** Role being generated for */ - botRole: string; - /** Level of bot being generated */ - botLevel: number; + spawnChances: IChances; + /** Bot-specific properties */ + botData: IBotData; inventory: PmcInventory; botEquipmentConfig: EquipmentFilters; /** Settings from bot.json to adjust how item is generated */ - randomisationDetails: RandomisationDetails; + randomisationDetails: IRandomisationDetails; /** OPTIONAL - Do not generate mods for tpls in this array */ generateModsBlacklist?: string[]; + generatingPlayerLevel: number; } diff --git a/types/models/spt/bots/IGenerateWeaponRequest.d.ts b/types/models/spt/bots/IGenerateWeaponRequest.d.ts index 4bc8adf8..3be9412c 100644 --- a/types/models/spt/bots/IGenerateWeaponRequest.d.ts +++ b/types/models/spt/bots/IGenerateWeaponRequest.d.ts @@ -1,18 +1,18 @@ -import { Mods, ModsChances } from "@spt/models/eft/common/tables/IBotType"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IMods, IModsChances } from "@spt/models/eft/common/tables/IBotType"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { BotModLimits } from "@spt/services/BotWeaponModLimitService"; export interface IGenerateWeaponRequest { /** Weapon to add mods to / result that is returned */ - weapon: Item[]; + weapon: IItem[]; /** Pool of compatible mods to attach to weapon */ - modPool: Mods; + modPool: IMods; /** ParentId of weapon */ weaponId: string; /** Weapon which mods will be generated on */ parentTemplate: ITemplateItem; /** Chance values mod will be added */ - modSpawnChances: ModsChances; + modSpawnChances: IModsChances; /** Ammo tpl to use when generating magazines/cartridges */ ammoTpl: string; /** Bot-specific properties */ @@ -21,6 +21,8 @@ export interface IGenerateWeaponRequest { modLimits: BotModLimits; /** Info related to the weapon being generated */ weaponStats: IWeaponStats; + /** Array of item tpls the weapon does not support */ + conflictingItemTpls: Set; } export interface IBotData { /** Role of bot weapon is generated for */ diff --git a/types/models/spt/bots/IGenerateWeaponResult.d.ts b/types/models/spt/bots/IGenerateWeaponResult.d.ts new file mode 100644 index 00000000..8e1e318e --- /dev/null +++ b/types/models/spt/bots/IGenerateWeaponResult.d.ts @@ -0,0 +1,10 @@ +import { IMods } from "@spt/models/eft/common/tables/IBotType"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; +export interface IGenerateWeaponResult { + weapon: IItem[]; + chosenAmmoTpl: string; + chosenUbglAmmoTpl: string; + weaponMods: IMods; + weaponTemplate: ITemplateItem; +} diff --git a/types/models/spt/bots/IModToSpawnRequest.d.ts b/types/models/spt/bots/IModToSpawnRequest.d.ts index 58e9a1d4..c004664f 100644 --- a/types/models/spt/bots/IModToSpawnRequest.d.ts +++ b/types/models/spt/bots/IModToSpawnRequest.d.ts @@ -1,21 +1,22 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { ModSpawn } from "@spt/models/enums/ModSpawn"; -import { IWeaponStats } from "@spt/models/spt/bots/IGenerateWeaponRequest"; -import { EquipmentFilterDetails } from "@spt/models/spt/config/IBotConfig"; +import { IBotData, IWeaponStats } from "@spt/models/spt/bots/IGenerateWeaponRequest"; +import { IEquipmentFilterDetails, IRandomisationDetails } from "@spt/models/spt/config/IBotConfig"; export interface IModToSpawnRequest { /** Slot mod will fit into */ modSlot: string; /** Will generate a randomised mod pool if true */ isRandomisableSlot: boolean; + randomisationSettings: IRandomisationDetails; /** Parent slot the item will be a part of */ botWeaponSightWhitelist: Record; /** Blacklist to prevent mods from being picked */ - botEquipBlacklist: EquipmentFilterDetails; + botEquipBlacklist: IEquipmentFilterDetails; /** Pool of items to pick from */ itemModPool: Record; /** Array with only weapon tpl in it, ready for mods to be added */ - weapon: Item[]; + weapon: IItem[]; /** Ammo tpl to use if slot requires a cartridge to be added (e.g. mod_magazine) */ ammoTpl: string; /** Parent item the mod will go into */ @@ -24,4 +25,7 @@ export interface IModToSpawnRequest { modSpawnResult: ModSpawn; /** Weapon stats for weapon being generated */ weaponStats: IWeaponStats; + /** Array of item tpls the weapon does not support */ + conflictingItemTpls: Set; + botData: IBotData; } diff --git a/types/models/spt/callbacks/IDataCallbacks.d.ts b/types/models/spt/callbacks/IDataCallbacks.d.ts deleted file mode 100644 index cd0adabf..00000000 --- a/types/models/spt/callbacks/IDataCallbacks.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; -import { IGlobals } from "@spt/models/eft/common/IGlobals"; -import { IHideoutArea } from "@spt/models/eft/hideout/IHideoutArea"; -import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction"; -import { IHideoutScavCase } from "@spt/models/eft/hideout/IHideoutScavCase"; -import { IHideoutSettingsBase } from "@spt/models/eft/hideout/IHideoutSettingsBase"; -import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; -import { ISettingsBase } from "@spt/models/spt/server/ISettingsBase"; -export interface IDataCallbacks { - getSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getGlobals(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getTemplateItems(url: string, info: IEmptyRequestData, sessionID: string): string; - getTemplateHandbook(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getTemplateSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getTemplateCharacter(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getHideoutSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getHideoutAreas(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gethideoutProduction(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getHideoutScavcase(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getLocalesLanguages(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; - getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getLocalesGlobal(url: string, info: IEmptyRequestData, sessionID: string): string; -} diff --git a/types/models/spt/callbacks/IDialogueCallbacks.d.ts b/types/models/spt/callbacks/IDialogueCallbacks.d.ts index b30c042f..2ff36dca 100644 --- a/types/models/spt/callbacks/IDialogueCallbacks.d.ts +++ b/types/models/spt/callbacks/IDialogueCallbacks.d.ts @@ -14,11 +14,11 @@ import { ISendMessageRequest } from "@spt/models/eft/dialog/ISendMessageRequest" import { ISetDialogReadRequestData } from "@spt/models/eft/dialog/ISetDialogReadRequestData"; import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; -import { DialogueInfo } from "@spt/models/eft/profile/ISptProfile"; +import { IDialogueInfo } from "@spt/models/eft/profile/ISptProfile"; export interface IDialogueCallbacks { getFriendList(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getChatServerList(url: string, info: IGetChatServerListRequestData, sessionID: string): IGetBodyResponseData; - getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; + getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData; getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData; diff --git a/types/models/spt/callbacks/IInraidCallbacks.d.ts b/types/models/spt/callbacks/IInraidCallbacks.d.ts deleted file mode 100644 index b2679427..00000000 --- a/types/models/spt/callbacks/IInraidCallbacks.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData"; -import { INullResponseData } from "@spt/models/eft/httpResponse/INullResponseData"; -import { IRegisterPlayerRequestData } from "@spt/models/eft/inRaid/IRegisterPlayerRequestData"; -import { ISaveProgressRequestData } from "@spt/models/eft/inRaid/ISaveProgressRequestData"; -import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; -export interface IInraidCallbacks { - onLoad(sessionID: string): ISptProfile; - registerPlayer(url: string, info: IRegisterPlayerRequestData, sessionID: string): INullResponseData; - saveProgress(url: string, info: ISaveProgressRequestData, sessionID: string): INullResponseData; - getRaidEndState(): string; - getRaidMenuSettings(url: string, info: IEmptyRequestData, sessionID: string): string; - getWeaponDurability(url: string, info: any, sessionID: string): string; - getAirdropConfig(url: string, info: any, sessionID: string): string; -} diff --git a/types/models/spt/callbacks/IWishlistCallbacks.d.ts b/types/models/spt/callbacks/IWishlistCallbacks.d.ts deleted file mode 100644 index 16f056d0..00000000 --- a/types/models/spt/callbacks/IWishlistCallbacks.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IWishlistActionData } from "@spt/models/eft/wishlist/IWishlistActionData"; -export interface IWishlistCallbacks { - addToWishlist(pmcData: IPmcData, body: IWishlistActionData, sessionID: string): IItemEventRouterResponse; - removeFromWishlist(pmcData: IPmcData, body: IWishlistActionData, sessionID: string): IItemEventRouterResponse; -} diff --git a/types/models/spt/config/IAirdropConfig.d.ts b/types/models/spt/config/IAirdropConfig.d.ts index d438f006..ceca3cc6 100644 --- a/types/models/spt/config/IAirdropConfig.d.ts +++ b/types/models/spt/config/IAirdropConfig.d.ts @@ -1,31 +1,15 @@ import { MinMax } from "@spt/models/common/MinMax"; -import { AirdropTypeEnum } from "@spt/models/enums/AirdropType"; +import { AirdropTypeEnum, SptAirdropTypeEnum } from "@spt/models/enums/AirdropType"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IAirdropConfig extends IBaseConfig { kind: "spt-airdrop"; - airdropChancePercent: AirdropChancePercent; - airdropTypeWeightings: Record; - /** Lowest point plane will fly at */ - planeMinFlyHeight: number; - /** Highest point plane will fly at */ - planeMaxFlyHeight: number; - /** Loudness of plane engine */ - planeVolume: number; - /** Speed plane flies overhead */ - planeSpeed: number; - /** Speed loot crate falls after being dropped */ - crateFallSpeed: number; - /** Container tpls to use when spawning crate - affects container size, keyed by drop type e.g. mixed/weaponArmor/foodMedical/barter */ - containerIds: Record; - /** Earliest time aircraft will spawn in raid */ - airdropMinStartTimeSeconds: number; - /** Latest time aircraft will spawn in raid */ - airdropMaxStartTimeSeconds: number; + airdropTypeWeightings: Record; /** What rewards will the loot crate contain, keyed by drop type e.g. mixed/weaponArmor/foodMedical/barter */ - loot: Record; + loot: Record; + customAirdropMapping: Record; } /** Chance map will have an airdrop occur out of 100 - locations not included count as 0% */ -export interface AirdropChancePercent { +export interface IAirdropChancePercent { bigmap: number; woods: number; lighthouse: number; @@ -36,7 +20,8 @@ export interface AirdropChancePercent { sandbox: number; } /** Loot inside crate */ -export interface AirdropLoot { +export interface IAirdropLoot { + icon: AirdropTypeEnum; /** Min/max of weapons inside crate */ weaponPresetCount?: MinMax; /** Min/max of armors (head/chest/rig) inside crate */ @@ -57,4 +42,6 @@ export interface AirdropLoot { armorLevelWhitelist?: number[]; /** Should boss items be added to airdrop crate */ allowBossItems: boolean; + useForcedLoot?: boolean; + forcedLoot?: Record; } diff --git a/types/models/spt/config/IBTRConfig.d.ts b/types/models/spt/config/IBTRConfig.d.ts deleted file mode 100644 index 2f56f73e..00000000 --- a/types/models/spt/config/IBTRConfig.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { MinMax } from "@spt/models/common/MinMax"; -import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; -export interface IBTRConfig extends IBaseConfig { - kind: "spt-btr"; - /** How fast the BTR moves */ - moveSpeed: number; - /** How long the cover fire service lasts for */ - coverFireTime: number; - /** How long the BTR waits at every point in its path */ - pointWaitTime: MinMax; - /** How long after purchasing the taxi service before the BTR leaves */ - taxiWaitTime: number; -} diff --git a/types/models/spt/config/IBotConfig.d.ts b/types/models/spt/config/IBotConfig.d.ts index b8c782af..92f7b34e 100644 --- a/types/models/spt/config/IBotConfig.d.ts +++ b/types/models/spt/config/IBotConfig.d.ts @@ -1,11 +1,11 @@ import { MinMax } from "@spt/models/common/MinMax"; -import { GenerationData } from "@spt/models/eft/common/tables/IBotType"; +import { IGenerationData } from "@spt/models/eft/common/tables/IBotType"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; import { IBotDurability } from "@spt/models/spt/config/IBotDurability"; export interface IBotConfig extends IBaseConfig { kind: "spt-bot"; /** How many variants of each bot should be generated on raid start */ - presetBatch: PresetBatch; + presetBatch: IPresetBatch; /** Bot roles that should not have PMC types (pmcBEAR/pmcUSEC) added as enemies to */ botsToNotAddPMCsAsEnemiesTo: string[]; /** What bot types should be classified as bosses */ @@ -44,6 +44,10 @@ export interface IBotConfig extends IBaseConfig { /** What bottypes should be excluded from having loot generated on them (backpack/pocket/vest) does not disable food/drink/special/ */ disableLootOnBotTypes: string[]; assaultToBossConversion: IAssaultToBossConversion; + /** Max length a bots name can be */ + botNameLengthLimit: number; + /** Bot roles that must have a unique name when generated vs other bots in raid */ + botRolesThatMustHaveUniqueName: string[]; } export interface IAssaultToBossConversion { bossConvertEnabled: boolean; @@ -51,7 +55,7 @@ export interface IAssaultToBossConversion { bossConvertMinMax: Record; } /** Number of bots to generate and store in cache on raid start per bot type */ -export interface PresetBatch { +export interface IPresetBatch { assault: number; bossBully: number; bossGluhar: number; @@ -100,7 +104,7 @@ export interface IWalletLootSettings { } export interface EquipmentFilters { /** Limits for mod types per weapon .e.g. scopes */ - weaponModLimits: ModLimits; + weaponModLimits: IModLimits; /** Whitelist for weapon sight types allowed per gun */ weaponSightWhitelist: Record; /** Chance face shield is down/active */ @@ -121,29 +125,30 @@ export interface EquipmentFilters { /** What additional slot ids should be seen as required when choosing a mod to add to a weapon */ weaponSlotIdsToMakeRequired?: string[]; /** Adjust weighting/chances of items on bot by level of bot */ - randomisation: RandomisationDetails[]; + randomisation: IRandomisationDetails[]; /** Blacklist equipment by level of bot */ - blacklist: EquipmentFilterDetails[]; + blacklist: IEquipmentFilterDetails[]; /** Whitelist equipment by level of bot */ - whitelist: EquipmentFilterDetails[]; + whitelist: IEquipmentFilterDetails[]; /** Adjust equipment/ammo */ - weightingAdjustmentsByBotLevel: WeightingAdjustmentDetails[]; + weightingAdjustmentsByBotLevel: IWeightingAdjustmentDetails[]; /** Same as weightingAdjustments but based on player level instead of bot level */ - weightingAdjustmentsByPlayerLevel?: WeightingAdjustmentDetails[]; + weightingAdjustmentsByPlayerLevel?: IWeightingAdjustmentDetails[]; /** Should the stock mod be forced to spawn on bot */ forceStock?: boolean; armorPlateWeighting?: IArmorPlateWeights[]; + forceRigWhenNoVest?: boolean; } -export interface ModLimits { +export interface IModLimits { /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */ scopeLimit?: number; /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */ lightLaserLimit?: number; } -export interface RandomisationDetails { +export interface IRandomisationDetails { /** Between what levels do these randomisation setting apply to */ levelRange: MinMax; - generation?: Record; + generation?: Record; /** Mod slots that should be fully randomised -ignores mods from bottype.json and instaed creates a pool using items.json */ randomisedWeaponModSlots?: string[]; /** Armor slots that should be randomised e.g. 'Headwear, Armband' */ @@ -154,16 +159,25 @@ export interface RandomisationDetails { weaponMods?: Record; /** Equipment mod chances */ equipmentMods?: Record; + nighttimeChanges?: INighttimeChanges; + /** Key = weapon tpl, value = min size of magaizne allowed */ + minimumMagazineSize?: Record; } -export interface EquipmentFilterDetails { +export interface INighttimeChanges { + /** Applies changes to values stored in equipmentMods */ + equipmentModsModifiers: Record; +} +export interface IEquipmentFilterDetails { /** Between what levels do these equipment filter setting apply to */ levelRange: MinMax; /** Key: mod slot name e.g. mod_magazine, value: item tpls */ - equipment: Record; + equipment?: Record; + /** Key: equipment slot name e.g. FirstPrimaryWeapon, value: item tpls */ + gear?: Record; /** Key: cartridge type e.g. Caliber23x75, value: item tpls */ - cartridge: Record; + cartridge?: Record; } -export interface WeightingAdjustmentDetails { +export interface IWeightingAdjustmentDetails { /** Between what levels do these weight settings apply to */ levelRange: MinMax; /** Key: ammo type e.g. Caliber556x45NATO, value: item tpl + weight */ diff --git a/types/models/spt/config/IBotDurability.d.ts b/types/models/spt/config/IBotDurability.d.ts index 728db97d..b7103e18 100644 --- a/types/models/spt/config/IBotDurability.d.ts +++ b/types/models/spt/config/IBotDurability.d.ts @@ -1,45 +1,45 @@ export interface IBotDurability { - default: DefaultDurability; - pmc: PmcDurability; - boss: BotDurability; - follower: BotDurability; - assault: BotDurability; - cursedassault: BotDurability; - marksman: BotDurability; - pmcbot: BotDurability; - arenafighterevent: BotDurability; - arenafighter: BotDurability; - crazyassaultevent: BotDurability; - exusec: BotDurability; - gifter: BotDurability; - sectantpriest: BotDurability; - sectantwarrior: BotDurability; + default: IDefaultDurability; + pmc: IPmcDurability; + boss: IBotDurability; + follower: IBotDurability; + assault: IBotDurability; + cursedassault: IBotDurability; + marksman: IBotDurability; + pmcbot: IBotDurability; + arenafighterevent: IBotDurability; + arenafighter: IBotDurability; + crazyassaultevent: IBotDurability; + exusec: IBotDurability; + gifter: IBotDurability; + sectantpriest: IBotDurability; + sectantwarrior: IBotDurability; } /** Durability values to be used when a more specific bot type cant be found */ -export interface DefaultDurability { - armor: ArmorDurability; - weapon: WeaponDurability; +export interface IDefaultDurability { + armor: IArmorDurability; + weapon: IWeaponDurability; } -export interface PmcDurability { - armor: PmcDurabilityArmor; - weapon: WeaponDurability; +export interface IPmcDurability { + armor: IPmcDurabilityArmor; + weapon: IWeaponDurability; } -export interface PmcDurabilityArmor { +export interface IPmcDurabilityArmor { lowestMaxPercent: number; highestMaxPercent: number; maxDelta: number; minDelta: number; } -export interface BotDurability { - armor: ArmorDurability; - weapon: WeaponDurability; +export interface IBotDurability { + armor: IArmorDurability; + weapon: IWeaponDurability; } -export interface ArmorDurability { +export interface IArmorDurability { maxDelta: number; minDelta: number; minLimitPercent: number; } -export interface WeaponDurability { +export interface IWeaponDurability { lowestMax: number; highestMax: number; maxDelta: number; diff --git a/types/models/spt/config/ICoreConfig.d.ts b/types/models/spt/config/ICoreConfig.d.ts index 6d086f7f..aedba0cb 100644 --- a/types/models/spt/config/ICoreConfig.d.ts +++ b/types/models/spt/config/ICoreConfig.d.ts @@ -1,3 +1,4 @@ +import { ISurveyResponseData } from "@spt/models/eft/game/ISurveyResponseData"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface ICoreConfig extends IBaseConfig { kind: "spt-core"; @@ -11,6 +12,7 @@ export interface ICoreConfig extends IBaseConfig { bsgLogging: IBsgLogging; release: IRelease; fixes: IGameFixes; + survey: ISurveyResponseData; features: IServerFeatures; /** Commit hash build server was created from */ commit?: string; @@ -55,6 +57,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; + /** Remove invalid traders from profile - trader data can be leftover when player removes trader mod */ + removeInvalidTradersFromProfile: boolean; /** Fix issues that cause the game to not start due to inventory item issues */ fixProfileBreakingInventoryItemIssues: boolean; } @@ -67,9 +71,11 @@ export interface IServerFeatures { } export interface IChatbotFeatures { sptFriendEnabled: boolean; + sptFriendGiftsEnabled: boolean; commandoEnabled: boolean; commandoFeatures: ICommandoFeatures; commandUseLimits: Record; + ids: Record; } export interface ICommandoFeatures { giveCommandEnabled: boolean; diff --git a/types/models/spt/config/IGiftsConfig.d.ts b/types/models/spt/config/IGiftsConfig.d.ts index 736c4b76..4a9450e6 100644 --- a/types/models/spt/config/IGiftsConfig.d.ts +++ b/types/models/spt/config/IGiftsConfig.d.ts @@ -1,4 +1,4 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; import { GiftSenderType } from "@spt/models/enums/GiftSenderType"; import { SeasonalEventType } from "@spt/models/enums/SeasonalEventType"; @@ -7,11 +7,11 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; import { IProfileChangeEvent } from "@spt/models/spt/dialog/ISendMessageDetails"; export interface IGiftsConfig extends IBaseConfig { kind: "spt-gifts"; - gifts: Record; + gifts: Record; } -export interface Gift { +export interface IGift { /** Items to send to player */ - items: Item[]; + items: IItem[]; /** Who is sending the gift to player */ sender: GiftSenderType; /** Optinal - supply a users id to send from, not necessary when sending from SYSTEM or TRADER */ diff --git a/types/models/spt/config/IHealthConfig.d.ts b/types/models/spt/config/IHealthConfig.d.ts index b86c208c..f7521ca5 100644 --- a/types/models/spt/config/IHealthConfig.d.ts +++ b/types/models/spt/config/IHealthConfig.d.ts @@ -1,14 +1,14 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IHealthConfig extends IBaseConfig { kind: "spt-health"; - healthMultipliers: HealthMultipliers; - save: Save; + healthMultipliers: IHealthMultipliers; + save: ISave; } -export interface HealthMultipliers { +export interface IHealthMultipliers { death: number; blacked: number; } -export interface Save { +export interface ISave { health: boolean; effects: boolean; } diff --git a/types/models/spt/config/IHideoutConfig.d.ts b/types/models/spt/config/IHideoutConfig.d.ts index c1967c0e..52577772 100644 --- a/types/models/spt/config/IHideoutConfig.d.ts +++ b/types/models/spt/config/IHideoutConfig.d.ts @@ -1,3 +1,4 @@ +import { MinMax } from "@spt/models/common/MinMax"; import { IBaseConfig, IRunIntervalValues } from "@spt/models/spt/config/IBaseConfig"; export interface IHideoutConfig extends IBaseConfig { kind: "spt-hideout"; @@ -11,4 +12,28 @@ export interface IHideoutConfig extends IBaseConfig { overrideBuildTimeSeconds: number; /** Only process a profiles hideout crafts when it has been active in the last x minutes */ updateProfileHideoutWhenActiveWithinMinutes: number; + cultistCircle: ICultistCircleSettings; +} +export interface ICultistCircleSettings { + maxRewardItemCount: number; + maxAttemptsToPickRewardsWithinBudget: number; + rewardPriceMultiplerMinMax: MinMax; + craftTimeThreshholds: ICraftTimeThreshhold[]; + /** -1 means no override */ + craftTimeOverride: number; + /** Specific reward pool when player sacrificed one specific item */ + directRewards: Record; + directRewardStackSize: Record; + /** Item tpls to exclude from the reward pool */ + rewardItemBlacklist: string[]; + /** Item tpls to include in the reward pool */ + additionalRewardItemPool: string[]; + currencyRewards: Record; +} +export interface ICraftTimeThreshhold extends MinMax { + craftTimeSeconds: number; +} +export interface IDirectRewardSettings { + rewardTpls: string[]; + craftTimeSeconds: number; } diff --git a/types/models/spt/config/IInRaidConfig.d.ts b/types/models/spt/config/IInRaidConfig.d.ts index 7d6befdf..d70f6380 100644 --- a/types/models/spt/config/IInRaidConfig.d.ts +++ b/types/models/spt/config/IInRaidConfig.d.ts @@ -1,11 +1,10 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IInRaidConfig extends IBaseConfig { kind: "spt-inraid"; - MIAOnRaidEnd: boolean; /** Overrides to apply to the pre-raid settings screen */ - raidMenuSettings: RaidMenuSettings; + raidMenuSettings: IRaidMenuSettings; /** What effects should be saved post-raid */ - save: Save; + save: ISave; /** Names of car extracts */ carExtracts: string[]; /** Names of coop extracts */ @@ -15,15 +14,17 @@ export interface IInRaidConfig extends IBaseConfig { /** Fence rep gain from a single coop extract */ coopExtractBaseStandingGain: number; /** Fence rep gain when successfully extracting as pscav */ - scavExtractGain: number; + scavExtractStandingGain: number; /** The likelihood of PMC eliminating a minimum of 2 scavs while you engage them as a pscav. */ pmcKillProbabilityForScavGain: number; /** On death should items in your secure keep their Find in raid status regardless of how you finished the raid */ keepFiRSecureContainerOnDeath: boolean; + /** If enabled always keep found in raid status on items */ + alwaysKeepFoundInRaidonRaidEnd: boolean; /** Percentage chance a player scav hot is hostile to the player when scavving */ playerScavHostileChancePercent: number; } -export interface RaidMenuSettings { +export interface IRaidMenuSettings { aiAmount: string; aiDifficulty: string; bossEnabled: boolean; @@ -33,7 +34,7 @@ export interface RaidMenuSettings { randomWeather: boolean; randomTime: boolean; } -export interface Save { +export interface ISave { /** Should loot gained from raid be saved */ loot: boolean; } diff --git a/types/models/spt/config/IInsuranceConfig.d.ts b/types/models/spt/config/IInsuranceConfig.d.ts index 2bbd7b30..fd15e947 100644 --- a/types/models/spt/config/IInsuranceConfig.d.ts +++ b/types/models/spt/config/IInsuranceConfig.d.ts @@ -7,10 +7,13 @@ export interface IInsuranceConfig extends IBaseConfig { blacklistedEquipment: string[]; /** Some slots should always be removed, e.g. 'cartridges' */ slotIdsToAlwaysRemove: string[]; - /** Override to control how quickly insurance is processed/returned in second */ + /** Override to control how quickly insurance is processed/returned in seconds */ returnTimeOverrideSeconds: number; + /** Override to control how long insurance returns stay in mail before expiring - in seconds */ + storageTimeOverrideSeconds: number; /** How often server should process insurance in seconds */ runIntervalSeconds: number; minAttachmentRoublePriceToBeTaken: number; chanceNoAttachmentsTakenPercent: number; + simulateItemsBeingTaken: boolean; } diff --git a/types/models/spt/config/IInventoryConfig.d.ts b/types/models/spt/config/IInventoryConfig.d.ts index b4893932..af0ec79c 100644 --- a/types/models/spt/config/IInventoryConfig.d.ts +++ b/types/models/spt/config/IInventoryConfig.d.ts @@ -4,18 +4,18 @@ export interface IInventoryConfig extends IBaseConfig { kind: "spt-inventory"; /** Should new items purchased by flagged as found in raid */ newItemsMarkedFound: boolean; - randomLootContainers: Record; + randomLootContainers: Record; sealedAirdropContainer: ISealedAirdropContainerSettings; /** Contains item tpls that the server should consider money and treat the same as roubles/euros/dollars */ customMoneyTpls: string[]; /** Multipliers for skill gain when inside menus, NOT in-game */ skillGainMultiplers: Record; } -export interface RewardDetails { +export interface IRewardDetails { rewardCount: number; foundInRaid: boolean; rewardTplPool?: Record; - rewardTypePool?: Record; + rewardTypePool?: string[]; } export interface ISealedAirdropContainerSettings { weaponRewardWeight: Record; diff --git a/types/models/spt/config/IItemConfig.d.ts b/types/models/spt/config/IItemConfig.d.ts index b9dfaea7..a8833bf0 100644 --- a/types/models/spt/config/IItemConfig.d.ts +++ b/types/models/spt/config/IItemConfig.d.ts @@ -9,5 +9,11 @@ export interface IItemConfig extends IBaseConfig { rewardItemBlacklist: string[]; /** Items that can only be found on bosses */ bossItems: string[]; - handbookPriceOverride: Record; + handbookPriceOverride: Record; +} +export interface IHandbookPriceOverride { + /** Price in roubles */ + price: number; + /** NOT parentId from items.json, but handbook.json */ + parentId: string; } diff --git a/types/models/spt/config/ILocationConfig.d.ts b/types/models/spt/config/ILocationConfig.d.ts index 1e113b28..cbccd204 100644 --- a/types/models/spt/config/ILocationConfig.d.ts +++ b/types/models/spt/config/ILocationConfig.d.ts @@ -1,18 +1,16 @@ import { MinMax } from "@spt/models/common/MinMax"; -import { BossLocationSpawn, Wave } from "@spt/models/eft/common/ILocationBase"; +import { IBossLocationSpawn, IWave } from "@spt/models/eft/common/ILocationBase"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface ILocationConfig extends IBaseConfig { kind: "spt-location"; - /** Waves with a min/max of the same value don't spawn any bots, bsg only spawn the difference between min and max */ - fixEmptyBotWavesSettings: IFixEmptyBotWavesSettings; /** Rogues are classified as bosses and spawn immediatly, this can result in no scavs spawning, delay rogues spawning to allow scavs to spawn first */ rogueLighthouseSpawnTimeSettings: IRogueLighthouseSpawnTimeSettings; /** When a map has hit max alive bots, any wave that should spawn will be reduced to 1 bot in size and placed in a spawn queue, this splits waves into smaller sizes to reduce the impact of this behaviour */ splitWaveIntoSingleSpawnsSettings: ISplitWaveSettings; - looseLootMultiplier: LootMultiplier; - staticLootMultiplier: LootMultiplier; + looseLootMultiplier: ILootMultiplier; + staticLootMultiplier: ILootMultiplier; /** Custom bot waves to add to a locations base json on game start if addCustomBotWavesToMaps is true */ - customWaves: CustomWaves; + customWaves: ICustomWaves; /** Open zones to add to map */ openZones: Record; /** Key = map id, value = item tpls that should only have one forced loot spawn position */ @@ -44,8 +42,14 @@ export interface ILocationConfig extends IBaseConfig { scavRaidTimeSettings: IScavRaidTimeSettings; /** Settings to adjust mods for lootable equipment in raid */ equipmentLootSettings: IEquipmentLootSettings; - /** Sets the max Patrol Value of the Boxzone on the map Ground Zero */ - sandboxMaxPatrolvalue: number; + /** min percentage to set raider spawns at, -1 makes no changes */ + reserveRaiderSpawnChanceOverrides: IReserveRaiderSpawnChanceOverrides; + /** Map ids players cannot visit */ + nonMaps: string[]; +} +export interface IReserveRaiderSpawnChanceOverrides { + nonTriggered: number; + triggered: number; } export interface IEquipmentLootSettings { modSpawnChancePercent: Record; @@ -63,16 +67,16 @@ export interface ISplitWaveSettings { ignoreMaps: string[]; waveSizeThreshold: number; } -export interface CustomWaves { +export interface ICustomWaves { /** Bosses spawn on raid start */ - boss: Record; - normal: Record; + boss: Record; + normal: Record; } export interface IBotTypeLimit extends MinMax { type: string; } /** Multiplier to apply to the loot count for a given map */ -export interface LootMultiplier { +export interface ILootMultiplier { bigmap: number; develop: number; factory4_day: number; diff --git a/types/models/spt/config/ILootConfig.d.ts b/types/models/spt/config/ILootConfig.d.ts index e22c3ea8..4e73ea0e 100644 --- a/types/models/spt/config/ILootConfig.d.ts +++ b/types/models/spt/config/ILootConfig.d.ts @@ -1,9 +1,9 @@ -import { Spawnpoint } from "@spt/models/eft/common/ILooseLoot"; +import { ISpawnpoint } from "@spt/models/eft/common/ILooseLoot"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface ILootConfig extends IBaseConfig { kind: "spt-loot"; /** Spawn positions to add into a map, key=mapid */ - looseLoot: Record; + looseLoot: Record; /** Loose loot probability adjustments to apply on game start */ looseLootSpawnPointAdjustments: Record>; } diff --git a/types/models/spt/config/ILostOnDeathConfig.d.ts b/types/models/spt/config/ILostOnDeathConfig.d.ts index 85746460..71408ce4 100644 --- a/types/models/spt/config/ILostOnDeathConfig.d.ts +++ b/types/models/spt/config/ILostOnDeathConfig.d.ts @@ -2,13 +2,13 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface ILostOnDeathConfig extends IBaseConfig { kind: "spt-lostondeath"; /** What equipment in each slot should be lost on death */ - equipment: Equipment; + equipment: ILostEquipment; /** Should special slot items be removed from quest inventory on death e.g. wifi camera/markers */ specialSlotItems: boolean; /** Should quest items be removed from quest inventory on death */ questItems: boolean; } -export interface Equipment { +export interface ILostEquipment { ArmBand: boolean; Headwear: boolean; Earpiece: boolean; diff --git a/types/models/spt/config/IPlayerScavConfig.d.ts b/types/models/spt/config/IPlayerScavConfig.d.ts index 8834768f..f684f45c 100644 --- a/types/models/spt/config/IPlayerScavConfig.d.ts +++ b/types/models/spt/config/IPlayerScavConfig.d.ts @@ -1,25 +1,25 @@ -import { GenerationData } from "@spt/models/eft/common/tables/IBotType"; +import { IGenerationData } from "@spt/models/eft/common/tables/IBotType"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IPlayerScavConfig extends IBaseConfig { kind: "spt-playerscav"; - karmaLevel: Record; + karmaLevel: Record; } -export interface KarmaLevel { +export interface IKarmaLevel { botTypeForLoot: string; - modifiers: Modifiers; + modifiers: IModifiers; itemLimits: ItemLimits; equipmentBlacklist: Record; lootItemsToAddChancePercent: Record; } -export interface Modifiers { +export interface IModifiers { equipment: Record; mod: Record; } export interface ItemLimits { - healing: GenerationData; - drugs: GenerationData; - stims: GenerationData; - looseLoot: GenerationData; - magazines: GenerationData; - grenades: GenerationData; + healing: IGenerationData; + drugs: IGenerationData; + stims: IGenerationData; + looseLoot: IGenerationData; + magazines: IGenerationData; + grenades: IGenerationData; } diff --git a/types/models/spt/config/IPmcConfig.d.ts b/types/models/spt/config/IPmcConfig.d.ts index 00fabb35..2e682190 100644 --- a/types/models/spt/config/IPmcConfig.d.ts +++ b/types/models/spt/config/IPmcConfig.d.ts @@ -1,4 +1,5 @@ import { MinMax } from "@spt/models/common/MinMax"; +import { IChancedEnemy } from "@spt/models/eft/common/ILocationBase"; import { MemberCategory } from "@spt/models/enums/MemberCategory"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IPmcConfig extends IBaseConfig { @@ -8,11 +9,11 @@ export interface IPmcConfig extends IBaseConfig { /** What account type should the PMC have */ accountTypeWeight: Record; /** Global whitelist/blacklist of vest loot for PMCs */ - vestLoot: SlotLootSettings; + vestLoot: ISlotLootSettings; /** Global whitelist/blacklist of pocket loot for PMCs */ - pocketLoot: SlotLootSettings; + pocketLoot: ISlotLootSettings; /** Global whitelist/blacklist of backpack loot for PMCs */ - backpackLoot: SlotLootSettings; + backpackLoot: ISlotLootSettings; /** Use difficulty defined in config/bot.json/difficulty instead of chosen difficulty dropdown value */ useDifficultyOverride: boolean; /** Difficulty override e.g. "AsOnline/Hard" */ @@ -29,32 +30,45 @@ export interface IPmcConfig extends IBaseConfig { usecType: string; /** WildSpawnType enum value BEAR PMCs use */ bearType: string; - chanceSameSideIsHostilePercent: number; /** What 'brain' does a PMC use, keyed by map and side (USEC/BEAR) key: map location, value: type for usec/bear */ pmcType: Record>>; - maxBackpackLootTotalRub: number; + maxBackpackLootTotalRub: IMinMaxLootValue[]; maxPocketLootTotalRub: number; maxVestLootTotalRub: number; - /** Percentage chance a bot from a wave is converted into a PMC, key = bot wildspawn tpye (assault/exusec), value: min+max chance to be converted */ - convertIntoPmcChance: Record; - /** WildSpawnType bots PMCs should see as hostile */ - enemyTypes: string[]; + /** Percentage chance a bot from a wave is converted into a PMC, first key = map, second key = bot wildspawn type (assault/exusec), value: min+max chance to be converted */ + convertIntoPmcChance: Record>; /** How many levels above player level can a PMC be */ botRelativeLevelDeltaMax: number; /** How many levels below player level can a PMC be */ botRelativeLevelDeltaMin: number; /** Force a number of healing items into PMCs secure container to ensure they can heal */ forceHealingItemsIntoSecure: boolean; + hostilitySettings: Record; allPMCsHavePlayerNameWithRandomPrefixChance: number; locationSpecificPmcLevelOverride: Record; /** Should secure container loot from usec.json/bear.json be added to pmc bots secure */ addSecureContainerLootFromBotConfig: boolean; } -export interface PmcTypes { +export interface IHostilitySettings { + /** Bot roles that are 100% an enemy */ + additionalEnemyTypes?: string[]; + /** Objects that determine the % chance another bot type is an enemy */ + chancedEnemies?: IChancedEnemy[]; + bearEnemyChance?: number; + usecEnemyChance?: number; + savageEnemyChance?: number; + /** Bot roles that are 100% an friendly */ + additionalFriendlyTypes?: string[]; + savagePlayerBehaviour?: string; +} +export interface IPmcTypes { usec: string; bear: string; } -export interface SlotLootSettings { +export interface ISlotLootSettings { whitelist: string[]; blacklist: string[]; } +export interface IMinMaxLootValue extends MinMax { + value: number; +} diff --git a/types/models/spt/config/IQuestConfig.d.ts b/types/models/spt/config/IQuestConfig.d.ts index a4257cfc..19bb3aa4 100644 --- a/types/models/spt/config/IQuestConfig.d.ts +++ b/types/models/spt/config/IQuestConfig.d.ts @@ -13,6 +13,10 @@ export interface IQuestConfig extends IBaseConfig { locationIdMap: Record; bearOnlyQuests: string[]; usecOnlyQuests: string[]; + /** Quests that the keyed game version do not see/access */ + profileBlacklist: Record; + /** key=questid, gameversions that can see/access quest */ + profileWhitelist: Record; } export interface IPlayerTypeQuestIds { pmc: IQuestTypeIds; @@ -49,6 +53,7 @@ export interface IRepeatableQuestConfig { rewardAmmoStackMinSize: number; freeChangesAvailable: number; freeChanges: number; + keepDailyQuestTypeOnReplacement: boolean; } export interface IRewardScaling { levels: number[]; diff --git a/types/models/spt/config/IRagfairConfig.d.ts b/types/models/spt/config/IRagfairConfig.d.ts index bb318de4..36122c56 100644 --- a/types/models/spt/config/IRagfairConfig.d.ts +++ b/types/models/spt/config/IRagfairConfig.d.ts @@ -7,12 +7,13 @@ export interface IRagfairConfig extends IBaseConfig { /** Default values used to hydrate `runIntervalSeconds` with */ runIntervalValues: IRunIntervalValues; /** Player listing settings */ - sell: Sell; + sell: ISell; /** Trader ids + should their assorts be listed on flea */ traders: Record; - dynamic: Dynamic; + dynamic: IDynamic; + tieredFlea: ITieredFlea; } -export interface Sell { +export interface ISell { /** Should a fee be deducted from player when liting an item for sale */ fees: boolean; /** Settings to control chances of offer being sold */ @@ -32,7 +33,7 @@ export interface Chance { /** Min possible sell chance % for a player listed offer */ minSellChancePercent: number; } -export interface Dynamic { +export interface IDynamic { purchasesAreFoundInRaid: boolean; /** Use the highest trader price for an offer if its greater than the price in templates/prices.json */ useTraderPriceForOffersIfHigher: boolean; @@ -40,7 +41,7 @@ export interface Dynamic { barter: IBarterDetails; pack: IPackDetails; /** Dynamic offer price below handbook adjustment values */ - offerAdjustment: OfferAdjustment; + offerAdjustment: IOfferAdjustment; /** How many offers should expire before an offer regeneration occurs */ expiredOfferThreshold: number; /** How many offers should be listed */ @@ -49,6 +50,8 @@ export interface Dynamic { priceRanges: IPriceRanges; /** Should default presets to listed only or should non-standard presets found in globals.json be listed too */ showDefaultPresetsOnly: boolean; + /** Tpls that should not use the variable price system when their quality is < 100% (lower dura/uses = lower price) */ + ignoreQualityPriceVarianceBlacklist: string[]; endTimeSeconds: MinMax; /** Settings to control the durability range of item items listed on flea */ condition: Condition; @@ -69,7 +72,7 @@ export interface Dynamic { /** Should christmas/halloween items be removed from flea when not within the seasonal bounds */ removeSeasonalItemsWhenNotInEvent: boolean; /** Flea blacklist settings */ - blacklist: Blacklist; + blacklist: IRagfairBlacklist; /** Dict of price limits keyed by item type */ unreasonableModPrices: Record; } @@ -89,6 +92,8 @@ export interface IBarterDetails { priceRangeVariancePercent: number; /** Min rouble price for an offer to be considered for turning into a barter */ minRoubleCostToBecomeBarter: number; + /** Should barter offers only single stack */ + makeSingleStackOnly: boolean; /** Item Tpls to never be turned into a barter */ itemTypeBlacklist: string[]; } @@ -102,7 +107,7 @@ export interface IPackDetails { /** item types to allow being a pack */ itemTypeWhitelist: string[]; } -export interface OfferAdjustment { +export interface IOfferAdjustment { /** Shuld offer price be adjusted when below handbook price */ adjustPriceWhenBelowHandbookPrice: boolean; /** How big a percentage difference does price need to vary from handbook to be considered for adjustment */ @@ -118,7 +123,7 @@ export interface Condition { current: MinMax; max: MinMax; } -export interface Blacklist { +export interface IRagfairBlacklist { /** Damaged ammo packs */ damagedAmmoPacks: boolean; /** Custom blacklist for item Tpls */ @@ -156,3 +161,12 @@ export interface IArmorSettings { /** What slots are to be removed when removeRemovablePlateChance is true */ plateSlotIdToRemovePool: string[]; } +export interface ITieredFlea { + enabled: boolean; + /** key: tpl, value: playerlevel */ + unlocksTpl: Record; + /** key: item type id, value: playerlevel */ + unlocksType: Record; + ammoTiersEnabled: boolean; + ammoTplUnlocks: Record; +} diff --git a/types/models/spt/config/IRepairConfig.d.ts b/types/models/spt/config/IRepairConfig.d.ts index 12a87fa0..eca8e6c0 100644 --- a/types/models/spt/config/IRepairConfig.d.ts +++ b/types/models/spt/config/IRepairConfig.d.ts @@ -10,7 +10,7 @@ export interface IRepairConfig extends IBaseConfig { repairKitIntellectGainMultiplier: IIntellectGainValues; maxIntellectGainPerRepair: IMaxIntellectGainValues; weaponTreatment: IWeaponTreatmentRepairValues; - repairKit: RepairKit; + repairKit: IRepairKit; } export interface IIntellectGainValues { weapon: number; @@ -30,17 +30,17 @@ export interface IWeaponTreatmentRepairValues { /** The multiplier used for calculating weapon maintenance XP */ pointGainMultiplier: number; } -export interface RepairKit { - armor: BonusSettings; - weapon: BonusSettings; +export interface IRepairKit { + armor: IBonusSettings; + weapon: IBonusSettings; } -export interface BonusSettings { +export interface IBonusSettings { rarityWeight: Record; bonusTypeWeight: Record; - common: Record; - rare: Record; + common: Record; + rare: Record; } -export interface BonusValues { +export interface IBonusValues { valuesMinMax: MinMax; /** What dura is buff active between (min max of current max) */ activeDurabilityPercentMinMax: MinMax; diff --git a/types/models/spt/config/IScavCaseConfig.d.ts b/types/models/spt/config/IScavCaseConfig.d.ts index f2ff2f2b..949180ea 100644 --- a/types/models/spt/config/IScavCaseConfig.d.ts +++ b/types/models/spt/config/IScavCaseConfig.d.ts @@ -3,27 +3,27 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IScavCaseConfig extends IBaseConfig { kind: "spt-scavcase"; rewardItemValueRangeRub: Record; - moneyRewards: MoneyRewards; - ammoRewards: AmmoRewards; + moneyRewards: IMoneyRewards; + ammoRewards: IAmmoRewards; rewardItemParentBlacklist: string[]; rewardItemBlacklist: string[]; allowMultipleMoneyRewardsPerRarity: boolean; allowMultipleAmmoRewardsPerRarity: boolean; allowBossItemsAsRewards: boolean; } -export interface MoneyRewards { +export interface IMoneyRewards { moneyRewardChancePercent: number; - rubCount: MoneyLevels; - usdCount: MoneyLevels; - eurCount: MoneyLevels; - gpCount: MoneyLevels; + rubCount: IMoneyLevels; + usdCount: IMoneyLevels; + eurCount: IMoneyLevels; + gpCount: IMoneyLevels; } -export interface MoneyLevels { +export interface IMoneyLevels { common: MinMax; rare: MinMax; superrare: MinMax; } -export interface AmmoRewards { +export interface IAmmoRewards { ammoRewardChancePercent: number; ammoRewardBlacklist: Record; ammoRewardValueRangeRub: Record; diff --git a/types/models/spt/config/ISeasonalEventConfig.d.ts b/types/models/spt/config/ISeasonalEventConfig.d.ts index da7070b1..5e119faa 100644 --- a/types/models/spt/config/ISeasonalEventConfig.d.ts +++ b/types/models/spt/config/ISeasonalEventConfig.d.ts @@ -1,4 +1,4 @@ -import { BossLocationSpawn } from "@spt/models/eft/common/ILocationBase"; +import { IAdditionalHostilitySettings, IBossLocationSpawn, IWave } from "@spt/models/eft/common/ILocationBase"; import { SeasonalEventType } from "@spt/models/enums/SeasonalEventType"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface ISeasonalEventConfig extends IBaseConfig { @@ -8,18 +8,29 @@ export interface ISeasonalEventConfig extends IBaseConfig { eventGear: Record>>>; events: ISeasonalEvent[]; eventBotMapping: Record; - eventBossSpawns: Record>; - gifterSettings: GifterSetting[]; + eventBossSpawns: Record>; + eventWaves: Record>; + gifterSettings: IGifterSetting[]; + /** key = event, second key = map name */ + hostilitySettingsForEvent: Record>; } export interface ISeasonalEvent { + enabled: boolean; name: string; type: SeasonalEventType; startDay: number; startMonth: number; endDay: number; endMonth: number; + settings?: Record; } -export interface GifterSetting { +export interface IZombieSettings { + enabled: boolean; + mapInfectionAmount: Record; + disableBosses: string[]; + disableWaves: string[]; +} +export interface IGifterSetting { map: string; zones: string; spawnChance: number; diff --git a/types/models/spt/config/ITraderConfig.d.ts b/types/models/spt/config/ITraderConfig.d.ts index d60b496a..5d2d4a68 100644 --- a/types/models/spt/config/ITraderConfig.d.ts +++ b/types/models/spt/config/ITraderConfig.d.ts @@ -1,23 +1,24 @@ import { MinMax } from "@spt/models/common/MinMax"; import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; -import { LootRequest } from "@spt/models/spt/services/LootRequest"; +import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; - updateTime: UpdateTime[]; + updateTime: IUpdateTime[]; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; updateTimeDefault: number; traderPriceMultipler: number; - fence: FenceConfig; + fence: IFenceConfig; + moddedTraders: IModdedTraders; } -export interface UpdateTime { +export interface IUpdateTime { traderId: string; /** Seconds between trader resets */ seconds: MinMax; } -export interface FenceConfig { - discountOptions: DiscountOptions; +export interface IFenceConfig { + discountOptions: IDiscountOptions; partialRefreshTimeSeconds: number; partialRefreshChangePercent: number; assortSize: number; @@ -44,22 +45,31 @@ export interface FenceConfig { /** Max pen value allowed to be listed on flea - affects ammo + ammo boxes */ ammoMaxPenLimit: number; blacklist: string[]; - coopExtractGift: CoopExtractReward; + coopExtractGift: ICoopExtractReward; btrDeliveryExpireHours: number; + /** Smallest value player rep with fence can fall to */ + playerRepMin: number; + /** Highest value player rep with fence can climb to */ + playerRepMax: number; } export interface IItemDurabilityCurrentMax { current: MinMax; max: MinMax; } -export interface CoopExtractReward extends LootRequest { +export interface ICoopExtractReward extends ILootRequest { sendGift: boolean; messageLocaleIds: string[]; giftExpiryHours: number; } -export interface DiscountOptions { +export interface IDiscountOptions { assortSize: number; itemPriceMult: number; presetPriceMult: number; weaponPresetMinMax: MinMax; equipmentPresetMinMax: MinMax; } +/** Custom trader data needed client side for things such as the clothing service */ +export interface IModdedTraders { + /** Trader Ids to enable the clothing service for */ + clothingService: string[]; +} diff --git a/types/models/spt/config/IWeatherConfig.d.ts b/types/models/spt/config/IWeatherConfig.d.ts index 970ade54..012f26c6 100644 --- a/types/models/spt/config/IWeatherConfig.d.ts +++ b/types/models/spt/config/IWeatherConfig.d.ts @@ -5,7 +5,7 @@ import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; export interface IWeatherConfig extends IBaseConfig { kind: "spt-weather"; acceleration: number; - weather: Weather; + weather: IWeatherValues; seasonDates: ISeasonDateTimes[]; overrideSeason?: Season; } @@ -17,7 +17,9 @@ export interface ISeasonDateTimes { endDay: number; endMonth: number; } -export interface Weather { +export interface IWeatherValues { + /** How many hours to generate weather data into the future */ + generateWeatherAmountHours: number; clouds: WeatherSettings; windSpeed: WeatherSettings; windDirection: WeatherSettings; @@ -25,8 +27,14 @@ export interface Weather { rain: WeatherSettings; rainIntensity: MinMax; fog: WeatherSettings; - temp: MinMax; + temp: Record; pressure: MinMax; + /** Length of each weather period */ + timePeriod: WeatherSettings; +} +export interface ITempDayNight { + day: MinMax; + night: MinMax; } export interface WeatherSettings { values: T[]; diff --git a/types/models/spt/controllers/IBotController.d.ts b/types/models/spt/controllers/IBotController.d.ts index e5774970..329dd439 100644 --- a/types/models/spt/controllers/IBotController.d.ts +++ b/types/models/spt/controllers/IBotController.d.ts @@ -1,10 +1,10 @@ import { IGenerateBotsRequestData } from "@spt/models/eft/bot/IGenerateBotsRequestData"; import { IBotBase } from "@spt/models/eft/common/tables/IBotBase"; import { IBotCore } from "@spt/models/eft/common/tables/IBotCore"; -import { Difficulty } from "@spt/models/eft/common/tables/IBotType"; +import { IDifficultyCategories } from "@spt/models/eft/common/tables/IBotType"; export interface IBotController { getBotLimit(type: string): number; - getBotDifficulty(type: string, difficulty: string): IBotCore | Difficulty; + getBotDifficulty(type: string, difficulty: string): IBotCore | IDifficultyCategories; isBotPmc(botRole: string): boolean; isBotBoss(botRole: string): boolean; isBotFollower(botRole: string): boolean; diff --git a/types/models/spt/dialog/ISendMessageDetails.d.ts b/types/models/spt/dialog/ISendMessageDetails.d.ts index 1625f47c..8cb11f2a 100644 --- a/types/models/spt/dialog/ISendMessageDetails.d.ts +++ b/types/models/spt/dialog/ISendMessageDetails.d.ts @@ -1,5 +1,5 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { ISystemData, IUserDialogInfo, MessageContentRagfair } from "@spt/models/eft/profile/ISptProfile"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IMessageContentRagfair, ISystemData, IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; import { MessageType } from "@spt/models/enums/MessageType"; import { Traders } from "@spt/models/enums/Traders"; export interface ISendMessageDetails { @@ -16,7 +16,7 @@ export interface ISendMessageDetails { /** Optional - used in player/system messages, otherwise templateId is used */ messageText?: string; /** Optinal - Items to send to player */ - items?: Item[]; + items?: IItem[]; /** Optional - How long items will be stored in mail before expiry */ itemsMaxStorageLifetimeSeconds?: number; /** Optional - Used when sending messages from traders who send text from locale json */ @@ -24,7 +24,7 @@ export interface ISendMessageDetails { /** Optional - ragfair related */ systemData?: ISystemData; /** Optional - Used by ragfair messages */ - ragfairDetails?: MessageContentRagfair; + ragfairDetails?: IMessageContentRagfair; /** OPTIONAL - allows modification of profile settings via mail */ profileChangeEvents?: IProfileChangeEvent[]; } diff --git a/types/models/spt/fence/ICreateFenceAssortsResult.d.ts b/types/models/spt/fence/ICreateFenceAssortsResult.d.ts index 553f4e29..1af9f84d 100644 --- a/types/models/spt/fence/ICreateFenceAssortsResult.d.ts +++ b/types/models/spt/fence/ICreateFenceAssortsResult.d.ts @@ -1,7 +1,7 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; export interface ICreateFenceAssortsResult { - sptItems: Item[][]; + sptItems: IItem[][]; barter_scheme: Record; loyal_level_items: Record; } diff --git a/types/models/spt/generators/IBotGenerator.d.ts b/types/models/spt/generators/IBotGenerator.d.ts index e46ce24e..ebc954de 100644 --- a/types/models/spt/generators/IBotGenerator.d.ts +++ b/types/models/spt/generators/IBotGenerator.d.ts @@ -1,5 +1,5 @@ -import { Inventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; -import { Chances, Generation, Inventory } from "@spt/models/eft/common/tables/IBotType"; +import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase"; +import { IChances, IGeneration, IInventory } from "@spt/models/eft/common/tables/IBotType"; export interface IBotGenerator { - generateInventory(templateInventory: Inventory, equipmentChances: Chances, generation: Generation, botRole: string, isPmc: boolean): PmcInventory; + generateInventory(templateInventory: IInventory, equipmentChances: IChances, generation: IGeneration, botRole: string, isPmc: boolean): PmcInventory; } diff --git a/types/models/spt/generators/ILocationGenerator.d.ts b/types/models/spt/generators/ILocationGenerator.d.ts index 2df98e72..80905385 100644 --- a/types/models/spt/generators/ILocationGenerator.d.ts +++ b/types/models/spt/generators/ILocationGenerator.d.ts @@ -1,6 +1,6 @@ import { IStaticAmmoDetails, IStaticContainerProps, IStaticForcedProps, IStaticLootDetails } from "@spt/models/eft/common/ILocation"; -import { ILooseLoot, SpawnpointTemplate } from "@spt/models/eft/common/ILooseLoot"; +import { ILooseLoot, ISpawnpointTemplate } from "@spt/models/eft/common/ILooseLoot"; export interface ILocationGenerator { generateContainerLoot(containerIn: IStaticContainerProps, staticForced: IStaticForcedProps[], staticLootDist: Record, staticAmmoDist: Record, locationName: string): IStaticContainerProps; - generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; + generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): ISpawnpointTemplate[]; } diff --git a/types/models/spt/generators/IRagfairAssortGenerator.d.ts b/types/models/spt/generators/IRagfairAssortGenerator.d.ts index 193b6856..380387ed 100644 --- a/types/models/spt/generators/IRagfairAssortGenerator.d.ts +++ b/types/models/spt/generators/IRagfairAssortGenerator.d.ts @@ -1,4 +1,4 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IRagfairAssortGenerator { - getAssortItems(): Item[]; + getAssortItems(): IItem[]; } diff --git a/types/models/spt/generators/IRagfairOfferGenerator.d.ts b/types/models/spt/generators/IRagfairOfferGenerator.d.ts index 66d28e94..e3d3f1b2 100644 --- a/types/models/spt/generators/IRagfairOfferGenerator.d.ts +++ b/types/models/spt/generators/IRagfairOfferGenerator.d.ts @@ -1,6 +1,6 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; export interface IRagfairOfferGenerator { - createOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece: boolean): IRagfairOffer; + createOffer(userID: string, time: number, items: IItem[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece: boolean): IRagfairOffer; } diff --git a/types/models/spt/hideout/IHideout.d.ts b/types/models/spt/hideout/IHideout.d.ts index 57fed470..40f2d9ba 100644 --- a/types/models/spt/hideout/IHideout.d.ts +++ b/types/models/spt/hideout/IHideout.d.ts @@ -1,12 +1,10 @@ import { IHideoutArea } from "@spt/models/eft/hideout/IHideoutArea"; -import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction"; -import { IHideoutScavCase } from "@spt/models/eft/hideout/IHideoutScavCase"; +import { IHideoutProductionData } from "@spt/models/eft/hideout/IHideoutProduction"; import { IHideoutSettingsBase } from "@spt/models/eft/hideout/IHideoutSettingsBase"; import { IQteData } from "@spt/models/eft/hideout/IQteData"; export interface IHideout { areas: IHideoutArea[]; - production: IHideoutProduction[]; - scavcase: IHideoutScavCase[]; + production: IHideoutProductionData; settings: IHideoutSettingsBase; qte: IQteData[]; } diff --git a/types/models/spt/hideout/ScavCaseRewardCountsAndPrices.d.ts b/types/models/spt/hideout/ScavCaseRewardCountsAndPrices.d.ts index ee1893d9..3b4174f8 100644 --- a/types/models/spt/hideout/ScavCaseRewardCountsAndPrices.d.ts +++ b/types/models/spt/hideout/ScavCaseRewardCountsAndPrices.d.ts @@ -1,9 +1,9 @@ -export interface ScavCaseRewardCountsAndPrices { - Common: RewardCountAndPriceDetails; - Rare: RewardCountAndPriceDetails; - Superrare: RewardCountAndPriceDetails; +export interface IScavCaseRewardCountsAndPrices { + Common: IRewardCountAndPriceDetails; + Rare: IRewardCountAndPriceDetails; + Superrare: IRewardCountAndPriceDetails; } -export interface RewardCountAndPriceDetails { +export interface IRewardCountAndPriceDetails { minCount: number; maxCount: number; minPriceRub: number; diff --git a/types/models/spt/inventory/IOwnerInventoryItems.d.ts b/types/models/spt/inventory/IOwnerInventoryItems.d.ts index dd4efab2..95ed39ec 100644 --- a/types/models/spt/inventory/IOwnerInventoryItems.d.ts +++ b/types/models/spt/inventory/IOwnerInventoryItems.d.ts @@ -1,9 +1,9 @@ -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IOwnerInventoryItems { /** Inventory items from source */ - from: Item[]; + from: IItem[]; /** Inventory items at destination */ - to: Item[]; + to: IItem[]; sameInventory: boolean; isMail: boolean; } diff --git a/types/models/spt/mod/NewItemDetails.d.ts b/types/models/spt/mod/NewItemDetails.d.ts index 65996c1c..87de4295 100644 --- a/types/models/spt/mod/NewItemDetails.d.ts +++ b/types/models/spt/mod/NewItemDetails.d.ts @@ -1,4 +1,4 @@ -import { ITemplateItem, Props } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IProps, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; export declare abstract class NewItemDetailsBase { /** Price of the item on flea market */ fleaPriceRoubles: number; @@ -16,7 +16,7 @@ export declare class NewItemFromCloneDetails extends NewItemDetailsBase { /** Id of the item to copy and use as a base */ itemTplToClone: string; /** Item properties that should be applied over the top of the cloned base */ - overrideProperties: Props; + overrideProperties: IProps; /** ParentId for the new item (item type) */ parentId: string; /** diff --git a/types/models/spt/ragfair/ITplWithFleaPrice.d.ts b/types/models/spt/ragfair/ITplWithFleaPrice.d.ts new file mode 100644 index 00000000..4b768365 --- /dev/null +++ b/types/models/spt/ragfair/ITplWithFleaPrice.d.ts @@ -0,0 +1,5 @@ +export interface ITplWithFleaPrice { + tpl: string; + /** Roubles */ + price: number; +} diff --git a/types/models/spt/server/ISettingsBase.d.ts b/types/models/spt/server/ISettingsBase.d.ts index 2bca633e..4e98dd5f 100644 --- a/types/models/spt/server/ISettingsBase.d.ts +++ b/types/models/spt/server/ISettingsBase.d.ts @@ -1,25 +1,25 @@ export interface ISettingsBase { - config: Config; + config: IConfig; } -export interface Config { +export interface IConfig { AFKTimeoutSeconds: number; AdditionalRandomDelaySeconds: number; ClientSendRateLimit: number; CriticalRetriesCount: number; DefaultRetriesCount: number; FirstCycleDelaySeconds: number; - FramerateLimit: FramerateLimit; + FramerateLimit: IFramerateLimit; GroupStatusInterval: number; GroupStatusButtonInterval: number; KeepAliveInterval: number; LobbyKeepAliveInterval: number; Mark502and504AsNonImportant: boolean; - MemoryManagementSettings: MemoryManagementSettings; + MemoryManagementSettings: IMemoryManagementSettings; NVidiaHighlights: boolean; NextCycleDelaySeconds: number; PingServerResultSendInterval: number; PingServersInterval: number; - ReleaseProfiler: ReleaseProfiler; + ReleaseProfiler: IReleaseProfiler; RequestConfirmationTimeouts: number[]; RequestsMadeThroughLobby: string[]; SecondCycleDelaySeconds: number; @@ -30,12 +30,12 @@ export interface Config { NetworkStateView: INetworkStateView; WsReconnectionDelays: string[]; } -export interface FramerateLimit { +export interface IFramerateLimit { MaxFramerateGameLimit: number; MaxFramerateLobbyLimit: number; MinFramerateLimit: number; } -export interface MemoryManagementSettings { +export interface IMemoryManagementSettings { AggressiveGC: boolean; GigabytesRequiredToDisableGCDuringRaid: number; HeapPreAllocationEnabled: boolean; @@ -43,7 +43,7 @@ export interface MemoryManagementSettings { OverrideRamCleanerSettings: boolean; RamCleanerEnabled: boolean; } -export interface ReleaseProfiler { +export interface IReleaseProfiler { Enabled: boolean; MaxRecords: number; RecordTriggerValue: number; diff --git a/types/models/spt/services/CustomPreset.d.ts b/types/models/spt/services/CustomPreset.d.ts deleted file mode 100644 index 3301a551..00000000 --- a/types/models/spt/services/CustomPreset.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { IPreset } from "@spt/models/eft/common/IGlobals"; -export interface CustomPreset { - key: string; - preset: IPreset; -} diff --git a/types/models/spt/services/CustomTraderAssortData.d.ts b/types/models/spt/services/CustomTraderAssortData.d.ts deleted file mode 100644 index 7ad63418..00000000 --- a/types/models/spt/services/CustomTraderAssortData.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ITraderAssort } from "@spt/models/eft/common/tables/ITrader"; -import { Traders } from "@spt/models/enums/Traders"; -export interface CustomTraderAssortData { - traderId: Traders; - assorts: ITraderAssort; -} diff --git a/types/models/spt/services/IInsuranceEquipmentPkg.d.ts b/types/models/spt/services/IInsuranceEquipmentPkg.d.ts index 92d05655..93aecfa0 100644 --- a/types/models/spt/services/IInsuranceEquipmentPkg.d.ts +++ b/types/models/spt/services/IInsuranceEquipmentPkg.d.ts @@ -1,8 +1,8 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; export interface IInsuranceEquipmentPkg { sessionID: string; pmcData: IPmcData; - itemToReturnToPlayer: Item; + itemToReturnToPlayer: IItem; traderId: string; } diff --git a/types/models/spt/services/ILootRequest.d.ts b/types/models/spt/services/ILootRequest.d.ts new file mode 100644 index 00000000..22bff2f2 --- /dev/null +++ b/types/models/spt/services/ILootRequest.d.ts @@ -0,0 +1,33 @@ +import { MinMax } from "@spt/models/common/MinMax"; +import { AirdropTypeEnum } from "@spt/models/enums/AirdropType"; +export interface ILootRequest { + /** Count of weapons to generate */ + weaponPresetCount: MinMax; + /** Count of armor to generate */ + armorPresetCount: MinMax; + /** Count of items to generate */ + itemCount: MinMax; + /** Count of sealed weapon crates to generate */ + weaponCrateCount: MinMax; + /** Item tpl blacklist to exclude */ + itemBlacklist: string[]; + /** Item tpl whitelist to pick from */ + itemTypeWhitelist: string[]; + /** key: item base type: value: max count */ + itemLimits: Record; + itemStackLimits: Record; + /** Allowed armor plate levels 2/3/4/5/6 for armor generated */ + armorLevelWhitelist: number[]; + /** Should boss items be included in allowed items */ + allowBossItems: boolean; + /** Should item.json item reward blacklist be used */ + useRewardItemBlacklist?: boolean; + /** Should forced loot be used instead of randomised loot */ + useForcedLoot?: boolean; + /** Item tpls + count of items to force include */ + forcedLoot?: Record; +} +export interface IAirdropLootRequest extends ILootRequest { + /** Airdrop icon used by client to show crate type */ + icon?: AirdropTypeEnum; +} diff --git a/types/models/spt/services/LootItem.d.ts b/types/models/spt/services/LootItem.d.ts index acb7606d..2d2f2360 100644 --- a/types/models/spt/services/LootItem.d.ts +++ b/types/models/spt/services/LootItem.d.ts @@ -1,4 +1,4 @@ -export declare class LootItem { +export declare class ILootItem { id?: string; tpl: string; isPreset: boolean; diff --git a/types/models/spt/services/LootRequest.d.ts b/types/models/spt/services/LootRequest.d.ts deleted file mode 100644 index c52a8763..00000000 --- a/types/models/spt/services/LootRequest.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { MinMax } from "@spt/models/common/MinMax"; -export interface LootRequest { - weaponPresetCount: MinMax; - armorPresetCount: MinMax; - itemCount: MinMax; - weaponCrateCount: MinMax; - itemBlacklist: string[]; - itemTypeWhitelist: string[]; - /** key: item base type: value: max count */ - itemLimits: Record; - itemStackLimits: Record; - armorLevelWhitelist: number[]; - allowBossItems: boolean; - useRewarditemBlacklist?: boolean; -} diff --git a/types/models/spt/templates/ITemplates.d.ts b/types/models/spt/templates/ITemplates.d.ts index c2ebbf9f..9f9b0d5f 100644 --- a/types/models/spt/templates/ITemplates.d.ts +++ b/types/models/spt/templates/ITemplates.d.ts @@ -1,6 +1,7 @@ import { IAchievement } from "@spt/models/eft/common/tables/IAchievement"; import { ICustomizationItem } from "@spt/models/eft/common/tables/ICustomizationItem"; import { IHandbookBase } from "@spt/models/eft/common/tables/IHandbookBase"; +import { ILocationServices } from "@spt/models/eft/common/tables/ILocationServices"; import { IProfileTemplates } from "@spt/models/eft/common/tables/IProfileTemplate"; import { IQuest } from "@spt/models/eft/common/tables/IQuest"; import { IRepeatableQuestDatabase } from "@spt/models/eft/common/tables/IRepeatableQuests"; @@ -21,4 +22,6 @@ export interface ITemplates { defaultEquipmentPresets: IDefaultEquipmentPreset[]; /** Achievements */ achievements: IAchievement[]; + /** Location services data */ + locationServices: ILocationServices; } diff --git a/types/models/spt/utils/ILogger.d.ts b/types/models/spt/utils/ILogger.d.ts index 1b9726d4..32c4941a 100644 --- a/types/models/spt/utils/ILogger.d.ts +++ b/types/models/spt/utils/ILogger.d.ts @@ -1,8 +1,8 @@ -import { Daum } from "@spt/models/eft/itemEvent/IItemEventRouterRequest"; +import { IDaum } from "@spt/models/eft/itemEvent/IItemEventRouterRequest"; import { LogBackgroundColor } from "@spt/models/spt/logging/LogBackgroundColor"; import { LogTextColor } from "@spt/models/spt/logging/LogTextColor"; export interface ILogger { - writeToLogFile(data: string | Daum): void; + writeToLogFile(data: string | IDaum): void; log(data: string | Record | Error, color: string, backgroundColor?: string): void; logWithColor(data: string | Record, textColor: LogTextColor, backgroundColor?: LogBackgroundColor): void; error(data: string): void; diff --git a/types/models/spt/weather/IGetLocalWeatherResponseData.d.ts b/types/models/spt/weather/IGetLocalWeatherResponseData.d.ts new file mode 100644 index 00000000..ba1782b1 --- /dev/null +++ b/types/models/spt/weather/IGetLocalWeatherResponseData.d.ts @@ -0,0 +1,5 @@ +import { IWeather } from "@spt/models/eft/weather/IWeatherData"; +export interface IGetLocalWeatherResponseData { + season: number; + weather: IWeather[]; +} diff --git a/types/routers/EventOutputHolder.d.ts b/types/routers/EventOutputHolder.d.ts index 148461a0..88ffb5d0 100644 --- a/types/routers/EventOutputHolder.d.ts +++ b/types/routers/EventOutputHolder.d.ts @@ -1,7 +1,7 @@ import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderInfo } from "@spt/models/eft/common/tables/IBotBase"; -import { TraderData } from "@spt/models/eft/itemEvent/IItemEventRouterBase"; +import { IHideoutImprovement, IMoneyTransferLimits, IProductive, ITraderInfo } from "@spt/models/eft/common/tables/IBotBase"; +import { ITraderData } from "@spt/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { TimeUtil } from "@spt/utils/TimeUtil"; import { ICloner } from "@spt/utils/cloners/ICloner"; @@ -30,12 +30,13 @@ export declare class EventOutputHolder { * @param sessionId Session id */ updateOutputProperties(sessionId: string): void; + protected resetMoneyTransferLimit(limit: IMoneyTransferLimits): void; /** * Convert the internal trader data object into an object we can send to the client * @param traderData server data for traders * @returns dict of trader id + TraderData */ - protected constructTraderRelations(traderData: Record): Record; + protected constructTraderRelations(traderData: Record): Record; /** * Return all hideout Improvements from player profile, adjust completed Improvements' completed property to be true * @param pmcData Player profile @@ -47,10 +48,10 @@ export declare class EventOutputHolder { * @param pmcData Player profile * @returns dictionary of hideout productions */ - protected getProductionsFromProfileAndFlagComplete(productions: Record, sessionId: string): Record | undefined; + protected getProductionsFromProfileAndFlagComplete(productions: Record, sessionId: string): Record | undefined; /** * 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 cleanUpCompleteCraftsInProfile(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/types/routers/HttpRouter.d.ts b/types/routers/HttpRouter.d.ts index 3fdb53f2..5eb9af31 100644 --- a/types/routers/HttpRouter.d.ts +++ b/types/routers/HttpRouter.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage } from "node:http"; import { DynamicRouter, Router, StaticRouter } from "@spt/di/Router"; export declare class HttpRouter { diff --git a/types/routers/ImageRouter.d.ts b/types/routers/ImageRouter.d.ts index eb3697f2..cd29c815 100644 --- a/types/routers/ImageRouter.d.ts +++ b/types/routers/ImageRouter.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { ImageRouteService } from "@spt/services/mod/image/ImageRouteService"; import { HttpFileUtil } from "@spt/utils/HttpFileUtil"; @@ -9,6 +8,6 @@ export declare class ImageRouter { protected httpFileUtil: HttpFileUtil; constructor(vfs: VFS, imageRouteService: ImageRouteService, httpFileUtil: HttpFileUtil); addRoute(key: string, valueToAdd: string): void; - sendImage(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void; + sendImage(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise; getImage(): string; } diff --git a/types/routers/item_events/WishlistItemEventRouter.d.ts b/types/routers/item_events/WishlistItemEventRouter.d.ts index bc6d2571..712f484f 100644 --- a/types/routers/item_events/WishlistItemEventRouter.d.ts +++ b/types/routers/item_events/WishlistItemEventRouter.d.ts @@ -6,5 +6,5 @@ export declare class WishlistItemEventRouter extends ItemEventRouterDefinition { protected wishlistCallbacks: WishlistCallbacks; constructor(wishlistCallbacks: WishlistCallbacks); getHandledRoutes(): HandledRoute[]; - handleItemEvent(url: string, pmcData: IPmcData, body: any, sessionID: string): Promise; + handleItemEvent(url: string, pmcData: IPmcData, request: any, sessionID: string): Promise; } diff --git a/types/routers/serializers/BundleSerializer.d.ts b/types/routers/serializers/BundleSerializer.d.ts index dc71cd8b..93e647d7 100644 --- a/types/routers/serializers/BundleSerializer.d.ts +++ b/types/routers/serializers/BundleSerializer.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { Serializer } from "@spt/di/Serializer"; import { BundleLoader } from "@spt/loaders/BundleLoader"; @@ -9,6 +8,6 @@ export declare class BundleSerializer extends Serializer { protected bundleLoader: BundleLoader; protected httpFileUtil: HttpFileUtil; constructor(logger: ILogger, bundleLoader: BundleLoader, httpFileUtil: HttpFileUtil); - serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void; + serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise; canHandle(route: string): boolean; } diff --git a/types/routers/serializers/ImageSerializer.d.ts b/types/routers/serializers/ImageSerializer.d.ts index 5c772437..84430c70 100644 --- a/types/routers/serializers/ImageSerializer.d.ts +++ b/types/routers/serializers/ImageSerializer.d.ts @@ -1,10 +1,9 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { Serializer } from "@spt/di/Serializer"; import { ImageRouter } from "@spt/routers/ImageRouter"; export declare class ImageSerializer extends Serializer { protected imageRouter: ImageRouter; constructor(imageRouter: ImageRouter); - serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): void; + serialize(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: any): Promise; canHandle(route: string): boolean; } diff --git a/types/routers/serializers/NotifySerializer.d.ts b/types/routers/serializers/NotifySerializer.d.ts index 8c07f81f..20d90957 100644 --- a/types/routers/serializers/NotifySerializer.d.ts +++ b/types/routers/serializers/NotifySerializer.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { NotifierController } from "@spt/controllers/NotifierController"; import { Serializer } from "@spt/di/Serializer"; @@ -9,6 +8,6 @@ export declare class NotifySerializer extends Serializer { protected jsonUtil: JsonUtil; protected httpServerHelper: HttpServerHelper; constructor(notifierController: NotifierController, jsonUtil: JsonUtil, httpServerHelper: HttpServerHelper); - serialize(_sessionID: string, req: IncomingMessage, resp: ServerResponse, _: any): void; + serialize(_sessionID: string, req: IncomingMessage, resp: ServerResponse, _: any): Promise; canHandle(route: string): boolean; } diff --git a/types/routers/static/GameStaticRouter.d.ts b/types/routers/static/GameStaticRouter.d.ts index bf045af0..f7287a25 100644 --- a/types/routers/static/GameStaticRouter.d.ts +++ b/types/routers/static/GameStaticRouter.d.ts @@ -1,6 +1,8 @@ import { GameCallbacks } from "@spt/callbacks/GameCallbacks"; import { StaticRouter } from "@spt/di/Router"; +import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; export declare class GameStaticRouter extends StaticRouter { + protected httpResponse: HttpResponseUtil; protected gameCallbacks: GameCallbacks; - constructor(gameCallbacks: GameCallbacks); + constructor(httpResponse: HttpResponseUtil, gameCallbacks: GameCallbacks); } diff --git a/types/servers/HttpServer.d.ts b/types/servers/HttpServer.d.ts index 0024ba38..c01b30ca 100644 --- a/types/servers/HttpServer.d.ts +++ b/types/servers/HttpServer.d.ts @@ -1,17 +1,14 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { ApplicationContext } from "@spt/context/ApplicationContext"; import { HttpServerHelper } from "@spt/helpers/HttpServerHelper"; import { IHttpConfig } from "@spt/models/spt/config/IHttpConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; -import { DatabaseServer } from "@spt/servers/DatabaseServer"; import { WebSocketServer } from "@spt/servers/WebSocketServer"; import { IHttpListener } from "@spt/servers/http/IHttpListener"; import { LocalisationService } from "@spt/services/LocalisationService"; export declare class HttpServer { protected logger: ILogger; - protected databaseServer: DatabaseServer; protected httpServerHelper: HttpServerHelper; protected localisationService: LocalisationService; protected httpListeners: IHttpListener[]; @@ -20,12 +17,12 @@ export declare class HttpServer { protected webSocketServer: WebSocketServer; protected httpConfig: IHttpConfig; protected started: boolean; - constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, localisationService: LocalisationService, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); + constructor(logger: ILogger, httpServerHelper: HttpServerHelper, localisationService: LocalisationService, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); /** * Handle server loading event */ load(): void; - protected handleRequest(req: IncomingMessage, resp: ServerResponse): void; + protected handleRequest(req: IncomingMessage, resp: ServerResponse): Promise; /** * Check against hardcoded values that determine its from a local address * @param remoteAddress Address to check diff --git a/types/servers/WebSocketServer.d.ts b/types/servers/WebSocketServer.d.ts index 61218247..f936d0f1 100644 --- a/types/servers/WebSocketServer.d.ts +++ b/types/servers/WebSocketServer.d.ts @@ -1,4 +1,3 @@ -/// import http, { IncomingMessage } from "node:http"; import { HttpServerHelper } from "@spt/helpers/HttpServerHelper"; import { ILogger } from "@spt/models/spt/utils/ILogger"; diff --git a/types/servers/http/IHttpListener.d.ts b/types/servers/http/IHttpListener.d.ts index ff148d64..50101489 100644 --- a/types/servers/http/IHttpListener.d.ts +++ b/types/servers/http/IHttpListener.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; export interface IHttpListener { canHandle(sessionId: string, req: IncomingMessage): boolean; diff --git a/types/servers/http/SptHttpListener.d.ts b/types/servers/http/SptHttpListener.d.ts index ef681431..64d4f047 100644 --- a/types/servers/http/SptHttpListener.d.ts +++ b/types/servers/http/SptHttpListener.d.ts @@ -1,5 +1,3 @@ -/// -/// import { IncomingMessage, ServerResponse } from "node:http"; import { Serializer } from "@spt/di/Serializer"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -21,16 +19,28 @@ export declare class SptHttpListener implements IHttpListener { canHandle(_: string, req: IncomingMessage): boolean; handle(sessionId: string, req: IncomingMessage, resp: ServerResponse): Promise; /** - * Send http response to the client - * @param sessionID Player id + * Send HTTP response back to sender + * @param sessionID Player id making request * @param req Incoming request * @param resp Outgoing response * @param body Buffer * @param output Server generated response data */ - sendResponse(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: Buffer, output: string): void; + sendResponse(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: Buffer, output: string): Promise; + /** + * Is request flagged as debug enabled + * @param req Incoming request + * @returns True if request is flagged as debug + */ + protected isDebugRequest(req: IncomingMessage): boolean; + /** + * Log request if enabled + * @param req Incoming message request + * @param output Output string + */ + protected logRequest(req: IncomingMessage, output: string): void; getResponse(sessionID: string, req: IncomingMessage, body: Buffer): Promise; protected getBodyInfo(body: Buffer, requestUrl?: any): any; sendJson(resp: ServerResponse, output: string, sessionID: string): void; - sendZlibJson(resp: ServerResponse, output: string, sessionID: string): void; + sendZlibJson(resp: ServerResponse, output: string, sessionID: string): Promise; } diff --git a/types/servers/ws/IWebSocketConnectionHandler.d.ts b/types/servers/ws/IWebSocketConnectionHandler.d.ts index 920dad49..9045dca8 100644 --- a/types/servers/ws/IWebSocketConnectionHandler.d.ts +++ b/types/servers/ws/IWebSocketConnectionHandler.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage } from "node:http"; import { WebSocket } from "ws"; export interface IWebSocketConnectionHandler { diff --git a/types/servers/ws/SptWebSocketConnectionHandler.d.ts b/types/servers/ws/SptWebSocketConnectionHandler.d.ts index 70fc96ad..cdfc42d9 100644 --- a/types/servers/ws/SptWebSocketConnectionHandler.d.ts +++ b/types/servers/ws/SptWebSocketConnectionHandler.d.ts @@ -1,6 +1,4 @@ -/// -/// -import { IncomingMessage } from "http"; +import { IncomingMessage } from "node:http"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent"; import { IHttpConfig } from "@spt/models/spt/config/IHttpConfig"; diff --git a/types/services/AirdropService.d.ts b/types/services/AirdropService.d.ts new file mode 100644 index 00000000..02e6fad3 --- /dev/null +++ b/types/services/AirdropService.d.ts @@ -0,0 +1,56 @@ +import { LootGenerator } from "@spt/generators/LootGenerator"; +import { ItemHelper } from "@spt/helpers/ItemHelper"; +import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IGetAirdropLootRequest } from "@spt/models/eft/location/IGetAirdropLootRequest"; +import { IGetAirdropLootResponse } from "@spt/models/eft/location/IGetAirdropLootResponse"; +import { AirdropTypeEnum, SptAirdropTypeEnum } from "@spt/models/enums/AirdropType"; +import { IAirdropConfig } from "@spt/models/spt/config/IAirdropConfig"; +import { IAirdropLootRequest } from "@spt/models/spt/services/ILootRequest"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { DatabaseService } from "@spt/services/DatabaseService"; +import { ItemFilterService } from "@spt/services/ItemFilterService"; +import { LocalisationService } from "@spt/services/LocalisationService"; +import { HashUtil } from "@spt/utils/HashUtil"; +import { ICloner } from "@spt/utils/cloners/ICloner"; +export declare class AirdropService { + protected logger: ILogger; + protected hashUtil: HashUtil; + protected itemHelper: ItemHelper; + protected weightedRandomHelper: WeightedRandomHelper; + protected localisationService: LocalisationService; + protected itemFilterService: ItemFilterService; + protected lootGenerator: LootGenerator; + protected databaseService: DatabaseService; + protected configServer: ConfigServer; + protected cloner: ICloner; + protected airdropConfig: IAirdropConfig; + constructor(logger: ILogger, hashUtil: HashUtil, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, localisationService: LocalisationService, itemFilterService: ItemFilterService, lootGenerator: LootGenerator, databaseService: DatabaseService, configServer: ConfigServer, cloner: ICloner); + generateCustomAirdropLoot(request: IGetAirdropLootRequest): IGetAirdropLootResponse; + /** + * Handle client/location/getAirdropLoot + * Get loot for an airdrop container + * Generates it randomly based on config/airdrop.json values + * @param forcedAirdropType OPTIONAL - Desired airdrop type, randomised when not provided + * @returns Array of LootItem objects + */ + generateAirdropLoot(forcedAirdropType?: any): IGetAirdropLootResponse; + /** + * Create a container create item based on passed in airdrop type + * @param airdropType What tpye of container: weapon/common etc + * @returns Item + */ + protected getAirdropCrateItem(airdropType: SptAirdropTypeEnum): IItem; + /** + * Randomly pick a type of airdrop loot using weighted values from config + * @returns airdrop type value + */ + protected chooseAirdropType(): SptAirdropTypeEnum; + /** + * Get the configuration for a specific type of airdrop + * @param airdropType Type of airdrop to get settings for + * @returns LootRequest + */ + protected getAirdropLootConfigByType(airdropType: AirdropTypeEnum): IAirdropLootRequest; +} diff --git a/types/services/BotEquipmentFilterService.d.ts b/types/services/BotEquipmentFilterService.d.ts index 780d7a2f..10b8af6b 100644 --- a/types/services/BotEquipmentFilterService.d.ts +++ b/types/services/BotEquipmentFilterService.d.ts @@ -1,8 +1,8 @@ import { BotHelper } from "@spt/helpers/BotHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; -import { EquipmentChances, Generation, GenerationData, IBotType, ModsChances } from "@spt/models/eft/common/tables/IBotType"; -import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; -import { EquipmentFilterDetails, EquipmentFilters, IAdjustmentDetails, IBotConfig, WeightingAdjustmentDetails } from "@spt/models/spt/config/IBotConfig"; +import { EquipmentChances, IBotType, IGeneration, IGenerationData, IModsChances } from "@spt/models/eft/common/tables/IBotType"; +import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; +import { EquipmentFilters, IAdjustmentDetails, IBotConfig, IEquipmentFilterDetails, IWeightingAdjustmentDetails } from "@spt/models/spt/config/IBotConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; export declare class BotEquipmentFilterService { @@ -20,19 +20,19 @@ export declare class BotEquipmentFilterService { * @param botLevel Level of the bot * @param botGenerationDetails details on how to generate a bot */ - filterBotEquipment(sessionId: string, baseBotNode: IBotType, botLevel: number, botGenerationDetails: BotGenerationDetails): void; + filterBotEquipment(sessionId: string, baseBotNode: IBotType, botLevel: number, botGenerationDetails: IBotGenerationDetails): void; /** * Iterate over the changes passed in and apply them to baseValues parameter * @param equipmentChanges Changes to apply * @param baseValues data to update */ - protected adjustChances(equipmentChanges: Record, baseValues: EquipmentChances | ModsChances): void; + protected adjustChances(equipmentChanges: Record, baseValues: EquipmentChances | IModsChances): void; /** * Iterate over the Generation changes and alter data in baseValues.Generation * @param generationChanges Changes to apply * @param baseBotGeneration dictionary to update */ - protected adjustGenerationChances(generationChanges: Record, baseBotGeneration: Generation): void; + protected adjustGenerationChances(generationChanges: Record, baseBotGeneration: IGeneration): void; /** * Get equipment settings for bot * @param botEquipmentRole equipment role to return @@ -51,28 +51,28 @@ export declare class BotEquipmentFilterService { * @param playerLevel Level of the player * @returns EquipmentBlacklistDetails object */ - getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails | undefined; + getBotEquipmentBlacklist(botRole: string, playerLevel: number): IEquipmentFilterDetails | undefined; /** * Get the whitelist for a specific bot type that's within the players level * @param botRole Bot type * @param playerLevel Players level * @returns EquipmentFilterDetails object */ - protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): EquipmentFilterDetails | undefined; + protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): IEquipmentFilterDetails | undefined; /** * Retrieve item weighting adjustments from bot.json config based on bot level * @param botRole Bot type to get adjustments for * @param botLevel Level of bot * @returns Weighting adjustments for bot items */ - protected getBotWeightingAdjustments(botRole: string, botLevel: number): WeightingAdjustmentDetails | undefined; + protected getBotWeightingAdjustments(botRole: string, botLevel: number): IWeightingAdjustmentDetails | undefined; /** * Retrieve item weighting adjustments from bot.json config based on player level * @param botRole Bot type to get adjustments for * @param playerlevel Level of bot * @returns Weighting adjustments for bot items */ - protected getBotWeightingAdjustmentsByPlayerLevel(botRole: string, playerlevel: number): WeightingAdjustmentDetails | undefined; + protected getBotWeightingAdjustmentsByPlayerLevel(botRole: string, playerlevel: number): IWeightingAdjustmentDetails | undefined; /** * Filter bot equipment based on blacklist and whitelist from config/bot.json * Prioritizes whitelist first, if one is found blacklist is ignored @@ -80,7 +80,7 @@ export declare class BotEquipmentFilterService { * @param blacklist equipment blacklist * @returns Filtered bot file */ - protected filterEquipment(baseBotNode: IBotType, blacklist: EquipmentFilterDetails, whitelist: EquipmentFilterDetails): void; + protected filterEquipment(baseBotNode: IBotType, blacklist: IEquipmentFilterDetails, whitelist: IEquipmentFilterDetails): void; /** * Filter bot cartridges based on blacklist and whitelist from config/bot.json * Prioritizes whitelist first, if one is found blacklist is ignored @@ -89,7 +89,7 @@ export declare class BotEquipmentFilterService { * @param whitelist equipment on this list should be used exclusively * @returns Filtered bot file */ - protected filterCartridges(baseBotNode: IBotType, blacklist: EquipmentFilterDetails, whitelist: EquipmentFilterDetails): void; + protected filterCartridges(baseBotNode: IBotType, blacklist: IEquipmentFilterDetails, whitelist: IEquipmentFilterDetails): void; /** * Add/Edit weighting changes to bot items using values from config/bot.json/equipment * @param weightingAdjustments Weighting change to apply to bot diff --git a/types/services/BotEquipmentModPoolService.d.ts b/types/services/BotEquipmentModPoolService.d.ts index 7b2b4420..080dc7b1 100644 --- a/types/services/BotEquipmentModPoolService.d.ts +++ b/types/services/BotEquipmentModPoolService.d.ts @@ -1,5 +1,5 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { Mods } from "@spt/models/eft/common/tables/IBotType"; +import { IMods } from "@spt/models/eft/common/tables/IBotType"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -16,8 +16,8 @@ export declare class BotEquipmentModPoolService { protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - protected weaponModPool: Mods; - protected gearModPool: Mods; + protected weaponModPool: IMods; + protected gearModPool: IMods; protected weaponPoolGenerated: boolean; protected armorPoolGenerated: boolean; constructor(logger: ILogger, vfs: VFS, itemHelper: ItemHelper, databaseService: DatabaseService, localisationService: LocalisationService, configServer: ConfigServer); diff --git a/types/services/BotGenerationCacheService.d.ts b/types/services/BotGenerationCacheService.d.ts index ba27266c..181031a5 100644 --- a/types/services/BotGenerationCacheService.d.ts +++ b/types/services/BotGenerationCacheService.d.ts @@ -43,5 +43,7 @@ export declare class BotGenerationCacheService { * Does cache have a bot with requested key * @returns false if empty */ - cacheHasBotOfRole(key: string): boolean; + cacheHasBotWithKey(key: string, size?: number): boolean; + getCachedBotCount(key: string): number; + createCacheKey(role: string, difficulty: string): string; } diff --git a/types/services/BotLootCacheService.d.ts b/types/services/BotLootCacheService.d.ts index 2b51c5bc..815d2ab1 100644 --- a/types/services/BotLootCacheService.d.ts +++ b/types/services/BotLootCacheService.d.ts @@ -1,7 +1,7 @@ import { PMCLootGenerator } from "@spt/generators/PMCLootGenerator"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { IBotType } from "@spt/models/eft/common/tables/IBotType"; -import { ITemplateItem, Props } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IProps, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IBotLootCache, LootCacheType } from "@spt/models/spt/bots/IBotLootCache"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseServer } from "@spt/servers/DatabaseServer"; @@ -50,25 +50,25 @@ export declare class BotLootCacheService { * @param props * @returns */ - protected isBulletOrGrenade(props: Props): boolean; + protected isBulletOrGrenade(props: IProps): boolean; /** * Internal and external magazine have this property * @param props * @returns */ - protected isMagazine(props: Props): boolean; + protected isMagazine(props: IProps): boolean; /** * Medical use items (e.g. morphine/lip balm/grizzly) * @param props * @returns */ - protected isMedicalItem(props: Props): boolean; + protected isMedicalItem(props: IProps): boolean; /** * Grenades have this property (e.g. smoke/frag/flash grenades) * @param props * @returns */ - protected isGrenade(props: Props): boolean; + protected isGrenade(props: IProps): boolean; protected isFood(tpl: string): boolean; protected isDrink(tpl: string): boolean; protected isCurrency(tpl: string): boolean; diff --git a/types/services/BotNameService.d.ts b/types/services/BotNameService.d.ts new file mode 100644 index 00000000..056bd0f3 --- /dev/null +++ b/types/services/BotNameService.d.ts @@ -0,0 +1,47 @@ +import { BotHelper } from "@spt/helpers/BotHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { IBotType } from "@spt/models/eft/common/tables/IBotType"; +import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails"; +import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; +import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { RandomUtil } from "@spt/utils/RandomUtil"; +import { ICloner } from "@spt/utils/cloners/ICloner"; +import { DatabaseService } from "./DatabaseService"; +import { LocalisationService } from "./LocalisationService"; +export declare class BotNameService { + protected logger: ILogger; + protected randomUtil: RandomUtil; + protected profileHelper: ProfileHelper; + protected botHelper: BotHelper; + protected databaseService: DatabaseService; + protected localisationService: LocalisationService; + protected configServer: ConfigServer; + protected cloner: ICloner; + protected botConfig: IBotConfig; + protected pmcConfig: IPmcConfig; + protected usedNameCache: Set; + constructor(logger: ILogger, randomUtil: RandomUtil, profileHelper: ProfileHelper, botHelper: BotHelper, databaseService: DatabaseService, localisationService: LocalisationService, configServer: ConfigServer, cloner: ICloner); + /** + * Clear out any entries in Name Set + */ + clearNameCache(): void; + /** + * Create a unique bot nickname + * @param botJsonTemplate bot JSON data from db + * @param botGenerationDetails + * @param botRole role of bot e.g. assault + * @param uniqueRoles Lowercase roles to always make unique + * @param sessionId OPTIONAL: profile session id + * @returns Nickname for bot + */ + generateUniqueBotNickname(botJsonTemplate: IBotType, botGenerationDetails: IBotGenerationDetails, botRole: string, uniqueRoles?: string[]): string; + /** + * Should this bot have a name like "name (Pmc Name)" + * @param botRole Role bot has + * @returns True if name should be simulated pscav + */ + protected shouldSimulatePlayerScavName(botRole: string): boolean; + protected addPlayerScavNameSimulationSuffix(nickname: string): string; +} diff --git a/types/services/BotWeaponModLimitService.d.ts b/types/services/BotWeaponModLimitService.d.ts index 63c4967f..cce8f294 100644 --- a/types/services/BotWeaponModLimitService.d.ts +++ b/types/services/BotWeaponModLimitService.d.ts @@ -1,5 +1,5 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -39,7 +39,7 @@ export declare class BotWeaponModLimitService { * @param modsParent The parent of the mod to be checked * @returns true if over item limit */ - weaponModHasReachedLimit(botRole: string, modTemplate: ITemplateItem, modLimits: BotModLimits, modsParent: ITemplateItem, weapon: Item[]): boolean; + weaponModHasReachedLimit(botRole: string, modTemplate: ITemplateItem, modLimits: BotModLimits, modsParent: ITemplateItem, weapon: IItem[]): boolean; /** * Check if the specific item type on the weapon has reached the set limit * @param modTpl log mod tpl if over type limit diff --git a/types/services/CircleOfCultistService.d.ts b/types/services/CircleOfCultistService.d.ts new file mode 100644 index 00000000..e4d34108 --- /dev/null +++ b/types/services/CircleOfCultistService.d.ts @@ -0,0 +1,132 @@ +import { HideoutHelper } from "@spt/helpers/HideoutHelper"; +import { InventoryHelper } from "@spt/helpers/InventoryHelper"; +import { ItemHelper } from "@spt/helpers/ItemHelper"; +import { PresetHelper } from "@spt/helpers/PresetHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { IPmcData } from "@spt/models/eft/common/IPmcData"; +import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; +import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; +import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; +import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { DatabaseService } from "@spt/services/DatabaseService"; +import { ItemFilterService } from "@spt/services/ItemFilterService"; +import { SeasonalEventService } from "@spt/services/SeasonalEventService"; +import { HashUtil } from "@spt/utils/HashUtil"; +import { RandomUtil } from "@spt/utils/RandomUtil"; +import { TimeUtil } from "@spt/utils/TimeUtil"; +import { ICloner } from "@spt/utils/cloners/ICloner"; +export declare class CircleOfCultistService { + protected logger: ILogger; + protected timeUtil: TimeUtil; + protected cloner: ICloner; + protected eventOutputHolder: EventOutputHolder; + protected randomUtil: RandomUtil; + protected hashUtil: HashUtil; + protected itemHelper: ItemHelper; + protected presetHelper: PresetHelper; + protected profileHelper: ProfileHelper; + protected inventoryHelper: InventoryHelper; + protected hideoutHelper: HideoutHelper; + protected databaseService: DatabaseService; + protected itemFilterService: ItemFilterService; + protected seasonalEventService: SeasonalEventService; + protected configServer: ConfigServer; + protected static circleOfCultistSlotId: string; + protected hideoutConfig: IHideoutConfig; + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + /** + * Start a sacrifice event + * Generate rewards + * Delete sacrificed items + * @param sessionId Session id + * @param pmcData Player profile doing sacrifice + * @param request Client request + * @returns IItemEventRouterResponse + */ + startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Register production inside player profile + * @param sessionId Session id + * @param pmcData Player profile + * @param recipeId Recipe id + * @param sacrificedItems Items player sacrificed + * @param rewardAmountRoubles Rouble amount to reward player in items with + * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + */ + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + /** + * Get the circle craft time as seconds, value is based on reward item value + * OR rewards are direct, then use custom craft time defined in oarameter object + * @param rewardAmountRoubles Value of rewards in roubles + * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @returns craft time seconds + */ + protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + /** + * Get the items player sacrificed in circle + * @param pmcData Player profile + * @returns Array of its from player inventory + */ + protected getSacrificedItems(pmcData: IPmcData): IItem[]; + /** + * Given a pool of items + rouble budget, pick items until the budget is reached + * @param rewardItemTplPool Items that can be picekd + * @param rewardBudget Rouble budget to reach + * @param cultistCircleStashId Id of stash item + * @returns Array of item arrays + */ + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + /** + * Give every item as a reward that's passed in + * @param rewardTpls Item tpls to turn into reward items + * @param cultistCircleStashId Id of stash item + * @returns Array of item arrays + */ + protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool + * @param rewardTpl Item being rewarded to get stack size of + * @returns stack size of item + */ + protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Get the size of a reward items stack + * 1 for everything except ammo, ammo can be between min stack and max stack + * @param itemTpl Item chosen + * @param rewardPoolRemaining Rouble amount of pool remaining to fill + * @returns Size of stack + */ + protected getRewardStackSize(itemTpl: string, rewardPoolRemaining: number): number; + /** + * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas + * @param sessionId Session id + * @param pmcData Profile of player who will be getting the rewards + * @returns Array of tpls + */ + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + /** + * Get all active hideout areas + * @param areas Hideout areas to iterate over + * @returns Active area array + */ + protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; + /** + * Get all recipes the player has access to, includes base + unlocked recipes + * @param unlockedRecipes Recipes player has flagged as unlocked + * @param allRecipes All recipes + * @returns Array of recipes + */ + protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + /** + * Iterate over passed in hideout requirements and return the Item + * @param requirements Requirements to iterate over + * @returns Array of item requirements + */ + protected getItemRequirements(requirements: IRequirementBase[]): (IStageRequirement | IRequirement)[]; +} diff --git a/types/services/CustomLocationWaveService.d.ts b/types/services/CustomLocationWaveService.d.ts index c72d5bb1..f69ce2b0 100644 --- a/types/services/CustomLocationWaveService.d.ts +++ b/types/services/CustomLocationWaveService.d.ts @@ -1,4 +1,4 @@ -import { BossLocationSpawn, Wave } from "@spt/models/eft/common/ILocationBase"; +import { IBossLocationSpawn, IWave } from "@spt/models/eft/common/ILocationBase"; import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -16,13 +16,13 @@ export declare class CustomLocationWaveService { * @param locationId e.g. factory4_day, bigmap * @param waveToAdd Boss wave to add to map */ - addBossWaveToMap(locationId: string, waveToAdd: BossLocationSpawn): void; + addBossWaveToMap(locationId: string, waveToAdd: IBossLocationSpawn): void; /** * Add a normal bot wave to a map * @param locationId e.g. factory4_day, bigmap * @param waveToAdd Wave to add to map */ - addNormalWaveToMap(locationId: string, waveToAdd: Wave): void; + addNormalWaveToMap(locationId: string, waveToAdd: IWave): void; /** * Clear all custom boss waves from a map * @param locationId e.g. factory4_day, bigmap diff --git a/types/services/DatabaseService.d.ts b/types/services/DatabaseService.d.ts index 711a0698..934617a2 100644 --- a/types/services/DatabaseService.d.ts +++ b/types/services/DatabaseService.d.ts @@ -3,6 +3,7 @@ import { ILocation } from "@spt/models/eft/common/ILocation"; import { IAchievement } from "@spt/models/eft/common/tables/IAchievement"; import { ICustomizationItem } from "@spt/models/eft/common/tables/ICustomizationItem"; import { IHandbookBase } from "@spt/models/eft/common/tables/IHandbookBase"; +import { ILocationServices } from "@spt/models/eft/common/tables/ILocationServices"; import { IMatch } from "@spt/models/eft/common/tables/IMatch"; import { IProfileTemplates } from "@spt/models/eft/common/tables/IProfileTemplate"; import { IQuest } from "@spt/models/eft/common/tables/IQuest"; @@ -20,12 +21,15 @@ import { ITemplates } from "@spt/models/spt/templates/ITemplates"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseServer } from "@spt/servers/DatabaseServer"; import { LocalisationService } from "@spt/services/LocalisationService"; +import { HashUtil } from "@spt/utils/HashUtil"; export declare class DatabaseService { protected logger: ILogger; protected databaseServer: DatabaseServer; protected localisationService: LocalisationService; + protected hashUtil: HashUtil; protected locationConfig: ILocationConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, localisationService: LocalisationService); + protected isDataValid: boolean; + constructor(logger: ILogger, databaseServer: DatabaseServer, localisationService: LocalisationService, hashUtil: HashUtil); /** * @returns assets/database/ */ @@ -110,4 +114,24 @@ export declare class DatabaseService { * @returns assets/database/traders/ */ getTrader(traderId: string): ITrader; + /** + * @returns assets/database/locationServices/ + */ + getLocationServices(): ILocationServices; + /** + * Validates that the database doesn't contain invalid ID data + */ + validateDatabase(): void; + /** + * Validate that the given table only contains valid MongoIDs + * @param table Table to validate for MongoIDs + * @param tableType The type of table, used in output message + * @returns True if the table only contains valid data + */ + private validateTable; + /** + * Check if the database is valid + * @returns True if the database contains valid data, false otherwise + */ + isDatabaseValid(): boolean; } diff --git a/types/services/FenceService.d.ts b/types/services/FenceService.d.ts index 58dc0765..b4079e67 100644 --- a/types/services/FenceService.d.ts +++ b/types/services/FenceService.d.ts @@ -3,8 +3,8 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { IFenceLevel } from "@spt/models/eft/common/IGlobals"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item, Repairable } from "@spt/models/eft/common/tables/IItem"; -import { ITemplateItem, Slot } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IItem, IUpdRepairable } from "@spt/models/eft/common/tables/IItem"; +import { ISlot, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IBarterScheme, ITraderAssort } from "@spt/models/eft/common/tables/ITrader"; import { IItemDurabilityCurrentMax, ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ICreateFenceAssortsResult } from "@spt/models/spt/fence/ICreateFenceAssortsResult"; @@ -79,21 +79,21 @@ export declare class FenceService { * @param items the items to add with all its childrens * @param mainItem the most parent item of the array */ - addItemsToFenceAssort(items: Item[], mainItem: Item): void; + addItemsToFenceAssort(items: IItem[], mainItem: IItem): void; /** * Calculates the overall price for an item (with all its children) * @param itemTpl the item tpl to calculate the fence price for * @param items the items (with its children) to calculate fence price for * @returns the fence price of the item */ - getItemPrice(itemTpl: string, items: Item[]): number; + getItemPrice(itemTpl: string, items: IItem[]): number; /** * Calculate the overall price for an ammo box, where only one item is * the ammo box itself and every other items are the bullets in that box * @param items the ammo box (and all its children ammo items) * @returns the price of the ammo box */ - protected getAmmoBoxPrice(items: Item[]): number; + protected getAmmoBoxPrice(items: IItem[]): number; /** * Adjust all items contained inside an assort by a multiplier * @param assort (clone)Assort that contains items with prices to adjust @@ -115,7 +115,7 @@ export declare class FenceService { * @param modifier value to multiply item price by * @param presetModifier value to multiply preset price by */ - protected adjustItemPriceByModifier(item: Item, assort: ITraderAssort, modifier: number, presetModifier: number): void; + protected adjustItemPriceByModifier(item: IItem, assort: ITraderAssort, modifier: number, presetModifier: number): void; /** * Get fence assorts with no price adjustments based on fence rep * @returns ITraderAssort @@ -146,7 +146,7 @@ export declare class FenceService { * @param generationValues Base counts assorts should be adjusted to * @returns IGenerationAssortValues object with adjustments needed to reach desired state */ - protected getItemCountsToGenerate(assortItems: Item[], generationValues: IGenerationAssortValues): IGenerationAssortValues; + protected getItemCountsToGenerate(assortItems: IItem[], generationValues: IGenerationAssortValues): IGenerationAssortValues; /** * Delete desired number of items from assort (including children) * @param itemCountToReplace @@ -158,7 +158,7 @@ export declare class FenceService { * @param assort Trader assort to remove item from * @param rootItems Pool of root items to pick from to remove */ - protected removeRandomItemFromAssorts(assort: ITraderAssort, rootItems: Item[]): void; + protected removeRandomItemFromAssorts(assort: ITraderAssort, rootItems: IItem[]): void; /** * Get an integer rounded count of items to replace based on percentrage from traderConfig value * @param totalItemCount total item count @@ -217,14 +217,14 @@ export declare class FenceService { * @param itemsWithChildren Items to search through * @returns Matching assort item */ - protected getMatchingItem(rootItemBeingAdded: Item, itemDbDetails: ITemplateItem, itemsWithChildren: Item[][]): Item | undefined; + protected getMatchingItem(rootItemBeingAdded: IItem, itemDbDetails: ITemplateItem, itemsWithChildren: IItem[][]): IItem | undefined; /** * Should this item be forced into only 1 stack on fence * @param existingItem Existing item from fence assort * @param itemDbDetails Item we want to add db details * @returns True item should be force stacked */ - protected itemShouldBeForceStacked(existingItem: Item, itemDbDetails: ITemplateItem): boolean; + protected itemShouldBeForceStacked(existingItem: IItem, itemDbDetails: ITemplateItem): boolean; protected itemInPreventDupeCategoryList(tpl: string): boolean; /** * Adjust price of item based on what is left to buy (resource/uses left) @@ -232,7 +232,7 @@ export declare class FenceService { * @param itemRoot Root item having price adjusted * @param itemTemplate Db template of item */ - protected adjustItemPriceByQuality(barterSchemes: Record, itemRoot: Item, itemTemplate: ITemplateItem): void; + protected adjustItemPriceByQuality(barterSchemes: Record, itemRoot: IItem, itemTemplate: ITemplateItem): void; protected getMatchingItemLimit(itemTypeLimits: Record; + getGifts(): Record; /** * Get an array of all gift ids * @returns string array of gift ids @@ -47,13 +47,13 @@ export declare class GiftService { * @param giftData Gift to send player * @returns trader/user/system id */ - protected getSenderId(giftData: Gift): string | undefined; + protected getSenderId(giftData: IGift): string | undefined; /** * Convert GiftSenderType into a dialog MessageType * @param giftData Gift to send player * @returns MessageType enum value */ - protected getMessageType(giftData: Gift): MessageType | undefined; + protected getMessageType(giftData: IGift): MessageType | undefined; /** * Prapor sends gifts to player for first week after profile creation * @param sessionId Player id diff --git a/types/services/InMemoryCacheService.d.ts b/types/services/InMemoryCacheService.d.ts new file mode 100644 index 00000000..6f11dd7d --- /dev/null +++ b/types/services/InMemoryCacheService.d.ts @@ -0,0 +1,29 @@ +import { ICloner } from "@spt/utils/cloners/ICloner"; +export declare class InMemoryCacheService { + protected cloner: ICloner; + protected cacheData: Record; + constructor(cloner: ICloner); + /** + * Store data into an in-memory object + * @param key key to store data against + * @param dataToCache - Data to store in cache + */ + storeByKey(key: string, dataToCache: any): void; + /** + * Retreve data stored by a key + * @param key key + * @returns Stored data + */ + getDataByKey(key: string): any | undefined; + /** + * Does data exists against the provided key + * @param key Key to check for data against + * @returns true if exists + */ + hasStoredDataByKey(key: string): boolean; + /** + * Remove data stored against key + * @param key Key to remove data against + */ + clearDataStoredByKey(key: string): void; +} diff --git a/types/services/InsuranceService.d.ts b/types/services/InsuranceService.d.ts index f7991024..ac9cff5b 100644 --- a/types/services/InsuranceService.d.ts +++ b/types/services/InsuranceService.d.ts @@ -1,21 +1,15 @@ -import { DialogueHelper } from "@spt/helpers/DialogueHelper"; -import { HandbookHelper } from "@spt/helpers/HandbookHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { SecureContainerHelper } from "@spt/helpers/SecureContainerHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITraderBase } from "@spt/models/eft/common/tables/ITrader"; -import { IInsuredItemsData } from "@spt/models/eft/inRaid/IInsuredItemsData"; -import { ISaveProgressRequestData } from "@spt/models/eft/inRaid/ISaveProgressRequestData"; import { IInsuranceConfig } from "@spt/models/spt/config/IInsuranceConfig"; -import { ILostOnDeathConfig } from "@spt/models/spt/config/ILostOnDeathConfig"; import { IInsuranceEquipmentPkg } from "@spt/models/spt/services/IInsuranceEquipmentPkg"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; import { DatabaseService } from "@spt/services/DatabaseService"; -import { LocaleService } from "@spt/services/LocaleService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { MailSendService } from "@spt/services/MailSendService"; import { HashUtil } from "@spt/utils/HashUtil"; @@ -25,57 +19,41 @@ import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class InsuranceService { protected logger: ILogger; protected databaseService: DatabaseService; - protected secureContainerHelper: SecureContainerHelper; protected randomUtil: RandomUtil; protected itemHelper: ItemHelper; protected hashUtil: HashUtil; protected timeUtil: TimeUtil; protected saveServer: SaveServer; protected traderHelper: TraderHelper; - protected dialogueHelper: DialogueHelper; - protected handbookHelper: HandbookHelper; + protected profileHelper: ProfileHelper; protected localisationService: LocalisationService; - protected localeService: LocaleService; protected mailSendService: MailSendService; protected configServer: ConfigServer; protected cloner: ICloner; - protected insured: Record>; + protected insured: Record>; protected insuranceConfig: IInsuranceConfig; - protected lostOnDeathConfig: ILostOnDeathConfig; - constructor(logger: ILogger, databaseService: DatabaseService, secureContainerHelper: SecureContainerHelper, randomUtil: RandomUtil, itemHelper: ItemHelper, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, traderHelper: TraderHelper, dialogueHelper: DialogueHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, localeService: LocaleService, mailSendService: MailSendService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, databaseService: DatabaseService, randomUtil: RandomUtil, itemHelper: ItemHelper, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, traderHelper: TraderHelper, profileHelper: ProfileHelper, localisationService: LocalisationService, mailSendService: MailSendService, configServer: ConfigServer, cloner: ICloner); /** * Does player have insurance array * @param sessionId Player id * @returns True if exists */ - insuranceExists(sessionId: string): boolean; + isuranceDictionaryExists(sessionId: string): boolean; /** * Get all insured items by all traders for a profile * @param sessionId Profile id (session id) * @returns Item array */ - getInsurance(sessionId: string): Record; - /** - * Get insured items by profile id + trader id - * @param sessionId Profile id (session id) - * @param traderId Trader items were insured with - * @returns Item array - */ - getInsuranceItems(sessionId: string, traderId: string): Item[]; + getInsurance(sessionId: string): Record; resetInsurance(sessionId: string): void; /** - * Sends stored insured items as message to player - * @param pmcData profile to send insured items to + * Sends `i will go look for your stuff` trader message + + * Store lost insurance items inside profile for later retreval + * @param pmcData Profile to send insured items to * @param sessionID SessionId of current player - * @param mapId Id of the map player died/exited that caused the insurance to be issued on + * @param mapId Id of the location player died/exited that caused the insurance to be issued on */ - sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void; - /** - * Check all root insured items and remove location property + set slotId to 'hideout' - * @param sessionId Session id - * @param traderId Trader id - */ - protected removeLocationProperty(sessionId: string, traderId: string): void; + startPostRaidInsuranceLostProcess(pmcData: IPmcData, sessionID: string, mapId: string): void; /** * Get a timestamp of when insurance items should be sent to player based on trader used to insure * Apply insurance return bonus if found in profile @@ -84,23 +62,6 @@ export declare class InsuranceService { * @returns Timestamp to return items to player in seconds */ protected getInsuranceReturnTimestamp(pmcData: IPmcData, trader: ITraderBase): number; - /** - * Create insurance equipment packages that should be sent to the user. The packages should contain items that have - * been lost in a raid and should be returned to the player through the insurance system. - * - * NOTE: We do not have data on items that were dropped in a raid. This means we have to pull item data from the - * profile at the start of the raid to return to the player in insurance. Because of this, the item - * positioning may differ from the position the item was in when the player died. Apart from removing all - * positioning, this is the best we can do. >:{} - * - * @param pmcData Player profile - * @param offraidData Post-raid data - * @param preRaidGear Pre-raid data - * @param sessionID Session id - * @param playerDied Did player die in raid - * @returns Array of insured items lost in raid - */ - getGearLostInRaid(pmcData: IPmcData, offraidData: ISaveProgressRequestData, preRaidGear: Item[], sessionID: string, playerDied: boolean): IInsuranceEquipmentPkg[]; /** * Take the insurance item packages within a profile session and ensure that each of the items in that package are * not orphaned from their parent ID. @@ -109,25 +70,27 @@ export declare class InsuranceService { * @returns void */ protected adoptOrphanedInsEquipment(sessionID: string): void; + protected getMaxInsuranceStorageTime(traderBase: ITraderBase): number; /** * Store lost gear post-raid inside profile, ready for later code to pick it up and mail it * @param equipmentPkg Gear to store - generated by getGearLostInRaid() */ storeGearLostInRaidToSendLater(sessionID: string, equipmentPkg: IInsuranceEquipmentPkg[]): void; /** - * Take preraid item and update properties to ensure its ready to be given to player in insurance return mail - * @param pmcData Player profile - * @param preRaidItemWithChildren Insured item (with children) as it was pre-raid - * @param allItemsFromClient Item data when player left raid (durability values) - * @returns Item (with children) to send to player + * For the passed in items, find the trader it was insured against + * @param sessionId Session id + * @param lostInsuredItems Insured items lost in a raid + * @param pmcProfile Player profile + * @returns IInsuranceEquipmentPkg array */ - protected getInsuredItemDetails(pmcData: IPmcData, preRaidItem: Item, insuredItemFromClient: IInsuredItemsData): Item; + mapInsuredItemsToTrader(sessionId: string, lostInsuredItems: IItem[], pmcProfile: IPmcData): IInsuranceEquipmentPkg[]; /** - * Reset slotId property to "hideout" when necessary (used to be in ) - * @param pmcData Players pmcData.Inventory.equipment value - * @param itemToReturn item we will send to player as insurance return + * Some items should never be returned in insurance but BSG send them in the request + * @param lostItem Item being returned in insurance + * @param inventoryItems Player inventory + * @returns True if item */ - protected updateSlotIdValue(playerBaseInventoryEquipmentId: string, itemToReturn: Item): void; + protected itemCannotBeLostOnDeath(lostItem: IItem, inventoryItems: IItem[]): boolean; /** * Add gear item to InsuredItems array in player profile * @param sessionID Session id @@ -155,7 +118,7 @@ export declare class InsuranceService { * @param traderId Trader item insured with * @param itemToAdd Insured item (with children) */ - addInsuranceItemToArray(sessionId: string, traderId: string, itemToAdd: Item): void; + addInsuranceItemToArray(sessionId: string, traderId: string, itemToAdd: IItem): void; /** * Get price of insurance * multiplier from config * @param pmcData Player profile @@ -163,7 +126,7 @@ export declare class InsuranceService { * @param traderId Trader item is insured with * @returns price in roubles */ - getRoublePriceToInsureItemWithTrader(pmcData: IPmcData, inventoryItem: Item, traderId: string): number; + getRoublePriceToInsureItemWithTrader(pmcData: IPmcData, inventoryItem: IItem, traderId: string): number; /** * Returns the ID that should be used for a root-level Item's parentId property value within in the context of insurance. * @param sessionID Players id diff --git a/types/services/LegacyLocationLifecycleService.d.ts b/types/services/LegacyLocationLifecycleService.d.ts new file mode 100644 index 00000000..b3c20df3 --- /dev/null +++ b/types/services/LegacyLocationLifecycleService.d.ts @@ -0,0 +1,105 @@ +import { ApplicationContext } from "@spt/context/ApplicationContext"; +import { LocationLootGenerator } from "@spt/generators/LocationLootGenerator"; +import { LootGenerator } from "@spt/generators/LootGenerator"; +import { PlayerScavGenerator } from "@spt/generators/PlayerScavGenerator"; +import { HealthHelper } from "@spt/helpers/HealthHelper"; +import { InRaidHelper } from "@spt/helpers/InRaidHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { TraderHelper } from "@spt/helpers/TraderHelper"; +import { IPmcData } from "@spt/models/eft/common/IPmcData"; +import { IEndOfflineRaidRequestData } from "@spt/models/eft/match/IEndOfflineRaidRequestData"; +import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { IInRaidConfig } from "@spt/models/spt/config/IInRaidConfig"; +import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; +import { IMatchConfig } from "@spt/models/spt/config/IMatchConfig"; +import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { SaveServer } from "@spt/servers/SaveServer"; +import { BotGenerationCacheService } from "@spt/services/BotGenerationCacheService"; +import { BotLootCacheService } from "@spt/services/BotLootCacheService"; +import { DatabaseService } from "@spt/services/DatabaseService"; +import { InsuranceService } from "@spt/services/InsuranceService"; +import { LocalisationService } from "@spt/services/LocalisationService"; +import { MailSendService } from "@spt/services/MailSendService"; +import { MatchBotDetailsCacheService } from "@spt/services/MatchBotDetailsCacheService"; +import { PmcChatResponseService } from "@spt/services/PmcChatResponseService"; +import { RaidTimeAdjustmentService } from "@spt/services/RaidTimeAdjustmentService"; +import { HashUtil } from "@spt/utils/HashUtil"; +import { RandomUtil } from "@spt/utils/RandomUtil"; +import { TimeUtil } from "@spt/utils/TimeUtil"; +import { ICloner } from "@spt/utils/cloners/ICloner"; +export declare class LegacyLocationLifecycleService { + protected logger: ILogger; + protected hashUtil: HashUtil; + protected saveServer: SaveServer; + protected timeUtil: TimeUtil; + protected randomUtil: RandomUtil; + protected profileHelper: ProfileHelper; + protected databaseService: DatabaseService; + protected inRaidHelper: InRaidHelper; + protected healthHelper: HealthHelper; + protected matchBotDetailsCacheService: MatchBotDetailsCacheService; + protected pmcChatResponseService: PmcChatResponseService; + protected playerScavGenerator: PlayerScavGenerator; + protected traderHelper: TraderHelper; + protected localisationService: LocalisationService; + protected insuranceService: InsuranceService; + protected botLootCacheService: BotLootCacheService; + protected configServer: ConfigServer; + protected botGenerationCacheService: BotGenerationCacheService; + protected mailSendService: MailSendService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; + protected lootGenerator: LootGenerator; + protected applicationContext: ApplicationContext; + protected locationLootGenerator: LocationLootGenerator; + protected cloner: ICloner; + protected matchConfig: IMatchConfig; + protected inRaidConfig: IInRaidConfig; + protected traderConfig: ITraderConfig; + protected ragfairConfig: IRagfairConfig; + protected hideoutConfig: IHideoutConfig; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, hashUtil: HashUtil, saveServer: SaveServer, timeUtil: TimeUtil, randomUtil: RandomUtil, profileHelper: ProfileHelper, databaseService: DatabaseService, inRaidHelper: InRaidHelper, healthHelper: HealthHelper, matchBotDetailsCacheService: MatchBotDetailsCacheService, pmcChatResponseService: PmcChatResponseService, playerScavGenerator: PlayerScavGenerator, traderHelper: TraderHelper, localisationService: LocalisationService, insuranceService: InsuranceService, botLootCacheService: BotLootCacheService, configServer: ConfigServer, botGenerationCacheService: BotGenerationCacheService, mailSendService: MailSendService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, applicationContext: ApplicationContext, locationLootGenerator: LocationLootGenerator, cloner: ICloner); + /** + * Handle client/match/offline/end + * @deprecated + */ + endOfflineRaid(info: IEndOfflineRaidRequestData, sessionId: string): void; + /** + * Handle when a player extracts using a car - Add rep to fence + * @param extractName name of the extract used + * @param pmcData Player profile + * @param sessionId Session id + */ + protected handleCarExtract(extractName: string, pmcData: IPmcData, sessionId: string): void; + /** + * Get the fence rep gain from using a car or coop extract + * @param pmcData Profile + * @param baseGain amount gained for the first extract + * @param extractCount Number of times extract was taken + * @returns Fence standing after taking extract + */ + protected getFenceStandingAfterExtract(pmcData: IPmcData, baseGain: number, extractCount: number): number; + /** + * Was extract by car + * @param extractName name of extract + * @returns true if car extract + */ + protected extractWasViaCar(extractName: string): boolean; + /** + * Did player take a COOP extract + * @param extractName Name of extract player took + * @returns True if coop extract + */ + protected extractWasViaCoop(extractName: string): boolean; + /** + * Handle when a player extracts using a coop extract - add rep to fence + * @param sessionId Session/player id + * @param pmcData Profile + * @param extractName Name of extract taken + */ + protected handleCoopExtract(sessionId: string, pmcData: IPmcData, extractName: string): void; + protected sendCoopTakenFenceMessage(sessionId: string): void; +} diff --git a/types/services/LocaleService.d.ts b/types/services/LocaleService.d.ts index 2326dcc1..a14c89c8 100644 --- a/types/services/LocaleService.d.ts +++ b/types/services/LocaleService.d.ts @@ -44,7 +44,7 @@ export declare class LocaleService { * Get the full locale of the computer running the server lowercased e.g. en-gb / pt-pt * @returns string */ - protected getPlatformForServerLocale(): string; + getPlatformForServerLocale(): string; /** * Get the locale of the computer running the server * @returns langage part of locale e.g. 'en' part of 'en-US' diff --git a/types/services/LocationLifecycleService.d.ts b/types/services/LocationLifecycleService.d.ts new file mode 100644 index 00000000..93b1b963 --- /dev/null +++ b/types/services/LocationLifecycleService.d.ts @@ -0,0 +1,220 @@ +import { ApplicationContext } from "@spt/context/ApplicationContext"; +import { LocationLootGenerator } from "@spt/generators/LocationLootGenerator"; +import { LootGenerator } from "@spt/generators/LootGenerator"; +import { PlayerScavGenerator } from "@spt/generators/PlayerScavGenerator"; +import { HealthHelper } from "@spt/helpers/HealthHelper"; +import { InRaidHelper } from "@spt/helpers/InRaidHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; +import { TraderHelper } from "@spt/helpers/TraderHelper"; +import { ILocationBase } from "@spt/models/eft/common/ILocationBase"; +import { IPmcData } from "@spt/models/eft/common/IPmcData"; +import { Common, IQuestStatus, ITraderInfo } from "@spt/models/eft/common/tables/IBotBase"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IEndLocalRaidRequestData, IEndRaidResult } from "@spt/models/eft/match/IEndLocalRaidRequestData"; +import { IStartLocalRaidRequestData } from "@spt/models/eft/match/IStartLocalRaidRequestData"; +import { IStartLocalRaidResponseData } from "@spt/models/eft/match/IStartLocalRaidResponseData"; +import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { IInRaidConfig } from "@spt/models/spt/config/IInRaidConfig"; +import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; +import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; +import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { SaveServer } from "@spt/servers/SaveServer"; +import { BotGenerationCacheService } from "@spt/services/BotGenerationCacheService"; +import { BotLootCacheService } from "@spt/services/BotLootCacheService"; +import { BotNameService } from "@spt/services/BotNameService"; +import { DatabaseService } from "@spt/services/DatabaseService"; +import { InsuranceService } from "@spt/services/InsuranceService"; +import { LocalisationService } from "@spt/services/LocalisationService"; +import { MailSendService } from "@spt/services/MailSendService"; +import { MatchBotDetailsCacheService } from "@spt/services/MatchBotDetailsCacheService"; +import { PmcChatResponseService } from "@spt/services/PmcChatResponseService"; +import { RaidTimeAdjustmentService } from "@spt/services/RaidTimeAdjustmentService"; +import { HashUtil } from "@spt/utils/HashUtil"; +import { RandomUtil } from "@spt/utils/RandomUtil"; +import { TimeUtil } from "@spt/utils/TimeUtil"; +import { ICloner } from "@spt/utils/cloners/ICloner"; +export declare class LocationLifecycleService { + protected logger: ILogger; + protected hashUtil: HashUtil; + protected saveServer: SaveServer; + protected timeUtil: TimeUtil; + protected randomUtil: RandomUtil; + protected profileHelper: ProfileHelper; + protected databaseService: DatabaseService; + protected inRaidHelper: InRaidHelper; + protected healthHelper: HealthHelper; + protected questHelper: QuestHelper; + protected matchBotDetailsCacheService: MatchBotDetailsCacheService; + protected pmcChatResponseService: PmcChatResponseService; + protected playerScavGenerator: PlayerScavGenerator; + protected traderHelper: TraderHelper; + protected localisationService: LocalisationService; + protected insuranceService: InsuranceService; + protected botLootCacheService: BotLootCacheService; + protected configServer: ConfigServer; + protected botGenerationCacheService: BotGenerationCacheService; + protected mailSendService: MailSendService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; + protected botNameService: BotNameService; + protected lootGenerator: LootGenerator; + protected applicationContext: ApplicationContext; + protected locationLootGenerator: LocationLootGenerator; + protected cloner: ICloner; + protected inRaidConfig: IInRaidConfig; + protected traderConfig: ITraderConfig; + protected ragfairConfig: IRagfairConfig; + protected hideoutConfig: IHideoutConfig; + protected locationConfig: ILocationConfig; + protected pmcConfig: IPmcConfig; + constructor(logger: ILogger, hashUtil: HashUtil, saveServer: SaveServer, timeUtil: TimeUtil, randomUtil: RandomUtil, profileHelper: ProfileHelper, databaseService: DatabaseService, inRaidHelper: InRaidHelper, healthHelper: HealthHelper, questHelper: QuestHelper, matchBotDetailsCacheService: MatchBotDetailsCacheService, pmcChatResponseService: PmcChatResponseService, playerScavGenerator: PlayerScavGenerator, traderHelper: TraderHelper, localisationService: LocalisationService, insuranceService: InsuranceService, botLootCacheService: BotLootCacheService, configServer: ConfigServer, botGenerationCacheService: BotGenerationCacheService, mailSendService: MailSendService, raidTimeAdjustmentService: RaidTimeAdjustmentService, botNameService: BotNameService, lootGenerator: LootGenerator, applicationContext: ApplicationContext, locationLootGenerator: LocationLootGenerator, cloner: ICloner); + /** Handle client/match/local/start */ + startLocalRaid(sessionId: string, request: IStartLocalRaidRequestData): IStartLocalRaidResponseData; + /** + * Replace map exits with scav exits when player is scavving + * @param playerSide Playders side (savage/usec/bear) + * @param location id of map being loaded + * @param locationData Maps locationbase data + */ + protected adjustExtracts(playerSide: string, location: string, locationData: ILocationBase): void; + /** + * Adjust the bot hostility values prior to entering a raid + * @param location map to adjust values of + */ + protected adjustBotHostilitySettings(location: ILocationBase): void; + /** + * Generate a maps base location (cloned) and loot + * @param name Map name + * @param generateLoot OPTIONAL - Should loot be generated for the map before being returned + * @returns ILocationBase + */ + protected generateLocationAndLoot(name: string, generateLoot?: boolean): ILocationBase; + /** Handle client/match/local/end */ + endLocalRaid(sessionId: string, request: IEndLocalRaidRequestData): void; + /** + * Was extract by car + * @param extractName name of extract + * @returns True if extract was by car + */ + protected extractWasViaCar(extractName: string): boolean; + /** + * Handle when a player extracts using a car - Add rep to fence + * @param extractName name of the extract used + * @param pmcData Player profile + * @param sessionId Session id + */ + protected handleCarExtract(extractName: string, pmcData: IPmcData, sessionId: string): void; + /** + * Handle when a player extracts using a coop extract - add rep to fence + * @param sessionId Session/player id + * @param pmcData Profile + * @param extractName Name of extract taken + */ + protected handleCoopExtract(sessionId: string, pmcData: IPmcData, extractName: string): void; + /** + * Get the fence rep gain from using a car or coop extract + * @param pmcData Profile + * @param baseGain amount gained for the first extract + * @param extractCount Number of times extract was taken + * @returns Fence standing after taking extract + */ + protected getFenceStandingAfterExtract(pmcData: IPmcData, baseGain: number, extractCount: number): number; + protected sendCoopTakenFenceMessage(sessionId: string): void; + /** + * Did player take a COOP extract + * @param extractName Name of extract player took + * @returns True if coop extract + */ + protected extractTakenWasCoop(extractName: string): boolean; + protected handlePostRaidPlayerScav(sessionId: string, pmcProfile: IPmcData, scavProfile: IPmcData, isDead: boolean, isTransfer: boolean, request: IEndLocalRaidRequestData): void; + /** + * + * @param sessionId Player id + * @param pmcProfile Pmc profile + * @param scavProfile Scav profile + * @param isDead Player died/got left behind in raid + * @param isSurvived Not same as opposite of `isDead`, specific status + * @param request + * @param locationName + */ + protected handlePostRaidPmc(sessionId: string, pmcProfile: IPmcData, scavProfile: IPmcData, isDead: boolean, isSurvived: boolean, isTransfer: boolean, request: IEndLocalRaidRequestData, locationName: string): void; + /** + * On death Quest items are lost, the client does not clean up completed conditions for picking up those quest items, + * If the completed conditions remain in the profile the player is unable to pick the item up again + * @param sessionId Session id + * @param lostQuestItems Quest items lost on player death + * @param profileQuests Quest status data from player profile + */ + protected checkForAndFixPickupQuestsAfterDeath(sessionId: string, lostQuestItems: IItem[], profileQuests: IQuestStatus[]): void; + /** + * In 0.15 Lightkeeper quests do not give rewards in PvE, this issue also occurs in spt + * We check for newly completed Lk quests and run them through the servers `CompleteQuest` process + * This rewards players with items + craft unlocks + new trader assorts + * @param sessionId Session id + * @param postRaidQuests Quest statuses post-raid + * @param preRaidQuests Quest statuses pre-raid + * @param pmcProfile Players profile + */ + protected lightkeeperQuestWorkaround(sessionId: string, postRaidQuests: IQuestStatus[], preRaidQuests: IQuestStatus[], pmcProfile: IPmcData): void; + /** + * Convert post-raid quests into correct format + * Quest status comes back as a string version of the enum `Success`, not the expected value of 1 + * @param questsToProcess quests data from client + * @param preRaidQuestStatuses quest data from before raid + * @returns IQuestStatus + */ + protected processPostRaidQuests(questsToProcess: IQuestStatus[]): IQuestStatus[]; + /** + * Adjust server trader settings if they differ from data sent by client + * @param tradersServerProfile Server + * @param tradersClientProfile Client + */ + protected applyTraderStandingAdjustments(tradersServerProfile: Record, tradersClientProfile: Record): void; + /** + * Check if player used BTR or transit item sending service and send items to player via mail if found + * @param sessionId Session id + * @param request End raid request + */ + protected handleItemTransferEvent(sessionId: string, request: IEndLocalRaidRequestData): void; + protected transferItemDelivery(sessionId: string, traderId: string, items: IItem[]): void; + protected handleInsuredItemLostEvent(sessionId: string, preRaidPmcProfile: IPmcData, request: IEndLocalRaidRequestData, locationName: string): void; + /** + * Return the equipped items from a players inventory + * @param items Players inventory to search through + * @returns an array of equipped items + */ + protected getEquippedGear(items: IItem[]): IItem[]; + /** + * Checks to see if player survives. run through will return false + * @param statusOnExit Exit value from offraidData object + * @returns true if Survived + */ + protected isPlayerSurvived(results: IEndRaidResult): boolean; + /** + * Is the player dead after a raid - dead = anything other than "survived" / "runner" + * @param results Post raid request + * @returns true if dead + */ + protected isPlayerDead(results: IEndRaidResult): boolean; + /** + * Has the player moved from one map to another + * @param results Post raid request + * @returns True if players transfered + */ + protected isMapToMapTransfer(results: IEndRaidResult): boolean; + /** + * Reset the skill points earned in a raid to 0, ready for next raid + * @param commonSkills Profile common skills to update + */ + protected resetSkillPointsEarnedDuringRaid(commonSkills: Common[]): void; + /** + * merge two dictionaries together + * Prioritise pair that has true as a value + * @param primary main dictionary + * @param secondary Secondary dictionary + */ + protected mergePmcAndScavEncyclopedias(primary: IPmcData, secondary: IPmcData): void; +} diff --git a/types/services/MailSendService.d.ts b/types/services/MailSendService.d.ts index 8f1f9749..5887ee7f 100644 --- a/types/services/MailSendService.d.ts +++ b/types/services/MailSendService.d.ts @@ -3,8 +3,8 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper"; import { NotifierHelper } from "@spt/helpers/NotifierHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; -import { Dialogue, ISystemData, IUserDialogInfo, Message, MessageContentRagfair, MessageItems } from "@spt/models/eft/profile/ISptProfile"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { IDialogue, IMessage, IMessageContentRagfair, IMessageItems, ISystemData, IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; import { MessageType } from "@spt/models/enums/MessageType"; import { Traders } from "@spt/models/enums/Traders"; import { IProfileChangeEvent, ISendMessageDetails } from "@spt/models/spt/dialog/ISendMessageDetails"; @@ -37,7 +37,7 @@ export declare class MailSendService { * @param items Optional items to send to player * @param maxStorageTimeSeconds Optional time to collect items before they expire */ - sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: number, systemData?: ISystemData, ragfair?: MessageContentRagfair): void; + sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: IItem[], maxStorageTimeSeconds?: number, systemData?: ISystemData, ragfair?: IMessageContentRagfair): void; /** * Send a message from an NPC (e.g. prapor) to the player with or without items * @param sessionId The session ID to send the message to @@ -47,7 +47,7 @@ export declare class MailSendService { * @param items Optional items to send to player * @param maxStorageTimeSeconds Optional time to collect items before they expire */ - sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: number, systemData?: ISystemData, ragfair?: MessageContentRagfair): void; + sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: IItem[], maxStorageTimeSeconds?: number, systemData?: ISystemData, ragfair?: IMessageContentRagfair): void; /** * Send a message from SYSTEM to the player with or without items * @param sessionId The session ID to send the message to @@ -55,7 +55,7 @@ export declare class MailSendService { * @param items Optional items to send to player * @param maxStorageTimeSeconds Optional time to collect items before they expire */ - sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: number, profileChangeEvents?: IProfileChangeEvent[]): void; + sendSystemMessageToPlayer(sessionId: string, message: string, items?: IItem[], maxStorageTimeSeconds?: number, profileChangeEvents?: IProfileChangeEvent[]): void; /** * Send a message from SYSTEM to the player with or without items with localised text * @param sessionId The session ID to send the message to @@ -63,7 +63,7 @@ export declare class MailSendService { * @param items Optional items to send to player * @param maxStorageTimeSeconds Optional time to collect items before they expire */ - sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], profileChangeEvents?: IProfileChangeEvent[], maxStorageTimeSeconds?: number): void; + sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: IItem[], profileChangeEvents?: IProfileChangeEvent[], maxStorageTimeSeconds?: number): void; /** * Send a USER message to a player with or without items * @param sessionId The session ID to send the message to @@ -72,7 +72,7 @@ export declare class MailSendService { * @param items Optional items to send to player * @param maxStorageTimeSeconds Optional time to collect items before they expire */ - sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: number): void; + sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: IItem[], maxStorageTimeSeconds?: number): void; /** * Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER) * Helper functions in this class are available to simplify common actions @@ -92,34 +92,34 @@ export declare class MailSendService { * @param messageDetails Various details on what the message must contain/do * @returns Message */ - protected createDialogMessage(dialogId: string, messageDetails: ISendMessageDetails): Message; + protected createDialogMessage(dialogId: string, messageDetails: ISendMessageDetails): IMessage; /** * Add items to message and adjust various properties to reflect the items being added * @param message Message to add items to * @param itemsToSendToPlayer Items to add to message * @param maxStorageTimeSeconds total time items are stored in mail before being deleted */ - protected addRewardItemsToMessage(message: Message, itemsToSendToPlayer: MessageItems | undefined, maxStorageTimeSeconds: number | undefined): void; + protected addRewardItemsToMessage(message: IMessage, itemsToSendToPlayer: IMessageItems | undefined, maxStorageTimeSeconds: number | undefined): void; /** * perform various sanitising actions on the items before they're considered ready for insertion into message * @param dialogType The type of the dialog that will hold the reward items being processed * @param messageDetails * @returns Sanitised items */ - protected processItemsBeforeAddingToMail(dialogType: MessageType, messageDetails: ISendMessageDetails): MessageItems; + protected processItemsBeforeAddingToMail(dialogType: MessageType, messageDetails: ISendMessageDetails): IMessageItems; /** * Try to find the most correct item to be the 'primary' item in a reward mail * @param items Possible items to choose from * @returns Chosen 'primary' item */ - protected getBaseItemFromRewards(items: Item[]): Item; + protected getBaseItemFromRewards(items: IItem[]): IItem; /** * Get a dialog with a specified entity (user/trader) * Create and store empty dialog if none exists in profile * @param messageDetails Data on what message should do * @returns Relevant Dialogue */ - protected getDialog(messageDetails: ISendMessageDetails): Dialogue; + protected getDialog(messageDetails: ISendMessageDetails): IDialogue; /** * Get the appropriate sender id by the sender enum type * @param messageDetails diff --git a/types/services/MapMarkerService.d.ts b/types/services/MapMarkerService.d.ts index aed5430b..a3ef6dfd 100644 --- a/types/services/MapMarkerService.d.ts +++ b/types/services/MapMarkerService.d.ts @@ -1,5 +1,5 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IInventoryCreateMarkerRequestData } from "@spt/models/eft/inventory/IInventoryCreateMarkerRequestData"; import { IInventoryDeleteMarkerRequestData } from "@spt/models/eft/inventory/IInventoryDeleteMarkerRequestData"; import { IInventoryEditMarkerRequestData } from "@spt/models/eft/inventory/IInventoryEditMarkerRequestData"; @@ -13,21 +13,21 @@ export declare class MapMarkerService { * @param request Add marker request * @returns Item */ - createMarkerOnMap(pmcData: IPmcData, request: IInventoryCreateMarkerRequestData): Item; + createMarkerOnMap(pmcData: IPmcData, request: IInventoryCreateMarkerRequestData): IItem; /** * Delete a map marker * @param pmcData Player profile * @param request Delete marker request * @returns Item */ - deleteMarkerFromMap(pmcData: IPmcData, request: IInventoryDeleteMarkerRequestData): Item; + deleteMarkerFromMap(pmcData: IPmcData, request: IInventoryDeleteMarkerRequestData): IItem; /** * Edit an existing map marker * @param pmcData Player profile * @param request Edit marker request * @returns Item */ - editMarkerOnMap(pmcData: IPmcData, request: IInventoryEditMarkerRequestData): Item; + editMarkerOnMap(pmcData: IPmcData, request: IInventoryEditMarkerRequestData): IItem; /** * Strip out characters from note string that are not: letter/numbers/unicode/spaces * @param mapNoteText Marker text to sanitise diff --git a/types/services/PaymentService.d.ts b/types/services/PaymentService.d.ts index 61d57318..f6ec79dc 100644 --- a/types/services/PaymentService.d.ts +++ b/types/services/PaymentService.d.ts @@ -4,7 +4,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PaymentHelper } from "@spt/helpers/PaymentHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { IProcessBuyTradeRequestData } from "@spt/models/eft/trade/IProcessBuyTradeRequestData"; import { IProcessSellTradeRequestData } from "@spt/models/eft/trade/IProcessSellTradeRequestData"; @@ -60,13 +60,14 @@ export declare class PaymentService { */ addPaymentToOutput(pmcData: IPmcData, currencyTpl: string, amountToPay: number, sessionID: string, output: IItemEventRouterResponse): void; /** + * TODO - ensure money in containers inside secure container are LAST * Get all money stacks in inventory and prioritise items in stash - * @param pmcData + * @param pmcData Player profile * @param currencyTpl * @param playerStashId Players stash id * @returns Sorting money items */ - protected getSortedMoneyItemsInInventory(pmcData: IPmcData, currencyTpl: string, playerStashId: string): Item[]; + protected getSortedMoneyItemsInInventory(pmcData: IPmcData, currencyTpl: string, playerStashId: string): IItem[]; /** * Prioritise player stash first over player inventory * Post-raid healing would often take money out of the players pockets/secure container @@ -76,7 +77,7 @@ export declare class PaymentService { * @param playerStashId Players stash id * @returns sort order */ - protected prioritiseStashSort(a: Item, b: Item, inventoryItems: Item[], playerStashId: string): number; + protected prioritiseStashSort(a: IItem, b: IItem, inventoryItems: IItem[], playerStashId: string): number; /** * Recursivly check items parents to see if it is inside the players inventory, not stash * @param itemId item id to check @@ -84,5 +85,5 @@ export declare class PaymentService { * @param playerStashId Players stash id * @returns true if its in inventory */ - protected isInStash(itemId: string | undefined, inventoryItems: Item[], playerStashId: string): boolean; + protected isInStash(itemId: string | undefined, inventoryItems: IItem[], playerStashId: string): boolean; } diff --git a/types/services/PmcChatResponseService.d.ts b/types/services/PmcChatResponseService.d.ts index 4a22f102..d1df249c 100644 --- a/types/services/PmcChatResponseService.d.ts +++ b/types/services/PmcChatResponseService.d.ts @@ -1,13 +1,14 @@ import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Aggressor, Victim } from "@spt/models/eft/common/tables/IBotBase"; +import { IAggressor, IVictim } from "@spt/models/eft/common/tables/IBotBase"; import { IUserDialogInfo } from "@spt/models/eft/profile/ISptProfile"; import { IGiftsConfig } from "@spt/models/spt/config/IGiftsConfig"; import { IPmcChatResponse } from "@spt/models/spt/config/IPmChatResponse"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { GiftService } from "@spt/services/GiftService"; +import { LocaleService } from "@spt/services/LocaleService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { MatchBotDetailsCacheService } from "@spt/services/MatchBotDetailsCacheService"; import { HashUtil } from "@spt/utils/HashUtil"; @@ -19,33 +20,42 @@ export declare class PmcChatResponseService { protected notificationSendHelper: NotificationSendHelper; protected matchBotDetailsCacheService: MatchBotDetailsCacheService; protected localisationService: LocalisationService; + protected localeService: LocaleService; protected giftService: GiftService; protected weightedRandomHelper: WeightedRandomHelper; protected configServer: ConfigServer; protected pmcResponsesConfig: IPmcChatResponse; protected giftConfig: IGiftsConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, notificationSendHelper: NotificationSendHelper, matchBotDetailsCacheService: MatchBotDetailsCacheService, localisationService: LocalisationService, giftService: GiftService, weightedRandomHelper: WeightedRandomHelper, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, notificationSendHelper: NotificationSendHelper, matchBotDetailsCacheService: MatchBotDetailsCacheService, localisationService: LocalisationService, localeService: LocaleService, giftService: GiftService, weightedRandomHelper: WeightedRandomHelper, configServer: ConfigServer); /** * For each PMC victim of the player, have a chance to send a message to the player, can be positive or negative * @param sessionId Session id * @param pmcVictims Array of bots killed by player * @param pmcData Player profile */ - sendVictimResponse(sessionId: string, pmcVictims: Victim[], pmcData: IPmcData): void; + sendVictimResponse(sessionId: string, pmcVictims: IVictim[], pmcData: IPmcData): void; /** * Not fully implemented yet, needs method of acquiring killers details after raid * @param sessionId Session id * @param pmcData Players profile * @param killer The bot who killed the player */ - sendKillerResponse(sessionId: string, pmcData: IPmcData, killer: Aggressor): void; + sendKillerResponse(sessionId: string, pmcData: IPmcData, killer: IAggressor): void; /** * Choose a localised message to send the player (different if sender was killed or killed player) * @param isVictim Is the message coming from a bot killed by the player * @param pmcData Player profile + * @param victimData OPTIMAL - details of the pmc killed * @returns Message from PMC to player */ - protected chooseMessage(isVictim: boolean, pmcData: IPmcData): string | undefined; + protected chooseMessage(isVictim: boolean, pmcData: IPmcData, victimData?: IVictim): string | undefined; + /** + * use map key to get a localised location name + * e.g. factory4_day becomes "Factory" + * @param locationKey location key to localise + * @returns Localised location name + */ + protected getLocationName(locationKey: string): string; /** * Should capitalisation be stripped from the message response before sending * @param isVictim Was responder a victim of player @@ -63,7 +73,7 @@ export declare class PmcChatResponseService { * @param isVictim Was responder a victim of player * @returns true = should be stripped */ - appendSuffixToMessageEnd(isVictim: boolean): boolean; + protected appendSuffixToMessageEnd(isVictim: boolean): boolean; /** * Choose a type of response based on the weightings in pmc response config * @param isVictim Was responder killed by player @@ -87,11 +97,11 @@ export declare class PmcChatResponseService { * @param pmcVictims Possible victims to choose from * @returns IUserDialogInfo */ - protected chooseRandomVictim(pmcVictims: Victim[]): IUserDialogInfo; + protected chooseRandomVictim(pmcVictims: IVictim[]): IUserDialogInfo; /** * Convert a victim object into a IUserDialogInfo object * @param pmcVictim victim to convert * @returns IUserDialogInfo */ - protected getVictimDetails(pmcVictim: Victim): IUserDialogInfo; + protected getVictimDetails(pmcVictim: IVictim): IUserDialogInfo; } diff --git a/types/services/PostDbLoadService.d.ts b/types/services/PostDbLoadService.d.ts new file mode 100644 index 00000000..c9e4bbe5 --- /dev/null +++ b/types/services/PostDbLoadService.d.ts @@ -0,0 +1,77 @@ +import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; +import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; +import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; +import { ILootConfig } from "@spt/models/spt/config/ILootConfig"; +import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig"; +import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { CustomLocationWaveService } from "@spt/services/CustomLocationWaveService"; +import { DatabaseService } from "@spt/services/DatabaseService"; +import { ItemBaseClassService } from "@spt/services/ItemBaseClassService"; +import { LocalisationService } from "@spt/services/LocalisationService"; +import { OpenZoneService } from "@spt/services/OpenZoneService"; +import { SeasonalEventService } from "@spt/services/SeasonalEventService"; +import { ICloner } from "@spt/utils/cloners/ICloner"; +export declare class PostDbLoadService { + protected logger: ILogger; + protected databaseService: DatabaseService; + protected localisationService: LocalisationService; + protected customLocationWaveService: CustomLocationWaveService; + protected openZoneService: OpenZoneService; + protected seasonalEventService: SeasonalEventService; + protected itemBaseClassService: ItemBaseClassService; + protected configServer: ConfigServer; + protected cloner: ICloner; + protected coreConfig: ICoreConfig; + protected locationConfig: ILocationConfig; + protected ragfairConfig: IRagfairConfig; + protected hideoutConfig: IHideoutConfig; + protected pmcConfig: IPmcConfig; + protected lootConfig: ILootConfig; + protected botConfig: IBotConfig; + constructor(logger: ILogger, databaseService: DatabaseService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, configServer: ConfigServer, cloner: ICloner); + performPostDbLoadActions(): void; + protected adjustMinReserveRaiderSpawnChance(): void; + protected addCustomLooseLootPositions(): void; + /** + * BSG have two values for shotgun dispersion, we make sure both have the same value + */ + protected fixShotgunDispersions(): void; + /** Apply custom limits on bot types as defined in configs/location.json/botTypeLimits */ + protected adjustMapBotLimits(): void; + protected adjustLooseLootSpawnProbabilities(): void; + /** + * Out of date/incorrectly made trader mods forget this data + */ + protected checkTraderRepairValuesExist(): void; + protected adjustLocationBotValues(): void; + /** + * Make Rogues spawn later to allow for scavs to spawn first instead of rogues filling up all spawn positions + */ + protected fixRoguesSpawningInstantlyOnLighthouse(): void; + /** + * Find and split waves with large numbers of bots into smaller waves - BSG appears to reduce the size of these + * waves to one bot when they're waiting to spawn for too long + */ + protected splitBotWavesIntoSingleWaves(): void; + /** + * Make non-trigger-spawned raiders spawn earlier + always + */ + protected adjustLabsRaiderSpawnRate(): void; + protected adjustHideoutCraftTimes(overrideSeconds: number): void; + /** + * Adjust all hideout craft times to be no higher than the override + */ + protected adjustHideoutBuildTimes(overrideSeconds: number): void; + /** + * Blank out the "test" mail message from prapor + */ + protected removePraporTestMessage(): void; + /** + * Check for any missing assorts inside each traders assort.json data, checking against traders questassort.json + */ + protected validateQuestAssortUnlocksExist(): void; + protected setAllDbItemsAsSellableOnFlea(): void; +} diff --git a/types/services/ProfileFixerService.d.ts b/types/services/ProfileFixerService.d.ts index 91e47808..6ffda1b9 100644 --- a/types/services/ProfileFixerService.d.ts +++ b/types/services/ProfileFixerService.d.ts @@ -4,10 +4,10 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Bonus, HideoutSlot } from "@spt/models/eft/common/tables/IBotBase"; +import { IBonus, IHideoutSlot } from "@spt/models/eft/common/tables/IBotBase"; import { IPmcDataRepeatableQuest, IRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; -import { StageBonus } from "@spt/models/eft/hideout/IHideoutArea"; +import { IStageBonus } from "@spt/models/eft/hideout/IHideoutArea"; import { IEquipmentBuild, IMagazineBuild, ISptProfile, IWeaponBuild } from "@spt/models/eft/profile/ISptProfile"; import { HideoutAreas } from "@spt/models/enums/HideoutAreas"; import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; @@ -49,74 +49,46 @@ export declare class ProfileFixerService { * @param scavProfile profile to check and fix */ checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; - protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; - protected addMissingHallOfFameContainerImprovements(pmcProfile: IPmcData): void; - protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; - protected addHideoutAreaStashes(pmcProfile: IPmcData): void; - protected addMissingHideoutWallAreas(pmcProfile: IPmcData): void; /** - * Add tag to profile to indicate when it was made - * @param fullProfile + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of */ - addMissingSptVersionTagToProfile(fullProfile: ISptProfile): void; + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * TODO - make this non-public - currently used by RepeatableQuestController * Remove unused condition counters * @param pmcProfile profile to remove old counters from */ removeDanglingConditionCounters(pmcProfile: IPmcData): void; - addLighthouseKeeperIfMissing(pmcProfile: IPmcData): void; - protected addUnlockedInfoObjectIfMissing(pmcProfile: IPmcData): void; /** * Repeatable quests leave behind TaskConditionCounter objects that make the profile bloat with time, remove them * @param pmcProfile Player profile to check */ protected removeDanglingTaskConditionCounters(pmcProfile: IPmcData): void; protected getActiveRepeatableQuests(repeatableQuests: IPmcDataRepeatableQuest[]): IRepeatableQuest[]; - protected fixNullRagfairRatings(pmcProfile: IPmcData): void; - protected fixNullTraderSalesSums(pmcProfile: IPmcData): void; - protected addMissingBonusesProperty(pmcProfile: IPmcData): void; - /** - * 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 profile profile to update - */ - protected updateProfileQuestDataValues(profile: IPmcData): void; - protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; - /** - * Some profiles have hideout maxed and therefore no improvements - * @param pmcProfile Profile to add improvement data to - */ - protected addMissingWallImprovements(pmcProfile: IPmcData): void; /** - * A new property was added to slot items "locationIndex", if this is missing, the hideout slot item must be removed - * @param pmcProfile Profile to find and remove slots from + * After removing mods that add quests, the quest panel will break without removing these + * @param pmcProfile Profile to remove dead quests from */ - protected removeResourcesFromSlotsInHideoutWithoutLocationIndexValue(pmcProfile: IPmcData): void; + protected removeOrphanedQuests(pmcProfile: IPmcData): void; /** - * Hideout slots need to be in a specific order, locationIndex in ascending order - * @param pmcProfile profile to edit + * If the profile has elite Hideout Managment skill, add the additional slots from globals + * NOTE: This seems redundant, but we will leave it here just incase. + * @param pmcProfile profile to add slots to */ - protected reorderHideoutAreasWithResouceInputs(pmcProfile: IPmcData): void; + protected addHideoutEliteSlots(pmcProfile: IPmcData): void; /** * add in objects equal to the number of slots * @param areaType area to check * @param pmcProfile profile to update */ protected addEmptyObjectsToHideoutAreaSlots(areaType: HideoutAreas, emptyItemCount: number, pmcProfile: IPmcData): void; - protected addObjectsToArray(count: number, slots: HideoutSlot[]): HideoutSlot[]; + protected addObjectsToArray(count: number, slots: IHideoutSlot[]): IHideoutSlot[]; /** - * Iterate over players hideout areas and find what's build, look for missing bonuses those areas give and add them if missing - * @param pmcProfile Profile to update - */ - addMissingHideoutBonusesToProfile(pmcProfile: IPmcData): void; - /** - * @param profileBonuses bonuses from profile - * @param bonus bonus to find - * @returns matching bonus + * Check for and cap profile skills at 5100. + * @param pmcProfile profile to check and fix */ - protected getBonusFromProfile(profileBonuses: Bonus[], bonus: StageBonus): Bonus | undefined; + protected checkForSkillsOverMaxLevel(pmcProfile: IPmcData): void; /** * Checks profile inventiory for items that do not exist inside the items db * @param sessionId Session id @@ -137,58 +109,16 @@ export declare class ProfileFixerService { */ protected shouldRemoveMagazineBuild(magazineBuild: IMagazineBuild, itemsDb: Record): boolean; /** - * 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 - */ - addMissingUpgradesPropertyToHideout(pmcProfile: IPmcData): void; - /** - * Iterate over associated profile template and check all hideout areas exist, add if not - * @param fullProfile Profile to update - */ - addMissingHideoutAreasToProfile(fullProfile: ISptProfile): void; - /** - * These used to be used for storing scav case rewards, rewards are now generated on pickup + * REQUIRED for dev profiles + * Iterate over players hideout areas and find what's build, look for missing bonuses those areas give and add them if missing * @param pmcProfile Profile to update */ - removeLegacyScavCaseProductionCrafts(pmcProfile: IPmcData): void; - /** - * 3.7.0 moved AIDs to be numeric, old profiles need to be migrated - * We store the old AID value in new field `sessionId` - * @param fullProfile Profile to update - */ - fixIncorrectAidValue(fullProfile: ISptProfile): void; - /** - * Bsg nested `stats` into a sub object called 'eft' - * @param fullProfile Profile to check for and migrate stats data - */ - migrateStatsToNewStructure(fullProfile: ISptProfile): void; - /** - * 26126 (7th August) requires bonuses to have an ID, these were not included in the default profile presets - * @param pmcProfile Profile to add missing IDs to - */ - addMissingIdsToBonuses(pmcProfile: IPmcData): void; - /** - * 3.8.0 utilized the wrong ProductionTime for bitcoin, fix it if it's found - */ - fixBitcoinProductionTime(pmcProfile: IPmcData): void; - /** - * At some point the property name was changed,migrate data across to new name - * @param pmcProfile Profile to migrate improvements in - */ - protected migrateImprovements(pmcProfile: IPmcData): void; - /** - * After removing mods that add quests, the quest panel will break without removing these - * @param pmcProfile Profile to remove dead quests from - */ - protected removeOrphanedQuests(pmcProfile: IPmcData): void; + addMissingHideoutBonusesToProfile(pmcProfile: IPmcData): void; /** - * If someone has run a mod from pre-3.8.0, it results in an invalid `nextResupply` value - * Resolve this by setting the nextResupply to 0 if it's undefined + * @param profileBonuses bonuses from profile + * @param bonus bonus to find + * @returns matching bonus */ - protected fixNullTraderNextResupply(pmcProfile: IPmcData): void; + protected getBonusFromProfile(profileBonuses: IBonus[], bonus: IStageBonus): IBonus | undefined; + checkForAndRemoveInvalidTraders(fullProfile: ISptProfile): void; } diff --git a/types/services/ProfileSnapshotService.d.ts b/types/services/ProfileSnapshotService.d.ts deleted file mode 100644 index 4492ddae..00000000 --- a/types/services/ProfileSnapshotService.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; -import { ICloner } from "@spt/utils/cloners/ICloner"; -export declare class ProfileSnapshotService { - protected cloner: ICloner; - protected storedProfileSnapshots: Record; - constructor(cloner: ICloner); - /** - * Store a profile into an in-memory object - * @param sessionID session id - acts as the key - * @param profile - profile to save - */ - storeProfileSnapshot(sessionID: string, profile: ISptProfile): void; - /** - * Retreve a stored profile - * @param sessionID key - * @returns A player profile object - */ - getProfileSnapshot(sessionID: string): ISptProfile | undefined; - /** - * Does a profile exists against the provided key - * @param sessionID key - * @returns true if exists - */ - hasProfileSnapshot(sessionID: string): boolean; - /** - * Remove a stored profile by key - * @param sessionID key - */ - clearProfileSnapshot(sessionID: string): void; -} diff --git a/types/services/RagfairLinkedItemService.d.ts b/types/services/RagfairLinkedItemService.d.ts index 0d03459c..c9509d0f 100644 --- a/types/services/RagfairLinkedItemService.d.ts +++ b/types/services/RagfairLinkedItemService.d.ts @@ -1,11 +1,13 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseService } from "@spt/services/DatabaseService"; export declare class RagfairLinkedItemService { protected databaseService: DatabaseService; protected itemHelper: ItemHelper; + protected logger: ILogger; protected linkedItemsCache: Record>; - constructor(databaseService: DatabaseService, itemHelper: ItemHelper); + constructor(databaseService: DatabaseService, itemHelper: ItemHelper, logger: ILogger); getLinkedItems(linkedSearchId: string): Set; /** * Use ragfair linked item service to get an array of items that can fit on or in designated itemtpl diff --git a/types/services/RagfairOfferService.d.ts b/types/services/RagfairOfferService.d.ts index 98dd1799..7f28fe08 100644 --- a/types/services/RagfairOfferService.d.ts +++ b/types/services/RagfairOfferService.d.ts @@ -1,7 +1,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { RagfairServerHelper } from "@spt/helpers/RagfairServerHelper"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; @@ -10,6 +10,7 @@ import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; import { DatabaseService } from "@spt/services/DatabaseService"; import { LocalisationService } from "@spt/services/LocalisationService"; +import { HashUtil } from "@spt/utils/HashUtil"; import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; import { RagfairOfferHolder } from "@spt/utils/RagfairOfferHolder"; import { TimeUtil } from "@spt/utils/TimeUtil"; @@ -17,6 +18,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class RagfairOfferService { protected logger: ILogger; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected databaseService: DatabaseService; protected saveServer: SaveServer; protected ragfairServerHelper: RagfairServerHelper; @@ -32,7 +34,7 @@ export declare class RagfairOfferService { protected expiredOffers: Record; protected ragfairConfig: IRagfairConfig; protected ragfairOfferHandler: RagfairOfferHolder; - constructor(logger: ILogger, timeUtil: TimeUtil, databaseService: DatabaseService, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, localisationService: LocalisationService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, timeUtil: TimeUtil, hashUtil: HashUtil, databaseService: DatabaseService, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, localisationService: LocalisationService, configServer: ConfigServer, cloner: ICloner); /** * Get all offers * @returns IRagfairOffer array @@ -51,7 +53,7 @@ export declare class RagfairOfferService { * Get an array of arrays of expired offer items + children * @returns Expired offer assorts */ - getExpiredOfferAssorts(): Item[][]; + getExpiredOfferAssorts(): IItem[][]; /** * Clear out internal expiredOffers dictionary of all items */ @@ -95,5 +97,5 @@ export declare class RagfairOfferService { * @param items Offer items to unstack * @returns Unstacked array of items */ - protected unstackOfferItems(items: Item[]): Item[]; + protected unstackOfferItems(items: IItem[]): IItem[]; } diff --git a/types/services/RagfairPriceService.d.ts b/types/services/RagfairPriceService.d.ts index 0a2f26e4..0284aee3 100644 --- a/types/services/RagfairPriceService.d.ts +++ b/types/services/RagfairPriceService.d.ts @@ -5,8 +5,8 @@ import { PresetHelper } from "@spt/helpers/PresetHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { MinMax } from "@spt/models/common/MinMax"; import { IPreset } from "@spt/models/eft/common/IGlobals"; -import { HandbookItem } from "@spt/models/eft/common/tables/IHandbookBase"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IHandbookItem } from "@spt/models/eft/common/tables/IHandbookBase"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IRagfairConfig, IUnreasonableModPrices } from "@spt/models/spt/config/IRagfairConfig"; import { IRagfairServerPrices } from "@spt/models/spt/ragfair/IRagfairServerPrices"; @@ -56,7 +56,7 @@ export declare class RagfairPriceService implements OnLoad { * @param offerItems offer item + children to process * @returns Rouble price */ - getFleaPriceForOfferItems(offerItems: Item[]): number; + getFleaPriceForOfferItems(offerItems: IItem[]): number; /** * get the dynamic (flea) price for an item * @param itemTpl item template id to look up @@ -96,7 +96,7 @@ export declare class RagfairPriceService implements OnLoad { * @param isPackOffer Price is for a pack type offer * @returns cost of item in desired currency */ - getDynamicOfferPriceForOffer(offerItems: Item[], desiredCurrency: string, isPackOffer: boolean): number; + getDynamicOfferPriceForOffer(offerItems: IItem[], desiredCurrency: string, isPackOffer: boolean): number; /** * @param itemTemplateId items tpl value * @param desiredCurrency Currency to return result in @@ -105,7 +105,7 @@ export declare class RagfairPriceService implements OnLoad { * @param isPackOffer * @returns */ - getDynamicItemPrice(itemTemplateId: string, desiredCurrency: string, item?: Item, offerItems?: Item[], isPackOffer?: boolean): number; + getDynamicItemPrice(itemTemplateId: string, desiredCurrency: string, item?: IItem, offerItems?: IItem[], isPackOffer?: boolean): number; /** * using data from config, adjust an items price to be relative to its handbook price * @param handbookPrices Prices of items in handbook @@ -114,7 +114,7 @@ export declare class RagfairPriceService implements OnLoad { * @param price Current price of item * @returns Adjusted price of item */ - protected adjustUnreasonablePrice(handbookPrices: HandbookItem[], unreasonableItemChange: IUnreasonableModPrices, itemTpl: string, price: number): number; + protected adjustUnreasonablePrice(handbookPrices: IHandbookItem[], unreasonableItemChange: IUnreasonableModPrices, itemTpl: string, price: number): number; /** * Get different min/max price multipliers for different offer types (preset/pack/default) * @param isPreset Offer is a preset @@ -143,7 +143,7 @@ export declare class RagfairPriceService implements OnLoad { * @param existingPrice price of existing base weapon * @returns price of weapon in roubles */ - protected getWeaponPresetPrice(weaponRootItem: Item, weaponWithChildren: Item[], existingPrice: number): number; + protected getWeaponPresetPrice(weaponRootItem: IItem, weaponWithChildren: IItem[], existingPrice: number): number; /** * Get the highest price for an item that is stored in handbook or trader assorts * @param itemTpl Item to get highest price of @@ -156,7 +156,7 @@ export declare class RagfairPriceService implements OnLoad { * @param presets weapon presets to choose from * @returns Default preset object */ - protected getWeaponPreset(weapon: Item): { + protected getWeaponPreset(weapon: IItem): { isDefault: boolean; preset: IPreset; }; diff --git a/types/services/RagfairTaxService.d.ts b/types/services/RagfairTaxService.d.ts index effb9f06..f42f1e8f 100644 --- a/types/services/RagfairTaxService.d.ts +++ b/types/services/RagfairTaxService.d.ts @@ -1,18 +1,22 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IStorePlayerOfferTaxAmountRequestData } from "@spt/models/eft/ragfair/IStorePlayerOfferTaxAmountRequestData"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseService } from "@spt/services/DatabaseService"; import { RagfairPriceService } from "@spt/services/RagfairPriceService"; +import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class RagfairTaxService { protected logger: ILogger; protected databaseService: DatabaseService; protected ragfairPriceService: RagfairPriceService; protected itemHelper: ItemHelper; + protected profileHelper: ProfileHelper; + protected cloner: ICloner; protected playerOfferTaxCache: Record; - constructor(logger: ILogger, databaseService: DatabaseService, ragfairPriceService: RagfairPriceService, itemHelper: ItemHelper); + constructor(logger: ILogger, databaseService: DatabaseService, ragfairPriceService: RagfairPriceService, itemHelper: ItemHelper, profileHelper: ProfileHelper, cloner: ICloner); storeClientOfferTaxValue(sessionId: string, offer: IStorePlayerOfferTaxAmountRequestData): void; clearStoredOfferTaxById(offerIdToRemove: string): void; getStoredClientOfferTaxValueById(offerIdToGet: string): IStorePlayerOfferTaxAmountRequestData; @@ -26,6 +30,6 @@ export declare class RagfairTaxService { * @param sellInOnePiece * @returns Tax in roubles */ - calculateTax(item: Item, pmcData: IPmcData, requirementsValue: number, offerItemCount: number, sellInOnePiece: boolean): number; - protected calculateItemWorth(item: Item, itemTemplate: ITemplateItem, itemCount: number, pmcData: IPmcData, isRootItem?: boolean): number; + calculateTax(item: IItem, pmcData: IPmcData, requirementsValue: number, offerItemCount: number, sellInOnePiece: boolean): number; + protected calculateItemWorth(item: IItem, itemTemplate: ITemplateItem, itemCount: number, pmcData: IPmcData, isRootItem?: boolean): number; } diff --git a/types/services/RaidTimeAdjustmentService.d.ts b/types/services/RaidTimeAdjustmentService.d.ts index bfc099ae..3f32776e 100644 --- a/types/services/RaidTimeAdjustmentService.d.ts +++ b/types/services/RaidTimeAdjustmentService.d.ts @@ -3,7 +3,7 @@ import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { ILocationBase } from "@spt/models/eft/common/ILocationBase"; import { IGetRaidTimeRequest } from "@spt/models/eft/game/IGetRaidTimeRequest"; import { ExtractChange, IGetRaidTimeResponse } from "@spt/models/eft/game/IGetRaidTimeResponse"; -import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt/models/spt/config/ILocationConfig"; +import { ILocationConfig, ILootMultiplier, IScavRaidTimeLocationSettings } from "@spt/models/spt/config/ILocationConfig"; import { IRaidChanges } from "@spt/models/spt/location/IRaidChanges"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -30,7 +30,7 @@ export declare class RaidTimeAdjustmentService { * @param mapLootMultiplers Multiplers to adjust * @param loosePercent Percent to change values to */ - protected adjustLootMultipliers(mapLootMultiplers: LootMultiplier, loosePercent: number): void; + protected adjustLootMultipliers(mapLootMultiplers: ILootMultiplier, loosePercent: number): void; /** * Adjust bot waves to act as if player spawned later * @param mapBase map to adjust diff --git a/types/services/RaidWeatherService.d.ts b/types/services/RaidWeatherService.d.ts new file mode 100644 index 00000000..fd82da24 --- /dev/null +++ b/types/services/RaidWeatherService.d.ts @@ -0,0 +1,43 @@ +import { WeatherGenerator } from "@spt/generators/WeatherGenerator"; +import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; +import { IWeather } from "@spt/models/eft/weather/IWeatherData"; +import { Season } from "@spt/models/enums/Season"; +import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +import { DatabaseService } from "@spt/services/DatabaseService"; +import { SeasonalEventService } from "@spt/services/SeasonalEventService"; +import { TimeUtil } from "@spt/utils/TimeUtil"; +export declare class RaidWeatherService { + protected logger: ILogger; + protected databaseService: DatabaseService; + protected timeUtil: TimeUtil; + protected weatherGenerator: WeatherGenerator; + protected seasonalEventService: SeasonalEventService; + protected weightedRandomHelper: WeightedRandomHelper; + protected configServer: ConfigServer; + protected weatherConfig: IWeatherConfig; + protected weatherForecast: IWeather[]; + constructor(logger: ILogger, databaseService: DatabaseService, timeUtil: TimeUtil, weatherGenerator: WeatherGenerator, seasonalEventService: SeasonalEventService, weightedRandomHelper: WeightedRandomHelper, configServer: ConfigServer); + /** + * Generate 24 hours of weather data starting from midnight today + */ + generateWeather(currentSeason: Season): void; + /** + * Get a time period to increment by, e.g 15 or 30 minutes as milliseconds + * @returns milliseconds + */ + protected getWeightedWeatherTimePeriodMs(): number; + /** + * Find the first matching weather object that applies to the current time + */ + getCurrentWeather(): IWeather; + /** + * Find the first matching weather object that applies to the current time + all following weather data generated + */ + getUpcomingWeather(): IWeather[]; + /** + * Ensure future weather data exists + */ + protected validateWeatherDataExists(currentSeason: Season): void; +} diff --git a/types/services/RepairService.d.ts b/types/services/RepairService.d.ts index 48f306e1..c4772cf4 100644 --- a/types/services/RepairService.d.ts +++ b/types/services/RepairService.d.ts @@ -4,14 +4,14 @@ import { RepairHelper } from "@spt/helpers/RepairHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; -import { Item } from "@spt/models/eft/common/tables/IItem"; +import { IItem } from "@spt/models/eft/common/tables/IItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { RepairKitsInfo } from "@spt/models/eft/repair/IRepairActionDataRequest"; -import { RepairItem } from "@spt/models/eft/repair/ITraderRepairActionDataRequest"; +import { IRepairKitsInfo } from "@spt/models/eft/repair/IRepairActionDataRequest"; +import { IRepairItem } from "@spt/models/eft/repair/ITraderRepairActionDataRequest"; import { BonusType } from "@spt/models/enums/BonusType"; import { SkillTypes } from "@spt/models/enums/SkillTypes"; -import { BonusSettings, IRepairConfig } from "@spt/models/spt/config/IRepairConfig"; +import { IBonusSettings, IRepairConfig } from "@spt/models/spt/config/IRepairConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { DatabaseService } from "@spt/services/DatabaseService"; @@ -40,7 +40,7 @@ export declare class RepairService { * @param traderId Trader being used to repair item * @returns RepairDetails object */ - repairItemByTrader(sessionID: string, pmcData: IPmcData, repairItemDetails: RepairItem, traderId: string): RepairDetails; + repairItemByTrader(sessionID: string, pmcData: IPmcData, repairItemDetails: IRepairItem, traderId: string): RepairDetails; /** * @param sessionID Session id * @param pmcData profile to take money from @@ -72,7 +72,7 @@ export declare class RepairService { * @param output IItemEventRouterResponse * @returns Details of repair, item/price */ - repairItemByKit(sessionId: string, pmcData: IPmcData, repairKits: RepairKitsInfo[], itemToRepairId: string, output: IItemEventRouterResponse): RepairDetails; + repairItemByKit(sessionId: string, pmcData: IPmcData, repairKits: IRepairKitsInfo[], itemToRepairId: string, output: IItemEventRouterResponse): RepairDetails; /** * Calculate value repairkit points need to be divided by to get the durability points to be added to an item * @param itemToRepairDetails Item to repair details @@ -100,7 +100,7 @@ export declare class RepairService { * @param repairKitDetails Repair kit details from db * @param repairKitInInventory Repair kit to update */ - protected addMaxResourceToKitIfMissing(repairKitDetails: ITemplateItem, repairKitInInventory: Item): void; + protected addMaxResourceToKitIfMissing(repairKitDetails: ITemplateItem, repairKitInInventory: IItem): void; /** * Chance to apply buff to an item (Armor/weapon) if repaired by armor kit * @param repairDetails Repair details of item @@ -112,7 +112,7 @@ export declare class RepairService { * @param itemConfig weapon/armor config * @param repairDetails Details for item to repair */ - addBuff(itemConfig: BonusSettings, item: Item): void; + addBuff(itemConfig: IBonusSettings, item: IItem): void; /** * Check if item should be buffed by checking the item type and relevant player skill level * @param repairDetails Item that was repaired @@ -138,7 +138,7 @@ export declare class RepairService { export declare class RepairDetails { repairCost?: number; repairPoints?: number; - repairedItem: Item; + repairedItem: IItem; repairedItemIsArmor: boolean; repairAmount: number; repairedByKit: boolean; diff --git a/types/services/SeasonalEventService.d.ts b/types/services/SeasonalEventService.d.ts index 0750f387..d239ee97 100644 --- a/types/services/SeasonalEventService.d.ts +++ b/types/services/SeasonalEventService.d.ts @@ -1,12 +1,14 @@ import { BotHelper } from "@spt/helpers/BotHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { IConfig } from "@spt/models/eft/common/IGlobals"; -import { Inventory } from "@spt/models/eft/common/tables/IBotType"; +import { IAdditionalHostilitySettings } from "@spt/models/eft/common/ILocationBase"; +import { IInventory } from "@spt/models/eft/common/tables/IBotType"; import { Season } from "@spt/models/enums/Season"; import { SeasonalEventType } from "@spt/models/enums/SeasonalEventType"; import { IHttpConfig } from "@spt/models/spt/config/IHttpConfig"; +import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig"; -import { ISeasonalEvent, ISeasonalEventConfig } from "@spt/models/spt/config/ISeasonalEventConfig"; +import { ISeasonalEvent, ISeasonalEventConfig, IZombieSettings } from "@spt/models/spt/config/ISeasonalEventConfig"; import { IWeatherConfig } from "@spt/models/spt/config/IWeatherConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -27,10 +29,11 @@ export declare class SeasonalEventService { protected questConfig: IQuestConfig; protected httpConfig: IHttpConfig; protected weatherConfig: IWeatherConfig; + protected locationConfig: ILocationConfig; protected halloweenEventActive?: boolean; protected christmasEventActive?: boolean; /** All events active at this point in time */ - protected currentlyActiveEvents: SeasonalEventType[]; + protected currentlyActiveEvents: ISeasonalEvent[]; constructor(logger: ILogger, databaseService: DatabaseService, databaseImporter: DatabaseImporter, giftService: GiftService, localisationService: LocalisationService, botHelper: BotHelper, profileHelper: ProfileHelper, configServer: ConfigServer); protected get christmasEventItems(): string[]; protected get halloweenEventItems(): string[]; @@ -98,28 +101,56 @@ export declare class SeasonalEventService { */ isQuestRelatedToEvent(questId: string, event: SeasonalEventType): boolean; /** - * Handle seasonal events - * @param sessionId Players id + * Handle activating seasonal events + */ + enableSeasonalEvents(): void; + forceSeasonalEvent(eventType: SeasonalEventType): boolean; + /** + * Store active events inside class array property `currentlyActiveEvents` + set class properties: christmasEventActive/halloweenEventActive */ - enableSeasonalEvents(sessionId: string): void; protected cacheActiveEvents(): void; + /** + * Get the currently active weather season e.g. SUMMER/AUTUMN/WINTER + * @returns Season enum value + */ getActiveWeatherSeason(): Season; /** * Iterate through bots inventory and loot to find and remove christmas items (as defined in SeasonalEventService) * @param botInventory Bots inventory to iterate over * @param botRole the role of the bot being processed */ - removeChristmasItemsFromBotInventory(botInventory: Inventory, botRole: string): void; + removeChristmasItemsFromBotInventory(botInventory: IInventory, botRole: string): void; /** * Make adjusted to server code based on the name of the event passed in - * @param sessionId Player id * @param globalConfig globals.json * @param eventName Name of the event to enable. e.g. Christmas */ - protected updateGlobalEvents(sessionId: string, globalConfig: IConfig, eventType: SeasonalEventType): void; + protected updateGlobalEvents(globalConfig: IConfig, event: ISeasonalEvent): void; + protected replaceBotHostility(hostilitySettings: Record): void; + protected removeEntryRequirement(locationIds: string[]): void; + givePlayerSeasonalGifts(sessionId: string): void; + /** + * Force zryachiy to always have a melee weapon + */ protected adjustZryachiyMeleeChance(): void; + /** + * Enable the halloween zryachiy summon event + */ protected enableHalloweenSummonEvent(): void; - protected addEventBossesToMaps(eventType: SeasonalEventType): void; + protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs + * @param infectedLocationKey Key to convert + * @returns Array of locations + */ + protected getLocationFromInfectedLocation(infectedLocationKey: string): string[]; + protected addEventWavesToMaps(eventType: string): void; + /** + * Add event bosses to maps + * @param eventType Seasonal event, e.g. HALLOWEEN/CHRISTMAS + * @param mapWhitelist OPTIONAL - Maps to add bosses to + */ + protected addEventBossesToMaps(eventType: string, mapIdWhitelist?: string[]): void; /** * Change trader icons to be more event themed (Halloween only so far) * @param eventType What event is active @@ -134,7 +165,11 @@ export declare class SeasonalEventService { * @param eventName Name of the event to read equipment in from config */ protected addEventGearToBots(eventType: SeasonalEventType): void; + /** + * Add pumpkin loot boxes to scavs + */ protected addPumpkinsToScavBackpacks(): void; + protected renameBitcoin(): void; /** * Set Khorovod(dancing tree) chance to 100% on all maps that support it */ @@ -143,6 +178,7 @@ export declare class SeasonalEventService { * Add santa to maps */ protected addGifterBotToMaps(): void; + protected handleModEvent(event: ISeasonalEvent): void; /** * Send gift to player if they'e not already received it * @param playerId Player to send gift to @@ -155,5 +191,8 @@ export declare class SeasonalEventService { * @returns Bot role as string */ getBaseRoleForEventBot(eventBotRole: string): string; + /** + * Force the weather to be snow + */ enableSnow(): void; } diff --git a/types/services/TraderPurchasePersisterService.d.ts b/types/services/TraderPurchasePersisterService.d.ts index 6bef9f5e..ba85a678 100644 --- a/types/services/TraderPurchasePersisterService.d.ts +++ b/types/services/TraderPurchasePersisterService.d.ts @@ -1,5 +1,5 @@ import { ProfileHelper } from "@spt/helpers/ProfileHelper"; -import { TraderPurchaseData } from "@spt/models/eft/profile/ISptProfile"; +import { ITraderPurchaseData } from "@spt/models/eft/profile/ISptProfile"; import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -24,7 +24,7 @@ export declare class TraderPurchasePersisterService { * @param traderId Trader to loop up purchases for * @returns Dict of assort id and count purchased */ - getProfileTraderPurchases(sessionId: string, traderId: string): Record | undefined; + getProfileTraderPurchases(sessionId: string, traderId: string): Record | undefined; /** * Get a purchase made from a trader for requested profile before the last trader reset * @param sessionId Session id @@ -32,7 +32,7 @@ export declare class TraderPurchasePersisterService { * @param assortId Id of assort to get data for * @returns TraderPurchaseData */ - getProfileTraderPurchase(sessionId: string, traderId: string, assortId: string): TraderPurchaseData | undefined; + getProfileTraderPurchase(sessionId: string, traderId: string, assortId: string): ITraderPurchaseData | undefined; /** * Remove all trader purchase records from all profiles that exist * @param traderId Traders id diff --git a/types/services/TraderServicesService.d.ts b/types/services/TraderServicesService.d.ts deleted file mode 100644 index e441eb62..00000000 --- a/types/services/TraderServicesService.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ProfileHelper } from "@spt/helpers/ProfileHelper"; -import { ITraderServiceModel } from "@spt/models/spt/services/ITraderServiceModel"; -import { ILogger } from "@spt/models/spt/utils/ILogger"; -import { DatabaseService } from "@spt/services/DatabaseService"; -import { ICloner } from "@spt/utils/cloners/ICloner"; -export declare class TraderServicesService { - protected profileHelper: ProfileHelper; - protected logger: ILogger; - protected databaseService: DatabaseService; - protected cloner: ICloner; - constructor(profileHelper: ProfileHelper, logger: ILogger, databaseService: DatabaseService, cloner: ICloner); - getTraderServices(sessionId: string, traderId: string): ITraderServiceModel[]; -} diff --git a/types/services/mod/CustomItemService.d.ts b/types/services/mod/CustomItemService.d.ts index f112872e..bbc0453c 100644 --- a/types/services/mod/CustomItemService.d.ts +++ b/types/services/mod/CustomItemService.d.ts @@ -1,5 +1,5 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; -import { ITemplateItem, Props } from "@spt/models/eft/common/tables/ITemplateItem"; +import { IProps, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { CreateItemResult, LocaleDetails, NewItemDetails, NewItemFromCloneDetails } from "@spt/models/spt/mod/NewItemDetails"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { DatabaseService } from "@spt/services/DatabaseService"; @@ -47,7 +47,7 @@ export declare class CustomItemService { * @param overrideProperties new properties to apply * @param itemClone item to update */ - protected updateBaseItemPropertiesWithOverrides(overrideProperties: Props, itemClone: ITemplateItem): void; + protected updateBaseItemPropertiesWithOverrides(overrideProperties: IProps, itemClone: ITemplateItem): void; /** * Addd a new item object to the in-memory representation of items.json * @param newItemId id of the item to add to items.json diff --git a/types/services/mod/httpListener/HttpListenerMod.d.ts b/types/services/mod/httpListener/HttpListenerMod.d.ts index 75e42eef..84c46c3c 100644 --- a/types/services/mod/httpListener/HttpListenerMod.d.ts +++ b/types/services/mod/httpListener/HttpListenerMod.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { IHttpListener } from "@spt/servers/http/IHttpListener"; export declare class HttpListenerMod implements IHttpListener { diff --git a/types/services/mod/httpListener/HttpListenerModService.d.ts b/types/services/mod/httpListener/HttpListenerModService.d.ts index 23abfbed..ba73afe3 100644 --- a/types/services/mod/httpListener/HttpListenerModService.d.ts +++ b/types/services/mod/httpListener/HttpListenerModService.d.ts @@ -1,4 +1,3 @@ -/// import { IncomingMessage, ServerResponse } from "node:http"; import { DependencyContainer } from "tsyringe"; export declare class HttpListenerModService { diff --git a/types/tools/ItemTplGenerator/itemOverrides.d.ts b/types/tools/ItemTplGenerator/itemOverrides.d.ts index fb2ba9a2..5c4914a0 100644 --- a/types/tools/ItemTplGenerator/itemOverrides.d.ts +++ b/types/tools/ItemTplGenerator/itemOverrides.d.ts @@ -31,6 +31,7 @@ declare const _default: { "5a29276886f77435ed1b117c": string; "628393620d8524273e7eb028": string; "638dfc803083a019d447768e": string; + "66760b3deb51b08bd40c2b08": string; "638e0057ab150a5f56238960": string; "6393262086e646067c176aa2": string; "63989ced706b793c7d60cfef": string; @@ -54,12 +55,14 @@ declare const _default: { "6614230055afee107f05e998": string; "661421c7c1f2f548c50ee649": string; "661423200d240a5f5d0f679b": string; + "66a0f0926fee20fa70036da6": string; "5d1340b3d7ad1a0b52682ed7": string; "55802d5f4bdc2dac148b458e": string; "5d1340cad7ad1a0b0b249869": string; "5d1340bdd7ad1a0e8d245aab": string; "5cbdaf89ae9215000e5b9c94": string; "5e21a3c67e40bd02257a008a": string; + "6241c2c2117ad530666a5108": string; "5914944186f774189e5e76c2": string; "5937ef2b86f77408a47244b3": string; "59387ac686f77401442ddd61": string; @@ -71,5 +74,7 @@ declare const _default: { "5e81ebcd8e146c7080625e15": string; "639c3fbbd0446708ee622ee9": string; "639af924d0446708ee62294e": string; + "66da1b49099cf6adcc07a36b": string; + "66da1b546916142b3b022777": string; }; export default _default; diff --git a/types/tools/ProductionQuestsGen/ProductionQuestsGen.d.ts b/types/tools/ProductionQuestsGen/ProductionQuestsGen.d.ts new file mode 100644 index 00000000..960f8ae0 --- /dev/null +++ b/types/tools/ProductionQuestsGen/ProductionQuestsGen.d.ts @@ -0,0 +1,16 @@ +import { OnLoad } from "@spt/di/OnLoad"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { DatabaseServer } from "@spt/servers/DatabaseServer"; +export declare class ProductionQuestsGen { + protected databaseServer: DatabaseServer; + protected logger: ILogger; + protected onLoadComponents: OnLoad[]; + private questProductionOutputList; + private questProductionMap; + private blacklistedProductions; + constructor(databaseServer: DatabaseServer, logger: ILogger, onLoadComponents: OnLoad[]); + run(): Promise; + private updateProductionQuests; + private isValidQuestProduction; + private buildQuestProductionList; +} diff --git a/types/tools/ProductionQuestsGen/ProductionQuestsGenProgram.d.ts b/types/tools/ProductionQuestsGen/ProductionQuestsGenProgram.d.ts new file mode 100644 index 00000000..56637380 --- /dev/null +++ b/types/tools/ProductionQuestsGen/ProductionQuestsGenProgram.d.ts @@ -0,0 +1,7 @@ +import "reflect-metadata"; +import "source-map-support/register"; +export declare class ProductionQuestsGenProgram { + private errorHandler; + constructor(); + start(): Promise; +} diff --git a/types/utils/App.d.ts b/types/utils/App.d.ts index 211044e8..0e4850ea 100644 --- a/types/utils/App.d.ts +++ b/types/utils/App.d.ts @@ -7,6 +7,7 @@ import { HttpServer } from "@spt/servers/HttpServer"; import { LocalisationService } from "@spt/services/LocalisationService"; import { EncodingUtil } from "@spt/utils/EncodingUtil"; import { TimeUtil } from "@spt/utils/TimeUtil"; +import { DatabaseService } from "@spt/services/DatabaseService"; export declare class App { protected logger: ILogger; protected timeUtil: TimeUtil; @@ -14,11 +15,12 @@ export declare class App { protected configServer: ConfigServer; protected encodingUtil: EncodingUtil; protected httpServer: HttpServer; + protected databaseService: DatabaseService; protected onLoadComponents: OnLoad[]; protected onUpdateComponents: OnUpdate[]; protected onUpdateLastRun: {}; protected coreConfig: ICoreConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, localisationService: LocalisationService, configServer: ConfigServer, encodingUtil: EncodingUtil, httpServer: HttpServer, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); + constructor(logger: ILogger, timeUtil: TimeUtil, localisationService: LocalisationService, configServer: ConfigServer, encodingUtil: EncodingUtil, httpServer: HttpServer, databaseService: DatabaseService, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); load(): Promise; protected update(onUpdateComponents: OnUpdate[]): Promise; protected logUpdateException(err: any, updateable: OnUpdate): void; diff --git a/types/utils/HashUtil.d.ts b/types/utils/HashUtil.d.ts index 427c1860..c938b6cf 100644 --- a/types/utils/HashUtil.d.ts +++ b/types/utils/HashUtil.d.ts @@ -1,5 +1,3 @@ -/// -/// import crypto from "node:crypto"; import fs from "node:fs"; import { TimeUtil } from "@spt/utils/TimeUtil"; @@ -11,6 +9,12 @@ export declare class HashUtil { * @returns 24 character hash */ generate(): string; + /** + * is the passed in string a valid mongo id + * @param stringToCheck String to check + * @returns True when string is a valid mongo id + */ + isValidMongoId(stringToCheck: string): boolean; generateMd5ForData(data: string): string; generateSha1ForData(data: string): string; generateCRC32ForFile(filePath: fs.PathLike): number; diff --git a/types/utils/HttpFileUtil.d.ts b/types/utils/HttpFileUtil.d.ts index cc0d9ef4..9569f816 100644 --- a/types/utils/HttpFileUtil.d.ts +++ b/types/utils/HttpFileUtil.d.ts @@ -1,8 +1,7 @@ -/// import { ServerResponse } from "node:http"; import { HttpServerHelper } from "@spt/helpers/HttpServerHelper"; export declare class HttpFileUtil { protected httpServerHelper: HttpServerHelper; constructor(httpServerHelper: HttpServerHelper); - sendFile(resp: ServerResponse, filePath: string): void; + sendFileAsync(resp: ServerResponse, filePath: string): Promise; } diff --git a/types/utils/ObjectId.d.ts b/types/utils/ObjectId.d.ts index 91f64d33..4f873447 100644 --- a/types/utils/ObjectId.d.ts +++ b/types/utils/ObjectId.d.ts @@ -1,4 +1,3 @@ -/// import { TimeUtil } from "@spt/utils/TimeUtil"; export declare class ObjectId { protected timeUtil: TimeUtil; diff --git a/types/utils/TimeUtil.d.ts b/types/utils/TimeUtil.d.ts index 6c14b9d1..48d769b9 100644 --- a/types/utils/TimeUtil.d.ts +++ b/types/utils/TimeUtil.d.ts @@ -42,11 +42,17 @@ export declare class TimeUtil { * @returns {number} The current timestamp in seconds since the Unix epoch in UTC. */ getTimestamp(): number; + getStartOfDayTimestamp(timestamp?: number): number; /** * Get timestamp of today + passed in day count * @param daysFromNow Days from now */ getTimeStampFromNowDays(daysFromNow: number): number; + /** + * Get timestamp of today + passed in hour count + * @param daysFromNow Days from now + */ + getTimeStampFromNowHours(hoursFromNow: number): number; /** * Gets the current time in UTC in a format suitable for mail in EFT. * @@ -67,4 +73,10 @@ export declare class TimeUtil { */ getHoursAsSeconds(hours: number): number; getTimestampOfNextHour(): number; + /** + * Returns the current days timestamp at 00:00 + * e.g. current time: 13th march 14:22 will return 13th march 00:00 + * @returns Timestamp + */ + getTodaysMidnightTimestamp(): number; } diff --git a/types/utils/VFS.d.ts b/types/utils/VFS.d.ts index 6287a2fa..9c4fcc2e 100644 --- a/types/utils/VFS.d.ts +++ b/types/utils/VFS.d.ts @@ -1,5 +1,3 @@ -/// -/// import "reflect-metadata"; import fs from "node:fs"; import { IAsyncQueue } from "@spt/models/spt/utils/IAsyncQueue"; diff --git a/types/utils/logging/AbstractWinstonLogger.d.ts b/types/utils/logging/AbstractWinstonLogger.d.ts index ef544348..fb84b83d 100644 --- a/types/utils/logging/AbstractWinstonLogger.d.ts +++ b/types/utils/logging/AbstractWinstonLogger.d.ts @@ -1,6 +1,5 @@ -/// import fs from "node:fs"; -import { Daum } from "@spt/models/eft/itemEvent/IItemEventRouterRequest"; +import { IDaum } from "@spt/models/eft/itemEvent/IItemEventRouterRequest"; import { LogBackgroundColor } from "@spt/models/spt/logging/LogBackgroundColor"; import { LogTextColor } from "@spt/models/spt/logging/LogTextColor"; import { SptLogger } from "@spt/models/spt/logging/SptLogger"; @@ -51,7 +50,7 @@ export declare abstract class AbstractWinstonLogger implements ILogger { protected getLogFrequency(): string; protected getLogMaxSize(): string; protected getLogMaxFiles(): string; - writeToLogFile(data: string | Daum): Promise; + writeToLogFile(data: string | IDaum): Promise; log(data: string | Error | Record, color: string, backgroundColor?: string): Promise; error(data: string | Record): Promise; warning(data: string | Record): Promise; From bfd2382cc50125b594eaf895da5bf0508f1c1bc7 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 13:16:03 +0100 Subject: [PATCH 005/203] feat: update of available ALL_EXFILS and external resources --- ALL_EXFILS.md | 4 +- external-resources/locales_global_en.json | 4804 +++++++++++++---- external-resources/mapgenie_locations.json | 10 +- external-resources/maps/customs.json | 5567 +++++++++++--------- external-resources/maps/factory.json | 1614 ++++-- external-resources/maps/groundzero.json | 470 +- external-resources/maps/interchange.json | 646 +-- external-resources/maps/laboratory.json | 1871 ++++--- external-resources/maps/lighthouse.json | 4175 ++++++++------- external-resources/maps/reserve.json | 389 +- external-resources/maps/shoreline.json | 4420 +++++++++------- external-resources/maps/streets.json | 635 ++- external-resources/maps/woods.json | 4921 ++++++++++------- 13 files changed, 18510 insertions(+), 11016 deletions(-) diff --git a/ALL_EXFILS.md b/ALL_EXFILS.md index d8acf00d..1a67bbe7 100644 --- a/ALL_EXFILS.md +++ b/ALL_EXFILS.md @@ -35,6 +35,7 @@ | "Gate 3" | Gate 3 | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25056) | | "Gate 0" | Gate 0 | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25057) | | "Gate m" | Med Tent Gate | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=88025) | +| "Gate_o" | Courtyard Gate | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=403860) | | "Office Window" | Office Window | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25060) | | "Camera Bunker Door" | Camera Bunker Door | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25058) | @@ -57,8 +58,9 @@ | "RUAF Gate" | RUAF Gate | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24857) | | "ZB-014" | ZB-014 | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24862) | | "South V-Ex" | Bridge V-Ex | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65037) | -| "Factory Gate" | Factory Gate (Co-Op) | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24856) | +| "Factory Gate" | Friendship Bridge (Co-Op) | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24856) | | "un-sec" | Northern UN Roadblock | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65038) | +| "wood_sniper_exit" | Power Line Passage | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=410432) | | "East Gate" | Scav Bunker | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65036) | | "Outskirts Water" | Scav Bridge | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65035) | | "Mountain Stash" | Mountain Stash | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24859) | diff --git a/external-resources/locales_global_en.json b/external-resources/locales_global_en.json index 0046adc0..6bee0a6e 100644 --- a/external-resources/locales_global_en.json +++ b/external-resources/locales_global_en.json @@ -140,7 +140,7 @@ "5449016a4bdc2d6f028b456f Name": "Roubles", "5449016a4bdc2d6f028b456f ShortName": "RUB", "5449016a4bdc2d6f028b456f Description": "A few notes of the still-valued Russian rouble.", - "544909bb4bdc2d6f028b4577 Name": "AN/PEQ-15 tactical device", + "544909bb4bdc2d6f028b4577 Name": "L3Harris AN/PEQ-15 tactical device", "544909bb4bdc2d6f028b4577 ShortName": "AN/PEQ-15", "544909bb4bdc2d6f028b4577 Description": "The Advanced Target Pointer Illuminator Aiming Laser (ATPIAL) produced by L3 Technologies is a rugged, combat-proven and easy-to-use aiming system with integrated infrared and visible aim lasers as well as an infrared illuminator.", "54490a4d4bdc2dbc018b4573 Name": "SilencerCo Sparrow 22 sound suppressor", @@ -276,7 +276,7 @@ "55802f5d4bdc2dac148b458f ShortName": "MOE AR15", "55802f5d4bdc2dac148b458f Description": "The polymer Magpul MOE (Magpul Original Equipment) pistol grip can be installed on any weapon compatible with AR-15 pistol grips. Thanks to the ergonomic shape and anti-slip texture, it makes the weapon grip and control more comfortably. The inside of the grip contains free space for spare parts, tools, batteries, and an accessories kit.", "558032614bdc2de7118b4585 Name": "TangoDown Stubby BGV-MK46K foregrip (Black)", - "558032614bdc2de7118b4585 ShortName": "BGV-MK46K", + "558032614bdc2de7118b4585 ShortName": "MK46K", "558032614bdc2de7118b4585 Description": "The TangoDown Stubby BGV-MK46K tactical grip is a short grip for use with weapons in close and extra close quarters combat. It ideally fits assault shotguns and also contains a compartment for batteries or SPTA. Black version.", "55818a104bdc2db9688b4569 Name": "Handguard", "55818a104bdc2db9688b4569 ShortName": "Item", @@ -503,9 +503,9 @@ "5645bcb74bdc2ded0b8b4578 Name": "Headphones", "5645bcb74bdc2ded0b8b4578 ShortName": "Item", "5645bcb74bdc2ded0b8b4578 Description": "Item", - "5645bcc04bdc2d363b8b4572 Name": "Peltor ComTac 2 headset (OD Green)", - "5645bcc04bdc2d363b8b4572 ShortName": "ComTac 2", - "5645bcc04bdc2d363b8b4572 Description": "The ComTac 2 amplifies low-level sounds while suppressing impulse noises. Water resistant for outdoor usage. Manufactured by Peltor.", + "5645bcc04bdc2d363b8b4572 Name": "Peltor ComTac II headset (OD Green)", + "5645bcc04bdc2d363b8b4572 ShortName": "ComTac II", + "5645bcc04bdc2d363b8b4572 Description": "The ComTac II amplifies low-level sounds while suppressing impulse noises. Water resistant for outdoor usage. Manufactured by Peltor.", "5648a69d4bdc2ded0b8b457b Name": "BlackRock chest rig (Gray)", "5648a69d4bdc2ded0b8b457b ShortName": "BlackRock", "5648a69d4bdc2ded0b8b457b Description": "A custom-made chest rig for wearing on top of body armor in urban operations. Sturdy and versatile, it features both MOLLE and ALICE attachment systems.", @@ -518,12 +518,12 @@ "5648ae314bdc2d3d1c8b457f Name": "AK CAA RS47 handguard", "5648ae314bdc2d3d1c8b457f ShortName": "RS47", "5648ae314bdc2d3d1c8b457f Description": "The RS47 lightweight polymer handguard, fits the majority of rifles and carbines built on the base of AK-family rifles. Equipped with two short and two long rail mounts for installing additional devices. Manufactured by Command Arms.", - "5648b0744bdc2d363b8b4578 Name": "AK-74 wooden handguard (6P20 Sb.6)", - "5648b0744bdc2d363b8b4578 ShortName": "6P20 Sb.6", - "5648b0744bdc2d363b8b4578 Description": "A standard Izhmash-produced wooden handguard for AK-74 assault rifles.", - "5648b1504bdc2d9d488b4584 Name": "AK-74 polymer handguard (6P20 Sb.9)", - "5648b1504bdc2d9d488b4584 ShortName": "6P20 Sb.9", - "5648b1504bdc2d9d488b4584 Description": "A polymer handguard for AK-74 automatic rifles which replaced the classic wooden one. Manufactured by Izhmash.", + "5648b0744bdc2d363b8b4578 Name": "AK-74 wooden handguard", + "5648b0744bdc2d363b8b4578 ShortName": "AK-74 wood", + "5648b0744bdc2d363b8b4578 Description": "A standard Izhmash-produced 6P20 Sb.6 wooden handguard for AK-74 assault rifles.", + "5648b1504bdc2d9d488b4584 Name": "AK-74M polymer handguard", + "5648b1504bdc2d9d488b4584 ShortName": "AK-74M", + "5648b1504bdc2d9d488b4584 Description": "A 6P20 Sb.9 polymer handguard for AK-74M automatic rifles which replaced the classic wooden one. Manufactured by Izhmash.", "5648b4534bdc2d3d1c8b4580 Name": "AK Zenit B-10M handguard with B-19 upper mount", "5648b4534bdc2d3d1c8b4580 ShortName": "B10M+B19", "5648b4534bdc2d3d1c8b4580 Description": "The integrally machined B-10M handguard is manufactured from D16T aluminum alloy with black coating and can be installed instead of the standard-issue handguard on AK series 103, 104, 105, 74S, 74M, AKM, and AKMS. B-19 rail mount is basically a sight mount hovering over the gas tube. Also integrally machined from D16T aluminum alloy with black coating, it can be installed on B-10M or B-21M foregrips. ©Zenit", @@ -533,36 +533,36 @@ "5649a2464bdc2d91118b45a8 Name": "NcSTAR MPR45 Backup mount", "5649a2464bdc2d91118b45a8 ShortName": "MPR45", "5649a2464bdc2d91118b45a8 Description": "A universal mount by NcStar that allows installing an auxiliary sight at 45 degrees angle.", - "5649aa744bdc2ded0b8b457e Name": "AK-74 5.45x39 muzzle brake-compensator (6P20 0-20)", - "5649aa744bdc2ded0b8b457e ShortName": "6P20 0-20", - "5649aa744bdc2ded0b8b457e Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-74 and weapon systems based on it.", + "5649aa744bdc2ded0b8b457e Name": "AK-74 5.45x39 muzzle brake-compensator", + "5649aa744bdc2ded0b8b457e ShortName": "AK-74", + "5649aa744bdc2ded0b8b457e Description": "A standard Izhmash-produced 6P20 0-20 muzzle brake and compensator for the AK-74 and weapon systems based on it.", "5649ab884bdc2ded0b8b457f Name": "AK Zenit DTK-1 7.62x39/5.45x39 muzzle brake-compensator", "5649ab884bdc2ded0b8b457f ShortName": "DTK-1", "5649ab884bdc2ded0b8b457f Description": "The DTK-1 muzzle brake-compensator by Zenit is designed to be installed on 7.62x39 and 5.45x39 AK-based weapon systems. It reduces recoil and counters barrel climb. The crown on the DTK nose is meant for breaking through tempered glass. It has 24x1.5 mm threading. ©Zenit", - "5649ad3f4bdc2df8348b4585 Name": "AK bakelite pistol grip (6P1 Sb.8V)", - "5649ad3f4bdc2df8348b4585 ShortName": "6P1 Sb.8V", - "5649ad3f4bdc2df8348b4585 Description": "An Izhmash-manufactured bakelite pistol grip for the AK automatic rifle and compatible weapon systems.", - "5649ade84bdc2d1b2b8b4587 Name": "AK polymer pistol grip (6P1 Sb.8)", - "5649ade84bdc2d1b2b8b4587 ShortName": "6P1 Sb.8", - "5649ade84bdc2d1b2b8b4587 Description": "An Izhmash polymer pistol grip for AK and compatibles, designed to replace the old bakelite grip.", + "5649ad3f4bdc2df8348b4585 Name": "AK-74 bakelite pistol grip", + "5649ad3f4bdc2df8348b4585 ShortName": "AK-74 bak.", + "5649ad3f4bdc2df8348b4585 Description": "An Izhmash-manufactured 6P1 Sb.8V bakelite pistol grip for the AK automatic rifle and compatible weapon systems.", + "5649ade84bdc2d1b2b8b4587 Name": "AK-74 polymer pistol grip", + "5649ade84bdc2d1b2b8b4587 ShortName": "AK-74 poly", + "5649ade84bdc2d1b2b8b4587 Description": "An Izhmash 6P1 Sb.8 polymer pistol grip for AK and compatibles, designed to replace the old bakelite grip.", "5649ae4a4bdc2d1b2b8b4588 Name": "AK Zenit RK-3 pistol grip", "5649ae4a4bdc2d1b2b8b4588 ShortName": "RK-3", "5649ae4a4bdc2d1b2b8b4588 Description": "The RK-3 Klassika anatomic pistol grip features a built-in hermetically sealed battery storage compartment and is designed for installation as a replacement for the standard AK pistol grip. ©Zenit", - "5649af094bdc2df8348b4586 Name": "AK-74 dust cover (6P20 0-1)", - "5649af094bdc2df8348b4586 ShortName": "6P1 0-1", - "5649af094bdc2df8348b4586 Description": "A standard-issue dust cover for AK-74 automatic rifles, manufactured by Izhmash.", + "5649af094bdc2df8348b4586 Name": "AK-74 dust cover", + "5649af094bdc2df8348b4586 ShortName": "AK-74 DC", + "5649af094bdc2df8348b4586 Description": "A standard-issue 6P1 0-1 dust cover for AK-74 automatic rifles, manufactured by Izhmash.", "5649af884bdc2d1b2b8b4589 Name": "AK Zenit B-33 dust cover", "5649af884bdc2d1b2b8b4589 ShortName": "B-33", "5649af884bdc2d1b2b8b4589 Description": "The B-33 dust cover with an integrated Picatinny rail is compatible with all models of Kalashnikov automatic rifles and carbines based on AK system. Allows installation of all Picatinny-mountable sights, ensuring the consistency of median aimpoint even after repeated removal and replacement of dust cover. © Zenit", - "5649b0544bdc2d1b2b8b458a Name": "AK-74 rear sight (6P20 Sb.2)", - "5649b0544bdc2d1b2b8b458a ShortName": "6P20 Sb.2", - "5649b0544bdc2d1b2b8b458a Description": "A standard rear sight for AK-74 automatic rifles, manufactured by Izhmash.", - "5649b0fc4bdc2d17108b4588 Name": "AK-74 polymer stock (6P20 Sb.7)", - "5649b0fc4bdc2d17108b4588 ShortName": "6P20 Sb.7", - "5649b0fc4bdc2d17108b4588 Description": "A polymer stock for AK-74 automatic rifles which replaced the classic wooden one. Manufactured by Izhmash.", - "5649b1c04bdc2d16268b457c Name": "AK-74 wooden stock (6P20 Sb.5)", - "5649b1c04bdc2d16268b457c ShortName": "6P20 Sb.5", - "5649b1c04bdc2d16268b457c Description": "A standard-issue wooden stock for AK-74 automatic rifles, manufactured by Izhmash.", + "5649b0544bdc2d1b2b8b458a Name": "AK-74 rear sight", + "5649b0544bdc2d1b2b8b458a ShortName": "AK-74 RS", + "5649b0544bdc2d1b2b8b458a Description": "A standard 6P20 Sb.2 rear sight for AK-74 automatic rifles, manufactured by Izhmash.", + "5649b0fc4bdc2d17108b4588 Name": "AK-74 polymer stock", + "5649b0fc4bdc2d17108b4588 ShortName": "AK-74 poly", + "5649b0fc4bdc2d17108b4588 Description": "A polymer 6P20 Sb.7 stock for AK-74 automatic rifles which replaced the classic wooden one. Manufactured by Izhmash.", + "5649b1c04bdc2d16268b457c Name": "AK-74 wooden stock", + "5649b1c04bdc2d16268b457c ShortName": "AK-74 wood", + "5649b1c04bdc2d16268b457c Description": "A standard-issue 6P20 Sb.5 wooden stock for AK-74 automatic rifles, manufactured by Izhmash.", "5649b2314bdc2d79388b4576 Name": "AKM/AK-74 ME4 buffer tube adapter", "5649b2314bdc2d79388b4576 ShortName": "ME4", "5649b2314bdc2d79388b4576 Description": "An adapter for the installation of telescopic stock buffer tubes on AKs with non-folding stocks.", @@ -690,7 +690,7 @@ "56deeefcd2720bc8328b4568 ShortName": "MP153x8", "56deeefcd2720bc8328b4568 Description": "An 8-shell magazine extension tube for MP-153 12 gauge shotguns.", "56def37dd2720bec348b456a Name": "SureFire X400 Ultra tactical flashlight with laser", - "56def37dd2720bec348b456a ShortName": "X400", + "56def37dd2720bec348b456a ShortName": "X400U", "56def37dd2720bec348b456a Description": "The X400U flashlight by SureFire is engineered to fit virtually any rail-equipped pistol or rifle. Combines a laser designator and a flashlight.", "56dfef82d2720bbd668b4567 Name": "5.45x39mm BP gs", "56dfef82d2720bbd668b4567 ShortName": "BP", @@ -734,6 +734,9 @@ "56e05b06d2720bb2668b4586 Name": "PB 9x18PM sound suppressor", "56e05b06d2720bb2668b4586 ShortName": "PB supp.", "56e05b06d2720bb2668b4586 Description": "A standard-issue detachable sound suppressor for the PB pistol.", + "56e294cdd2720b603a8b4575 Name": "Mystery Ranch Terraplane backpack", + "56e294cdd2720b603a8b4575 ShortName": "Terraplane 85L", + "56e294cdd2720b603a8b4575 Description": "This durable, made with 500 Cordura, spacious, comfortable to wear, and well-organized extra large backpack can hold half of Tarkov and still have some space left.", "56e335e4d2720b6c058b456d Name": "Scav backpack", "56e335e4d2720b6c058b456d ShortName": "ScavBP", "56e335e4d2720b6c058b456d Description": "A cheap replica of some 3-day assault pack with a MOLLE attachment system, adapted and enhanced by the owner as much as their creativity allowed. Does not offer much comfort, and volume is far lower than that of a proper 3-day pack, but it's still a backpack alright.", @@ -759,7 +762,7 @@ "56ea8180d2720bf2698b456a ShortName": "QDC 556", "56ea8180d2720bf2698b456a Description": "The KAC 5.56 QD muzzle compensator/flash hider is an effective flash suppressor that also serves as a platform for attaching a KAC quick detach QDSS-NT4 sound suppressor. Installed on weapons based on AR-15/M16/M4.", "56ea8222d2720b69698b4567 Name": "SV-98 bipod", - "56ea8222d2720b69698b4567 ShortName": "SV98 Bipod", + "56ea8222d2720b69698b4567 ShortName": "SV-98", "56ea8222d2720b69698b4567 Description": "A standard-issue Izhmash bipod for the SV-98 sniper rifle. Folded into the handguard when not used.", "56ea8d2fd2720b7c698b4570 Name": "AR-15 Windham Weaponry Rail Gas Block", "56ea8d2fd2720b7c698b4570 ShortName": "RGBlock", @@ -806,7 +809,7 @@ "571a29dc2459771fb2755a6a Name": "TT 7.62x25 tt-105 8-round magazine", "571a29dc2459771fb2755a6a ShortName": "tt-105", "571a29dc2459771fb2755a6a Description": "A standard late-issue 8-round magazine for the TT pistol. It comes without a lanyard ring.", - "57235b6f24597759bf5a30f1 Name": "AN/PVS-14 Night Vision Monocular", + "57235b6f24597759bf5a30f1 Name": "L3Harris AN/PVS-14 night vision monocular", "57235b6f24597759bf5a30f1 ShortName": "PVS-14", "57235b6f24597759bf5a30f1 Description": "The AN/PVS-14 monocular night vision device for army/navy that allows nighttime detection of targets on distances of up to 350m with 40° FOV and has an adjustable brightness.", "572b7adb24597762ae139821 Name": "Scav Vest", @@ -869,7 +872,7 @@ "57347b8b24597737dd42e192 Name": "Classic matches", "57347b8b24597737dd42e192 ShortName": "Matches", "57347b8b24597737dd42e192 Description": "A matchbox full of safety matches. Lighters are more reliable and easier to use, but that's exactly why everybody tries to keep them hidden when asked for a light.", - "57347baf24597738002c6178 Name": "RAM", + "57347baf24597738002c6178 Name": "RAM stick", "57347baf24597738002c6178 ShortName": "RAM", "57347baf24597738002c6178 Description": "Old RAM is a primary source of IC chips for various microcontroller purposes of the local population.", "57347c1124597737fb1379e3 Name": "Duct tape", @@ -1169,28 +1172,28 @@ "576167ab2459773cad038c43 Name": "SOK-12 thread protection tube", "576167ab2459773cad038c43 ShortName": "SOK-12 thr.", "576167ab2459773cad038c43 Description": "A standard-issue threading protection tube for SOK-12.", - "576169e62459773c69055191 Name": "SOK-12 polymer handguard (Sb.7-1)", - "576169e62459773c69055191 ShortName": "Sb.7-1", + "576169e62459773c69055191 Name": "SOK-12 polymer handguard", + "576169e62459773c69055191 ShortName": "SOK-12", "576169e62459773c69055191 Description": "Sb.7-1 is a standard polymer handguard with a sling swivel, installs on SOK-12 and SOK-12S.", - "57616a9e2459773c7a400234 Name": "SOK-12 12/76 sb.5 5-round magazine", + "57616a9e2459773c7a400234 Name": "SOK-12 12ga Sb.5 5-round magazine", "57616a9e2459773c7a400234 ShortName": "Sb.5", "57616a9e2459773c7a400234 Description": "A 5-round Sb.5 polymer plastic magazine for the SOK-12 and compatible weapons, intended for use with 12/76 or 12/70 shells.", - "57616c112459773cce774d66 Name": "SOK-12 dust cover (Sb.0-2)", - "57616c112459773cce774d66 ShortName": "Sb.0-2", - "57616c112459773cce774d66 Description": "A standard-issue dust cover for Saiga 12, manufactured by Izhmash.", + "57616c112459773cce774d66 Name": "SOK-12 dust cover ", + "57616c112459773cce774d66 ShortName": "SOK-12 DC", + "57616c112459773cce774d66 Description": "A standard-issue Sb.0-2 dust cover for Saiga 12, manufactured by Izhmash.", "57616ca52459773c69055192 Name": "SOK-12 AK-style stock", - "57616ca52459773c69055192 ShortName": "SOK12 AK", + "57616ca52459773c69055192 ShortName": "SOK-12 AK", "57616ca52459773c69055192 Description": "A folding polymer AK-styled stock for SOK-12, manufactured by Izhmash.", - "576a581d2459771e7b1bc4f1 Name": "Yarygin MP-443 \"Grach\" 9x19 pistol", - "576a581d2459771e7b1bc4f1 ShortName": "MP-443 \"Grach\"", + "576a581d2459771e7b1bc4f1 Name": "Yarygin MP-443 Grach 9x19 pistol", + "576a581d2459771e7b1bc4f1 ShortName": "MP-443 Grach", "576a581d2459771e7b1bc4f1 Description": "The PYa MP-443 (Pistolét Yarýgina MP-443 - \"Yarygin Pistol MP-443\", GRAU Index - 6P35) widely known as \"Grach\" is a Russian semiautomatic pistol chambered in 9x19 mm. It was designed by Vladimir Yarygin in the 1990s and adopted as a standard sidearm by the Russian military, law enforcement agencies, and special units of the Ministry of Internal Affairs. It features a high capacity magazine and can be equipped with the Zenit B-8 mount to install additional attachments beneath the barrel.", - "576a5ed62459771e9c2096cb Name": "MP-443 \"Grach\" 9x19 18-round magazine", + "576a5ed62459771e9c2096cb Name": "MP-443 Grach 9x19 18-round magazine", "576a5ed62459771e9c2096cb ShortName": "MP-443", "576a5ed62459771e9c2096cb Description": "A standard 18-round 9x19 magazine for the MP-443 pistol.", - "576a63cd2459771e796e0e11 Name": "MP-443 \"Grach\" polymer pistol grip", + "576a63cd2459771e796e0e11 Name": "MP-443 Grach polymer pistol grip", "576a63cd2459771e796e0e11 ShortName": "MP443", "576a63cd2459771e796e0e11 Description": "A standard service pistol grip for MP-443 pistols manufactured by Izhmekh.", - "576a7c512459771e796e0e17 Name": "MP-443 \"Grach\" Zenit B-8 mount", + "576a7c512459771e796e0e17 Name": "MP-443 Grach Zenit B-8 mount", "576a7c512459771e796e0e17 ShortName": "B-8", "576a7c512459771e796e0e17 Description": "The B-8 rail mount can be installed on Yarygin pistols (MP-443 \"Grach\" and its civilian version MP-446 \"Viking\") for use with additional attachments, like Zenit Klesch-2P tactical flashlight/laser. Manufactured by Zenit.", "576fd4ec2459777f0b518431 Name": "BelOMO PSO-1M2-1 4x24 scope", @@ -1236,25 +1239,25 @@ "5780d07a2459777de4559324 ShortName": "Cabin", "5780d07a2459777de4559324 Description": "A key to one of the portable on-site customs control guard cabins.", "57838ad32459774a17445cd2 Name": "VSS Vintorez 9x39 special sniper rifle", - "57838ad32459774a17445cd2 ShortName": "VSS \"Vintorez\"", + "57838ad32459774a17445cd2 ShortName": "VSS Vintorez", "57838ad32459774a17445cd2 Description": "VSS (Vintovka Sniperskaya Specialnaya - \"Special Sniper Rifle\") is an integrally suppressed sniper rifle, designed in the 80s in the TsNIITochMash institute for the needs of special-purpose teams and task forces.", "57838c962459774a1651ec63 Name": "VSS 9x39 integral barrel-suppressor", - "57838c962459774a1651ec63 ShortName": "VSS supp.", + "57838c962459774a1651ec63 ShortName": "VSS", "57838c962459774a1651ec63 Description": "A TsNIITochMash-manufactured integral barrel-suppressor module for VSS Vintorez.", "57838e1b2459774a256959b1 Name": "VSS rear sight", "57838e1b2459774a256959b1 ShortName": "VSS RS", "57838e1b2459774a256959b1 Description": "A standard vertically adjustable mechanical rear sight for the VSS Vintorez sniper rifle.", - "57838f0b2459774a256959b2 Name": "VSS 9x39 6L24 10-round magazine", + "57838f0b2459774a256959b2 Name": "VSS/VAL 9x39 6L24 10-round magazine", "57838f0b2459774a256959b2 ShortName": "6L24", "57838f0b2459774a256959b2 Description": "A 10-round polymer TsNIITochMash 6L24 9x39 magazine for the VSS sniper rifle.", - "57838f9f2459774a150289a0 Name": "VSS 9x39 6L25 20-round magazine", + "57838f9f2459774a150289a0 Name": "VSS/VAL 9x39 6L25 20-round magazine (Plum)", "57838f9f2459774a150289a0 ShortName": "6L25", - "57838f9f2459774a150289a0 Description": "A 20-round polymer TsNIITochMash 6L25 9x39 magazine for the AS VAL special assault rifle.", + "57838f9f2459774a150289a0 Description": "A 20-round polymer TsNIITochMash 6L25 9x39 magazine for the AS VAL special assault rifle. Made out of plum-colored polymer, earning the nickname \"Sliva\" (Plum).", "578395402459774a256959b5 Name": "VSS dust cover", "578395402459774a256959b5 ShortName": "VSS", "578395402459774a256959b5 Description": "A standard-issue dust cover for VSS Vintorez sniper rifles, manufactured by TsNIITochMash.", "578395e82459774a0e553c7b Name": "VSS wooden stock", - "578395e82459774a0e553c7b ShortName": "VSS Wood", + "578395e82459774a0e553c7b ShortName": "VSS wood", "578395e82459774a0e553c7b Description": "A standard-issue wooden stock for VSS Vintorez sniper rifles, manufactured by TsNIITochMash.", "5783c43d2459774bbe137486 Name": "Simple wallet", "5783c43d2459774bbe137486 ShortName": "Wallet", @@ -1353,7 +1356,7 @@ "57c44b372459772d2b39b8ce ShortName": "AS VAL", "57c44b372459772d2b39b8ce Description": "AS VAL (Avtomat Specialniy VAL - \"Special Automatic rifle VAL\") is a silenced automatic rifle with an integral suppressor designed for special forces units. Developed in TsNIITochMash and based on the VSS Vintorez platform.", "57c44dd02459772d2e0ae249 Name": "AS VAL 9x39 integral barrel-suppressor", - "57c44dd02459772d2e0ae249 ShortName": "VAL suppressor", + "57c44dd02459772d2e0ae249 ShortName": "VAL", "57c44dd02459772d2e0ae249 Description": "A TsNIITochMash-manufactured integral barrel-suppressor module for AS VAL.", "57c44e7b2459772d28133248 Name": "AS VAL rear sight", "57c44e7b2459772d28133248 ShortName": "VAL RS", @@ -1361,7 +1364,7 @@ "57c44f4f2459772d2c627113 Name": "AS VAL dust cover", "57c44f4f2459772d2c627113 ShortName": "VAL", "57c44f4f2459772d2c627113 Description": "A standard-issue dust cover for AS VAL, manufactured by TsNIItochmash.", - "57c44fa82459772d2d75e415 Name": "AS VAL pistol grip", + "57c44fa82459772d2d75e415 Name": "AS VAL pistol grip (Plum)", "57c44fa82459772d2d75e415 ShortName": "VAL", "57c44fa82459772d2d75e415 Description": "A standard-issue polymer pistol grip for AS VAL, manufactured by TSNIITochMash.", "57c450252459772d28133253 Name": "AS VAL skeleton stock", @@ -1418,8 +1421,8 @@ "57cffe20245977632f391a9d Name": "AK Magpul MOE AKM handguard (Stealth Grey)", "57cffe20245977632f391a9d ShortName": "MOE AKM", "57cffe20245977632f391a9d Description": "The Magpul MOE AKM hand guard is installed on AKM/AK-74 compatible weapon systems. It comes equipped with licensed M-LOK mounts for the installation of additional devices or rails. Stealth Grey version.", - "57d14d2524597714373db789 Name": "PP-91 \"Kedr\" 9x18PM submachine gun", - "57d14d2524597714373db789 ShortName": "PP-91 \"Kedr\"", + "57d14d2524597714373db789 Name": "PP-91 Kedr 9x18PM submachine gun", + "57d14d2524597714373db789 ShortName": "PP-91 Kedr", "57d14d2524597714373db789 Description": "The PP-91 Kedr is a submachine gun chambered in 9x18 PM, designed by Yevgeny Dragunov in the early 90s by order of the Ministry of Internal Affairs and produced at ZMZ (Zlatoústovskiy Mashinostroítelnyy Zavód - \"Zlatoust Machine-Building Plant\"). This submachine gun has a simple but effective design. Its light weight makes it more comfortable to carry without affecting its performance, and it provides a high rate of fire without affecting its recoil. Thanks to these characteristics, it's still used as a service weapon in almost all Russian law enforcement agencies.", "57d14e1724597714010c3f4b Name": "PP-91 \"Kedr\" 9x18PM 20-round magazine", "57d14e1724597714010c3f4b ShortName": "PP91", @@ -1427,7 +1430,7 @@ "57d1519e24597714373db79d Name": "PP-91 \"Kedr\" 9x18PM 30-round magazine", "57d1519e24597714373db79d ShortName": "PP91", "57d1519e24597714373db79d Description": "A standard 30-round capacity metal magazine for PP-91 Kedr-based 9x18PM SMGs, manufactured by ZMZ.", - "57d152ec245977144076ccdf Name": "PP-91 \"Kedr\" polymer pistol grip", + "57d152ec245977144076ccdf Name": "PP-91 Kedr polymer pistol grip", "57d152ec245977144076ccdf ShortName": "PP91", "57d152ec245977144076ccdf Description": "A ZMZ-produced polymer pistol grip for PP-91 Kedr family weapons.", "57d17c5e2459775a5c57d17d Name": "Ultrafire WF-501B flashlight", @@ -1445,44 +1448,44 @@ "57dc2fa62459775949412633 Name": "Kalashnikov AKS-74U 5.45x39 assault rifle", "57dc2fa62459775949412633 ShortName": "AKS-74U", "57dc2fa62459775949412633 Description": "AKS-74U (Avtomat Kalashnikova Skladnoy 74 Ukorochenny - \"Kalashnikov's Shortened Automatic rifle 74 with a foldable stock\") is a shortened version of the AKS-74 assault rifle, developed in the early 80s for combat vehicle crews and airborne troops, also became very popular with law enforcement and special forces for its compact size.", - "57dc324a24597759501edc20 Name": "AKS-74U 5.45x39 muzzle brake (6P26 0-20)", - "57dc324a24597759501edc20 ShortName": "6P26 0-20", - "57dc324a24597759501edc20 Description": "A standard-issue IzhMash muzzle brake for the AKS-74U and AKS-74UN, installed on 24x1.5 mm threading.", - "57dc32dc245977596d4ef3d3 Name": "AKS-74U wooden handguard (6P26 Sb.6)", - "57dc32dc245977596d4ef3d3 ShortName": "6P26 Sb.6", - "57dc32dc245977596d4ef3d3 Description": "A standard-issue wooden handguard for AKS-74U, AKS-74UN, and AKS-74UB, manufactured by Izhmash.", - "57dc334d245977597164366f Name": "AKS-74U dust cover (6P26 Sb.7)", - "57dc334d245977597164366f ShortName": "6P26 Sb.7", - "57dc334d245977597164366f Description": "A standard-issue dust cover for AKS-74U, AKS-74UN automatic rifles, manufactured by Izhmash.", - "57dc347d245977596754e7a1 Name": "AKS-74U metal skeleton stock (6P26 Sb.5)", - "57dc347d245977596754e7a1 ShortName": "6P26 Sb.5", - "57dc347d245977596754e7a1 Description": "A standard-issue metal skeleton stock for AKS-74U, AKS-74UN, and AKS-74UB, manufactured by Izhmash.", + "57dc324a24597759501edc20 Name": "AKS-74U 5.45x39 muzzle brake", + "57dc324a24597759501edc20 ShortName": "AKS-74U", + "57dc324a24597759501edc20 Description": "A standard-issue Izhmash 6P26 0-20 muzzle brake for the AKS-74U and AKS-74UN, installed on 24x1.5mm threading.", + "57dc32dc245977596d4ef3d3 Name": "AKS-74U wooden handguard", + "57dc32dc245977596d4ef3d3 ShortName": "AKS-74U", + "57dc32dc245977596d4ef3d3 Description": "A standard-issue 6P26 Sb.6 wooden handguard for AKS-74U, AKS-74UN, and AKS-74UB, manufactured by Izhmash.", + "57dc334d245977597164366f Name": "AKS-74U dust cover", + "57dc334d245977597164366f ShortName": "AKS-74U DC", + "57dc334d245977597164366f Description": "A standard-issue 6P26 Sb.7 dust cover for AKS-74U, AKS-74UN automatic rifles, manufactured by Izhmash.", + "57dc347d245977596754e7a1 Name": "AKS-74U skeletonized stock", + "57dc347d245977596754e7a1 ShortName": "AKS-74U", + "57dc347d245977596754e7a1 Description": "A standard-issue 6P26 Sb.5 metal skeleton stock for AKS-74U, AKS-74UN, and AKS-74UB, manufactured by Izhmash.", "57e26ea924597715ca604a09 Name": "Bars A-2607 Damascus knife", "57e26ea924597715ca604a09 ShortName": "A-2607", "57e26ea924597715ca604a09 Description": "The Bars A-2607 knife, forged of Damascus steel with a wenge handle and brass guard.", "57e26fc7245977162a14b800 Name": "Bars A-2607 95Kh18 knife", "57e26fc7245977162a14b800 ShortName": "A-2607", "57e26fc7245977162a14b800 Description": "The Bars A-2607 knife, forged of 95Kh18 steel with a fine wood handle and brass guard.", - "57e3dba62459770f0c32322b Name": "AK bakelite pistol grip (6P4 Sb.9)", - "57e3dba62459770f0c32322b ShortName": "6P4 Sb.9", - "57e3dba62459770f0c32322b Description": "A bakelite Izhmash-manufatured pistol grip for the AK automatic rifles and compatible weapon systems.", - "57ee59b42459771c7b045da5 Name": "PP-91 \"Kedr\" Rotor 43 RIS mount", + "57e3dba62459770f0c32322b Name": "AKS-74U bakelite pistol grip", + "57e3dba62459770f0c32322b ShortName": "AKS-74U bak.", + "57e3dba62459770f0c32322b Description": "An Izhmash-manufatured 6P4 Sb.9 bakelite pistol grip for the AK-74U automatic rifles and compatible weapon systems.", + "57ee59b42459771c7b045da5 Name": "PP-91 Kedr Rotor 43 RIS mount", "57ee59b42459771c7b045da5 ShortName": "PP91 RIS", "57ee59b42459771c7b045da5 Description": "A RIS mount for PP-91 Kedr SMG, manufactured by Rotor 43.", "57f3a5ae2459772b0e0bf19e Name": "PSO scope eyecup", "57f3a5ae2459772b0e0bf19e ShortName": "PSO eyecup", "57f3a5ae2459772b0e0bf19e Description": "A rubber eyecup for the PSO scopes family.", - "57f3c6bd24597738e730fa2f Name": "PP-91-01 \"Kedr-B\" 9x18PM submachine gun", - "57f3c6bd24597738e730fa2f ShortName": "PP-91-01 \"Kedr-B\"", + "57f3c6bd24597738e730fa2f Name": "PP-91-01 Kedr-B 9x18PM submachine gun", + "57f3c6bd24597738e730fa2f ShortName": "PP-91-01 Kedr-B", "57f3c6bd24597738e730fa2f Description": "A rare silenced version of the PP-91 Kedr submachine gun, denominated as PP-91-01 Kedr-B.", - "57f3c7e024597738ea4ba286 Name": "PP-91-01 \"Kedr-B\" threaded suppressor adapter", - "57f3c7e024597738ea4ba286 ShortName": "PP9101 thr.", + "57f3c7e024597738ea4ba286 Name": "PP-91-01 Kedr-B threaded suppressor adapter", + "57f3c7e024597738ea4ba286 ShortName": "Kedr thr.", "57f3c7e024597738ea4ba286 Description": "A muzzle thread piece for the PP-91-01 \"Kedr-B\" submachine gun with an expansion chamber, allows installation of sound suppressors.", - "57f3c8cc2459773ec4480328 Name": "PP-91-01 \"Kedr-B\" 9x18PM sound suppressor", + "57f3c8cc2459773ec4480328 Name": "PP-91-01 Kedr-B 9x18PM sound suppressor", "57f3c8cc2459773ec4480328 ShortName": "PP9101", "57f3c8cc2459773ec4480328 Description": "A standard-issue detachable PP-91-01 Kedr-B 9x18PM sound suppressor. It can be removed for compact carrying purposes.", - "57f4c844245977379d5c14d1 Name": "PP-9 \"Klin\" 9x18PMM submachine gun", - "57f4c844245977379d5c14d1 ShortName": "PP-9 \"Klin\"", + "57f4c844245977379d5c14d1 Name": "PP-9 Klin 9x18PMM submachine gun", + "57f4c844245977379d5c14d1 ShortName": "PP-9 Klin", "57f4c844245977379d5c14d1 Description": "The PP-9 Klin is a further evolution of the Kedr submachine gun. It has a higher rate of fire and its chamber is designed to use the 9x18 PMM cartridge. It was produced from 1996 to 2002 by order of the Ministry of Internal Affairs.", "57fd23e32459772d0805bcf1 Name": "Holosun LS321 Tactical device", "57fd23e32459772d0805bcf1 ShortName": "LS321", @@ -1527,7 +1530,7 @@ "5839a40f24597726f856b511 ShortName": "AKS-74UB", "5839a40f24597726f856b511 Description": "A special version of the AKS-74U assault rifle, modification B (Besshumny - \"Silenced\") is issued with a dovetail scope mount, a sound suppressor device, and special sights designed for firing subsonic ammunition.", "5839a7742459773cf9693481 Name": "AKS-74UB dust cover", - "5839a7742459773cf9693481 ShortName": "AKS-74UB", + "5839a7742459773cf9693481 ShortName": "AKS-74UB DC", "5839a7742459773cf9693481 Description": "A standard-issue dust cover for AKS-74UB automatic rifles, manufactured by Izhmash.", "58491f3324597764bc48fa02 Name": "EOTech XPS3-0 holographic sight", "58491f3324597764bc48fa02 ShortName": "XPS3-0", @@ -1613,7 +1616,7 @@ "5888956924597752983e182d Name": "DVL-10 M2 7.62x51 660mm barrel", "5888956924597752983e182d ShortName": "DVL10 660mm", "5888956924597752983e182d Description": "A 660mm long 7.62x51 match-grade stainless steel barrel manufactured by LOBAEV Hummer Barrels for the DVL-10 M2 sniper rifle.", - "5888961624597754281f93f3 Name": "Harris HBR Bipod", + "5888961624597754281f93f3 Name": "Harris HBR bipod", "5888961624597754281f93f3 ShortName": "Harris HBR", "5888961624597754281f93f3 Description": "The Harris HBR ultralight foldable bipod with a spring retraction mechanism. Used by service operators and civilian shooters worldwide.", "5888976c24597754281f93f5 Name": "DVL-10 M2 handguard", @@ -1649,8 +1652,8 @@ "5894a05586f774094708ef75 Name": "MPX 9x19 30-round magazine", "5894a05586f774094708ef75 ShortName": "MPX", "5894a05586f774094708ef75 Description": "A standard 30-round capacity semitransparent 9x19mm MPX magazine, manufactured by SIG Sauer.", - "5894a13e86f7742405482982 Name": "MPX/MCX collapsing/telescoping stock", - "5894a13e86f7742405482982 ShortName": "MPX/MCX", + "5894a13e86f7742405482982 Name": "MPX/MCX Collapsing/Telescoping Stock", + "5894a13e86f7742405482982 ShortName": "SIG CTS", "5894a13e86f7742405482982 Description": "A telescopic retractable stock for early issues of MCX/MPX manufactured by SIG Sauer.", "5894a2c386f77427140b8342 Name": "MPX 9x19 203mm barrel", "5894a2c386f77427140b8342 ShortName": "MPX 203mm", @@ -1676,9 +1679,9 @@ "58a5c12e86f7745d585a2b9e Name": "MPX GEN1 handguard 4 inch rail", "58a5c12e86f7745d585a2b9e ShortName": "MPX 4\"", "58a5c12e86f7745d585a2b9e Description": "The 4 inch SIG Sauer GEN1 handguard rail adapter allows you to install additional equipment on the 1st generation SIG MPX handguard.", - "58ac1bf086f77420ed183f9f Name": "MPX/MCX retractable stock adapter", - "58ac1bf086f77420ed183f9f ShortName": "MPX/MCX", - "58ac1bf086f77420ed183f9f Description": "An adapter for attaching telescopic tube stocks to the rail mount, manufactured by SIG Sauer.", + "58ac1bf086f77420ed183f9f Name": "MPX/MCX Folding Knuckle Stock Adapter", + "58ac1bf086f77420ed183f9f ShortName": "SIG FKSA", + "58ac1bf086f77420ed183f9f Description": "An adapter for attaching buffer tubes to the rail mount, manufactured by SIG Sauer.", "58ac60eb86f77401897560ff Name": "Balaclava_dev", "58ac60eb86f77401897560ff ShortName": "Balaclava_dev", "58ac60eb86f77401897560ff Description": "A definitive woolen balaclava is not only a head-warmer, but soul-warmer too for anyone who is too modest for public heroic deeds.", @@ -1689,10 +1692,10 @@ "58aeac1b86f77457c419f475 ShortName": "MPX-SD", "58aeac1b86f77457c419f475 Description": "An integrated sound suppressor manufactured by SIG Sauer for the special \"silent\" version of the MPX, designated as MPX-SD.", "58c157be86f77403c74b2bb6 Name": "TangoDown Stubby BGV-MK46K foregrip (FDE)", - "58c157be86f77403c74b2bb6 ShortName": "BGV-MK46K FDE", + "58c157be86f77403c74b2bb6 ShortName": "MK46K", "58c157be86f77403c74b2bb6 Description": "The TangoDown Stubby BGV-MK46K tactical grip is a short grip for use with weapons in close and extra close quarters combat. It ideally fits assault shotguns and also contains a compartment for batteries or SPTA. Flat Dark Earth version.", "58c157c886f774032749fb06 Name": "TangoDown Stubby BGV-MK46K foregrip (Stealth Grey)", - "58c157c886f774032749fb06 ShortName": "BGV-MK46K SG", + "58c157c886f774032749fb06 ShortName": "MK46K", "58c157c886f774032749fb06 Description": "The TangoDown Stubby BGV-MK46K tactical grip is a short grip for use with weapons in close and extra close quarters combat. It ideally fits assault shotguns and also contains a compartment for batteries or SPTA. Stealth Grey version.", "58d2664f86f7747fec5834f6 Name": "DeltaPoint Cross Slot Mount base", "58d2664f86f7747fec5834f6 ShortName": "DPCSM", @@ -2132,37 +2135,37 @@ "5996f6fc86f7745e585b4de3 Name": "M67 Shrapnel", "5996f6fc86f7745e585b4de3 ShortName": "M67 Shrapnel", "5996f6fc86f7745e585b4de3 Description": "M67 Shrapnel", - "59984ab886f7743e98271174 Name": "PP-19-01 \"Vityaz\" 9x19 submachine gun", + "59984ab886f7743e98271174 Name": "PP-19-01 Vityaz 9x19 submachine gun", "59984ab886f7743e98271174 ShortName": "PP-19-01", "59984ab886f7743e98271174 Description": "The PP-19-01, also known as \"Vityaz\", is a Russian submachine gun chambered in 9x19 developed in 2004 by Izhmash based on the AK platform. A standard-issue submachine gun in many law enforcement agencies and military units of the Russian Federation.", - "5998517986f7746017232f7e Name": "PP-19-01 \"Vityaz\" pistol grip", + "5998517986f7746017232f7e Name": "PP-19-01 Vityaz pistol grip", "5998517986f7746017232f7e ShortName": "PP-19-01", "5998517986f7746017232f7e Description": "An Izhmash-manufactured pistol grip for PP-19-01 Vityaz SMGs and Saiga-9 carbines.", - "599851db86f77467372f0a18 Name": "PP-19-01 \"Vityaz\" metal skeleton stock", + "599851db86f77467372f0a18 Name": "PP-19-01 Vityaz metal skeleton stock", "599851db86f77467372f0a18 ShortName": "PP-19-01", "599851db86f77467372f0a18 Description": "A skeletonized metal stock for PP-19-01 Vityaz SMGs and Saiga-9 carbines, manufactured by Izhmash.", "5998529a86f774647f44f421 Name": "Saiga-9 9x19 sb.7 10-round magazine", "5998529a86f774647f44f421 ShortName": "Sb.7", "5998529a86f774647f44f421 Description": "The Izh.9x19 Sb.7 magazine for Saiga-9 carbines with a 10-round capacity limiter.", - "5998597786f77414ea6da093 Name": "PP-19-01 \"Vityaz\" 9x19 muzzle brake-compensator", + "5998597786f77414ea6da093 Name": "PP-19-01 Vityaz 9x19 muzzle brake-compensator", "5998597786f77414ea6da093 ShortName": "PP-19-01", "5998597786f77414ea6da093 Description": "A standard muzzle brake/compensator made by Izhmash for PP-19-01 Vityaz 9x19 SMG.", "5998598e86f7740b3f498a86 Name": "Saiga-9 9x19 muzzle brake-compensator", "5998598e86f7740b3f498a86 ShortName": "Saiga-9", "5998598e86f7740b3f498a86 Description": "A standard muzzle brake-compensator made by Izhmash for Saiga-9 carbines.", - "59985a6c86f77414ec448d17 Name": "PP-19-01 \"Vityaz-SN\" dust cover", + "59985a6c86f77414ec448d17 Name": "PP-19-01 Vityaz-SN dust cover", "59985a6c86f77414ec448d17 ShortName": "Vityaz-SN", "59985a6c86f77414ec448d17 Description": "A standard-issue receiver dust cover for PP-19-01 Vityaz-SN (mod. 20) with a top rail for installation of various scopes, manufactured by Izhmash.", - "59985a8086f77414ec448d1a Name": "PP-19-01 \"Vityaz\" dust cover", + "59985a8086f77414ec448d1a Name": "PP-19-01 Vityaz dust cover", "59985a8086f77414ec448d1a ShortName": "Vityaz", "59985a8086f77414ec448d1a Description": "A standard-issue dust cover for PP-19-01 Vityaz SMGs, manufactured by Izhmash.", - "599860ac86f77436b225ed1a Name": "PP-19-01 \"Vityaz\" 9x19 30-round magazine", + "599860ac86f77436b225ed1a Name": "PP-19-01 Vityaz 9x19 30-round magazine", "599860ac86f77436b225ed1a ShortName": "PP-19-01", "599860ac86f77436b225ed1a Description": "A standard 30-round capacity 9x19 magazine for PP-19-01 Vityaz SMG.", - "599860e986f7743bb57573a6 Name": "PP-19-01 \"Vityaz\" rear sight", + "599860e986f7743bb57573a6 Name": "PP-19-01 Vityaz rear sight", "599860e986f7743bb57573a6 ShortName": "PP-19-01", "599860e986f7743bb57573a6 Description": "A standard rear sight for PP-19-01 Vityaz SMG produced by Izhmash.", - "59bfc5c886f7743bf6794e62 Name": "PP-19-01 \"Vityaz\" 9x19 sound suppressor", + "59bfc5c886f7743bf6794e62 Name": "PP-19-01 Vityaz 9x19 sound suppressor", "59bfc5c886f7743bf6794e62 ShortName": "Vityaz", "59bfc5c886f7743bf6794e62 Description": "An Izhmash-produced sound suppressing device for PP-19-01 Vityaz 9x19 SMG of previous generations.", "59bfe68886f7746004266202 Name": "AR-15 Vltor MUR-1S 5.56x45 upper receiver", @@ -2183,18 +2186,18 @@ "59c63b4486f7747afb151c1c Name": "HK MP5SD B&T tri-rail ring mount", "59c63b4486f7747afb151c1c ShortName": "SD TRR", "59c63b4486f7747afb151c1c Description": "The Tri-Rail Ring mount by B&T is installed on the MP5SD silencer and adds 3 Picatinny rails, designed for installation of additional equipment.", - "59c6633186f7740cf0493bb9 Name": "AK-74 gas tube (6P20 Sb.1-2)", - "59c6633186f7740cf0493bb9 ShortName": "6P20 Sb.1-2", - "59c6633186f7740cf0493bb9 Description": "A standard gas tube for AK-74 automatic rifles. Gas tubes channel the travel direction of gas piston.", - "59ccd11386f77428f24a488f Name": "PP-19-01 \"Vityaz\" gas tube", + "59c6633186f7740cf0493bb9 Name": "AK-74 gas tube", + "59c6633186f7740cf0493bb9 ShortName": "AK-74 gas", + "59c6633186f7740cf0493bb9 Description": "A standard 6P20 Sb.1-2 gas tube for AK-74 automatic rifles. Gas tubes channel the travel direction of gas piston.", + "59ccd11386f77428f24a488f Name": "PP-19-01 Vityaz gas tube", "59ccd11386f77428f24a488f ShortName": "19-01 gas", "59ccd11386f77428f24a488f Description": "A standard gas tube for PP-19-01 Vityaz submachine guns. Gas tubes channel the travel direction of gas piston.", "59ccfdba86f7747f2109a587 Name": "AK UltiMAK M1-B gas tube & handguard", "59ccfdba86f7747f2109a587 ShortName": "M1-B", "59ccfdba86f7747f2109a587 Description": "The UltiMAK M1-B gas tube for AK assault rifles sets the gas piston movement direction and, at the same time, serves as a mount for installing reflex sights and tactical devices.", - "59d36a0086f7747e673f3946 Name": "AKS-74U gas tube (6P26 Sb.1-2)", - "59d36a0086f7747e673f3946 ShortName": "6P26 Sb.1-2", - "59d36a0086f7747e673f3946 Description": "A standard gas tube for AKS-74U automatic rifles. Gas tubes channel the travel direction of gas piston.", + "59d36a0086f7747e673f3946 Name": "AKS-74U gas tube", + "59d36a0086f7747e673f3946 ShortName": "AKS-74U gas", + "59d36a0086f7747e673f3946 Description": "A standard 6P26 Sb.1-2 gas tube for AKS-74U automatic rifles. Gas tubes channel the travel direction of gas piston.", "59d6088586f774275f37482f Name": "Kalashnikov AKM 7.62x39 assault rifle", "59d6088586f774275f37482f ShortName": "AKM", "59d6088586f774275f37482f Description": "The AKM (Avtomát Kaláshnikova Modernizírovanny - Kalashnikov's Automatic Rifle Modernised) 7.62x39mm automatic rifle was adopted in 1959 to replace AK as a standard service weapon of the Soviet Army. Main differences compared to AK: enhanced accuracy range, lower weight, new stock, trigger, hammer retarder, muzzle compensator, and other design changes aimed at improving the efficiency of the rifle.", @@ -2204,24 +2207,24 @@ "59d6272486f77466146386ff Name": "AK 7.62x39 Magpul PMAG 30 GEN M3 30-round magazine", "59d6272486f77466146386ff ShortName": "GEN M3", "59d6272486f77466146386ff Description": "A 30-round polymer Magpul Pmag 30 AK/AKM GEN M3 magazine for 7.62x39 AK and compatible weapons. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", - "59d64ec286f774171d1e0a42 Name": "AKM gas tube (6P1 Sb.1-2)", - "59d64ec286f774171d1e0a42 ShortName": "6P1 Sb.1-2", - "59d64ec286f774171d1e0a42 Description": "A standard gas tube for AKM automatic rifles. Gas tubes channel the travel direction of gas piston.", - "59d64f2f86f77417193ef8b3 Name": "AKM wooden handguard (6P1 Sb.6-1)", - "59d64f2f86f77417193ef8b3 ShortName": "6P1 Sb.6-1", - "59d64f2f86f77417193ef8b3 Description": "A standard Izhmash-produced wooden AKM handguard.", - "59d64fc686f774171b243fe2 Name": "AKM 7.62x39 muzzle brake-compensator (6P1 0-14)", - "59d64fc686f774171b243fe2 ShortName": "6P1 0-14", - "59d64fc686f774171b243fe2 Description": "A standard Izhmash-produced muzzle brake-compensator for AKM automatic rifles and weapon systems based on it.", - "59d6507c86f7741b846413a2 Name": "AKM dust cover (6P1 0-1)", - "59d6507c86f7741b846413a2 ShortName": "6P1 0-1", - "59d6507c86f7741b846413a2 Description": "A standard-issue dust cover for AKM automatic rifles, manufactured by Izhmash.", - "59d650cf86f7741b846413a4 Name": "AKM rear sight (6P1 Sb.2-1)", - "59d650cf86f7741b846413a4 ShortName": "6P1 Sb.2-1", - "59d650cf86f7741b846413a4 Description": "A standard rear sight for AKM automatic rifles, manufactured by Izhmash.", - "59d6514b86f774171a068a08 Name": "AKM wooden stock (6P1 Sb.5)", - "59d6514b86f774171a068a08 ShortName": "6P1 Sb.5", - "59d6514b86f774171a068a08 Description": "A standard-issue wooden stock for AKM automatic rifles, manufactured by Izhmash.", + "59d64ec286f774171d1e0a42 Name": "AKM gas tube", + "59d64ec286f774171d1e0a42 ShortName": "AKM gas", + "59d64ec286f774171d1e0a42 Description": "A standard 6P1 Sb.1-2 gas tube for AKM automatic rifles. Gas tubes channel the travel direction of gas piston.", + "59d64f2f86f77417193ef8b3 Name": "AKM wooden handguard", + "59d64f2f86f77417193ef8b3 ShortName": "AKM wood", + "59d64f2f86f77417193ef8b3 Description": "A standard Izhmash-produced 6P1 Sb.6-1 wooden AKM handguard.", + "59d64fc686f774171b243fe2 Name": "AKM 7.62x39 muzzle brake-compensator", + "59d64fc686f774171b243fe2 ShortName": "AKM", + "59d64fc686f774171b243fe2 Description": "A standard Izhmash-produced 6P1 0-14 muzzle brake-compensator for AKM automatic rifles and weapon systems based on it.", + "59d6507c86f7741b846413a2 Name": "AKM dust cover", + "59d6507c86f7741b846413a2 ShortName": "AKM DC", + "59d6507c86f7741b846413a2 Description": "A standard-issue 6P1 0-1 dust cover for AKM automatic rifles, manufactured by Izhmash.", + "59d650cf86f7741b846413a4 Name": "AKM rear sight", + "59d650cf86f7741b846413a4 ShortName": "AKM RS", + "59d650cf86f7741b846413a4 Description": "A standard 6P1 Sb.2-1 rear sight for AKM automatic rifles, manufactured by Izhmash.", + "59d6514b86f774171a068a08 Name": "AKM wooden stock", + "59d6514b86f774171a068a08 ShortName": "AKM wood", + "59d6514b86f774171a068a08 Description": "A standard-issue wooden 6P1 Sb.5 stock for AKM automatic rifles, manufactured by Izhmash.", "59d790f486f77403cb06aec6 Name": "Armytek Predator Pro v3 XHP35 HI flashlight", "59d790f486f77403cb06aec6 ShortName": "XHP35", "59d790f486f77403cb06aec6 Description": "A powerful flashlight in a heavy-duty frame, manufactured by Armytek.", @@ -2272,7 +2275,7 @@ "59e35abd86f7741778269d82 Description": "An acidic salt of carbonic acid and sodium. It is usually a fine-grained white powder. Used in the food industry, cooking, or medicine as a neutralizer of skin burns and mucous membranes of human acids and reducing the acidity of gastric juice.", "59e35cbb86f7741778269d83 Name": "Corrugated hose", "59e35cbb86f7741778269d83 ShortName": "Hose", - "59e35cbb86f7741778269d83 Description": "Corrugated hose for use in the garden. Could be useful for organizing a Hideout.", + "59e35cbb86f7741778269d83 Description": "Corrugated hose for use in gardens. Could be useful for organizing a Hideout.", "59e35de086f7741778269d84 Name": "Electric drill", "59e35de086f7741778269d84 ShortName": "Drill", "59e35de086f7741778269d84 Description": "A cordless electric drill. Used in construction, furniture installation, and repair.", @@ -2312,29 +2315,29 @@ "59e5d83b86f7745aed03d262 Name": "AK 7.62x39 ribbed metal 10-round magazine", "59e5d83b86f7745aed03d262 ShortName": "AK ribbed", "59e5d83b86f7745aed03d262 Description": "A custom-cut ribbed metal 7.62x39mm 10-round magazine for AK-compatible systems. Made by sawing off a military magazine to comply with the Russian Federation's laws for use with civilian firearms. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", - "59e5f5a486f7746c530b3ce2 Name": "AK 7.62x39 Molot Arms 40-round magazine (6P2.Sb-11)", - "59e5f5a486f7746c530b3ce2 ShortName": "6P2 Sb-11", + "59e5f5a486f7746c530b3ce2 Name": "AK 7.62x39 Molot Arms 6P2.Sb-11 40-round magazine", + "59e5f5a486f7746c530b3ce2 ShortName": "6P2.Sb-11", "59e5f5a486f7746c530b3ce2 Description": "The 6P2 Sb-11 standard-issue 40-round 7.62x39 magazine for the RPK LMG from 1961 and onward, fits any AK-compatible weapon. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", - "59e6152586f77473dc057aa1 Name": "Molot Arms VPO-136 \"Vepr-KM\" 7.62x39 carbine", - "59e6152586f77473dc057aa1 ShortName": "VPO-136 \"Vepr-KM\"", + "59e6152586f77473dc057aa1 Name": "Molot Arms VPO-136 Vepr-KM 7.62x39 carbine", + "59e6152586f77473dc057aa1 ShortName": "VPO-136 Vepr-KM", "59e6152586f77473dc057aa1 Description": "The Molot Vepr-KM/VPO-136 carbine is based on the well-known Kalashnikov AKM and has an almost identical appearance, weight, and overall dimensions. Designed for hunting of medium and big game, as well as for sporting use.", - "59e61eb386f77440d64f5daf Name": "VPO-136 \"Vepr-KM\" 7.62x39 muzzle brake-compensator", - "59e61eb386f77440d64f5daf ShortName": "VPO136", + "59e61eb386f77440d64f5daf Name": "VPO-136 Vepr-KM 7.62x39 muzzle brake-compensator", + "59e61eb386f77440d64f5daf ShortName": "VPO-136", "59e61eb386f77440d64f5daf Description": "A standard muzzle brake/compensator manufactured by Molot Arms for VPO-136 Vepr KM 7.62x39 carbines. Also fits the AK family automatic rifles of the same caliber.", - "59e6227d86f77440d64f5dc2 Name": "VPO-136 \"Vepr-KM\" wooden stock", - "59e6227d86f77440d64f5dc2 ShortName": "VPO136", + "59e6227d86f77440d64f5dc2 Name": "VPO-136 Vepr-KM wooden stock", + "59e6227d86f77440d64f5dc2 ShortName": "VPO-136", "59e6227d86f77440d64f5dc2 Description": "A standard-issue wooden stock for VPO-136 Vepr KM carbines, manufactured by Molot Arms.", - "59e6284f86f77440d569536f Name": "VPO-136 \"Vepr-KM\" wooden handguard", - "59e6284f86f77440d569536f ShortName": "VPO136", + "59e6284f86f77440d569536f Name": "VPO-136 Vepr-KM wooden handguard", + "59e6284f86f77440d569536f ShortName": "VPO-136", "59e6284f86f77440d569536f Description": "A standard wooden handguard for VPO-136 Vepr KM carbines, manufactured by Molot Arms.", "59e62cc886f77440d40b52a1 Name": "AKM bakelite pistol grip", "59e62cc886f77440d40b52a1 ShortName": "AKM bak.", "59e62cc886f77440d40b52a1 Description": "A bakelite Izhmash-manufactured pistol grip for AKM automatic rifles.", - "59e6318286f77444dd62c4cc Name": "AK bakelite pistol grip", + "59e6318286f77444dd62c4cc Name": "AK Molot bakelite pistol grip", "59e6318286f77444dd62c4cc ShortName": "Molot bak.", "59e6318286f77444dd62c4cc Description": "A bakelite pistol grip for AK assault rifles and compatible weapon systems, manufactured by Molot Arms.", "59e6449086f7746c9f75e822 Name": "Molot Arms AKM-type dust cover", - "59e6449086f7746c9f75e822 ShortName": "Molot", + "59e6449086f7746c9f75e822 ShortName": "Molot DC", "59e6449086f7746c9f75e822 Description": "A standard-issue dust cover for AKM-type Vepr carbines, manufactured by Molot Arms.", "59e649f986f77411d949b246 Name": "Molot Arms AKM-type gas tube", "59e649f986f77411d949b246 ShortName": "Molot gas", @@ -2397,16 +2400,16 @@ "59e77a2386f7742ee578960a ShortName": "PS", "59e77a2386f7742ee578960a Description": "A 7.62x54mm R PS gzh (GRAU Index - 7N1) cartridge with a 9.8 gram bullet with a pointed steel core over a lead base with a bimetallic jacket, in a bimetallic case. This PS cartridge was developed by TsNIITochMash in the mid-1960s from the 7.62x54mm R LPS gzh cartridge specifically to increase its accuracy when fired from a sniper or designated marksman rifles, such as the SVD and its variants, being able of piercing through basic and intermediate ballistic body protections as well as providing an outstanding stopping power effect.", "59e8977386f77415a553c453 Name": "VPO-209 rear sight", - "59e8977386f77415a553c453 ShortName": "VPO209", + "59e8977386f77415a553c453 ShortName": "VPO-209 RS", "59e8977386f77415a553c453 Description": "A standard rear sight for VPO-209 AKM carbines, manufactured by Molot Arms.", "59e898ee86f77427614bd225 Name": "VPO-209 wooden handguard", - "59e898ee86f77427614bd225 ShortName": "VPO209", + "59e898ee86f77427614bd225 ShortName": "VPO-209", "59e898ee86f77427614bd225 Description": "A standard wooden handguard for VPO-209 AKM carbines, manufactured by Molot Arms.", "59e89d0986f77427600d226e Name": "VPO-209 wooden stock", - "59e89d0986f77427600d226e ShortName": "VPO209", + "59e89d0986f77427600d226e ShortName": "VPO-209", "59e89d0986f77427600d226e Description": "A standard-issue wooden stock for VPO-209 AKM carbines, manufactured by Molot Arms.", "59e8a00d86f7742ad93b569c Name": "VPO-209 thread protector", - "59e8a00d86f7742ad93b569c ShortName": "209 thr.", + "59e8a00d86f7742ad93b569c ShortName": "VPO-209", "59e8a00d86f7742ad93b569c Description": "A thread protector for muzzle brake/compensator for VPO-209 AKM carbines. Also fits the AKM 7.62x39 series automatic rifles.", "59eb7ebe86f7740b373438ce Name": "VSS/VAL TOZ 6P29M mount", "59eb7ebe86f7740b373438ce ShortName": "6P29M", @@ -2489,9 +2492,9 @@ "59ff346386f77477562ff5e2 Name": "Kalashnikov AKMS 7.62x39 assault rifle", "59ff346386f77477562ff5e2 ShortName": "AKMS", "59ff346386f77477562ff5e2 Description": "AKMS (Avtomát Kaláshnikova Modernizírovanny Skladnóy - \"Kalashnikov's Automatic rifle Modernised with foldable stock\") 7.62x39 assault rifle (GRAU Index — 6P4) is a variant of the AKM rifle with a folding shoulder piece (stock). Folds forward-down, under the handguard. Designed specifically for airborne troops.", - "59ff3b6a86f77477562ff5ed Name": "AKMS shoulder piece (6P4 Sb.1-19)", - "59ff3b6a86f77477562ff5ed ShortName": "6P4 Sb.1-19", - "59ff3b6a86f77477562ff5ed Description": "A folding shoulder piece assembly for AKMS automatic rifles, manufactured by Izhmash.", + "59ff3b6a86f77477562ff5ed Name": "AKMS folding stock", + "59ff3b6a86f77477562ff5ed ShortName": "AKMS", + "59ff3b6a86f77477562ff5ed Description": "A 6P4 Sb.1-19 folding shoulder piece assembly for AKMS automatic rifles, manufactured by Izhmash.", "5a0060fc86f7745793204432 Name": "AKMS 7.62x39 aluminium 30-round magazine", "5a0060fc86f7745793204432 ShortName": "AKMS al.", "5a0060fc86f7745793204432 Description": "A 30-round aluminum magazine for 7.62x39 AKMS and compatibles, nicknamed “Airborne”. Made of light aluminum alloy and reinforced by additional ribs. It's quite a rarity, as it was never in mass production. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", @@ -2501,7 +2504,7 @@ "5a01ad4786f77450561fda02 Name": "AK Kiba Arms VDM CS gas tube", "5a01ad4786f77450561fda02 ShortName": "VDM CS", "5a01ad4786f77450561fda02 Description": "A custom gas tube for specific AK family handguards.", - "5a01c29586f77474660c694c Name": "AK 7.62x39 6L10 30-round magazine", + "5a01c29586f77474660c694c Name": "AK 7.62x39 6L10 bakelite 30-round magazine", "5a01c29586f77474660c694c ShortName": "6L10", "5a01c29586f77474660c694c Description": "A 30-round 6L10 magazine made with an AG-4S moulding compound, for 7.62x39 AK and compatible weapons. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", "5a0448bc86f774736f14efa8 Name": "Key to the closed premises of the Health Resort", @@ -2870,7 +2873,7 @@ "5a687e7886f7740c4a5133fb Name": "Blood sample", "5a687e7886f7740c4a5133fb ShortName": "BSample", "5a687e7886f7740c4a5133fb Description": "A blood sample found on the car door. It was hard getting even this much.", - "5a69a2ed8dc32e000d46d1f1 Name": "AS VAL Rotor 43 pistol grip & buffer tube", + "5a69a2ed8dc32e000d46d1f1 Name": "AS VAL Rotor 43 pistol grip with buffer tube", "5a69a2ed8dc32e000d46d1f1 ShortName": "R43 VAL", "5a69a2ed8dc32e000d46d1f1 Description": "A pistol grip with an integrated Mil-Spec buffer tube for AS VAL, manufactured by Rotor 43.", "5a6b585a8dc32e5a9c28b4f1 Name": "Glock 9x19 Lone Wolf AlphaWolf thread protector", @@ -3080,7 +3083,7 @@ "5a966ec8a2750c00171b3f36 Name": "HK MP5 B&T tri-rail receiver mount", "5a966ec8a2750c00171b3f36 ShortName": "B&T 3x", "5a966ec8a2750c00171b3f36 Description": "A rail mount designed by Brügger & Thomet for the HK MP5 submachine gun. It is mounted on the weapon's receiver and allows additional installation of scopes and reflex sights.", - "5a966f51a2750c00156aacf6 Name": "SOK-12 12/76 SAI-02 10-round magazine", + "5a966f51a2750c00156aacf6 Name": "SOK-12 12ga SAI-02 10-round magazine", "5a966f51a2750c00156aacf6 ShortName": "SAI-02", "5a966f51a2750c00156aacf6 Description": "The SAI-02 is a 10-round polymer magazine for SOK-12 and compatible weapons, intended for use with 12/76 or 12/70 shells. Manufactured by ProMag.", "5a9685b1a2750c0032157104 Name": "Glock Moto Cut pistol slide", @@ -3101,7 +3104,7 @@ "5a9d6d34a2750c00141e07da Name": "AK Strike Industries TRAX 2 handguard extension", "5a9d6d34a2750c00141e07da ShortName": "TRAX 2", "5a9d6d34a2750c00141e07da Description": "TRAX 2 is a front rail section that covers the gas block. Provides additional places to mount accessories. Requires the TRAX Bridge rail to be mounted with the TRAX 1 handguard. Manufactured by Strike Industries.", - "5a9e81fba2750c00164f6b11 Name": "9x39 SR3M.130 30-round magazine", + "5a9e81fba2750c00164f6b11 Name": "VSS/VAL 9x39 SR3M.130 30-round magazine", "5a9e81fba2750c00164f6b11 ShortName": "SR3M.130", "5a9e81fba2750c00164f6b11 Description": "A 30-round steel TsNIITochMash SR3M.130 magazine for 9x39 caliber SR-3M, VSS, and AS VAL.", "5a9ea27ca2750c00137fa672 Name": "AK Spikes Tactical Dynacomp 7.62x39 muzzle brake-compensator", @@ -3110,18 +3113,18 @@ "5a9eb32da2750c00171b3f9c Name": "AR-15 FAB Defense GL-SHOCK buttstock", "5a9eb32da2750c00171b3f9c ShortName": "GL-SHOCK", "5a9eb32da2750c00171b3f9c Description": "A telescopic stock with an adjustable cheek rest kit, manufactured by FAB Defense.", - "5a9fb739a2750c003215717f Name": "Rotor 43 9x19 muzzle brake-compensator", + "5a9fb739a2750c003215717f Name": "Rotor 43 9x19 sound suppressor", "5a9fb739a2750c003215717f ShortName": "R43 9x19", "5a9fb739a2750c003215717f Description": "The Rotor 43 muzzle brake, designed for installation on PP-19-01 Vityaz 9x19 SMGs. Although positioned as a muzzle brake, it also works as a sound suppressor.", - "5a9fbacda2750c00141e080f Name": "Rotor 43 7.62x39 muzzle brake-compensator", + "5a9fbacda2750c00141e080f Name": "Rotor 43 7.62x39 sound suppressor", "5a9fbacda2750c00141e080f ShortName": "R43 7.62x39", "5a9fbacda2750c00141e080f Description": "The Rotor 43 muzzle brake is designed for installation on AK 7.62x39 family assault rifles. Although positioned as a muzzle brake, it also works as a sound suppressor.", - "5a9fbb74a2750c0032157181 Name": "Rotor 43 .366 TKM muzzle brake-compensator", + "5a9fbb74a2750c0032157181 Name": "Rotor 43 .366 TKM sound suppressor", "5a9fbb74a2750c0032157181 ShortName": "R43 .366TKM", "5a9fbb74a2750c0032157181 Description": "The Rotor 43 muzzle brake, designed for installation on VPO-209 .366TKM carbines. Although positioned as a muzzle brake, it also works as a sound suppressor.", - "5a9fbb84a2750c00137fa685 Name": "Rotor 43 5.56x45 muzzle brake-compensator", + "5a9fbb84a2750c00137fa685 Name": "Rotor 43 5.56x45 sound suppressor", "5a9fbb84a2750c00137fa685 ShortName": "R43 556", - "5a9fbb84a2750c00137fa685 Description": "The Rotor 43 muzzle brake is designed for installation on AR- or AK- based 5.56x45 rifles. Although positioned as a muzzle brake, it also works as a sound suppressor.", + "5a9fbb84a2750c00137fa685 Description": "The Rotor 43 muzzle brake is designed for installation on AR- or AK-based 5.56x45 rifles. Although positioned as a muzzle brake, it also works as a sound suppressor.", "5a9fc7e6a2750c0032157184 Name": "VSS/VAL Zenit B-3 mount combo", "5a9fc7e6a2750c0032157184 ShortName": "B-3", "5a9fc7e6a2750c0032157184 Description": "The B-3 combo mounts are installed on the VSS/VAL sound suppressor to form a Picatinny rail for installation of additional weapon equipment. Manufactured by Zenit.", @@ -3233,9 +3236,9 @@ "5ab3afb2d8ce87001660304d Name": "M1A Smith Enterprise SOCOM 16 7.62x51 threaded muzzle brake & gas block", "5ab3afb2d8ce87001660304d ShortName": "SOCOM16 thr.", "5ab3afb2d8ce87001660304d Description": "A muzzle brake/gas block for M1A rifles, manufactured by Smith Enterprise.", - "5ab626e4d8ce87272e4c6e43 Name": "AKS-74 metal skeletonized stock (6P21 Sb.5)", - "5ab626e4d8ce87272e4c6e43 ShortName": "6P21 Sb.5", - "5ab626e4d8ce87272e4c6e43 Description": "A metal skeleton stock for AKS-74 automatic rifles, manufactured by IzhMash.", + "5ab626e4d8ce87272e4c6e43 Name": "AKS-74 skeletonized stock", + "5ab626e4d8ce87272e4c6e43 ShortName": "AKS-74", + "5ab626e4d8ce87272e4c6e43 Description": "A 6P21 Sb.5 metal skeleton stock for AKS-74 automatic rifles, manufactured by Izhmash.", "5ab8dab586f77441cd04f2a2 Name": "WARTECH MK3 TV-104 chest rig (MultiCam)", "5ab8dab586f77441cd04f2a2 ShortName": "MK3 TV-104", "5ab8dab586f77441cd04f2a2 Description": "This chest rig platform is designed for placing equipment in the chest and abdomen areas, with an open back. Includes integrated pouches, designed for 8 magazines. Can be used both separately and on top of the armor vest. Manufactured by WARTECH.", @@ -3293,21 +3296,21 @@ "5abccb7dd8ce87001773e277 Name": "APB 9x18PM silenced machine pistol", "5abccb7dd8ce87001773e277 ShortName": "APB", "5abccb7dd8ce87001773e277 Description": "The APB pistol (Avtomatícheskiy Pistolét Besshúmnyy - \"Silenced Automatic Pistol\", GRAU Index - 6P13) is a silenced version of the Stechkin machine pistol, widely used by different Russian special forces.", - "5abcd472d8ce8700166032ae Name": "AKMSN shoulder piece (6P4N Sb.1-19)", - "5abcd472d8ce8700166032ae ShortName": "6P4N Sb.1-19", - "5abcd472d8ce8700166032ae Description": "A folding shoulder piece assembly for AKMSN automatic rifles, manufactured by Izhmash.", + "5abcd472d8ce8700166032ae Name": "AKMSN folding stock", + "5abcd472d8ce8700166032ae ShortName": "AKMSN", + "5abcd472d8ce8700166032ae Description": "A 6P4N Sb.1-19 folding shoulder piece assembly for AKMSN automatic rifles, manufactured by Izhmash.", "5ac4c50d5acfc40019262e87 Name": "Kolpak-1S face shield", "5ac4c50d5acfc40019262e87 ShortName": "K-1S", "5ac4c50d5acfc40019262e87 Description": "A weak protection from eye and face damage, made to mount on Kolpak-1S helmet.", "5ac4cd105acfc40016339859 Name": "Kalashnikov AK-74M 5.45x39 assault rifle", "5ac4cd105acfc40016339859 ShortName": "AK-74M", "5ac4cd105acfc40016339859 Description": "The AK-74M (Avtomat Kalashnikova 74 Modernizirovanny - \"Kalashnikov's Automatic rifle 74 Modernized\") 5.45x39mm assault rifle is a full-scale produced modernized version of the AK-74 that offers more versatility compared with its predecessor. Apart from several minor improvements, such as a lightened bolt and carrier assembly to reduce the impulse of the gas piston and bolt carrier during firing, the rifle features a new glass-filled polyamide stock that retains the shape of the original AK-74 fixed laminated wood stock, but side-folds to the left like the skeletonised AKS-74 buttstock, and also a dovetail side mount for installing various scopes. The AK-74M is a main service rifle of the Russian Federation.", - "5ac50c185acfc400163398d4 Name": "AK-74M polymer stock (6P34 Sb.15)", - "5ac50c185acfc400163398d4 ShortName": "6P34 Sb.15", - "5ac50c185acfc400163398d4 Description": "A polymer stock for AK-74M automatic rifles, manufactured by Izhmash.", - "5ac50da15acfc4001718d287 Name": "AK-74M dust cover (6P34 0-1)", - "5ac50da15acfc4001718d287 ShortName": "6P34 0-1", - "5ac50da15acfc4001718d287 Description": "A standard-issue dust cover for AK-74M automatic rifles, manufactured by Izhmash.", + "5ac50c185acfc400163398d4 Name": "AK-74M polymer stock", + "5ac50c185acfc400163398d4 ShortName": "AK-74M", + "5ac50c185acfc400163398d4 Description": "A polymer 6P34 Sb.15 stock for AK-74M automatic rifles, manufactured by Izhmash.", + "5ac50da15acfc4001718d287 Name": "AK-74M dust cover", + "5ac50da15acfc4001718d287 ShortName": "AK-74M DC", + "5ac50da15acfc4001718d287 Description": "A standard-issue 6P34 0-1 dust cover for AK-74M automatic rifles, manufactured by Izhmash.", "5ac620eb86f7743a8e6e0da0 Name": "Package of graphics cards", "5ac620eb86f7743a8e6e0da0 ShortName": "Package", "5ac620eb86f7743a8e6e0da0 Description": "A package sealed with a large amount of tape. It's quite battered, but the contents appear to be intact.", @@ -3332,30 +3335,30 @@ "5ac66d9b5acfc4001633997a Name": "Kalashnikov AK-105 5.45x39 assault rifle", "5ac66d9b5acfc4001633997a ShortName": "AK-105", "5ac66d9b5acfc4001633997a Description": "The AK-105 5.45x39mm assault rifle is a further modernized version of AK-74M base. A short compact version equipped with a side-folding shoulder stock and a side mount for optical and night scopes. The 100-series AKs are produced by the Izhmash factories in Izhevsk, Russia.", - "5ac72e475acfc400180ae6fe Name": "AK-74M rear sight (6P20 Sb.2)", - "5ac72e475acfc400180ae6fe ShortName": "6P20 Sb.2", - "5ac72e475acfc400180ae6fe Description": "A standard rear sight for AK-74M automatic rifles, manufactured by Izhmash.", + "5ac72e475acfc400180ae6fe Name": "AK-74M rear sight", + "5ac72e475acfc400180ae6fe ShortName": "AK-74M RS", + "5ac72e475acfc400180ae6fe Description": "A standard 6P20 Sb.2 rear sight for AK-74M automatic rifles, manufactured by Izhmash.", "5ac72e615acfc43f67248aa0 Name": "AK-101 5.56x45 muzzle brake-compensator", "5ac72e615acfc43f67248aa0 ShortName": "AK-101", "5ac72e615acfc43f67248aa0 Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-101 and weapon systems based on it.", - "5ac72e725acfc400180ae701 Name": "AK-102 5.56x45 muzzle brake-compensator (6P44 0-20)", - "5ac72e725acfc400180ae701 ShortName": "6P44 0-20", - "5ac72e725acfc400180ae701 Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-102 assault rifle.", + "5ac72e725acfc400180ae701 Name": "AK-102 5.56x45 muzzle brake-compensator", + "5ac72e725acfc400180ae701 ShortName": "AK-102", + "5ac72e725acfc400180ae701 Description": "A standard Izhmash-produced 6P44 0-20 muzzle brake and compensator for the AK-102 assault rifle.", "5ac72e7d5acfc40016339a02 Name": "AK-103 7.62x39 muzzle brake-compensator", "5ac72e7d5acfc40016339a02 ShortName": "AK-103", "5ac72e7d5acfc40016339a02 Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-103.", - "5ac72e895acfc43b321d4bd5 Name": "AK-104 7.62x39 muzzle brake-compensator (6P46 0-20)", - "5ac72e895acfc43b321d4bd5 ShortName": "6P46 0-20", - "5ac72e895acfc43b321d4bd5 Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-104 7.62x39 assault rifle.", - "5ac72e945acfc43f3b691116 Name": "AK-105 5.45x39 muzzle brake-compensator (6P44 0-20)", - "5ac72e945acfc43f3b691116 ShortName": "6P44 0-20", - "5ac72e945acfc43f3b691116 Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-105.", - "5ac733a45acfc400192630e2 Name": "AK-105 rear sight (6P44 Sb.1-30)", - "5ac733a45acfc400192630e2 ShortName": "6P44 Sb.1-30", - "5ac733a45acfc400192630e2 Description": "A standard rear sight for AK-105 automatic rifles, manufactured by Izhmash.", - "5ac7655e5acfc40016339a19 Name": "AK-74M 5.45x39 muzzle brake-compensator (6P20 0-20)", - "5ac7655e5acfc40016339a19 ShortName": "6P20 0-20", - "5ac7655e5acfc40016339a19 Description": "A standard Izhmash-produced muzzle brake and compensator for the AK-74M.", + "5ac72e895acfc43b321d4bd5 Name": "AK-104 7.62x39 muzzle brake-compensator", + "5ac72e895acfc43b321d4bd5 ShortName": "AK-104", + "5ac72e895acfc43b321d4bd5 Description": "A standard Izhmash-produced 6P46 0-20 muzzle brake and compensator for the AK-104 7.62x39 assault rifle.", + "5ac72e945acfc43f3b691116 Name": "AK-105 5.45x39 muzzle brake-compensator", + "5ac72e945acfc43f3b691116 ShortName": "AK-105", + "5ac72e945acfc43f3b691116 Description": "A standard Izhmash-produced 6P44 0-20 muzzle brake and compensator for the AK-105.", + "5ac733a45acfc400192630e2 Name": "AK-105 rear sight", + "5ac733a45acfc400192630e2 ShortName": "AK-105 RS", + "5ac733a45acfc400192630e2 Description": "A standard 6P44 Sb.1-30 rear sight for AK-105 automatic rifles, manufactured by Izhmash.", + "5ac7655e5acfc40016339a19 Name": "AK-74M 5.45x39 muzzle brake-compensator", + "5ac7655e5acfc40016339a19 ShortName": "AK-74M", + "5ac7655e5acfc40016339a19 Description": "A standard Izhmash-produced 6P20 0-20 muzzle brake and compensator for the AK-74M.", "5ac78a9b86f7741cca0bbd8d Name": "Signal Jammer", "5ac78a9b86f7741cca0bbd8d ShortName": "Jammer", "5ac78a9b86f7741cca0bbd8d Description": "An assembled signal jamming device. It emits waves of specific frequency to distort the signal and perevent the data exchange.", @@ -3611,7 +3614,7 @@ "5b1faa0f5acfc40dc528aeb5 Name": "Glock 18C pistol slide", "5b1faa0f5acfc40dc528aeb5 ShortName": "G18C", "5b1faa0f5acfc40dc528aeb5 Description": "A standard-issue slide for Glock 18C 9x19 pistols.", - "5b1fb3e15acfc4001637f068 Name": "AK 7.62x39 bakelite 40-round magazine", + "5b1fb3e15acfc4001637f068 Name": "AK 7.62x39 6P2 bakelite 40-round magazine", "5b1fb3e15acfc4001637f068 ShortName": "6P2 bak.", "5b1fb3e15acfc4001637f068 Description": "A standard 40-round bakelite magazine for the RPK. It fits into 7.62x39 AK and compatible weapons. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", "5b1fd4e35acfc40018633c39 Name": "AK 7.62x39 aluminium 10-round magazine", @@ -3623,9 +3626,9 @@ "5b222d405acfc400153af4fe Name": "AK Zenit PT-1 \"Klassika\" stock", "5b222d405acfc400153af4fe ShortName": "PT-1", "5b222d405acfc400153af4fe Description": "The telescopic PT-1 stock is mounted on the standard place of the stock AK 103, 104, 105, 74M, AKS74U and PP Vityaz, has a length adjustment mechanism and an adjustable cheek. A special lock is required for installation. Manufactured by Zenit.", - "5b2240bf5acfc40dc528af69 Name": "AR-15 Radian Weapons Raptor charging handle", + "5b2240bf5acfc40dc528af69 Name": "AR-15 Radian Weapons Raptor charging handle (FDE)", "5b2240bf5acfc40dc528af69 ShortName": "Raptor", - "5b2240bf5acfc40dc528af69 Description": "The Raptor charging handle for AR-15 and compatible systems. Manufactured by Radian Weapons.", + "5b2240bf5acfc40dc528af69 Description": "The Raptor charging handle for AR-15 and compatible systems. Manufactured by Radian Weapons. Flat Dark Earth version.", "5b237e425acfc4771e1be0b6 Name": "AK TROY Full Length Rail handguard & gas tube combo", "5b237e425acfc4771e1be0b6 ShortName": "TROY FLR", "5b237e425acfc4771e1be0b6 Description": "The Full Length Rail handguard and gas tube combo. The cooling holes allow the rail to run cool, even after extended firing. Machined from hardened aircraft aluminum with stainless steel components and finished in MIL-SPEC hardcoat anodizing. Features a 5 inch top rail for installation of optics and tactical devices. Manufactured by TROY Industries.", @@ -3764,9 +3767,9 @@ "5b4329075acfc400153b78ff Name": "Pompon hat", "5b4329075acfc400153b78ff ShortName": "Pompon", "5b4329075acfc400153b78ff Description": "A warm hat with a pompon. Only Scavs would wear something like this. Well, or some psychos who want to be in the spotlight.", - "5b4329f05acfc47a86086aa1 Name": "DevTac Ronin ballistic helmet", - "5b4329f05acfc47a86086aa1 ShortName": "Ronin", - "5b4329f05acfc47a86086aa1 Description": "A Japan-styled tactical helmet, manufactured by DevTac. Not used by any military or special forces. Just somehow happened to be in Tarkov for some frivolous price. Features a full protection of the whole head, but the armor class is not good enough to actually be useful in combat.", + "5b4329f05acfc47a86086aa1 Name": "DevTac Ronin Respirator", + "5b4329f05acfc47a86086aa1 ShortName": "Ronin Respirator", + "5b4329f05acfc47a86086aa1 Description": "A Japan-styled tactical helmet, manufactured by DevTac. Not used by any military or special forces. Just somehow happened to be in Tarkov for some frivolous price. Features a full NIJ level IIIA protection of the whole head, though you really don't want to get shot in the face with this thing.", "5b432b2f5acfc4771e1c6622 Name": "Shattered lightweight armored mask", "5b432b2f5acfc4771e1c6622 ShortName": "Shattered", "5b432b2f5acfc4771e1c6622 Description": "The \"Shattered\" face protection mask, reinforced with aramid fibers.", @@ -4058,9 +4061,9 @@ "5bbdb83fd4351e44f824c44b Name": "Mosin Rifle Tacfire Tanker Style 7.62x54R muzzle brake", "5bbdb83fd4351e44f824c44b ShortName": "Mosin Tanker", "5bbdb83fd4351e44f824c44b Description": "The Tanker style muzzle brake for the Mosin rifle. Manufactured by Tacfire.", - "5bbdb870d4351e00367fb67d Name": "Mosin Rifle ATI Monte Carlo chassis", + "5bbdb870d4351e00367fb67d Name": "Mosin Rifle ATI Monte Carlo stock", "5bbdb870d4351e00367fb67d ShortName": "Mosin MC", - "5bbdb870d4351e00367fb67d Description": "Monte Carlo-style chassis for the Mosin rifle, transforms the weapon into a more modern-looking rifle. Manufactured by ATI outdoors.", + "5bbdb870d4351e00367fb67d Description": "A Monte Carlo-style stock for the Mosin rifle, which transforms the weapon into a more modern-looking rifle. Manufactured by ATI Outdoors.", "5bbdb8bdd4351e4502011460 Name": "AR-10 Odin Works ATLAS-7 7.62x51 muzzle brake", "5bbdb8bdd4351e4502011460 ShortName": "ATLAS-7", "5bbdb8bdd4351e4502011460 Description": "The ATLAS-7 muzzle brake designed for installation on AR-10-type systems and compatibles. Manufactured by Odin Works.", @@ -4344,7 +4347,7 @@ "5c052cea86f7746b2101e8d8 ShortName": "Plastic suitcase", "5c052cea86f7746b2101e8d8 Description": "Plastic suitcase", "5c052e6986f7746b207bc3c9 Name": "Portable defibrillator", - "5c052e6986f7746b207bc3c9 ShortName": "Defibrillator", + "5c052e6986f7746b207bc3c9 ShortName": "Defib", "5c052e6986f7746b207bc3c9 Description": "Sudden cardiac arrest (SCA) can happen to anyone, anytime, anywhere. Phipils uses SMART Biphasic technology in its HeartStart Defibrillators to deliver an effective, high current defibrillation shock at a lower energy dose to minimize side effects.", "5c052f6886f7746b1e3db148 Name": "Military COFDM Wireless Signal Transmitter", "5c052f6886f7746b1e3db148 ShortName": "SG-C10", @@ -4367,25 +4370,25 @@ "5c0548ae0db834001966a3c2 Name": "SLR-106/AK 5.56x45 Circle 10 30-round magazine", "5c0548ae0db834001966a3c2 ShortName": "C-10 AK", "5c0548ae0db834001966a3c2 Description": "A Bulgarian 30-round 5.56x45 \"Waffle Pattern\" magazine for the SLR-106 civilian AK-based rifles. Manufactured by Circle 10 and distributed by Arsenal Inc.", - "5c0558060db834001b735271 Name": "GPNVG-18 Night Vision goggles", + "5c0558060db834001b735271 Name": "L3Harris GPNVG-18 night vision goggles", "5c0558060db834001b735271 ShortName": "GPNVG-18", "5c0558060db834001b735271 Description": "The GPNVG-18 (Ground Panoramic Night Vision Goggle) panoramic night vision goggles. The cardinal difference of this NVG from the others is the presence of four separate image intensifier tubes, two for each eye. Two Central IITs are directed forward, while two more are directed outward from the center. This innovative solution allowed to expand the field of view to 97 degrees.", "5c064c400db834001d23f468 Name": "LaRue LT101 QD Tactical Picatinny Riser mount", "5c064c400db834001d23f468 ShortName": "QD LT101", "5c064c400db834001d23f468 Description": "A Quick-Detach Picatinny riser to elevate the reflex or optical sight position, manufactured by LaRue.", - "5c06595c0db834001a66af6c Name": "LA-5B/PEQ tactical device", + "5c06595c0db834001a66af6c Name": "L3Harris LA-5B/PEQ tactical device", "5c06595c0db834001a66af6c ShortName": "LA-5B/PEQ", "5c06595c0db834001a66af6c Description": "ATPIAL (Advanced Target Pointer Illuminator Aiming Laser) LA-5B/PEQ produced by L3 Insight Technologies. Tactical device that combines laser designators in both visible and IR band with IR searchlight.", - "5c066e3a0db834001b7353f0 Name": "Armasight N-15 Night Vision Goggles", + "5c066e3a0db834001b7353f0 Name": "Armasight N-15 night vision goggles", "5c066e3a0db834001b7353f0 ShortName": "N-15", "5c066e3a0db834001b7353f0 Description": "The Armasight N-15-NVG binocular. Civilian alternative to contract military devices installed in a compact and ergonomic body.", "5c066ef40db834001966a595 Name": "Armasight NVG head strap", "5c066ef40db834001966a595 ShortName": "NVG strap", "5c066ef40db834001966a595 Description": "A standard head strap mounting system for various Armasight devices.", - "5c0672ed0db834001b7353f3 Name": "PP-19-01 \"Vityaz\" 9x19 PUFGUN SG-919 30 30-round magazine", + "5c0672ed0db834001b7353f3 Name": "PP-19-01 Vityaz 9x19 PUFGUN SG-919 30 30-round magazine", "5c0672ed0db834001b7353f3 ShortName": "SG-919", "5c0672ed0db834001b7353f3 Description": "The PUFGUN SG-919 30 magazine for PP-19-01 Vityaz 9x19 with a 30-round ammo capacity. Tactical banana yellow camouflage.", - "5c0673fb0db8340023300271 Name": "PP-19-01 \"Vityaz\" 9x19 PUFGUN SG-919 20 20-round magazine", + "5c0673fb0db8340023300271 Name": "PP-19-01 Vityaz 9x19 PUFGUN SG-919 20 20-round magazine", "5c0673fb0db8340023300271 ShortName": "SG-919", "5c0673fb0db8340023300271 Description": "The PUFGUN SG-919 20 magazine for PP-19-01 Vityaz 9x19 with a 20-round ammo capacity. Tactical banana yellow camouflage.", "5c06779c86f77426e00dd782 Name": "Bundle of wires", @@ -4400,7 +4403,7 @@ "5c0695860db834001b735461 Name": "PNV-10T dovetail adapter", "5c0695860db834001b735461 ShortName": "10T adpt", "5c0695860db834001b735461 Description": "The most common problem for owners of PNV-10T is its installation on modern helmets and suspension systems. The problem is solved by a simple adapter made of metal produced by many \"workshops\".", - "5c0696830db834001d23f5da Name": "PNV-10T Night Vision Goggles", + "5c0696830db834001d23f5da Name": "PNV-10T night vision goggles", "5c0696830db834001d23f5da ShortName": "PNV-10T", "5c0696830db834001d23f5da Description": "PNV-10T are pseudo-binocular night vision googles of the second generation. A widespread and popular device of low-price category among hunters and fans of tactical military games.", "5c06c6a80db834001b735491 Name": "SSh-68 steel helmet (Olive Drab)", @@ -4409,9 +4412,9 @@ "5c079ec50db834001966a706 Name": "TT Razor Arms rubber grip", "5c079ec50db834001966a706 ShortName": "TT RazorA", "5c079ec50db834001966a706 Description": "A rubber grip for TT pistols, manufactured by Razor Arms.", - "5c079ed60db834001a66b372 Name": "TT DLP Tactical Precision LAM-module", - "5c079ed60db834001a66b372 ShortName": "TT Precision", - "5c079ed60db834001a66b372 Description": "A precision laser designator for the TT pistol, manufactured by DLP Tactical.", + "5c079ed60db834001a66b372 Name": "TT DLP Tactical Precision Laser Sight", + "5c079ed60db834001a66b372 ShortName": "TT PLS", + "5c079ed60db834001a66b372 Description": "A laser designator for the TT pistol, manufactured by DLP Tactical.", "5c07a8770db8340023300450 Name": "AR-15 Noveske Gen.3 5.56x45 upper receiver", "5c07a8770db8340023300450 ShortName": "Gen.3", "5c07a8770db8340023300450 Description": "The Gen.3 modular upper receiver for AR-based weapons, manufactured by Noveske. Fitted with mounts for attaching additional equipment.", @@ -4478,7 +4481,7 @@ "5c0d5ae286f7741e46554302 Name": "5.56x45mm Warmageddon", "5c0d5ae286f7741e46554302 ShortName": "Warmage", "5c0d5ae286f7741e46554302 Description": "A .223 Remington (5.56x45mm) Warmageddon cartridge with a 3.6 gram lead core polymer tipped expansive bullet with a copper alloy jacket in a brass case; intended for hunting. This bullet features a ballistic tip that acts as a wedge on the lead core upon impact, allowing the bullet to expand and cause outstanding damage on the target, as well as being capable of causing severe adverse effects to the target upon impact, despite not having the full energy of an intermediate cartridge.", - "5c0d5e4486f77478390952fe Name": "5.45x39mm PPBS gs \"Igolnik\"", + "5c0d5e4486f77478390952fe Name": "5.45x39mm PPBS gs Igolnik", "5c0d5e4486f77478390952fe ShortName": "PPBS", "5c0d5e4486f77478390952fe Description": "A 5.45x39mm PPBS gs (GRAU Index - 7N39) cartridge with a 4 gram armor-piercing bullet with a pointed tungsten carbide core with two-layer jacket, a lead interior and a bimetallic exterior, in a steel case. This experimental cartridge was developed by TsNIITochMash and TechKomplekt under the name of PPBS (Povyshennoy Probivayemosti, Broneboynyy Serdechnik - \"Increased Penetration, Armor-piercing Core\") \"Igólnik\" (\"Needlecase\") based on the 5.45x39mm BS gs cartridge to increase its penetration capabilities, providing excellent results against the most modern specialized ballistic body protections, in addition to being capable of piercing light covers and light armored vehicles, however, due to its design, it has a high bounce probability off various surfaces.", "5c0d668f86f7747ccb7f13b2 Name": "9x39mm SPP gs", @@ -4616,7 +4619,7 @@ "5c12620d86f7743f8b198b72 Name": "Tetriz portable game console", "5c12620d86f7743f8b198b72 ShortName": "Tetriz", "5c12620d86f7743f8b198b72 Description": "An ancient artifact of a lost past. May be of interest to Mechanic, an avid collector of electronics.", - "5c1262a286f7743f8a69aab2 Name": "5.45x39mm PPBS gs \"Igolnik\" ammo pack (30 pcs)", + "5c1262a286f7743f8a69aab2 Name": "5.45x39mm PPBS gs Igolnik ammo pack (30 pcs)", "5c1262a286f7743f8a69aab2 ShortName": "PPBS", "5c1262a286f7743f8a69aab2 Description": "A paper package of 5.45x39 PPBS gs \"Igolnik\" cartridges, 30 pieces.", "5c1265fc86f7743f896a21c2 Name": "Broken GPhone X smartphone", @@ -4790,26 +4793,26 @@ "5c4eecde2e221602b3140418 Name": "SV-98 sound suppressor heat shield", "5c4eecde2e221602b3140418 ShortName": "SV98 HS", "5c4eecde2e221602b3140418 Description": "A standard-issue heat shield for SV-98 sound suppressors.", - "5c501a4d2e221602b412b540 Name": "Molot Arms VPO-101 \"Vepr-Hunter\" 7.62x51 carbine", - "5c501a4d2e221602b412b540 ShortName": "VPO-101 \"Vepr-Hunter\"", + "5c501a4d2e221602b412b540 Name": "Molot Arms VPO-101 Vepr-Hunter 7.62x51 carbine", + "5c501a4d2e221602b412b540 ShortName": "VPO-101 Vepr-Hunter", "5c501a4d2e221602b412b540 Description": "A semi-automatic 7.62x51mm caliber hunting carbine. It was created on the platform of Kalashnikov machine gun (RPK) and has a similar appearance, weight and dimensions. Designed for professional and amateur hunting of medium and big game, as well as sporting use.", - "5c5039be2e221602b177c9ff Name": "VPO-101 \"Vepr-Hunter\" gas tube", + "5c5039be2e221602b177c9ff Name": "VPO-101 gas tube", "5c5039be2e221602b177c9ff ShortName": "101 gas", "5c5039be2e221602b177c9ff Description": "A standard gas tube for VPO-101 Vepr Hunter carbines. Gas tubes channel the travel direction of gas piston.", - "5c503ac82e221602b21d6e9a Name": "VPO-101 \"Vepr-Hunter\" 7.62x51 5-round magazine", - "5c503ac82e221602b21d6e9a ShortName": "VPO101", + "5c503ac82e221602b21d6e9a Name": "VPO-101 7.62x51 5-round magazine", + "5c503ac82e221602b21d6e9a ShortName": "VPO-101", "5c503ac82e221602b21d6e9a Description": "A 5-round magazine for the VPO-101 carbines and compatible 7.62x51 systems, manufactured by Molot Arms.", - "5c503ad32e2216398b5aada2 Name": "VPO-101 \"Vepr-Hunter\" 7.62x51 10-round magazine", - "5c503ad32e2216398b5aada2 ShortName": "VPO101", + "5c503ad32e2216398b5aada2 Name": "VPO-101 7.62x51 10-round magazine", + "5c503ad32e2216398b5aada2 ShortName": "VPO-101", "5c503ad32e2216398b5aada2 Description": "A 10-round magazine for VPO-101 carbines and compatible 7.62x51 systems, manufactured by Molot Arms.", - "5c503af12e221602b177ca02 Name": "VPO-101 \"Vepr-Hunter\" stock", - "5c503af12e221602b177ca02 ShortName": "VPO101", + "5c503af12e221602b177ca02 Name": "VPO-101 wooden stock", + "5c503af12e221602b177ca02 ShortName": "VPO-101", "5c503af12e221602b177ca02 Description": "A standard-issue stock for VPO-101 Vepr-Hunter carbines.", - "5c503b1c2e221602b21d6e9d Name": "VPO-101 \"Vepr-Hunter\" rear sight", + "5c503b1c2e221602b21d6e9d Name": "VPO-101 rear sight", "5c503b1c2e221602b21d6e9d ShortName": "101 RS", "5c503b1c2e221602b21d6e9d Description": "A standard ramp-type rear sight for the VPO-101 Vepr-Hunter carbine.", - "5c503d0a2e221602b542b7ef Name": "VPO-101 \"Vepr-Hunter\" dust cover", - "5c503d0a2e221602b542b7ef ShortName": "VPO101", + "5c503d0a2e221602b542b7ef Name": "VPO-101 dust cover", + "5c503d0a2e221602b542b7ef ShortName": "VPO-101", "5c503d0a2e221602b542b7ef Description": "A standard-issue metal dust cover for VPO-101 Vepr-Hunter carbines, manufactured by Molot Arms.", "5c5952732e2216398b5abda2 Name": "Zenit Perst-3 tactical device", "5c5952732e2216398b5abda2 ShortName": "Perst-3", @@ -4856,12 +4859,12 @@ "5c5db6b32e221600102611a0 Name": "MPX Geissele SCH charging handle", "5c5db6b32e221600102611a0 ShortName": "MPX SCH", "5c5db6b32e221600102611a0 Description": "The SCH (Super Charging Handle) charging handle with two latches for MPX-based weapons, manufactured by Geissele.", - "5c5db6ee2e221600113fba54 Name": "MPX/MCX Maxim Defense CQB telescoping stock", - "5c5db6ee2e221600113fba54 ShortName": "MPX/MCX CQB", - "5c5db6ee2e221600113fba54 Description": "A telescopic retractable CQB stock for MPX/MCX weapons, manufactured by Maxim Defense.", + "5c5db6ee2e221600113fba54 Name": "MPX/MCX Maxim Defense CQB stock", + "5c5db6ee2e221600113fba54 ShortName": "MD CQB", + "5c5db6ee2e221600113fba54 Description": "A retractable CQB stock for MPX/MCX weapons, manufactured by Maxim Defense.", "5c5db6f82e2216003a0fe914 Name": "MPX/MCX PMM ULSS foldable stock", "5c5db6f82e2216003a0fe914 ShortName": "ULSS", - "5c5db6f82e2216003a0fe914 Description": "ULSS (UltraLight Skeleton Stock) is a foldable stock for MCX/MPX manufactured by Parker Mountain Machine.", + "5c5db6f82e2216003a0fe914 Description": "ULSS (UltraLight Skeleton Stock) is a foldable stock for MPX/MCX manufactured by Parker Mountain Machine.", "5c6161fb2e221600113fbde5 Name": "TOZ-106 20ga MTs 20-01 Sb.3 5-shot magazine", "5c6161fb2e221600113fbde5 ShortName": "Sb.3x5", "5c6161fb2e221600113fbde5 Description": "A 5-shot 20ga magazine for MTs 20-01 and TOZ-106 hunting shotguns.", @@ -4967,9 +4970,9 @@ "5c7d55de2e221644f31bff68 Name": "Aimpoint CompM4 reflex sight", "5c7d55de2e221644f31bff68 ShortName": "CompM4", "5c7d55de2e221644f31bff68 Description": "The Aimpoint CompM4 series of sights are the toughest sights that Aimpoint has ever produced and they are the standard infantry soldier sight in many NATO countries. These optics are extremely rugged and operate continuously for up to 8 years using a single AA battery. The Aimpoint CompM4s is the latest version of the U.S. Army's M68CCO (Close-Combat Optic), continuing a legacy that Aimpoint has maintained since 1997.", - "5c7d55f52e221644f31bff6a Name": "Aimpoint LRP mount for CompM4 sights", + "5c7d55f52e221644f31bff6a Name": "Aimpoint CompM4/PRO LRP mount", "5c7d55f52e221644f31bff6a ShortName": "LRP", - "5c7d55f52e221644f31bff6a Description": "Aimpoint LRP is a quick detach base mount for CompM4 sights.", + "5c7d55f52e221644f31bff6a Description": "Aimpoint LRP is a quick detach base mount for CompM4 and PRO sights.", "5c7d560b2e22160bc12c6139 Name": "Aimpoint Standard Spacer", "5c7d560b2e22160bc12c6139 ShortName": "SS", "5c7d560b2e22160bc12c6139 Description": "The Standard Spacer mount for Aimpoint CompM4 sight models, raises the scope mount position.", @@ -5089,7 +5092,7 @@ "5cadf6ddae9215051e1c23b2 Description": "A 12.7x55mm PS12 special cartridge with a 33 gram subsonic heavy bullet with a lead core and a bimetallic jacket, in a brass case. This cartridge was designed in the early 2010s for the ASh-12 assault rifle and despite its rudimentary design, the bullet is capable of piercing basic ballistic body protections, in addition to providing a considerable stopping power effect and being able to inflict severe adverse effects on the target after impact. However, due to its design, it has a high probability of bouncing off various surfaces.", "5cadf6e5ae921500113bb973 Name": "12.7x55mm PS12A", "5cadf6e5ae921500113bb973 ShortName": "PS12A", - "5cadf6e5ae921500113bb973 Description": "A 12.7x55mm PS12A special cartridge with a 7 gram subsonic light bullet with an aluminum core and two-layer semi-jacket, a lead interior, and a bimetallic exterior, in a brass case. The bullet in this cartridge was designed to crumble and rapidly lose speed when hitting a solid object in order to reduce the probability of ricochets during urban operations at the cost of penetration capabilities, consequently, this endows it with an outstanding stopping power effect thanks to its caliber and capability to inflict critical adverse effects on the target after impact.", + "5cadf6e5ae921500113bb973 Description": "A 12.7x55mm PS12A special cartridge with a 7 gram lightweight bullet with an aluminum core and two-layer semi-jacket, a lead interior, and a bimetallic exterior, in a brass case. The bullet in this cartridge was designed to crumble and rapidly lose speed when hitting a solid object in order to reduce the probability of ricochets during urban operations at the cost of penetration capabilities, consequently, this endows it with an outstanding stopping power effect thanks to its caliber and capability to inflict critical adverse effects on the target after impact.", "5cadf6eeae921500134b2799 Name": "12.7x55mm PS12B", "5cadf6eeae921500134b2799 ShortName": "PS12B", "5cadf6eeae921500134b2799 Description": "A 12.7x55mm PS12B special cartridge with an 18 gram subsonic armor-piercing bullet with a heat-strengthened steel core with a two-layer semi-jacket, a lead interior and a bimetallic exterior, in a brass case. This cartridge was designed in the early 2010s to provide the ASh-12 assault rifle with capabilities to neutralize hostile personnel equipped with basic and intermediate ballistic body protection, in addition to providing a significant stopping power effect due to its caliber and being able to inflict substantial adverse effects on the target after impact. However, due to its design, it has a high probability of bouncing off various surfaces.", @@ -5117,15 +5120,15 @@ "5cbda392ae92155f3c17c39f Name": "AK 100-series polymer handguard", "5cbda392ae92155f3c17c39f ShortName": "AK 100", "5cbda392ae92155f3c17c39f Description": "A polymer handguard for the 100-series AKs, manufactured by Izhmash. A further modification of the polymer AK-74M handguard. Features a bottom rail for installation of tactical foregrips.", - "5cbda9f4ae9215000e5b9bfc Name": "AK-74 \"Plum\" polymer handguard (6P20 Sb.9)", - "5cbda9f4ae9215000e5b9bfc ShortName": "6P20 Sb.9", - "5cbda9f4ae9215000e5b9bfc Description": "A polymer handguard for AK-74 automatic rifles, manufactured by Izhmash. Made out of plum-colored polymer, for which has earned the nickname \"Sliva\" (\"Plum\").", - "5cbdaf89ae9215000e5b9c94 Name": "AK-74 5.45x39 6L23 \"Plum\" 30-round magazine", + "5cbda9f4ae9215000e5b9bfc Name": "AK-74 polymer handguard (Plum)", + "5cbda9f4ae9215000e5b9bfc ShortName": "AK-74 poly", + "5cbda9f4ae9215000e5b9bfc Description": "A 6P20 Sb.9 polymer handguard for AK-74 automatic rifles, manufactured by Izhmash. Made out of plum-colored polymer, for which has earned the nickname \"Sliva\" (\"Plum\").", + "5cbdaf89ae9215000e5b9c94 Name": "AK-74 5.45x39 6L23 30-round magazine (Plum)", "5cbdaf89ae9215000e5b9c94 ShortName": "6L23", "5cbdaf89ae9215000e5b9c94 Description": "A 30-round 5.45x39 polymer Izhmash 6L23 magazine for AK-74 and compatible systems. Made out of plum-colored polymer, for which has earned the nickname \"Sliva\" (\"Plum\").", - "5cbdb1b0ae9215000d50e105 Name": "AK-74 \"Plum\" polymer stock (6P20 Sb.7)", - "5cbdb1b0ae9215000d50e105 ShortName": "6P20 Sb.7", - "5cbdb1b0ae9215000d50e105 Description": "A polymer stock for AK-74 automatic rifles, manufactured by Izhmash. Made out of plum-colored polymer, for which has earned the nickname \"Sliva\" (\"Plum\").", + "5cbdb1b0ae9215000d50e105 Name": "AK-74 polymer stock (Plum)", + "5cbdb1b0ae9215000d50e105 ShortName": "AK-74 poly", + "5cbdb1b0ae9215000d50e105 Description": "A polymer 6P20 Sb.7 stock for AK-74 automatic rifles, manufactured by Izhmash. Made out of plum-colored polymer, for which has earned the nickname \"Sliva\" (\"Plum\").", "5cbdc23eae9215001136a407 Name": "AK 7.62x39 Molot Arms 75-round drum magazine", "5cbdc23eae9215001136a407 ShortName": "Molot", "5cbdc23eae9215001136a407 Description": "A 75-round metal drum magazine for the RPK light machine gun. It fits in 7.62x39 AK and compatible weapon systems. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons.", @@ -5138,6 +5141,12 @@ "5cc0876314c02e000c6bea6b Name": "", "5cc0876314c02e000c6bea6b ShortName": "", "5cc0876314c02e000c6bea6b Description": "", + "5cc2e4d014c02e000d0115f8 Name": "", + "5cc2e4d014c02e000d0115f8 ShortName": "", + "5cc2e4d014c02e000d0115f8 Description": "", + "5cc2e68f14c02e28b47de290 Name": "", + "5cc2e68f14c02e28b47de290 ShortName": "", + "5cc2e68f14c02e28b47de290 Description": "", "5cc6ea78e4a949000e1ea3c1 Name": "FN P90 charging handle", "5cc6ea78e4a949000e1ea3c1 ShortName": "P90", "5cc6ea78e4a949000e1ea3c1 Description": "A standard-issue charging handle for the P90 SMG, manufactured by Fabrique Nationale Herstal.", @@ -5216,13 +5225,13 @@ "5cc9bcaed7f00c011c04e179 Name": "AR-15 Hera Arms HG-15 pistol grip", "5cc9bcaed7f00c011c04e179 ShortName": "HG-15", "5cc9bcaed7f00c011c04e179 Description": "The Hera Arms HG-15 pistol grip can be installed on any weapon compatible with AR-15 grips.", - "5cc9c20cd7f00c001336c65d Name": "NcSTAR Tactical blue laser LAM-module", + "5cc9c20cd7f00c001336c65d Name": "NcSTAR Tactical Blue Laser", "5cc9c20cd7f00c001336c65d ShortName": "TBL", "5cc9c20cd7f00c001336c65d Description": "A compact tactical Laser Aiming Module with a blue dot. Mounts on any Picatinny/Weaver rail for precise target acquisition. Manufactured by NcSTAR.", - "5cd945d71388ce000a659dfb Name": "BEAR standard", + "5cd945d71388ce000a659dfb Name": "BEAR Standard", "5cd945d71388ce000a659dfb ShortName": "", "5cd945d71388ce000a659dfb Description": "Combat shirt", - "5cd946231388ce000d572fe3 Name": "BEAR standard", + "5cd946231388ce000d572fe3 Name": "BEAR Standard", "5cd946231388ce000d572fe3 ShortName": "", "5cd946231388ce000d572fe3 Description": "Combat pants", "5cda9bcfd7f00c0c0b53e900 Name": "ASh-12 vertical foregrip", @@ -5261,15 +5270,21 @@ "5cde95fa7d6c8b04737c2d13 Name": "", "5cde95fa7d6c8b04737c2d13 ShortName": "", "5cde95fa7d6c8b04737c2d13 Description": "", - "5cde9e957d6c8b0474535da7 Name": "USEC standard", + "5cde9e957d6c8b0474535da7 Name": "USEC Standard", "5cde9e957d6c8b0474535da7 ShortName": "", "5cde9e957d6c8b0474535da7 Description": "Combat pants", - "5cde9ec17d6c8b04723cf479 Name": "USEC standard", + "5cde9ec17d6c8b04723cf479 Name": "USEC Standard", "5cde9ec17d6c8b04723cf479 ShortName": "", "5cde9ec17d6c8b04723cf479 Description": "Combat shirt", + "5cdea20c7d6c8b0474535dab Name": "Scav pants", + "5cdea20c7d6c8b0474535dab ShortName": "", + "5cdea20c7d6c8b0474535dab Description": "", "5cdea23c7d6c8b04723cf47b Name": "Scav upper", "5cdea23c7d6c8b04723cf47b ShortName": "", "5cdea23c7d6c8b04723cf47b Description": "", + "5cdea30c7d6c8b04737c2d15 Name": "", + "5cdea30c7d6c8b04737c2d15 ShortName": "", + "5cdea30c7d6c8b04737c2d15 Description": "", "5cdea3197d6c8b20b577f017 Name": "Scav upper 2", "5cdea3197d6c8b20b577f017 ShortName": "", "5cdea3197d6c8b20b577f017 Description": "", @@ -5291,8 +5306,8 @@ "5cdeaca5d7f00c00b61c4b70 Name": "M700 Magpul Pro 700 chassis inline mount", "5cdeaca5d7f00c00b61c4b70 ShortName": "Pro700 rail", "5cdeaca5d7f00c00b61c4b70 Description": "A universal mount rail by Magpul for installation of additional tactical devices, can be installed on the Pro 700 chasiss for the Remington M700 sniper rifle.", - "5cdeb229d7f00c000e7ce174 Name": "NSV \"Utyos\" 12.7x108 heavy machine gun", - "5cdeb229d7f00c000e7ce174 ShortName": "NSV \"Utyos\"", + "5cdeb229d7f00c000e7ce174 Name": "NSV Utyos 12.7x108 heavy machine gun", + "5cdeb229d7f00c000e7ce174 ShortName": "NSV Utyos", "5cdeb229d7f00c000e7ce174 Description": "NSV, also known as «Utyos», is a 12.7mm caliber heavy machine gun of Soviet origin, named after the designers, G. I. Nikitin, Y. S. Sokolov and V. I. Volkov (NSV). It was designed to replace the DShK machine gun and was adopted by the Soviet Army in 1971. The production is discontinued, the manufacturing license for the NSV ended up in Kazakhstan after the break-up of the Soviet Union. The NSV has been manufactured in Bulgaria, India, Poland and Yugoslavia under license.", "5ce69cbad7f00c00b61c5098 Name": "M700 7.62x51 Magpul PMAG AC 5-round magazine", "5ce69cbad7f00c00b61c5098 ShortName": "PMAG AC", @@ -5333,7 +5348,7 @@ "5cf54404d7f00c108840b2ef Name": "AK KGB MG-47 pistol grip", "5cf54404d7f00c108840b2ef ShortName": "MG-47 AK", "5cf54404d7f00c108840b2ef Description": "A machined aluminum grip with styling queues taken from triangle side folding stocks. Compatible with all AK family weapon systems. Manufactured by Kraft Gun Builders.", - "5cf638cbd7f00c06595bc936 Name": "NPZ USP-1 \"Tyulpan\" 4x scope", + "5cf638cbd7f00c06595bc936 Name": "NPZ USP-1 Tyulpan 4x scope", "5cf638cbd7f00c06595bc936 ShortName": "USP-1", "5cf638cbd7f00c06595bc936 Description": "The USP-1 \"Tyulpan\" unified rifle scope is designed to conduct accurate fire from AK-74N, AK-74M, AN-94 assault rifles and RPK-74N and PKMN machine guns in the daytime and at night. Installed on dovetail mount rail.", "5cf639aad7f00c065703d455 Name": "NPZ USP-1 scope eyecup", @@ -5348,9 +5363,9 @@ "5cf67cadd7f00c065a5abab7 Name": "SKS Weapon Tuning 7.62x39 thread adapter", "5cf67cadd7f00c065a5abab7 ShortName": "WT0032_1", "5cf67cadd7f00c065a5abab7 Description": "The Weapon Tuning muzzle adapter that provides the ability to install modern 7.62x39 muzzle devices on the SKS carbines.", - "5cf6935bd7f00c06585fb791 Name": "TACCOM Carbine Brake multi-caliber muzzle brake", + "5cf6935bd7f00c06585fb791 Name": "TACCOM Carbine Brake 9x19 muzzle brake", "5cf6935bd7f00c06585fb791 ShortName": "TACCOM", - "5cf6935bd7f00c06585fb791 Description": "The \"Carbine Brake\" muzzle brake manufactured by TACCOM for SIG MPX. It can also be used with compatible .308 rifles.", + "5cf6935bd7f00c06585fb791 Description": "The \"Carbine Brake\" muzzle brake manufactured by TACCOM for SIG MPX.", "5cf6937cd7f00c056c53fb39 Name": "AR-15 Bulletec ST-6012 5.56x45 muzzle brake", "5cf6937cd7f00c056c53fb39 ShortName": "ST6012 556", "5cf6937cd7f00c056c53fb39 Description": "ST-6012 is an effective muzzle brake for AR-15-type weapon systems and compatibles. Manufactured by Bulletec.", @@ -5369,7 +5384,7 @@ "5cf7acfcd7f00c1084477cf2 Name": "FN PS90 5.7x28 upper receiver", "5cf7acfcd7f00c1084477cf2 ShortName": "PS90", "5cf7acfcd7f00c1084477cf2 Description": "A regular upper receiver for the PS90, produced by Fabrique Nationale Herstal.", - "5cf8f3b0d7f00c00217872ef Name": "SOK-12 12/76 MaxRounds Powermag 20-round magazine", + "5cf8f3b0d7f00c00217872ef Name": "SOK-12 12ga MaxRounds Powermag 20-round magazine", "5cf8f3b0d7f00c00217872ef ShortName": "Powermag", "5cf8f3b0d7f00c00217872ef Description": "The MaxRounds Powermag 20-shell magazine for SOK-12 and compatible weapons, intended for use with 12/76 or 12/70 shells.", "5cfe8010d7ad1a59283b14c6 Name": "AK 7.62x39 X Products X-47 50-round drum magazine", @@ -5474,7 +5489,7 @@ "5d0b5cd3d7ad1a3fe32ad263 Name": "KMZ 1P59 scope eyecup", "5d0b5cd3d7ad1a3fe32ad263 ShortName": "1P59 cup", "5d0b5cd3d7ad1a3fe32ad263 Description": "A rubber eyecup for the KMZ 1P59 scope.", - "5d10b49bd7ad1a1a560708b0 Name": "AN/PEQ-2 tactical device", + "5d10b49bd7ad1a1a560708b0 Name": "Insight AN/PEQ-2 tactical device", "5d10b49bd7ad1a1a560708b0 ShortName": "AN/PEQ-2", "5d10b49bd7ad1a1a560708b0 Description": "ATPIAL (Advanced Target Pointer Illuminator Aiming Laser) AN/PEQ-2 produced by L3 Insight Technologies. Tactical device that combines an IR laser designator with an IR searchlight.", "5d120a10d7ad1a4e1026ba85 Name": "AR-15 DoubleStar ACE SOCOM Gen.4 stock", @@ -5774,6 +5789,9 @@ "5d28ae4986f7742926686187 Name": "", "5d28ae4986f7742926686187 ShortName": "", "5d28ae4986f7742926686187 Description": "", + "5d28afe786f774292668618d Name": "", + "5d28afe786f774292668618d ShortName": "", + "5d28afe786f774292668618d Description": "", "5d2c76ed48f03532f2136169 Name": "AK AKademia Bastion dust cover", "5d2c76ed48f03532f2136169 ShortName": "Bastion", "5d2c76ed48f03532f2136169 Description": "The Bastion dust cover with an integrated Picatinny rail is compatible with all models of Kalashnikov automatic rifles and carbines based on the AK platform. Manufactured by AKademia.", @@ -5891,9 +5909,9 @@ "5d440b9fa4b93601354d480c Name": "AR-15 5.56x45 20 inch barrel", "5d440b9fa4b93601354d480c ShortName": "AR-15 20\"", "5d440b9fa4b93601354d480c Description": "A barrel for AR-15 based weapons for 5.56x45 NATO ammo, 20 inches long.", - "5d44334ba4b9362b346d1948 Name": "AR-15 Radian Weapons Raptor charging handle (Grey)", - "5d44334ba4b9362b346d1948 ShortName": "Raptor Grey", - "5d44334ba4b9362b346d1948 Description": "The Raptor charging handle for AR-15 and compatible systems. Manufactured by Radian Weapons. Grey version.", + "5d44334ba4b9362b346d1948 Name": "AR-15 Radian Weapons Raptor charging handle (Tungsten Grey)", + "5d44334ba4b9362b346d1948 ShortName": "Raptor", + "5d44334ba4b9362b346d1948 Description": "The Raptor charging handle for AR-15 and compatible systems. Manufactured by Radian Weapons. Tungsten Grey version.", "5d443f8fa4b93678dd4a01aa Name": "AR-10 Thunder Beast Arms 30CB 7.62x51 muzzle brake", "5d443f8fa4b93678dd4a01aa ShortName": "30CB", "5d443f8fa4b93678dd4a01aa Description": "Thunder Beast Arms 30CB is an effective muzzle brake that also serves as a platform for attaching the Quick Detach \"Ultra 5\" sound suppressor.", @@ -5945,7 +5963,7 @@ "5d5e9c74a4b9364855191c40 Name": "MSA ACH TC-2002 MICH Series helmet (Olive Drab)", "5d5e9c74a4b9364855191c40 ShortName": "TC-2002", "5d5e9c74a4b9364855191c40 Description": "The MSA Advanced Combat Helmet (ACH) delivers advanced ballistic, fragmentation, and impact head protection, with comfort for long-term use. The helmet’s low-profile design reduces the risk of interference in target acquisition and ensures compatibility with NVGs and headsets.", - "5d5fca1ea4b93635fd598c07 Name": "Crossbow tactical glasses", + "5d5fca1ea4b93635fd598c07 Name": "ESS Crossbow tactical glasses", "5d5fca1ea4b93635fd598c07 ShortName": "Crossbow", "5d5fca1ea4b93635fd598c07 Description": "Ballistic glasses with impact-resistant polycarbonate lenses.", "5d63d33b86f7746ea9275524 Name": "Flat screwdriver", @@ -5990,15 +6008,15 @@ "5d6e6869a4b9361c140bcfde Name": "12/70 Grizzly 40 slug", "5d6e6869a4b9361c140bcfde ShortName": "Grizzly 40", "5d6e6869a4b9361c140bcfde Description": "The \"Grizzly 40\" 12/70 expanding slug shell for 12 gauge shotguns.", - "5d6e6891a4b9361bd473feea Name": "12/70 \"Poleva-3\" slug", + "5d6e6891a4b9361bd473feea Name": "12/70 Poleva-3 slug", "5d6e6891a4b9361bd473feea ShortName": "Poleva-3", "5d6e6891a4b9361bd473feea Description": "A \"Poleva-3\" 12/70 expanding slug shell for 12 gauge shotguns.", - "5d6e689ca4b9361bc8618956 Name": "12/70 \"Poleva-6u\" slug", + "5d6e689ca4b9361bc8618956 Name": "12/70 Poleva-6u slug", "5d6e689ca4b9361bc8618956 ShortName": "Poleva-6u", "5d6e689ca4b9361bc8618956 Description": "A \"Poleva-6u\" 12/70 cartridge with an FMJ slug shell for 12 gauge shotguns.", "5d6e68a8a4b9360b6c0d54e2 Name": "12/70 AP-20 armor-piercing slug", "5d6e68a8a4b9360b6c0d54e2 ShortName": "AP-20", - "5d6e68a8a4b9360b6c0d54e2 Description": "A 12/70 armor-piercing slug shell for 12 gauge shotguns. Designed for law enforcement forces of our overseas ʕ•ᴥ•ʔ friends ʕ•ᴥ•ʔ.", + "5d6e68a8a4b9360b6c0d54e2 Description": "A 12/70 armor-piercing slug shell for 12 gauge shotguns. Designed for stopping vehicles and penetrating targets behind cover.", "5d6e68b3a4b9361bca7e50b5 Name": "12/70 Copper Sabot Premier HP slug", "5d6e68b3a4b9361bca7e50b5 ShortName": "CSP", "5d6e68b3a4b9361bca7e50b5 Description": "A 12/70 copper solid slug shell for 12 gauge shotguns.", @@ -6029,10 +6047,10 @@ "5d6e6a05a4b93618084f58d0 Name": "20/70 Star slug", "5d6e6a05a4b93618084f58d0 ShortName": "Star", "5d6e6a05a4b93618084f58d0 Description": "A 20/70 slug shell for 20 gauge shotguns.", - "5d6e6a42a4b9364f07165f52 Name": "20/70 \"Poleva-6u\" slug", + "5d6e6a42a4b9364f07165f52 Name": "20/70 Poleva-6u slug", "5d6e6a42a4b9364f07165f52 ShortName": "Poleva-6u", "5d6e6a42a4b9364f07165f52 Description": "A \"Poleva-6u\" 20/70 FMJ slug shell for 20 gauge shotguns.", - "5d6e6a53a4b9361bd473feec Name": "20/70 \"Poleva-3\" slug", + "5d6e6a53a4b9361bd473feec Name": "20/70 Poleva-3 slug", "5d6e6a53a4b9361bd473feec ShortName": "Poleva-3", "5d6e6a53a4b9361bd473feec Description": "A \"Poleva-3\" 20/70 expanding slug shell for 20 gauge shotguns.", "5d6e6a5fa4b93614ec501745 Name": "20/70 Devastator slug", @@ -6170,22 +6188,22 @@ "5dcbe965e4ed22586443a79d Name": "Desert Tech 7.62x51 flash hider", "5dcbe965e4ed22586443a79d ShortName": "MDR 762", "5dcbe965e4ed22586443a79d Description": "A flash hider developed by Desert Tech specifically for the MDR 7.62x51 (.308) assault rifles.", - "5de652c31b7e3716273428be Name": "Molot Arms VPO-215 \"Gornostay\" .366 TKM bolt-action rifle", - "5de652c31b7e3716273428be ShortName": "VPO-215 \"Gornostay\"", + "5de652c31b7e3716273428be Name": "Molot Arms VPO-215 Gornostay .366 TKM bolt-action rifle", + "5de652c31b7e3716273428be ShortName": "VPO-215 Gornostay", "5de652c31b7e3716273428be Description": "VPO-215 \"Gornostay\" (\"Ermine\") is a Russian-made bolt-action rifle designed for hunting and sport shooting, manufactured by Molot Arms. Chambered in .366 TKM ammo.", - "5de653abf76fdc1ce94a5a2a Name": "VPO-215 \"Gornostay\" .366 TKM 4-round magazine", - "5de653abf76fdc1ce94a5a2a ShortName": "VPO215", + "5de653abf76fdc1ce94a5a2a Name": "VPO-215 .366 TKM 4-round magazine", + "5de653abf76fdc1ce94a5a2a ShortName": "VPO-215", "5de653abf76fdc1ce94a5a2a Description": "A 4-round magazine for VPO-215 rifles and compatible .366 TKM systems, manufactured by Molot Arms.", - "5de65547883dde217541644b Name": "VPO-215 \"Gornostay\" .366TKM 23 inch barrel", - "5de65547883dde217541644b ShortName": "215 23\"", - "5de65547883dde217541644b Description": "A 23 inch (600mm) barrel for VPO-215 rifle chambered in .366TKM.", - "5de6556a205ddc616a6bc4f7 Name": "VPO-215 \"Gornostay\" thread protection cap", + "5de65547883dde217541644b Name": "VPO-215-02 .366TKM 600mm barrel", + "5de65547883dde217541644b ShortName": "215 600mm", + "5de65547883dde217541644b Description": "A 600mm barrel for VPO-215 rifle chambered in .366TKM.", + "5de6556a205ddc616a6bc4f7 Name": "VPO-215 thread protector", "5de6556a205ddc616a6bc4f7 ShortName": "215 cap", "5de6556a205ddc616a6bc4f7 Description": "A threading protection cap for the VPO-215 .366TKM rifle barrel.", - "5de6558e9f98ac2bc65950fc Name": "VPO-215 \"Gornostay\" scope rail mount", + "5de6558e9f98ac2bc65950fc Name": "VPO-215 scope rail mount", "5de6558e9f98ac2bc65950fc ShortName": "215 rail", "5de6558e9f98ac2bc65950fc Description": "A universal rail mount for the VPO-215 \"Gornostay\" rifle, allows installation of various optics.", - "5de655be4a9f347bc92edb88 Name": "VPO-215 \"Gornostay\" stock", + "5de655be4a9f347bc92edb88 Name": "VPO-215 wooden stock", "5de655be4a9f347bc92edb88 ShortName": "VPO-215", "5de655be4a9f347bc92edb88 Description": "A standard-issue stock for the VPO-215 \"Gornostay\" rifle.", "5de7bd7bfd6b4e6e2276dc25 Name": "B&T MP9-N 9x19 submachine gun", @@ -6300,10 +6318,10 @@ "5df8ce05b11454561e39243b ShortName": "SR-25", "5df8ce05b11454561e39243b Description": "The SR-25 Precision Rifle is the latest evolution of the precision 7.62mm NATO semi-automatic rifle. An ambidextrous bolt release, selector, and magazine release offers the left-handed user the ergonomic advantages inherent to AR-15 based controls, as well as giving right-handed users alternate methods of manipulation to increase efficiency of movement. The Drop-In 2-Stage Trigger serves as an aid to long range precision marksmanship. The E2 bolt and gas system provides superior reliability in function whether suppressed or unsuppressed.", "5df8e053bb49d91fb446d6a6 Name": "AR-10 KAC charging handle", - "5df8e053bb49d91fb446d6a6 ShortName": "KAC AR10", + "5df8e053bb49d91fb446d6a6 ShortName": "KAC", "5df8e053bb49d91fb446d6a6 Description": "A regular charging handle for AR-10/SR-25 and compatible systems, manufactured by Knight's Armament Company.", "5df8e085bb49d91fb446d6a8 Name": "AR-10 KAC ambidextrous charging handle", - "5df8e085bb49d91fb446d6a8 ShortName": "AR10 Ambi", + "5df8e085bb49d91fb446d6a8 ShortName": "KAC Ambi", "5df8e085bb49d91fb446d6a8 Description": "An ambidextrous charging handle for the SR-25 marksman rifle and AR-10-compatible systems. Manufactured by Knight's Armament Company.", "5df8e4080b92095fd441e594 Name": "SR-25 7.62x51 upper receiver", "5df8e4080b92095fd441e594 ShortName": "SR-25", @@ -6392,7 +6410,7 @@ "5e01e9e273d8eb11426f5bc3 Name": "SVDS Rotor 43 thread adapter", "5e01e9e273d8eb11426f5bc3 ShortName": "SVDS thr.", "5e01e9e273d8eb11426f5bc3 Description": "A special thread adapter manufactured by Rotor 43. Allows installation of the Rotor 43 muzzle brake on the SVDS sniper rifle.", - "5e01ea19e9dc277128008c0b Name": "Rotor 43 7.62x54R muzzle brake-compensator", + "5e01ea19e9dc277128008c0b Name": "Rotor 43 7.62x54R sound suppressor", "5e01ea19e9dc277128008c0b ShortName": "R43 7.62x54R", "5e01ea19e9dc277128008c0b Description": "The Rotor 43 muzzle brake is designed for installation on SVD 7.62x54R. Although positioned as a muzzle brake, it also works as a sound suppressor.", "5e01ef6886f77445f643baa4 Name": "Team Wendy EXFIL Ballistic Helmet (Coyote Brown)", @@ -6436,7 +6454,7 @@ "5e21a3c67e40bd02257a008a Description": "A 30-round polymer Magpul Pmag 30 AK/AKM GEN M3 magazine 7.62x39 AK and compatible weapons. Can also be supplied with .366 TKM ammo for use with the corresponding caliber AK-compatible weapons. The magazine is painted in a tactical banana yellow color.", "5e21ca18e4d47f0da15e77dd Name": "AK CNC Warrior 5.56x45 muzzle device adapter", "5e21ca18e4d47f0da15e77dd ShortName": "CNC War.", - "5e21ca18e4d47f0da15e77dd Description": "The CNC Warrior AK adapter allows to install different AR-15 specific muzzle devices on 5.56x45 AK automatic rifles.", + "5e21ca18e4d47f0da15e77dd Description": "The CNC Warrior AK adapter allows to install different AR-15 specific muzzle devices on 5.56x45 or 5.45x39 AK automatic rifles.", "5e2aedd986f7746d404f3aa4 Name": "GreenBat lithium battery", "5e2aedd986f7746d404f3aa4 ShortName": "GreenBat", "5e2aedd986f7746d404f3aa4 Description": "3.7 volt battery with a nominal capacity of 3400 mAh. Used in lighting and engineering devices.", @@ -6674,7 +6692,7 @@ "5e87116b81c4ed43e83cefdd Name": "Mossberg 590A1 polymer stock", "5e87116b81c4ed43e83cefdd ShortName": "590A1", "5e87116b81c4ed43e83cefdd Description": "A classical-looking polymer stock for Mossberg 590A1 shotguns with a rubber butt-plate.", - "5e8f3423fd7471236e6e3b64 Name": "Bottle of \"Norvinskiy Yadreniy\" premium kvass (0.6L)", + "5e8f3423fd7471236e6e3b64 Name": "Bottle of Norvinsky Yadreniy premium kvass (0.6L)", "5e8f3423fd7471236e6e3b64 ShortName": "Kvass", "5e8f3423fd7471236e6e3b64 Description": "Norvinsky Premium, a truly refreshing kvass. Kvass is made by the natural fermentation of bread, such as wheat, rye, or barley, and sometimes flavoured using fruit, berries, raisins, or birch sap. One of the traditional Slavic drinks, it is not just a tasty, but also a healthy product. It is for a reason that in Russian tales it is constantly drunk by Bogatyrs to regain their power.", "5e99711486f7744bfc4af328 Name": "Sanitar's first aid kit", @@ -6765,7 +6783,7 @@ "5ea17bbc09aa976f2e7a51cd ShortName": "556-RC2", "5ea17bbc09aa976f2e7a51cd Description": "The SureFire SOCOM556-RC2 5.56x45 and .223 sound suppressor, can only be installed on compatible SureFire muzzle devices.", "5ea17ca01412a1425304d1c0 Name": "Diamond Age Bastion helmet (Black)", - "5ea17ca01412a1425304d1c0 ShortName": "Bastion", + "5ea17ca01412a1425304d1c0 ShortName": "DA Bastion", "5ea17ca01412a1425304d1c0 Description": "According to the manufacturer - the Bastion helmet is the first combat helmet that can withstand a hit from a rifle, even with a bullet with an armored core at a muzzle speed.", "5ea18c84ecf1982c7712d9a2 Name": "Diamond Age Bastion helmet armor plate", "5ea18c84ecf1982c7712d9a2 ShortName": "Bastion plate", @@ -6791,7 +6809,7 @@ "5ed51652f6c34d2cc26336a1 Name": "M.U.L.E. stimulant injector", "5ed51652f6c34d2cc26336a1 ShortName": "M.U.L.E.", "5ed51652f6c34d2cc26336a1 Description": "Muscular Ultra Large Exciter. It is used to expand the body's abilities before long marches. It allows the body to carry an increased weight for a long time. It has shown effectiveness in combat operations in areas where transport is not available. Authorized for use by special forces soldiers. Developed by TerraGroup Labs, marked with the name M. U. L. E.", - "5ed5166ad380ab312177c100 Name": "\"Obdolbos\" cocktail injector", + "5ed5166ad380ab312177c100 Name": "Obdolbos cocktail injector", "5ed5166ad380ab312177c100 ShortName": "Obdolbos", "5ed5166ad380ab312177c100 Description": "A syringe with a homemade drug, authored by a former employee of TerraGroup Labs. The negative effects are different each time. You could take the risk, got nothing to lose anyway.", "5ede4739e0350d05467f73e8 Name": "40x46mm M406 (HE) grenade", @@ -7006,7 +7024,7 @@ "5f5f64f947344c2e4f6c431e Description": "", "5f5f65180bc58666c37e784a Name": "Scav Hunter", "5f5f65180bc58666c37e784a ShortName": "", - "5f5f65180bc58666c37e784a Description": "", + "5f5f65180bc58666c37e784a Description": "Hunting pants", "5f5f653179db6e3f0e19b762 Name": "Scav Drystch", "5f5f653179db6e3f0e19b762 ShortName": "", "5f5f653179db6e3f0e19b762 Description": "", @@ -7058,10 +7076,10 @@ "5f633ff5c444ce7e3c30a006 Name": "AR-15 Rainier Arms Avalanche MOD2 charging handle", "5f633ff5c444ce7e3c30a006 ShortName": "Avalanche", "5f633ff5c444ce7e3c30a006 Description": "The Avalanche MOD2 charging handle for AR-15 and compatible systems. Manufactured by Rainier Arms.", - "5f63405df5750b524b45f114 Name": "VPO-101 \"Vepr-Hunter\" SVD-style stock", - "5f63405df5750b524b45f114 ShortName": "101 SVD-style", + "5f63405df5750b524b45f114 Name": "VPO-101 SVD-style walnut stock", + "5f63405df5750b524b45f114 ShortName": "101 SVD", "5f63405df5750b524b45f114 Description": "An SVD-style wooden stock designed for VPO-101 Vepr-Hunter carbines.", - "5f63407e1b231926f2329f15 Name": "VPO-101 \"Vepr-Hunter\" Rotor 43 7.62x51 muzzle brake-compensator", + "5f63407e1b231926f2329f15 Name": "VPO-101 Rotor 43 7.62x51 sound suppressor", "5f63407e1b231926f2329f15 ShortName": "R43 101", "5f63407e1b231926f2329f15 Description": "The Rotor 43 muzzle brake, designed for installation on VPO 7.62x51 family rifles. Although positioned as a muzzle brake, it also works as a sound suppressor.", "5f6340d3ca442212f4047eb2 Name": "Tactical Dynamics Skeletonized Foregrip", @@ -7082,6 +7100,9 @@ "5f647f31b6238e5dd066e196 Name": "23x75mm Shrapnel-25 buckshot", "5f647f31b6238e5dd066e196 ShortName": "Shrap-25", "5f647f31b6238e5dd066e196 Description": "A 23x75mmR \"Shrapnel-25\" buckshot round with a rated maximum effective range of 25 meters.", + "5f68c4a7c174a17c0f4c8945 Name": "", + "5f68c4a7c174a17c0f4c8945 ShortName": "", + "5f68c4a7c174a17c0f4c8945 Description": "", "5f68c4c217d579077152a252 Name": "", "5f68c4c217d579077152a252 ShortName": "", "5f68c4c217d579077152a252 Description": "", @@ -7097,6 +7118,12 @@ "5f9949d869e2777a0e779ba5 Name": "Armband (Rivals 2020)", "5f9949d869e2777a0e779ba5 ShortName": "Rivals", "5f9949d869e2777a0e779ba5 Description": "An exclusive armband from the Twitch Rivals 2020 event.", + "5fb53cc97b5d1342ee24bd63 Name": "", + "5fb53cc97b5d1342ee24bd63 ShortName": "", + "5fb53cc97b5d1342ee24bd63 Description": "", + "5fb53d0b7b5d1342ee24bd64 Name": "", + "5fb53d0b7b5d1342ee24bd64 ShortName": "", + "5fb53d0b7b5d1342ee24bd64 Description": "", "5fb64bc92b1b027b1f50bcf2 Name": "TDI KRISS Vector Gen.2 .45 ACP submachine gun", "5fb64bc92b1b027b1f50bcf2 ShortName": "Vector .45ACP", "5fb64bc92b1b027b1f50bcf2 Description": "The KRISS Vector SMG is the ideal choice for law enforcement and military seeking a controllable and compact weapon system for close quarter combat environments. The low bore axis and Super V recoil mitigation system allow for controllable shots when firing in full-automatic, or fast semi-automatic follow up shots. Compatible with Glock .45 ACP magazines.", @@ -7190,12 +7217,12 @@ "5fbcc3e4d6fa9c00c571bb58 Name": "MCX GEN1 .300 BLK upper receiver", "5fbcc3e4d6fa9c00c571bb58 ShortName": "MCX GEN1", "5fbcc3e4d6fa9c00c571bb58 Description": "An upper receiver for the first generation MCX assault rifles manufactured by SIG Sauer. Features a mount for attaching additional equipment.", - "5fbcc429900b1d5091531dd7 Name": "MPX/MCX telescoping stock", - "5fbcc429900b1d5091531dd7 ShortName": "MPX/MCX tele", + "5fbcc429900b1d5091531dd7 Name": "MPX/MCX Telescoping/Folding Stock", + "5fbcc429900b1d5091531dd7 ShortName": "SIG TFS", "5fbcc429900b1d5091531dd7 Description": "A telescopic stock for MPX/MCX manufactured by SIG Sauer.", - "5fbcc437d724d907e2077d5c Name": "MPX/MCX lightweight stock", - "5fbcc437d724d907e2077d5c ShortName": "MPX/MCX light", - "5fbcc437d724d907e2077d5c Description": "A thin and lightweight stock for MCX/MPX manufactured by SIG Sauer.", + "5fbcc437d724d907e2077d5c Name": "MPX/MCX Thin Side-Folding Stock", + "5fbcc437d724d907e2077d5c ShortName": "SIG TSFS", + "5fbcc437d724d907e2077d5c Description": "A lightweight stock for MPX/MCX, manufactured by SIG Sauer.", "5fbcc640016cce60e8341acc Name": "MCX charging handle", "5fbcc640016cce60e8341acc ShortName": "MCX", "5fbcc640016cce60e8341acc Description": "A standard charging handle for SIG Sauer MCX rifles and compatible systems.", @@ -7520,7 +7547,7 @@ "60363c0c92ec1c31037959f5 Name": "GP-7 gas mask", "60363c0c92ec1c31037959f5 ShortName": "GP-7", "60363c0c92ec1c31037959f5 Description": "The GP-7 civilian gas mask is a filtering means of individual protection of respiratory organs, eyes, and face skin.", - "603648ff5a45383c122086ac Name": "Azimut SS \"Zhuk\" chest harness (Black)", + "603648ff5a45383c122086ac Name": "Azimut SS Zhuk chest harness (Black)", "603648ff5a45383c122086ac ShortName": "Zhuk", "603648ff5a45383c122086ac Description": "A simple nylon bearing system with non-removable pouches. Allows you to carry a fairly impressive amount of ammunition at the expense of convenience.", "6038b228af2e28262649af14 Name": "BEAR Rash Guard", @@ -7553,7 +7580,7 @@ "603d01b9d10cbf667352dd4a Name": "USEC Sage Warrior", "603d01b9d10cbf667352dd4a ShortName": "", "603d01b9d10cbf667352dd4a Description": "Field pants", - "6040dd4ddcf9592f401632d2 Name": "Azimut SS \"Zhuk\" chest harness (SURPAT)", + "6040dd4ddcf9592f401632d2 Name": "Azimut SS Zhuk chest harness (SURPAT)", "6040dd4ddcf9592f401632d2 ShortName": "Zhuk", "6040dd4ddcf9592f401632d2 Description": "A simple nylon bearing system with non-removable pouches. Allows you to carry a fairly impressive amount of ammunition at the expense of convenience. SURPAT camouflage version.", "6040de02647ad86262233012 Name": "Army cap (CADPAT)", @@ -7889,7 +7916,7 @@ "61657230d92c473c770213d7 Name": "Aimpoint Micro H-2 reflex sight", "61657230d92c473c770213d7 ShortName": "H-2", "61657230d92c473c770213d7 Description": "The Micro H-2 compact reflex sight by Aimpoint was designed for use with any kind of firearms and even with bows. Lightweight, compact, and durable.", - "616584766ef05c2ce828ef57 Name": "Aimpoint QRP2 mount for CompM4/PRO sights", + "616584766ef05c2ce828ef57 Name": "Aimpoint CompM4/PRO QRP2 mount", "616584766ef05c2ce828ef57 ShortName": "QRP2", "616584766ef05c2ce828ef57 Description": "The QRP2 quick-detach base mount for the CompM4 and PRO series reflex sights, manufactured by Aimpoint.", "61659f79d92c473c770213ee Name": "Aimpoint PRO reflex sight", @@ -7913,7 +7940,7 @@ "61702be9faa1272e431522c3 Name": "HK417 7.62x51 16.5 inch barrel", "61702be9faa1272e431522c3 ShortName": "417 16.5\"", "61702be9faa1272e431522c3 Description": "A 16.5 inch (421mm) barrel for HK417-based weapons for 7.62x51 ammo.", - "61702d8a67085e45ef140b24 Name": "HK417 E1 extended charging handle", + "61702d8a67085e45ef140b24 Name": "HK417 E1 Extended Charging Handle", "61702d8a67085e45ef140b24 ShortName": "417 E1", "61702d8a67085e45ef140b24 Description": "An extended charging handle for HK417 and compatible systems, manufactured by Heckler & Koch.", "61702f1b67085e45ef140b26 Name": "HK417 low profile gas block", @@ -7949,9 +7976,9 @@ "61714b2467085e45ef140b2c Name": "Recknagel Era-Tac Sunshade mount for Aimpoint T-1 sights", "61714b2467085e45ef140b2c ShortName": "T-1 Sun", "61714b2467085e45ef140b2c Description": "The Recknagel Era-Tac Sunshade mount for the Aimpoint Micro T-1 reflex sight.", - "61714eec290d254f5e6b2ffc Name": "Schmidt & Bender PM II 3-12x50 34mm riflescope", - "61714eec290d254f5e6b2ffc ShortName": "PM II 3-12x50", - "61714eec290d254f5e6b2ffc Description": "The Schmidt & Bender PM II 3-12x50 riflescope was originally created for elite military forces for high-quality target acquisition and pinpoint accuracy.", + "61714eec290d254f5e6b2ffc Name": "Schmidt & Bender PM II 3-20x50 34mm riflescope", + "61714eec290d254f5e6b2ffc ShortName": "PM II 3-20x50", + "61714eec290d254f5e6b2ffc Description": "The Schmidt & Bender PM II 3-20x50 riflescope was originally created for elite military forces for high-quality target acquisition and pinpoint accuracy.", "617151c1d92c473c770214ab Name": "Schmidt & Bender PM II 1-8x24 30mm riflescope", "617151c1d92c473c770214ab ShortName": "PM II 1-8x24", "617151c1d92c473c770214ab Description": "The Schmidt & Bender PM II 1-8x24 riflescope was originally created for elite military forces for high-quality target acquisition and pinpoint accuracy. ", @@ -8006,9 +8033,9 @@ "61816df1d3a39d50044c139e Name": "FN SCAR bottom rail", "61816df1d3a39d50044c139e ShortName": "SCAR bott.", "61816df1d3a39d50044c139e Description": "A bottom rail for the SCAR-series handguards that allows installation of tactical foregrips or other devices.", - "61816dfa6ef05c2ce828f1ad Name": "FN SCAR side rail", + "61816dfa6ef05c2ce828f1ad Name": "FN SCAR side rails", "61816dfa6ef05c2ce828f1ad ShortName": "SCAR side", - "61816dfa6ef05c2ce828f1ad Description": "A side rail for the SCAR-series handguards that allows installation of additional tactical equipment.", + "61816dfa6ef05c2ce828f1ad Description": "Standard Picatinny side rails for the SCAR-series handguards that allow installation of additional tactical equipment. ", "61816fcad92c473c770215cc Name": "FN SCAR flip-up front sight", "61816fcad92c473c770215cc ShortName": "SCAR FS", "61816fcad92c473c770215cc Description": "A removable flip-up front sight for the SCAR-series assault rifles, installed on the gas block. Manufactured by Fabrique Nationale Herstal.", @@ -8072,8 +8099,8 @@ "618a431df1eb8e24b8741deb Name": "RGO hand grenade", "618a431df1eb8e24b8741deb ShortName": "RGO", "618a431df1eb8e24b8741deb Description": "RGO (Ruchnaya Granata Oboronitel'naya - \"Defensive Hand Grenade\") is a defensive anti-personnel fragmentation hand grenade of impact action.", - "618a5d5852ecee1505530b2a Name": "NPZ PK1 \"Obzor\" dovetail reflex sight", - "618a5d5852ecee1505530b2a ShortName": "\"Obzor\"", + "618a5d5852ecee1505530b2a Name": "NPZ PK1 Obzor dovetail reflex sight", + "618a5d5852ecee1505530b2a ShortName": "Obzor", "618a5d5852ecee1505530b2a Description": "A reflex sight designed for hunters for fast acquisition of the target while operating in highly cold temperatures, installed on dovetail rails. Manufactured by NPZ.", "618a75c9a3884f56c957ca1b Name": "NPZ 1P78-1 dovetail mount", "618a75c9a3884f56c957ca1b ShortName": "1P78 DT", @@ -8339,9 +8366,9 @@ "61a00bcb177fb945751bbe6a Name": "Stolen military documents", "61a00bcb177fb945751bbe6a ShortName": "Military documents", "61a00bcb177fb945751bbe6a Description": "Stolen military documents", - "61a49f549128666d8302b5f1 Name": "Raincoat", + "61a49f549128666d8302b5f1 Name": "Scav Lighthouse", "61a49f549128666d8302b5f1 ShortName": "", - "61a49f549128666d8302b5f1 Description": "", + "61a49f549128666d8302b5f1 Description": "Raincoat", "61a4a06dba63c0388e05613e Name": "Roadside maniac", "61a4a06dba63c0388e05613e ShortName": "", "61a4a06dba63c0388e05613e Description": "", @@ -8418,13 +8445,13 @@ "61f7b234ea4ab34f2f59c3ec ShortName": "MP18 wood", "61f7b234ea4ab34f2f59c3ec Description": "A wooden stock for MP-18 hunting rifles. Manufactured by IzhMekh.", "61f7b85367ddd414173fdb36 Name": "MP-18 wooden handguard", - "61f7b85367ddd414173fdb36 ShortName": "MP18 wood", + "61f7b85367ddd414173fdb36 ShortName": "MP-18 wood", "61f7b85367ddd414173fdb36 Description": "A wooden handguard for MP-18 hunting rifles. Manufactured by IzhMekh.", "61f7c9e189e6fb1a5e3ea78d Name": "MP-18 7.62x54R single-shot rifle", "61f7c9e189e6fb1a5e3ea78d ShortName": "MP-18", "61f7c9e189e6fb1a5e3ea78d Description": "MP-18 is the legendary Soviet single-barreled rifle. This gun behaves perfectly in all weather conditions, no breakdowns or failures have ever been identified.", "61f8024263dc1250e26eb029 Name": "MP-18 polymer handguard", - "61f8024263dc1250e26eb029 ShortName": "MP18 poly", + "61f8024263dc1250e26eb029 ShortName": "MP-18 poly", "61f8024263dc1250e26eb029 Description": "A polymer handguard for MP-18 hunting rifles. Manufactured by IzhMekh.", "61f803b8ced75b2e852e35f8 Name": "MP-18 polymer stock", "61f803b8ced75b2e852e35f8 ShortName": "MP18 poly", @@ -8472,7 +8499,7 @@ "622b38c56762c718e457e246 ShortName": "G36 480mm", "622b38c56762c718e457e246 Description": "A 480mm 5.56x45 NATO barrel for the HK G36 assault rifle.", "622b397c9a3d4327e41843b6 Name": "HK G36 bipod", - "622b397c9a3d4327e41843b6 ShortName": "G36 bipod", + "622b397c9a3d4327e41843b6 ShortName": "G36", "622b397c9a3d4327e41843b6 Description": "A standard-issue bipod for the HK G36 assault rifle.", "622b3c081b89c677a33bcda6 Name": "HK G36 sight mount", "622b3c081b89c677a33bcda6 ShortName": "G36", @@ -8570,9 +8597,9 @@ "623c2f652febb22c2777d8d7 Name": "CNC Guns KeyMod 2 inch rail", "623c2f652febb22c2777d8d7 ShortName": "CNC 2\"", "623c2f652febb22c2777d8d7 Description": "CNC Guns 2 inch rail for KeyMod systems allows installation of additional equipment on the handguards equipped with a standard KeyMod interface.", - "623c3be0484b5003161840dc Name": "AK FAB Defense AGR-47 pistol grip", - "623c3be0484b5003161840dc ShortName": "AGR47", - "623c3be0484b5003161840dc Description": "The AGR-47 pistol grip for AK-family automatic rifles and compatibles, manufactured by FAB Defense.", + "623c3be0484b5003161840dc Name": "AK FAB Defense AGR-47 pistol grip (FDE)", + "623c3be0484b5003161840dc ShortName": "AGR-47", + "623c3be0484b5003161840dc Description": "The AGR-47 pistol grip for AK-family automatic rifles and compatibles, manufactured by FAB Defense. Flat Dark Earth version.", "623c3c1f37b4b31470357737 Name": "SV-98 CNC Guns OV-SV98 KeyMod handguard", "623c3c1f37b4b31470357737 ShortName": "OV KM", "623c3c1f37b4b31470357737 Description": "CNC Guns Keymod System aircraft-grade aluminum handguard for the OV-SV98 stock with KeyMod slots for rail installation.", @@ -8828,22 +8855,22 @@ "628b57d800f171376e7b2634 Name": "", "628b57d800f171376e7b2634 ShortName": "", "628b57d800f171376e7b2634 Description": "", - "628b8d83717774443b15e248 Name": "AK-545 SAG Mk. 2.1 gas tube", - "628b8d83717774443b15e248 ShortName": "SAG Mk.2.1", + "628b8d83717774443b15e248 Name": "AK-545 Mk. 2.1 gas tube", + "628b8d83717774443b15e248 ShortName": "Mk.2.1", "628b8d83717774443b15e248 Description": "The Mk. 2.1 gas tube for AK-545 carbines manufactured by Sureshot Armament Group.", - "628b916469015a4e1711ed8d Name": "AK-545 SAG Mk.3 handguard", - "628b916469015a4e1711ed8d ShortName": "AK-545 HG", + "628b916469015a4e1711ed8d Name": "AK-545 Mk.3 handguard", + "628b916469015a4e1711ed8d ShortName": "SAG Mk.3", "628b916469015a4e1711ed8d Description": "The Sureshot Armament Group Mk.3 handguard for AK-545, equipped with an M-LOK interface for the installation of additional devices and accessories and a picatinny rail on top for sights and tactical equipment mounting.", - "628b9471078f94059a4b9bfb Name": "AK-545 SAG rear sight", + "628b9471078f94059a4b9bfb Name": "AK-545 rear sight", "628b9471078f94059a4b9bfb ShortName": "AK-545 RS", "628b9471078f94059a4b9bfb Description": "A standard rear sight for AK-545 carbines, manufactured by Sureshot Armament Group.", "628b9784bcf6e2659e09b8a2 Name": "S&S Precision PlateFrame plate carrier (Goons Edition)", "628b9784bcf6e2659e09b8a2 ShortName": "PlateFrame GE", "628b9784bcf6e2659e09b8a2 Description": "A plate carrier with a minimalistic, lightweight, semi rigid plastic design, which was configured by Big Pipe - member of the Goons squad. Manufactured by S&S Precision.", - "628b9a40717774443b15e9f2 Name": "AK-545 SAG buffer tube", + "628b9a40717774443b15e9f2 Name": "AK-545 buffer tube", "628b9a40717774443b15e9f2 ShortName": "SAG tube", "628b9a40717774443b15e9f2 Description": "Sureshot Armament Group Receiver Extension Buffer Tube, 6-position, Mil-Spec diameter, designed specifically for AK-545.", - "628b9be6cff66b70c002b14c Name": "AK-545 SAG railed dust cover", + "628b9be6cff66b70c002b14c Name": "AK-545 railed dust cover", "628b9be6cff66b70c002b14c ShortName": "AK-545 DC", "628b9be6cff66b70c002b14c Description": "A standard-issue dust cover for AK-545 carbines, manufactured by Sureshot Armament Group.", "628b9c37a733087d0d7fe84b Name": "SAG AK-545 Short 5.45x39 carbine", @@ -8876,8 +8903,8 @@ "628e4dd1f477aa12234918aa Name": "Big Pipe's bandana", "628e4dd1f477aa12234918aa ShortName": "Bandana", "628e4dd1f477aa12234918aa Description": "Big Pipe's personal headgear. A black bandana with the Goons squad identification symbol.", - "628e4e576d783146b124c64d Name": "Peltor ComTac 4 Hybrid headset (Coyote Brown)", - "628e4e576d783146b124c64d ShortName": "ComTac 4", + "628e4e576d783146b124c64d Name": "Peltor ComTac IV Hybrid headset (Coyote Brown)", + "628e4e576d783146b124c64d ShortName": "ComTac IV", "628e4e576d783146b124c64d Description": "The ComTac IV Hybrid Communication Headset is designed to help reduce exposure to hazardous levels of noise, improve situational awareness and at the same time enable two-way radio communication in noisy environments. The headset's electronics are contained completely inside the headset housing, eliminating the need for a large, heavy external radio control box. The headband mechanically stabilizes the headset to help relieve issues of earplugs dislodging from cable snags and body movement. Designed for comfortable use with a ballistic helmet.", "6295e63de08ed747e64ae991 Name": "bear_lower_tactical_long", "6295e63de08ed747e64ae991 ShortName": "", @@ -8891,6 +8918,9 @@ "6295e944e9de5e7b3751c4da Name": "usec_lower_chameleon_softshell", "6295e944e9de5e7b3751c4da ShortName": "", "6295e944e9de5e7b3751c4da Description": "", + "6295e95e2ff06264a71c7c1f Name": "", + "6295e95e2ff06264a71c7c1f ShortName": "", + "6295e95e2ff06264a71c7c1f Description": "", "6295eb15869a02221651d318 Name": "USEC Chameleon", "6295eb15869a02221651d318 ShortName": "", "6295eb15869a02221651d318 Description": "Tactical jacket", @@ -9005,15 +9035,15 @@ "62aca6a1310e67685a2fc2e7 Name": "Haywood", "62aca6a1310e67685a2fc2e7 ShortName": "Haywood", "62aca6a1310e67685a2fc2e7 Description": "Haywood", - "62e14904c2699c0ec93adc47 Name": "SR-2M \"Veresk\" 9x21 submachine gun", + "62e14904c2699c0ec93adc47 Name": "SR-2M Veresk 9x21 submachine gun", "62e14904c2699c0ec93adc47 ShortName": "SR-2M", "62e14904c2699c0ec93adc47 Description": "SR-2M \"Veresk\" is a compact submachine gun designed for a powerful 9x21mm armor-piercing cartridge by order of the FSB and the FSO of the Russian Federation. This submachine gun is part of a high-performance rifle complex designed for special forces. Equipped with a folding foregrip. Developed by TsNIItochmash.", "62e153bcdb1a5c41971c1b5b Name": "SR-2M 9x21 30-round magazine", "62e153bcdb1a5c41971c1b5b ShortName": "SR-2M", "62e153bcdb1a5c41971c1b5b Description": "A standard 30-round capacity magazine for SR-2M \"Veresk\", manufactured by TsNIItochmash.", - "62e15547db1a5c41971c1b5e Name": "SR-2M polymer handguard", + "62e15547db1a5c41971c1b5e Name": "SR-2M polymer handguard (Plum)", "62e15547db1a5c41971c1b5e ShortName": "SR-2M", - "62e15547db1a5c41971c1b5e Description": "A standard-issue SR-2M \"Veresk\" polymer handguard for burn protection. Manufactured by TsNIItochmash.", + "62e15547db1a5c41971c1b5e Description": "A standard-issue SR-2M \"Veresk\" polymer handguard for burn protection. Manufactured by TsNIItochmash. Made out of plum-colored polymer, earning the nickname \"Sliva\" (Plum).", "62e27a7865f0b1592a49e17b Name": "SR-2M dust cover", "62e27a7865f0b1592a49e17b ShortName": "SR-2M", "62e27a7865f0b1592a49e17b Description": "A standard-issue dust cover for SR-2M \"Veresk\" submachine gun, manufactured by TsNIItochmash.", @@ -9026,7 +9056,7 @@ "62e2969582ebf260c20539c2 Name": "SR-2MP top-folding stock", "62e2969582ebf260c20539c2 ShortName": "SR-2MP", "62e2969582ebf260c20539c2 Description": "A folding stock for SR-2MP submachine gun, manufactured by TsNIItochmash. The buttstock has a spring-loaded butt plate which reduces the time it takes to shoulder the weapon.", - "62e2a7138e1ac9380579c122 Name": "SR-2M 9x21 sound suppressor (SV-1381)", + "62e2a7138e1ac9380579c122 Name": "SR-2M 9x21 SV-1381 sound suppressor", "62e2a7138e1ac9380579c122 ShortName": "SV-1381", "62e2a7138e1ac9380579c122 Description": "A silencer for the SR-2M \"Veresk\" 9x21 submachine gun, manufactured by TsNIItochmash.", "62e2a754b6c0ee2f230cee0f Name": "SR-2M 9x21 hand stopper", @@ -9050,7 +9080,7 @@ "62e7c98b550c8218d602cbb4 Name": "Steyr AUG 5.56x45 30-round magazine", "62e7c98b550c8218d602cbb4 ShortName": "AUG", "62e7c98b550c8218d602cbb4 Description": "A 30-round polymer Steyr AUG magazine, for 5.56x45 ammunition.", - "62e7e7bbe6da9612f743f1e0 Name": "GP-25 \"Kostyor\" 40mm underbarrel grenade launcher", + "62e7e7bbe6da9612f743f1e0 Name": "GP-25 Kostyor 40mm underbarrel grenade launcher", "62e7e7bbe6da9612f743f1e0 ShortName": "GP-25", "62e7e7bbe6da9612f743f1e0 Description": "An underbarrel grenade launcher for 40mm VOG-25 grenades, designed for installation on all full length AK automatic rifles.", "62e910aaf957f2915e0a5e36 Name": "Digital secure DSP radio transmitter", @@ -9204,8 +9234,8 @@ "635267ab3c89e2112001f826 ShortName": "Skull", "635267ab3c89e2112001f826 Description": "A really scary skull mask, worn only by the spookiest operators.", "635267f063651329f75a4ee8 Name": "26x75mm flare cartridge (Acid Green)", - "635267f063651329f75a4ee8 ShortName": "Signal", - "635267f063651329f75a4ee8 Description": "A 26x75mm acid green flare cartridge for the SP-81 flare gun. The unusual color indicates that the cartridge is used for some special signals to \"friendlies\". Worth trying to and use it to save yourself when near aggressive Scavs and Bosses.", + "635267f063651329f75a4ee8 ShortName": "AG", + "635267f063651329f75a4ee8 Description": "A 26x75mm acid green flare cartridge for the SP-81 flare gun. The unusual color indicates that the cartridge is used for some special signals to \"friendlies\". Worth trying to use it to save yourself when near aggressive Scavs or Bosses.", "6353fe04f0de2294830a0dbe Name": "", "6353fe04f0de2294830a0dbe ShortName": "", "6353fe04f0de2294830a0dbe Description": "", @@ -9227,9 +9257,9 @@ "63737f448b28897f2802b874 Name": "Hexatac HPC Plate Carrier (MultiCam Black)", "63737f448b28897f2802b874 ShortName": "HPC", "63737f448b28897f2802b874 Description": "A plate carrier by Hexatac. A minimalistic version designed to be used with chest rigs. MultiCam Black version.", - "6374a7e7417239a7bf00f042 Name": "PM bakelite side grips", + "6374a7e7417239a7bf00f042 Name": "PM bakelite grip", "6374a7e7417239a7bf00f042 ShortName": "PM bak.", - "6374a7e7417239a7bf00f042 Description": "Standard-issue bakelite side grip panels for the PM pistol.", + "6374a7e7417239a7bf00f042 Description": "A standard-issue bakelite grip panel for the PM pistol.", "6374a822e629013b9c0645c8 Name": "PM pistol slide", "6374a822e629013b9c0645c8 ShortName": "PM", "6374a822e629013b9c0645c8 Description": "A standard-issue slide for Makarov Pistol 9x18.", @@ -9242,7 +9272,7 @@ "637784c5f7b3f4ac1a0d1a9a Name": "PM FAB Defense PM-G pistol grip", "637784c5f7b3f4ac1a0d1a9a ShortName": "PM-G", "637784c5f7b3f4ac1a0d1a9a Description": "A PM grip by FAB Defense with a built-in magazine release mechanism that turns the Soviet classic into a modern handy pistol, significantly improving ergonomics.", - "637b60c3b7afa97bfc3d7001 Name": "\"Obdolbos 2\" cocktail injector", + "637b60c3b7afa97bfc3d7001 Name": "Obdolbos 2 cocktail injector", "637b60c3b7afa97bfc3d7001 ShortName": "Dolbos 2", "637b60c3b7afa97bfc3d7001 Description": "A syringe with a homemade drug, developed by Sanitar. A new version of the old classic. Looks like TerraGroup Labs' experiments did not end with the closure of TerraGroup Labs itself.", "637b612fb7afa97bfc3d7005 Name": "SJ12 TGLabs combat stimulant injector", @@ -9263,9 +9293,9 @@ "637b945722e2a933ed0e33c8 Name": "usec_upper_carinthia_softshell", "637b945722e2a933ed0e33c8 ShortName": "", "637b945722e2a933ed0e33c8 Description": "", - "637b9c37b7e3bc41b21ce71a Name": "SR-2M pistol grip", + "637b9c37b7e3bc41b21ce71a Name": "SR-2M pistol grip (Plum)", "637b9c37b7e3bc41b21ce71a ShortName": "SR-2M", - "637b9c37b7e3bc41b21ce71a Description": "A standard-issue pistol grip for SR-2M \"Veresk\". Manufactured by TsNIItochmash.", + "637b9c37b7e3bc41b21ce71a Description": "A standard-issue pistol grip for SR-2M \"Veresk\". Manufactured by TsNIItochmash. Made out of plum-colored polymer, earning the nickname \"Sliva\" (Plum).", "637ba17aa10a96c2b605dbc2 Name": "usec_lower_carinthia_softshell", "637ba17aa10a96c2b605dbc2 ShortName": "", "637ba17aa10a96c2b605dbc2 Description": "", @@ -9707,7 +9737,7 @@ "6448f2f6d4928d46d30be3f6 Name": "VSK-94 handguard", "6448f2f6d4928d46d30be3f6 ShortName": "VSK-94", "6448f2f6d4928d46d30be3f6 Description": "A standard-issue handguard for the VSK-94 marksman rifle. Manufactured by Tula KPB Instrument Design Bureau.", - "644a3df63b0b6f03e101e065 Name": "MAWL-C1+ tactical device", + "644a3df63b0b6f03e101e065 Name": "B.E. Meyers MAWL-C1+ tactical device", "644a3df63b0b6f03e101e065 ShortName": "MAWL-C1+", "644a3df63b0b6f03e101e065 Description": "Modular Advanced Weapon Laser C1+ (MAWL-C1+) produced by B.E. Meyers is a rugged, combat-proven and easy-to-use aiming system with integrated infrared and visible aim lasers as well as an infrared illuminator.", "6450ec2e7da7133e5a09ca96 Name": "9A-91 9x39 20-round magazine", @@ -9756,7 +9786,7 @@ "64639a9aab86f8fd4300146c ShortName": "PKP 658mm", "64639a9aab86f8fd4300146c Description": "A standard-issue 658mm barrel for PKP \"Pecheneg\" with a built-in muzzle brake. Manufactured by V.A. Degtyarev Plant.", "6464d870bb2c580352070cc4 Name": "PK bipod", - "6464d870bb2c580352070cc4 ShortName": "PK bipod", + "6464d870bb2c580352070cc4 ShortName": "PK", "6464d870bb2c580352070cc4 Description": "A standard-issue bipod for Kalashnikov Machine gun. Manufactured by V.A. Degtyarev Plant.", "646f62fee779812413011ab7 Name": "Zenit 2D flashlight", "646f62fee779812413011ab7 ShortName": "2D", @@ -9794,6 +9824,9 @@ "647def638295ebcb5b02f05b Name": "AR-15 AB Arms MOD1 lower handguard", "647def638295ebcb5b02f05b ShortName": "ABA M1", "647def638295ebcb5b02f05b Description": "AB Arms MOD1 lower handguard for the AR-15 rifle.", + "648067b8aa32c2049f098463 Name": "", + "648067b8aa32c2049f098463 ShortName": "", + "648067b8aa32c2049f098463 Description": "", "648067db042be0705c0b3009 Name": "RTM Pillau tactical foregrip (Sand)", "648067db042be0705c0b3009 ShortName": "Pillau", "648067db042be0705c0b3009 Description": "A lightweight aluminum tactical grip manufactured by RTM. Sand version.", @@ -9998,9 +10031,9 @@ "6489d89debac5a4a1b73caf7 Name": "Sealed weapon case", "6489d89debac5a4a1b73caf7 ShortName": "Weapon (sealed)", "6489d89debac5a4a1b73caf7 Description": "Sealed weapon case", - "648ae3e356c6310a830fc291 Name": "AK CG101 AR-type pistol grip adapter", + "648ae3e356c6310a830fc291 Name": "AK Custom Guns CG101 AR-type pistol grip adapter", "648ae3e356c6310a830fc291 ShortName": "CG101", - "648ae3e356c6310a830fc291 Description": "An adapter that allows AR-type pistol grips installation on the AK rifles.", + "648ae3e356c6310a830fc291 Description": "An adapter that allows AR-type pistol grips installation on the AK rifles. Manufactured by Custom Guns.", "648afce7ec6bb25b2608defb Name": "PM FAB Defense PM-G pistol grip (Olive Drab)", "648afce7ec6bb25b2608defb ShortName": "PM-G OD", "648afce7ec6bb25b2608defb Description": "A PM grip by FAB Defense with a built-in magazine release mechanism that turns the Soviet classic into a modern handy pistol, significantly improving ergonomics. Olive Drab version.", @@ -10058,10 +10091,10 @@ "649ec2cec93611967b03495e Name": "AK-12 rear sight", "649ec2cec93611967b03495e ShortName": "AK-12 RS", "649ec2cec93611967b03495e Description": "A detachable rear sight for AK-12 automatic rifles. Manufactured by Izhmash.", - "649ec2da59cbb3c813042dca Name": "AK-12 rear sight base", - "649ec2da59cbb3c813042dca ShortName": "AK-12 RSB", + "649ec2da59cbb3c813042dca Name": "AK-12 rear sight mount", + "649ec2da59cbb3c813042dca ShortName": "AK-12 RSM", "649ec2da59cbb3c813042dca Description": "A detachable base for rear sights, installed on AK-12 automatic rifles. Manufactured by Izhmash.", - "649ec2f3961514b22506b111 Name": "AK-12 dust cover", + "649ec2f3961514b22506b111 Name": "AK-12 railed dust cover", "649ec2f3961514b22506b111 ShortName": "AK-12 DC", "649ec2f3961514b22506b111 Description": "A standard receiver dust cover with integrated Picatinny rail for AK-12 automatic rifles. Manufactured by Izhmash.", "649ec30cb013f04a700e60fb Name": "AK-12 5.45x39 early model 30-round magazine", @@ -10208,9 +10241,9 @@ "64b9e2037fdfb81df81e3c25 Name": "M1A 7.62x51 10-round magazine", "64b9e2037fdfb81df81e3c25 ShortName": "M1A", "64b9e2037fdfb81df81e3c25 Description": "A 10-round double-stack 7.62x51 NATO magazine for the M1A rifle, produced by Springfield Armory.", - "64b9e265c94d0d15c5027e35 Name": "AK-74 \"Saiga 545\" 5.45x39 20-round magazine", + "64b9e265c94d0d15c5027e35 Name": "AK-74 Delta-Tek Saiga 545 5.45x39 20-round magazine", "64b9e265c94d0d15c5027e35 ShortName": "Saiga 545", - "64b9e265c94d0d15c5027e35 Description": "A 20-round 5.45x39 Delta-Tech polymer magazine Saiga 545, for the AK-based civilian carbine of the same name.", + "64b9e265c94d0d15c5027e35 Description": "A 20-round 5.45x39 polymer magazine for the AK-based civilian carbine of the same name.", "64be7095047e826eae02b0c1 Name": "Zulu Nylon Gear M4 Reduced Signature Chest Rig (Ranger Green)", "64be7095047e826eae02b0c1 ShortName": "M4 RSCR", "64be7095047e826eae02b0c1 Description": "The M4 RSCR chest system was designed to be a lightweight and minimalist system for carrying just the essentials. Manufactured by Zulu Nylon Gear.", @@ -10279,7 +10312,7 @@ "64d11702dd0cd96ab82c3280 Description": "Bank safe", "64d4b23dc1b37504b41ac2b6 Name": "Rusted bloody key", "64d4b23dc1b37504b41ac2b6 ShortName": "Rusted", - "64d4b23dc1b37504b41ac2b6 Description": "A rusted and bloody key. Has \"The holder of this key will wander for eternity\" inscribed on it.", + "64d4b23dc1b37504b41ac2b6 Description": "A rusted bloody key, inscribed on it is: \"He who holds this key shall wander for eternity\".", "64e73909cd54ef0580746af3 Name": "Picture 1", "64e73909cd54ef0580746af3 ShortName": "Picture 1", "64e73909cd54ef0580746af3 Description": "", @@ -10340,6 +10373,12 @@ "64f6f4c5911bcdfe8b03b0dc Name": "Tournament secured container", "64f6f4c5911bcdfe8b03b0dc ShortName": "Tournament", "64f6f4c5911bcdfe8b03b0dc Description": "A secret TerraGroup invention - the tournament secured container.", + "651178336cad06c37c049eb4 Name": "VSS/VAL polymer handguard (Plum)", + "651178336cad06c37c049eb4 ShortName": "VSS/VAL", + "651178336cad06c37c049eb4 Description": "A polymer handguard for the AS Val and VSS Vintorez. Manufactured by TsNIITochMash. Made out of plum-colored polymer, earning the nickname \"Sliva\" (Plum).", + "65118f531b90b4fc77015083 Name": "VSS/VAL 9x39 30-round magazine", + "65118f531b90b4fc77015083 ShortName": "VSS/VAL", + "65118f531b90b4fc77015083 Description": "A 30-round polymer TsNIITochMash 9x39 magazine for the AS VAL special assault rifle.", "6513ef33e06849f06c0957ca Name": "Degtyarev RPD 7.62x39 machine gun", "6513ef33e06849f06c0957ca ShortName": "RPD", "6513ef33e06849f06c0957ca Description": "The Degtyarev hand-held machine gun chambered in 7.62x39 caliber. This machine gun was adopted by the Soviet Army and was used as a means of reinforcing infantry squads and platoons from the late forties to the early sixties. The RPD is elegantly designed, resulting in a compact, reliable and quite powerful fire support weapon. Manufactured by V.A. Degtyarev Plant.", @@ -10367,6 +10406,15 @@ "6513f1798cb24472490ee331 Name": "RPD wooden stock", "6513f1798cb24472490ee331 ShortName": "RPD wood", "6513f1798cb24472490ee331 Description": "A standard-issue wooden stock for the RPD machine gun. Manufactured by V.A. Degtyarev Plant.", + "65144f546ddb773afa0e35e1 Name": "SR-3M polymer handguard (Black)", + "65144f546ddb773afa0e35e1 ShortName": "SR-3M", + "65144f546ddb773afa0e35e1 Description": "A standard-issue polymer handguard for the SR-3M assault rifle.", + "65144ff50e00edc79406836f Name": "SR-3M 9x39 sound suppressor", + "65144ff50e00edc79406836f ShortName": "SR-3M", + "65144ff50e00edc79406836f Description": "A standard-issue sound suppressor for the SR-3M assault rifle.", + "651450ce0e00edc794068371 Name": "SR-3M 9x39 compact assault rifle", + "651450ce0e00edc794068371 ShortName": "SR-3M", + "651450ce0e00edc794068371 Description": "The SR-3M is a powerful assault rifle, featuring a very compact size comparable to submachine guns, but noticeably superior in terms of firepower due to the use of special armor-piercing ammunition. The main purpose of the SR-3M is to be used as a concealed carry weapon for Russian special forces units. Developed at TsNIITochMash and based on the AS VAL assault rifle.", "651580dc71a4f10aec4b6056 Name": "AK PUFGUN SG-M2 pistol grip", "651580dc71a4f10aec4b6056 ShortName": "SG-M2", "651580dc71a4f10aec4b6056 Description": "The SG-M2 pistol grip for AK and compatible rifles. Manufactured by PUFGUN.", @@ -10406,31 +10454,31 @@ "65268d8ecb944ff1e90ea385 Name": "Degtyarev RPDN 7.62x39 machine gun", "65268d8ecb944ff1e90ea385 ShortName": "RPDN", "65268d8ecb944ff1e90ea385 Description": "The Degtyarev hand-held machine gun chambered in 7.62x39 caliber. This machine gun was adopted by the Soviet Army and was used as a means of reinforcing infantry squads and platoons from the late forties to the early sixties. The RPD is elegantly designed, resulting in a compact, reliable and quite powerful fire support weapon. The RPDN variant is equipped with a hinged dovetail mount for installing optics. Manufactured by V.A. Degtyarev Plant.", - "65290f395ae2ae97b80fdf2d Name": "SIG MCX SPEAR 6.8x51 assault rifle", + "65290f395ae2ae97b80fdf2d Name": "SIG MCX-SPEAR 6.8x51 assault rifle", "65290f395ae2ae97b80fdf2d ShortName": "SPEAR 6.8", "65290f395ae2ae97b80fdf2d Description": "The MCX SPEAR is a multi-caliber assault rifle designed and manufactured by SIG Sauer based on the MCX assault rifle. Primarily chambered in the new 6.8x51mm (.277 FURY) ammunition. Designed specifically for the US Military to replace the M4 carbine.", - "652910565ae2ae97b80fdf35 Name": "MCX SPEAR 6.8x51 330mm barrel", + "652910565ae2ae97b80fdf35 Name": "MCX-SPEAR 6.8x51 330mm barrel", "652910565ae2ae97b80fdf35 ShortName": "SPEAR 330mm", - "652910565ae2ae97b80fdf35 Description": "A 13 inch (330mm) barrel for the MCX SPEAR assault rifle chambered in 6.8x51 (.277 FURY) ammo. Manufactured by SIG Sauer.", - "6529109524cbe3c74a05e5b7 Name": "MCX SPEAR charging handle", + "652910565ae2ae97b80fdf35 Description": "A 13 inch (330mm) barrel for the MCX-SPEAR assault rifle chambered in 6.8x51 (.277 FURY) ammo. Manufactured by SIG Sauer.", + "6529109524cbe3c74a05e5b7 Name": "MCX-SPEAR charging handle", "6529109524cbe3c74a05e5b7 ShortName": "SPEAR", - "6529109524cbe3c74a05e5b7 Description": "A standard-issue ambidextrous charging handle for the MCX SPEAR assault rifle. Manufactured by SIG Sauer.", - "652910bc24cbe3c74a05e5b9 Name": "MCX SPEAR Adjustable Gas Piston", + "6529109524cbe3c74a05e5b7 Description": "A standard-issue ambidextrous charging handle for the MCX-SPEAR assault rifle. Manufactured by SIG Sauer.", + "652910bc24cbe3c74a05e5b9 Name": "MCX-SPEAR Adjustable Gas Piston", "652910bc24cbe3c74a05e5b9 ShortName": "SPEAR gas", - "652910bc24cbe3c74a05e5b9 Description": "A gas piston for the MCX SPEAR assault rifle. Manufactured by SIG Sauer.", - "652910ef50dc782999054b97 Name": "MCX SPEAR 11 inch M-LOK handguard", + "652910bc24cbe3c74a05e5b9 Description": "A gas piston for the MCX-SPEAR assault rifle. Manufactured by SIG Sauer.", + "652910ef50dc782999054b97 Name": "MCX-SPEAR 11 inch M-LOK handguard", "652910ef50dc782999054b97 ShortName": "SPEAR 11\"", - "652910ef50dc782999054b97 Description": "An 11 inch handguard for the MCX SPEAR assault rifle equipped with an M-LOK interface for installation of additional devices and accessories. Manufactured by SIG Sauer.", - "6529113b5ae2ae97b80fdf39 Name": "MCX SPEAR Clutch-Lok QD 6.8x51 Shouldered Flash Hider", + "652910ef50dc782999054b97 Description": "An 11 inch handguard for the MCX-SPEAR assault rifle equipped with an M-LOK interface for installation of additional devices and accessories. Manufactured by SIG Sauer.", + "6529113b5ae2ae97b80fdf39 Name": "MCX-SPEAR Clutch-Lok QD 6.8x51 Shouldered Flash Hider", "6529113b5ae2ae97b80fdf39 ShortName": "CLQD", "6529113b5ae2ae97b80fdf39 Description": "The SPEAR Clutch-Lok Shouldered Flash Hider is an effective flash suppressor that also serves as an attachment platform for the SLX/SLH sound suppressor. Manufactured by SIG Sauer.", - "652911675ae2ae97b80fdf3c Name": "AR-15 SIG M400 Reduced Angle Pistol Grip (Coyote Tan)", - "652911675ae2ae97b80fdf3c ShortName": "M400", - "652911675ae2ae97b80fdf3c Description": "The polymer M400 Reduced Angle Pistol Grip fits any weapon compatible with AR-15 system. Manufactured by SIG Sauer. Coyote Tan version.", - "6529119424cbe3c74a05e5bb Name": "MCX SPEAR 6.8x51 upper receiver", + "652911675ae2ae97b80fdf3c Name": "AR-15 SIG Reduced Angle Pistol Grip (Coyote Tan)", + "652911675ae2ae97b80fdf3c ShortName": "SIG RAPG", + "652911675ae2ae97b80fdf3c Description": "The polymer Reduced Angle Pistol Grip fits any weapon compatible with AR-15 system. Manufactured by SIG Sauer. Coyote Tan version.", + "6529119424cbe3c74a05e5bb Name": "MCX-SPEAR 6.8x51 upper receiver", "6529119424cbe3c74a05e5bb ShortName": "SPEAR 6.8", - "6529119424cbe3c74a05e5bb Description": "A standard-issue upper receiver for the MCX SPEAR assault rifle, chambered in 6.8x51mm (.277 FURY). Equipped with a mount for attaching additional devices. Manufactured by SIG Sauer.", - "652911e650dc782999054b9d Name": "MCX SPEAR SLX68-MG-QD 6.8x51 sound suppressor", + "6529119424cbe3c74a05e5bb Description": "A standard-issue upper receiver for the MCX-SPEAR assault rifle, chambered in 6.8x51mm (.277 FURY). Equipped with a mount for attaching additional devices. Manufactured by SIG Sauer.", + "652911e650dc782999054b9d Name": "MCX-SPEAR SLX68-MG-QD 6.8x51 sound suppressor", "652911e650dc782999054b9d ShortName": "SLX68", "652911e650dc782999054b9d Description": "The SLX68-MG-QD suppressor is designed for use with the 6.8x51 (.277 FURY) caliber cartridge. Can only be mounted on Clutch-Lok flash hiders. Manufactured by SIG Sauer.", "6529243824cbe3c74a05e5c1 Name": "6.8x51mm SIG Hybrid", @@ -10439,11 +10487,11 @@ "6529302b8c26af6326029fb7 Name": "6.8x51mm SIG FMJ", "6529302b8c26af6326029fb7 ShortName": "FMJ", "6529302b8c26af6326029fb7 Description": "A civilian 6.8x51mm (.277 FURY) Elite Ball FMJ (Full Metal Jacket) 135 grain rifle round, manufactured by SIG Sauer.", - "6529348224cbe3c74a05e5c4 Name": "MCX/MPX Stock Locking Hinge Assembly", - "6529348224cbe3c74a05e5c4 ShortName": "MCX/MPX", + "6529348224cbe3c74a05e5c4 Name": "MPX/MCX Stock Locking Hinge Assembly", + "6529348224cbe3c74a05e5c4 ShortName": "SIG SLHA", "6529348224cbe3c74a05e5c4 Description": "A folding stock adapter for SIG rifles and SMGs. Manufactured by SIG Sauer.", - "6529366450dc782999054ba0 Name": "MCX/MPX folding stock adapter buffer tube (Coyote Tan)", - "6529366450dc782999054ba0 ShortName": "MCX/MPX", + "6529366450dc782999054ba0 Name": "MPX/MCX Stock Adapter Low Profile Tube (Coyote Tan)", + "6529366450dc782999054ba0 ShortName": "SIG LPT", "6529366450dc782999054ba0 Description": "A buffer tube for the folding stock adapter for SIG AR platform rifles and SMGs. Manufactured by SIG Sauer. Coyote Tan version.", "6529370c405a5f51dd023db8 Name": "AR-15 Magpul MOE SL-K buttstock (Coyote Tan)", "6529370c405a5f51dd023db8 ShortName": "MOE SL-K", @@ -10460,6 +10508,9 @@ "6531119b9afebff7ff0a1769 Name": "Vengeful Zryachiy's balaclava (folded)", "6531119b9afebff7ff0a1769 ShortName": "Vengeful", "6531119b9afebff7ff0a1769 Description": "An intimidating red face mask, worn by Zryachiy. Folded to be worn as a hat.", + "65329ebcc0d50d0c9204ace1 Name": "SR-3M polymer foregrip (Black)", + "65329ebcc0d50d0c9204ace1 ShortName": "SR-3M", + "65329ebcc0d50d0c9204ace1 Description": "A standard-issue polymer foregrip for the SR-3M assault rifle.", "65392f611406374f82152ba5 Name": "GBRS Aimpoint Hydra Mount Kit (Black)", "65392f611406374f82152ba5 ShortName": "Hydra", "65392f611406374f82152ba5 Description": "The Hydra Mount Kit for Aimpoint Micro T-1 and H-1 series sights and tactical equipment. Manufactured by GBRS Group.", @@ -10475,9 +10526,9 @@ "653ece125a1690d9d90491e8 Name": "SKS FAB Defense UAS gas tube cover", "653ece125a1690d9d90491e8 ShortName": "SKS UAS", "653ece125a1690d9d90491e8 Description": "A cover for the SKS carbine gas tube. Manufactured by FAB Defense.", - "653ecef836fae5a82f02b869 Name": "SKS ATI Monte Carlo chassis", + "653ecef836fae5a82f02b869 Name": "SKS ATI Monte Carlo stock", "653ecef836fae5a82f02b869 ShortName": "SKS MC", - "653ecef836fae5a82f02b869 Description": "A lightweight Monte Carlo-style stock for the SKS carbine, designed for sport shooting and hunting. Manufactured by ATI outdoors.", + "653ecef836fae5a82f02b869 Description": "A lightweight Monte Carlo-style stock for the SKS carbine, designed for sport shooting and hunting. Manufactured by ATI Outdoors.", "653ed132896b99b40a0292e6 Name": "SKS FAB Defense UAS buttstock", "653ed132896b99b40a0292e6 ShortName": "UAS SKS", "653ed132896b99b40a0292e6 Description": "A lightweight polymer folding buttstock for the SKS carbine. Manufactured by FAB Defense.", @@ -10541,6 +10592,9 @@ "654a9189bcc67a392b056c79 Name": "Layers of aramid fiber", "654a9189bcc67a392b056c79 ShortName": "", "654a9189bcc67a392b056c79 Description": "", + "654b5eb7a29f3736215dd030 Name": "", + "654b5eb7a29f3736215dd030 ShortName": "", + "654b5eb7a29f3736215dd030 Description": "", "6551fec55d0cf82e51014288 Name": "Hybrid composite materials", "6551fec55d0cf82e51014288 ShortName": "", "6551fec55d0cf82e51014288 Description": "", @@ -10576,16 +10630,16 @@ "655c66e40b2de553b618d4b8 Description": "The Tarko collectible figure of a politician called Mutkevich. The unknown craftsman was impressed with how the former politician and current fighter of the Arena cleanup crew from is fighting for his life.", "655c673673a43e23e857aebd Name": "Scav figurine", "655c673673a43e23e857aebd ShortName": "Scav", - "655c673673a43e23e857aebd Description": "The Tarko collectible figure of a Scav. An unknown craftsman decided to portray a regular representative of the Scavs on Streets of Tarkov. It is unclear what impressed the author more: the memorable hat or how diligently the Scav tried to aim.", + "655c673673a43e23e857aebd Description": "The Tarko collectible figure of a Scav. The unknown craftsman decided to portray a regular representative of the Scavs on Streets of Tarkov. It is unclear what impressed the author more: the memorable hat or how diligently the Scav tried to aim.", "655c67782a1356436041c9c5 Name": "Ryzhy figurine", "655c67782a1356436041c9c5 ShortName": "Ryzhy", - "655c67782a1356436041c9c5 Description": "The Tarko collectible figure of a Scav called Ryzhy. Having heard of the adventures of the well-known in certain circles Ryzhy, an unknown craftsman created this figurine.", + "655c67782a1356436041c9c5 Description": "The Tarko collectible figure of a Scav called Ryzhy. Having heard of the adventures of the well-known in certain circles Ryzhy, the unknown craftsman created this figurine.", "655c67ab0d37ca5135388f4b Name": "Ded Moroz figurine", "655c67ab0d37ca5135388f4b ShortName": "Ded Moroz", "655c67ab0d37ca5135388f4b Description": "The Tarko collectible figure of a Ded Moroz. This time, the craftsman portrayed a collective image of one of the Scavs who changes his clothes every Christmas and New Year and gives everyone in the city gifts that he managed to loot during the year. Traditionally, PMC fighters and Scavs do not attack this oddball.", - "655cb6b5d680a544f30607fa Name": "AKS-74U Legal Arsenal Piligrim railed dust cover", - "655cb6b5d680a544f30607fa ShortName": "Piligrim", - "655cb6b5d680a544f30607fa Description": "The \"Piligrim\" receiver dust cover with integrated Picatinny rail for AKS-74U. Allows installation of reflex sights and optics. Manufactured by Legal Arsenal.", + "655cb6b5d680a544f30607fa Name": "AKS-74U Legal Arsenal Pilgrim railed dust cover", + "655cb6b5d680a544f30607fa ShortName": "Pilgrim", + "655cb6b5d680a544f30607fa Description": "The Pilgrim receiver dust cover with integrated Picatinny rail for AKS-74U. Allows installation of reflex sights and optics. Manufactured by Legal Arsenal.", "655dccfdbdcc6b5df71382b6 Name": "Strike Industries Cobra Tactical foregrip (FDE)", "655dccfdbdcc6b5df71382b6 ShortName": "SI Cobra", "655dccfdbdcc6b5df71382b6 Description": "The Cobra Tactical foregrip integrates the form with functionality. Its hybrid-designed shape works both as a regular foregrip and as a comfortable hand stop when going with the thumb over bore method. The grip allows you to handle the weapon with confidence and the organic design enables the operator to manipulate the rifle in a way that’s most comfortable at any given moment. Flat Dark Earth version.", @@ -10595,12 +10649,27 @@ "655f13e0a246670fb0373245 Name": "Wilcox BOSS Xe reflex sight", "655f13e0a246670fb0373245 ShortName": "BOSS Xe", "655f13e0a246670fb0373245 Description": "The Ballistically Optimized Sighting System reflex sight that combines the functions of a red dot, tactical block and iron sights. Manufactured by Wilcox.", + "6565b91666492762f5029c0b Name": "AS VAL pistol grip (Black)", + "6565b91666492762f5029c0b ShortName": "VAL", + "6565b91666492762f5029c0b Description": "A standard-issue polymer pistol grip for AS VAL, manufactured by TSNIITochMash.", + "6565bb7eb4b12a56eb04b084 Name": "VSS/VAL polymer handguard (Black)", + "6565bb7eb4b12a56eb04b084 ShortName": "VSS/VAL", + "6565bb7eb4b12a56eb04b084 Description": "A black polymer handguard for the AS Val and VSS Vintorez. Manufactured by TsNIITochMash.", + "6565c0c2ff7eb7070409084c Name": "SR-3M polymer foregrip (Plum)", + "6565c0c2ff7eb7070409084c ShortName": "SR-3M", + "6565c0c2ff7eb7070409084c Description": "A standard-issue polymer foregrip for the SR-3M assault rifle. Made out of plum-colored polymer, earning the nickname \"Sliva\" (Plum).", + "6565c3ab977bcc2dbb01c2e7 Name": "SR-3M polymer handguard (Plum)", + "6565c3ab977bcc2dbb01c2e7 ShortName": "SR-3M", + "6565c3ab977bcc2dbb01c2e7 Description": "A standard-issue polymer handguard for the SR-3M assault rifle. Made out of plum-colored polymer, earning the nickname \"Sliva\" (Plum).", "6567e751a715f85433025998 Name": "SIG ALPHA4 30mm ring scope mount", "6567e751a715f85433025998 ShortName": "ALPHA4", "6567e751a715f85433025998 Description": "A mount for 30mm riflescopes, installed on Weaver/Picatinny type rails. Manufactured by SIG Sauer.", "6567e7681265c8a131069b0f Name": "SIG TANGO6T 1-6x24 30mm riflescope", "6567e7681265c8a131069b0f ShortName": "TANGO6T", "6567e7681265c8a131069b0f Description": "The TANGO6T is a rugged and well-built low power variable optic. This model features a 1x to 6x magnification and a first focal plane reticle. This rifle scope is ideal for short and medium distances, as well as for backcountry hunting. Manufactured by SIG Sauer.", + "6568a6bf2c5fb7afc70bc424 Name": "SR-3M railed polymer handguard (Black)", + "6568a6bf2c5fb7afc70bc424 ShortName": "SR-3M R", + "6568a6bf2c5fb7afc70bc424 Description": "A polymer handguard with Zenit Picatinny rails for the SR-3M assault rifle.", "656ddcf0f02d7bcea90bf395 Name": "Tehinkom RK-PT-25 patrol backpack (Digital Flora)", "656ddcf0f02d7bcea90bf395 ShortName": "RK-PT-25", "656ddcf0f02d7bcea90bf395 Description": "This backpack is a multifunctional piece of equipment designed for transportation of various items of combat and marching equipment, additional weaponry, etc. It can be used both as part of the UMTBS transportation and gear system (ZhTU 6Sh112) and independently, as part of various sets of individual combat equipment.", @@ -10740,10 +10809,10 @@ "657024011419851aef03e6f4 ShortName": "EKO", "657024011419851aef03e6f4 Description": "A box of .366 TKM EKO cartridges, 20 pieces.", "65702406bfc87b3a34093216 Name": ".45 ACP Hydra-Shok ammo pack (50 pcs)", - "65702406bfc87b3a34093216 ShortName": "H-Shock", + "65702406bfc87b3a34093216 ShortName": "HydraShok", "65702406bfc87b3a34093216 Description": "A box of .45 ACP Hydra-Shok cartridges, 50 pieces.", "6570240a1419851aef03e6f7 Name": ".45 ACP Lasermatch FMJ ammo pack (50 pcs)", - "6570240a1419851aef03e6f7 ShortName": "Laser-FMJ", + "6570240a1419851aef03e6f7 ShortName": "Lasermatch", "6570240a1419851aef03e6f7 Description": "A box of .45 ACP Lasermatch FMJ cartridges, 50 pieces.", "6570240ecfc010a0f50069f2 Name": ".45 ACP Match FMJ ammo pack (50 pcs)", "6570240ecfc010a0f50069f2 ShortName": "FMJ", @@ -10781,10 +10850,10 @@ "6570244ec5d7d4cb4d078558 Name": "12/70 Grizzly 40 slug ammo pack (25 pcs)", "6570244ec5d7d4cb4d078558 ShortName": "Grizzly 40", "6570244ec5d7d4cb4d078558 Description": "A box of 12/70 Grizzly 40 slug cartridges, 25 pieces.", - "65702452cfc010a0f50069fe Name": "12/70 \"Poleva-3\" slug ammo pack (25 pcs)", + "65702452cfc010a0f50069fe Name": "12/70 Poleva-3 slug ammo pack (25 pcs)", "65702452cfc010a0f50069fe ShortName": "Poleva-3", "65702452cfc010a0f50069fe Description": "A box of 12/70 \"Poleva-3\" slug cartridges, 25 pieces.", - "657024581419851aef03e700 Name": "12/70 \"Poleva-6u\" slug ammo pack (25 pcs)", + "657024581419851aef03e700 Name": "12/70 Poleva-6u slug ammo pack (25 pcs)", "657024581419851aef03e700 ShortName": "Poleva-6u", "657024581419851aef03e700 Description": "A box of 12/70 \"Poleva-6u\" slug cartridges, 25 pieces.", "65702469c5d7d4cb4d07855b Name": "12/70 makeshift .50 BMG slug ammo pack (25 pcs)", @@ -10820,10 +10889,10 @@ "6570249f1419851aef03e709 Name": "20/70 Star slug ammo pack (25 pcs)", "6570249f1419851aef03e709 ShortName": "Star", "6570249f1419851aef03e709 Description": "A box of 20/70 Star slug cartridges, 25 pieces.", - "657024a4bfc87b3a3409322c Name": "20/70 \"Poleva-3\" slug ammo pack (25 pcs)", + "657024a4bfc87b3a3409322c Name": "20/70 Poleva-3 slug ammo pack (25 pcs)", "657024a4bfc87b3a3409322c ShortName": "Poleva-3", "657024a4bfc87b3a3409322c Description": "A box of 20/70 \"Poleva-3\" slug cartridges, 25 pieces.", - "657024a91419851aef03e70c Name": "20/70 \"Poleva-6u\" slug ammo pack (25 pcs)", + "657024a91419851aef03e70c Name": "20/70 Poleva-6u slug ammo pack (25 pcs)", "657024a91419851aef03e70c ShortName": "Poleva-6u", "657024a91419851aef03e70c Description": "A box of 20/70 \"Poleva-6u\" slug cartridges, 25 pieces.", "657024aebfc87b3a3409322f Name": "23x75mm Shrapnel-10 buckshot ammo pack (5 pcs)", @@ -10979,7 +11048,7 @@ "657025dfcfc010a0f5006a3b Name": "9x39mm SPP gs ammo pack (20 pcs)", "657025dfcfc010a0f5006a3b ShortName": "SPP", "657025dfcfc010a0f5006a3b Description": "A box of 9x39mm SPP gs cartridges, 20 pieces.", - "657025ebc5d7d4cb4d078588 Name": "5.45x39mm PPBS gs \"Igolnik\" ammo pack (120 pcs)", + "657025ebc5d7d4cb4d078588 Name": "5.45x39mm PPBS gs Igolnik ammo pack (120 pcs)", "657025ebc5d7d4cb4d078588 ShortName": "PPBS", "657025ebc5d7d4cb4d078588 Description": "A box of 5.45x39mm PPBS gs \"Igolnik\" cartridges, 120 pieces.", "65702606cfc010a0f5006a3e Name": "9x18mm PM BZhT gzh ammo pack (50 pcs)", @@ -11282,19 +11351,19 @@ "657119fea330b8c9060f7afc Name": "Armor steel", "657119fea330b8c9060f7afc ShortName": "", "657119fea330b8c9060f7afc Description": "", - "65711b07a330b8c9060f7b01 Name": "Layers of aramid fiber", + "65711b07a330b8c9060f7b01 Name": "Hybrid composite materials", "65711b07a330b8c9060f7b01 ShortName": "", "65711b07a330b8c9060f7b01 Description": "", - "65711b489eb8c145180dbb9d Name": "Layers of aramid fiber", + "65711b489eb8c145180dbb9d Name": "Hybrid composite materials", "65711b489eb8c145180dbb9d ShortName": "", "65711b489eb8c145180dbb9d Description": "", - "65711b706d197c216005b31c Name": "Layers of aramid fiber", + "65711b706d197c216005b31c Name": "Hybrid composite materials", "65711b706d197c216005b31c ShortName": "", "65711b706d197c216005b31c Description": "", - "65711b9b65daf6aa960c9b1b Name": "Layers of aramid fiber", + "65711b9b65daf6aa960c9b1b Name": "Hybrid composite materials", "65711b9b65daf6aa960c9b1b ShortName": "", "65711b9b65daf6aa960c9b1b Description": "", - "65711bc79eb8c145180dbba1 Name": "Layers of aramid fiber", + "65711bc79eb8c145180dbba1 Name": "Hybrid composite materials", "65711bc79eb8c145180dbba1 ShortName": "", "65711bc79eb8c145180dbba1 Description": "", "65719f0775149d62ce0a670b Name": "NPP KlASS Tor-2 helmet (Olive Drab)", @@ -11828,7 +11897,7 @@ "6576504b526e320fbe035783 Name": "6.5 mm aramid insert and titanium plates", "6576504b526e320fbe035783 ShortName": "", "6576504b526e320fbe035783 Description": "", - "6576f4708ca9c4381d16cd9d Name": "9x21mm 7N42 \"Zubilo\"", + "6576f4708ca9c4381d16cd9d Name": "9x21mm 7N42 Zubilo", "6576f4708ca9c4381d16cd9d ShortName": "7N42", "6576f4708ca9c4381d16cd9d Description": "The 9x21mm PP cartridge (GRAU Index - 7N42) with increased penetration bullet is designed to engage armored personnel. The head part of the core is made with a cut edge. This design ensures the tearing of the threads of the fabric base of the body armor and significantly increases the penetration of the bullet. The core protrudes from the jacket, which increases its penetration capability. The bullet head is colored black.", "6576f93989f0062e741ba952 Name": "9x21mm 7U4", @@ -12071,10 +12140,10 @@ "65815f0e647e3d7246384e14 Name": "Pack of Tarker dried meat", "65815f0e647e3d7246384e14 ShortName": "Tarker", "65815f0e647e3d7246384e14 Description": "A vacuum pack with slices of beef jerky. Yum yum.", - "658188edf026a90c1708c827 Name": "PSh-97 DJETA helmet built-in face shield", + "658188edf026a90c1708c827 Name": "Built-in face shield", "658188edf026a90c1708c827 ShortName": "PSh-97 FS", "658188edf026a90c1708c827 Description": "A scratch-proof face shield for the PSh-97 riot helmet.", - "65818e4e566d2de69901b1b1 Name": "ShPM firefighter helmet built-in face shield", + "65818e4e566d2de69901b1b1 Name": "Built-in face shield", "65818e4e566d2de69901b1b1 ShortName": "ShPM FS", "65818e4e566d2de69901b1b1 Description": "A built-in heatproof face shield for the ShPM firefighter helmet, designed to protect the user's face from fire and heat.", "6581998038c79576a2569e11 Name": "Unity Credit Bank cash register key", @@ -12110,18 +12179,84 @@ "6582e6d7b14c3f72eb071420 Name": "PMC body", "6582e6d7b14c3f72eb071420 ShortName": "PMC body", "6582e6d7b14c3f72eb071420 Description": "PMC body", - "658420d8085fea07e674cdb6 Name": "Dead civilian", - "658420d8085fea07e674cdb6 ShortName": "", - "658420d8085fea07e674cdb6 Description": "", + "658420d8085fea07e674cdb6 Name": "Civilian body", + "658420d8085fea07e674cdb6 ShortName": "Civilian body", + "658420d8085fea07e674cdb6 Description": "Civilian body", "65ca457b4aafb5d7fc0dcb5d Name": "United Cutlery M48 Tactical Kukri", "65ca457b4aafb5d7fc0dcb5d ShortName": "M48 Kukri", "65ca457b4aafb5d7fc0dcb5d Description": "A 48 series tactical kukri manufactured by United Cutlery. Features a stainless steel blade and rubberized handle. A great addition to every survivalist's arsenal!", "65ddcc9cfa85b9f17d0dfb07 Name": "Mark of The Unheard", "65ddcc9cfa85b9f17d0dfb07 ShortName": "Unheard", - "65ddcc9cfa85b9f17d0dfb07 Description": "A radio transmitter reconfigured by unknown assailants. It's impossible to determine the modification technology, nor is it likely to figure out what kind of signal it's transmitting. When the user is in the area of low intensity combat zone (PVE) the user of the device becomes visible in Fence's agent network. However, using this device, you have to follow his rules. Fence pays half of the money spent in the raid and coordinates the Scavs when searching for the user's lost equipment. If trusted enough by Fence, the user will not be attacked by Scavs as long as they keep their distance and show no aggression. In return, Fence requires to minimize damage to Scavs, and if the death of a Scav could not be avoided - to reduce the number of interference with his activities in the face of other PMCs in the area of the incident.", + "65ddcc9cfa85b9f17d0dfb07 Description": "A radio transmitter reconfigured by unknown assailants. It's impossible to determine the modification technology, nor is it likely to figure out what kind of signal it's transmitting. When in the area of low intensity combat zone (PvE), the user of the device becomes visible in Fence's agent network. However, using this device, you have to follow his rules. Fence pays half of the money spent in the raid and coordinates the Scavs when searching for the user's lost equipment. If trusted enough by Fence, the user will not be attacked by Scavs as long as they keep their distance and show no aggression. In return, Fence requires to minimize damage to Scavs, and if the death of a Scav could not be avoided - to reduce the number of interference with his activities in the face of other PMCs in the area of the incident.", "65e080be269cbd5c5005e529 Name": "", "65e080be269cbd5c5005e529 ShortName": "", "65e080be269cbd5c5005e529 Description": "", + "65e5957613227bb7690ce9f6 Name": "", + "65e5957613227bb7690ce9f6 ShortName": "", + "65e5957613227bb7690ce9f6 Description": "", + "65e597266017f07a3204b775 Name": "", + "65e597266017f07a3204b775 ShortName": "", + "65e597266017f07a3204b775 Description": "", + "65e5972a13227bb7690cea07 Name": "", + "65e5972a13227bb7690cea07 ShortName": "", + "65e5972a13227bb7690cea07 Description": "", + "65f05b9d39dab9e9ec049cfd Name": "KOMZ Rusak reflex sight", + "65f05b9d39dab9e9ec049cfd ShortName": "Rusak", + "65f05b9d39dab9e9ec049cfd Description": "A collimator sight manufactured by Kazan Optical-Mechanical Plant in the mid-90s for use on hunting weapons. Installed on the Dovetail type rail, adjustment only possible after full disassembly. Heavy, uncomfortable, foggy sight with horrible parallax - a real product of its time. However, it's still slightly more effective than shooting with iron sights.", + "65f064eec4da400cbb0dc1fe Name": "M700 Badger Ordnance Scope Rail", + "65f064eec4da400cbb0dc1fe ShortName": "M700 SR", + "65f064eec4da400cbb0dc1fe Description": "A universal rail for mounting various sights on the Remington Model 700. Manufactured by Badger Ordnance.", + "65f1b1176dbd6c5ba2082eed Name": "RS Regulate AK-303M Full Length Lower dovetail mount", + "65f1b1176dbd6c5ba2082eed ShortName": "AK-303M", + "65f1b1176dbd6c5ba2082eed Description": "The AK-303M side platform is designed as a base for mounting RS Regulate top mounts on AK assault rifles and their variants: Saiga, SVD, and others. Manufactured by RS Regulate.", + "65f1b2a5c14a07890801fc70 Name": "RS Regulate AKR top mount", + "65f1b2a5c14a07890801fc70 ShortName": "AKR", + "65f1b2a5c14a07890801fc70 Description": "The AKR 1913 Railed 0 MOA Mount, installed on the AK-303M Lower Mount. Manufactured by RS Regulate.", + "65fb023261d5829b2d090755 Name": "U.S. Ordnance M60E4 7.62x51 light machine gun", + "65fb023261d5829b2d090755 ShortName": "Mk 43 Mod 1", + "65fb023261d5829b2d090755 Description": "The M60E4 (Mk 43 Mod 1) is a 7.62x51 caliber light machine gun, a modification of the M60E3 with a more reliable trigger mechanism, ability to attach optics, and a number of other improvements. The M60 was nicknamed \"The Pig\" due to its bulky size and design flaws. Despite its disadvantages, variants of the M60 are still used in some military units. Manufactured by U.S. Ordnance.", + "6601257f1347bc1a5f0f4db6 Name": "M60E4 trigger group", + "6601257f1347bc1a5f0f4db6 ShortName": "E4 TG", + "6601257f1347bc1a5f0f4db6 Description": "A trigger group for the M60E4 machine gun with an adapter that allows the installation of pistol grips from the M60. Manufactured by U.S. Ordnance.", + "660125bf1d087a96c60a54db Name": "M60E4 pistol grip", + "660125bf1d087a96c60a54db ShortName": "E4 PG", + "660125bf1d087a96c60a54db Description": "A standard-issue pistol grip for the M60E4 light machine gun. Manufactured by U.S Ordnance.", + "660126161347bc1a5f0f4dba Name": "M60E4 buttstock", + "660126161347bc1a5f0f4dba ShortName": "E4 BS", + "660126161347bc1a5f0f4dba Description": "A lightweight buttstock for the M60E4 light machine gun with articulated shoulder rest and improved buffer mounting mechanism. Manufactured by U.S. Ordnance.", + "6601265f98a610c1aa0ea637 Name": "M60 rear sight", + "6601265f98a610c1aa0ea637 ShortName": "M60 RS", + "6601265f98a610c1aa0ea637 Description": "A standard-issue foldable rear sight for the M60 machine gun. Manufactured by U.S Ordnance.", + "6601268bc752a02bbe05e686 Name": "M60E4 front sight", + "6601268bc752a02bbe05e686 ShortName": "E4 FS", + "6601268bc752a02bbe05e686 Description": "A standard-issue fixed front sight for the M60E4 light machine gun, installed on the barrel. Manufactured by U.S Ordnance.", + "660126a98f2b23af220b27e7 Name": "M60E6 front sight rail", + "660126a98f2b23af220b27e7 ShortName": "E6 FS", + "660126a98f2b23af220b27e7 Description": "A small front sight rail for the M60E6 light machine gun. Manufactured by U.S Ordnance.", + "660126f7c752a02bbe05e688 Name": "M60E4 7.62x51 458mm barrel", + "660126f7c752a02bbe05e688 ShortName": "E4 458mm", + "660126f7c752a02bbe05e688 Description": "A 458mm short barrel for the M60E4 light machine gun. Manufactured by U.S Ordnance.", + "66012788c752a02bbe05e68e Name": "M60E4 7.62x51 475mm heavy barrel", + "66012788c752a02bbe05e68e ShortName": "E4 475mm", + "66012788c752a02bbe05e68e Description": "A heavy fluted 475mm barrel for the M60E4 light machine gun. Manufactured by U.S Ordnance.", + "6601279cc752a02bbe05e692 Name": "M60E3 7.62x51 584mm barrel", + "6601279cc752a02bbe05e692 ShortName": "E3 584mm", + "6601279cc752a02bbe05e692 Description": "A long 584mm barrel for the M60E3 light machine gun. Manufactured by U.S Ordnance.", + "6601281fc752a02bbe05e696 Name": "M60E3 7.62x51 flash hider", + "6601281fc752a02bbe05e696 ShortName": "M60E3", + "6601281fc752a02bbe05e696 Description": "A standard-issue flash hider for the M60E3 light machine gun. Manufactured by U.S Ordnance.", + "66012a1d3dff5074ed002e2a Name": "M60E6 7.62x51 flash hider", + "66012a1d3dff5074ed002e2a ShortName": "M60E6", + "66012a1d3dff5074ed002e2a Description": "A standard-issue flash hider for the M60E6 light machine gun. Manufactured by U.S Ordnance.", + "66012d003dff5074ed002e2c Name": "M60E6 handguard", + "66012d003dff5074ed002e2c ShortName": "M60E6", + "66012d003dff5074ed002e2c Description": "A standard-issue railed handguard for the M60E6 light machine gun. Manufactured by U.S Ordnance.", + "66012d64c752a02bbe05e69b Name": "M60E4 Mod 1 handguard", + "66012d64c752a02bbe05e69b ShortName": "E4 Mod 1", + "66012d64c752a02bbe05e69b Description": "An aluminium railed handguard for the M60E4 Mod 1 light machine gun. Manufactured by U.S Ordnance.", + "66012d9a3dff5074ed002e33 Name": "M60 bipod", + "66012d9a3dff5074ed002e33 ShortName": "M60", + "66012d9a3dff5074ed002e33 Description": "A standard-issue bipod for the M60 machine gun. Manufactured by U.S Ordnance.", "66015072e9f84d5680039678 Name": "20x1mm toy gun", "66015072e9f84d5680039678 ShortName": "Blicky", "66015072e9f84d5680039678 Description": "A plastic semi-automatic toy gun firing 20x1mm disks. Designed for children over 5 years old. Manufactured in the USSR.", @@ -12206,6 +12341,9 @@ "660bc341c38b837877075e4c Name": "Documents with decrypted data", "660bc341c38b837877075e4c ShortName": "Documents", "660bc341c38b837877075e4c Description": "A stack of documents containing TerraGroup's classified data. Looks suspicious.", + "660ea4453786cc0af808a1be Name": "M60 7.62x51 Capco 100-round Assault Box", + "660ea4453786cc0af808a1be ShortName": "Assault Box", + "660ea4453786cc0af808a1be Description": "A 100-round 7.62x51 hard plastic ammo box for the M60 machine gun. Manufactured by Capco.", "6614217b6d9d5abcad0ff098 Name": "The Unheard's phone", "6614217b6d9d5abcad0ff098 ShortName": "Unheard", "6614217b6d9d5abcad0ff098 Description": "A phone from one of the most popular manufacturers. Belonged to The Unheard.", @@ -12221,183 +12359,264 @@ "6614238e0d240a5f5d0f679d Name": "Skier and Peacekeeper correspondence", "6614238e0d240a5f5d0f679d ShortName": "Letter", "6614238e0d240a5f5d0f679d Description": "One of the letters exchanged between Skier and Peacekeeper.", + "6615202b96461aa8360271eb Name": "M60E6 buttstock", + "6615202b96461aa8360271eb ShortName": "E6 BS", + "6615202b96461aa8360271eb Description": "A lightweight buttstock for the M60E6 light machine gun with articulated shoulder rest and improved buffer mounting mechanism. Manufactured by U.S. Ordnance.", + "66152060a031cbb5570e3466 Name": "M60E6 pistol grip", + "66152060a031cbb5570e3466 ShortName": "E6 PG", + "66152060a031cbb5570e3466 Description": "A standard-issue lightweight pistol grip for the M60E6 light machine gun. Manufactured by U.S Ordnance.", + "6615208aa031cbb5570e346a Name": "M60E6 trigger group", + "6615208aa031cbb5570e346a ShortName": "E6 TG", + "6615208aa031cbb5570e346a Description": "A trigger group for the M60E6 machine gun with an adapter that allows the installation of pistol grips from the M60. Manufactured by U.S. Ordnance.", + "661520fb6f8e1a96340afaa6 Name": "M60E6 buttstock (FDE)", + "661520fb6f8e1a96340afaa6 ShortName": "E6 BS", + "661520fb6f8e1a96340afaa6 Description": "A lightweight buttstock for the M60E6 light machine gun with articulated shoulder rest and improved buffer mounting mechanism. Manufactured by U.S. Ordnance. Flat Dark Earth version.", + "6615211ca031cbb5570e346d Name": "M60E6 pistol grip (FDE)", + "6615211ca031cbb5570e346d ShortName": "E6 PG", + "6615211ca031cbb5570e346d Description": "A standard-issue lightweight pistol grip for the M60E6 light machine gun. Manufactured by U.S Ordnance. Flat Dark Earth version.", + "66152153a031cbb5570e346f Name": "M60E6 trigger group (FDE)", + "66152153a031cbb5570e346f ShortName": "E6 TG", + "66152153a031cbb5570e346f Description": "A trigger group for the M60E6 machine gun with an adapter that allows the installation of pistol grips from the M60. Manufactured by U.S. Ordnance. Flat Dark Earth version.", "661666458c2aa9cb1602503b Name": "Hard drive", "661666458c2aa9cb1602503b ShortName": "HDD", "661666458c2aa9cb1602503b Description": "An unremarkable hard drive. Contains technical documentation on TerraGroup software development by Troikin A. P.", + "661ceb1b9311543c7104149b Name": "U.S. Ordnance M60E6 7.62x51 light machine gun", + "661ceb1b9311543c7104149b ShortName": "M60E6", + "661ceb1b9311543c7104149b Description": "The M60E6 is a 7.62x51 caliber light machine gun, a lightweight modification of the M60E4. The M60 was nicknamed \"The Pig\" due to its bulky size and design flaws. Despite its disadvantages, variants of the M60 are still used in some military units. Manufactured by U.S. Ordnance.", + "661cec09b2c6356b4d0c7a36 Name": "U.S. Ordnance M60E6 7.62x51 light machine gun (FDE)", + "661cec09b2c6356b4d0c7a36 ShortName": "M60E6", + "661cec09b2c6356b4d0c7a36 Description": "The M60E6 is a 7.62x51 caliber light machine gun, a lightweight modification of the M60E4. The M60 was nicknamed \"The Pig\" due to its bulky size and design flaws. Despite its disadvantages, variants of the M60 are still used in some military units. Manufactured by U.S. Ordnance. Flat Dark Earth version.", + "661e52415be02310ed07a07a Name": "TangoDown Stubby BGV-QDK foregrip (Black)", + "661e52415be02310ed07a07a ShortName": "BGV-QDK", + "661e52415be02310ed07a07a Description": "The Stubby BGV-QDK is a short grip for use with weapons in close and extra close quarters combat. Сontains a compartment for batteries or small items. Manufactured by TangoDown. Black version.", + "661e52b5b099f32c28003586 Name": "TangoDown Stubby BGV-QDK foregrip (FDE)", + "661e52b5b099f32c28003586 ShortName": "BGV-QDK", + "661e52b5b099f32c28003586 Description": "The Stubby BGV-QDK is a short grip for use with weapons in close and extra close quarters combat. Сontains a compartment for batteries or small items. Manufactured by TangoDown. Flat Dark Earth version.", + "661e52e29c8b4dadef008577 Name": "TangoDown BGV-QDITI foregrip (Black)", + "661e52e29c8b4dadef008577 ShortName": "BGV-QDITI", + "661e52e29c8b4dadef008577 Description": "The BGV-QDITI vertical grip with a compartment for batteries or small items. Manufactured by TangoDown. Black version.", + "661e53149c8b4dadef008579 Name": "TangoDown BGV-QDITI foregrip (FDE)", + "661e53149c8b4dadef008579 ShortName": "BGV-QDITI", + "661e53149c8b4dadef008579 Description": "The BGV-QDITI vertical grip with a compartment for batteries or small items. Manufactured by TangoDown. Flat Dark Earth version.", + "661f8995c341ea101e0d33e8 Name": "PM PM-Laser grip with laser sight", + "661f8995c341ea101e0d33e8 ShortName": "PM-L", + "661f8995c341ea101e0d33e8 Description": "A Makarov Pistol grip with built-in magazine release mechanism and laser designator. Manufactured by PM-Laser.", + "661fbe066751ee51930b01f2 Name": "M60E4 Mod 1 handguard (FDE)", + "661fbe066751ee51930b01f2 ShortName": "E4 Mod 1", + "661fbe066751ee51930b01f2 Description": "An aluminium railed handguard for the M60E4 Mod 1 light machine gun. Manufactured by U.S Ordnance. Flat Dark Earth version.", + "6621455e3aceea9e2b0b01e7 Name": "AR-15 DoubleStar Carlson Tac Comp 5.56x45 compensator", + "6621455e3aceea9e2b0b01e7 ShortName": "CC450 556", + "6621455e3aceea9e2b0b01e7 Description": "The Carlson Tac Comp compensator designed for AR-15 and compatible systems. Reduces recoil impulse and muzzle rise. Ideal for short barrel weapons. Manufactured by DoubleStar.", + "66225d88a1c7e3b81600c76f Name": "M60E6 7.62x51 458mm barrel", + "66225d88a1c7e3b81600c76f ShortName": "E6 458mm", + "66225d88a1c7e3b81600c76f Description": "A 458mm short barrel for the M60E6 light machine gun. Manufactured by U.S Ordnance.", "66265d7be65f224b2e17c6aa Name": "USEC cottage room key", "66265d7be65f224b2e17c6aa ShortName": "USEC cott.", "66265d7be65f224b2e17c6aa Description": "A key to one of the rooms in the cottages of former USEC operatives.", "6638a5474e92f038531e210e Name": "Mr Kerman's cat hologram", "6638a5474e92f038531e210e ShortName": "Mr Kerman", "6638a5474e92f038531e210e Description": "Greetings from Mr. Kerman.", + "6642f63667f5cb56a00662eb Name": "AR-10 Delta-Tek DTK-AR10 7.62x51 muzzle brake", + "6642f63667f5cb56a00662eb ShortName": "DTK-AR10", + "6642f63667f5cb56a00662eb Description": "The DTK-AR10 muzzle brake, designed for AR-10 and compatible systems. Greatly reduces recoil and muzzle rise due to the special compensation chamber. Manufactured by Delta-Tek.", + "664301213dd83ddae20dda18 Name": "AR-15 Delta-Tek DTK-M16 5.56x45 muzzle brake", + "664301213dd83ddae20dda18 ShortName": "DTK-M16", + "664301213dd83ddae20dda18 Description": "The DTK-M16 muzzle brake, designed for AR-15 and compatible systems. Greatly reduces recoil and muzzle rise due to the special compensation chamber. Manufactured by Delta-Tek.", + "6644920d49817dc7d505ca71 Name": "BT10 V8 Atlas Bipod", + "6644920d49817dc7d505ca71 ShortName": "BT10", + "6644920d49817dc7d505ca71 Description": "The Atlas V8 series BT10 bipod. Lightweight, foldable, adjustable. Manufactured by B&T Industries L.L.C.", + "6644d2da35d958070c02642c Name": "", + "6644d2da35d958070c02642c ShortName": "", + "6644d2da35d958070c02642c Description": "", + "6644d2ffd85107e63500a61c Name": "", + "6644d2ffd85107e63500a61c ShortName": "", + "6644d2ffd85107e63500a61c Description": "", + "6644d32235d958070c02642e Name": "Default mannequin lower", + "6644d32235d958070c02642e ShortName": "", + "6644d32235d958070c02642e Description": "", "664a5428d5e33a713b622379 Name": "APOK Tactical Wasteland Gladius", "664a5428d5e33a713b622379 ShortName": "TWG", - "664a5428d5e33a713b622379 Description": "\"Tactical Wasteland Gladius\" Tactical sword. Manufactured by APOK. Arena champion's prime melee weapon. Rumors are that this is the exact blade that gladiator Voron used to fight with. Or at least it looks like one.", - "664a5480bfcc521bad3192ca Name": "ARENA armband", + "664a5428d5e33a713b622379 Description": "The Tactical Wasteland Gladius sword, manufactured by APOK. Arena champion's prime melee weapon. Rumors are that this is the exact blade that the gladiator Voron used to fight with. Or at least it looks like one.", + "664a5480bfcc521bad3192ca Name": "Armband (ARENA)", "664a5480bfcc521bad3192ca ShortName": "ARENA", - "664a5480bfcc521bad3192ca Description": "Armband given by the Host. The mark of Tarkov Arena champion.", - "664a55d84a90fc2c8a6305c9 Name": "\"Theta\" Secure container", + "664a5480bfcc521bad3192ca Description": "Armband given by Ref. The mark of the Tarkov Arena champion.", + "664a55d84a90fc2c8a6305c9 Name": "Secure container Theta", "664a55d84a90fc2c8a6305c9 ShortName": "Theta", "664a55d84a90fc2c8a6305c9 Description": "A unique secure container available only for Tarkov Arena champions.", - "664a5775f3d3570fba06be64 Name": "Bison VS Undertaker poster pack.", - "664a5775f3d3570fba06be64 ShortName": "Arena posters", + "664a5775f3d3570fba06be64 Name": "Bison VS Undertaker poster pack", + "664a5775f3d3570fba06be64 ShortName": "Posters", "664a5775f3d3570fba06be64 Description": "A large pack of posters advertising the Arena supposed to be stashed on Customs.", - "664b69c5a082271bc46c4e11 Name": "A pack of Killa and Tagilla posters.", - "664b69c5a082271bc46c4e11 ShortName": "Arena posters", - "664b69c5a082271bc46c4e11 Description": "A large pack of posters advertising the Arena supposed to be stashed on Reserve.\n", - "664b69e8e1238e506d3630af Name": "A pack of 'Easy money on betting' posters", + "664b69c5a082271bc46c4e11 Name": "Killa and Tagilla poster pack", + "664b69c5a082271bc46c4e11 ShortName": "Posters", + "664b69c5a082271bc46c4e11 Description": "A large pack of posters advertising the Arena supposed to be stashed on Reserve.", + "664b69e8e1238e506d3630af Name": "Easy Money poster pack", "664b69e8e1238e506d3630af ShortName": "Arena posters", - "664b69e8e1238e506d3630af Description": "A large pack of Arena posters supposed to be stashed at the Lighthouse.\n", - "664b69f3a082271bc46c4e13 Name": "quest_flyers4", - "664b69f3a082271bc46c4e13 ShortName": "", - "664b69f3a082271bc46c4e13 Description": "", - "664d3db6db5dea2bad286955 Name": "Shatun's hideout", + "664b69e8e1238e506d3630af Description": "A large pack of Arena posters supposed to be stashed on Lighthouse.", + "664b69f3a082271bc46c4e13 Name": "Easy Money poster pack", + "664b69f3a082271bc46c4e13 ShortName": "Posters", + "664b69f3a082271bc46c4e13 Description": "A large pack of Arena posters supposed to be stashed on Woods.", + "664d3db6db5dea2bad286955 Name": "Shatun's hideout key", "664d3db6db5dea2bad286955 ShortName": "Shatun", - "664d3db6db5dea2bad286955 Description": "A key that unlocks a door to one of the village houses located somewhere in Priozersk natural reserve. Belonged to one of Arena gladiators by the name \"Shatun\"", + "664d3db6db5dea2bad286955 Description": "A key that unlocks a door to one of the village houses located somewhere in Priozersk natural reserve. Belonged to one of the Arena gladiators by the name \"Shatun\".", "664d3dd590294949fe2d81b7 Name": "Grumpy's hideout key", "664d3dd590294949fe2d81b7 ShortName": "Grumpy", - "664d3dd590294949fe2d81b7 Description": "A key that unlocks a room located in Fossil Powerplant next to Ultra mall. Belonged to one of the Arena gladiators by the name \"Grumpy\"", + "664d3dd590294949fe2d81b7 Description": "A key that unlocks the room located at the power station next to the ULTRA mall. Belonged to one of the Arena gladiators by the name \"Grumpy\".", "664d3ddfdda2e85aca370d75 Name": "Voron's hideout key", "664d3ddfdda2e85aca370d75 ShortName": "Voron", - "664d3ddfdda2e85aca370d75 Description": "A key that opens a room located somewhere near the health resort. Belonged to one of Arena gladiators by the name \"Voron\".", + "664d3ddfdda2e85aca370d75 Description": "A key that opens the room located somewhere near the Health Resort. Belonged to one of the Arena gladiators by the name \"Voron\".", "664d3de85f2355673b09aed5 Name": "Leon's hideout key", "664d3de85f2355673b09aed5 ShortName": "Leon", - "664d3de85f2355673b09aed5 Description": "A key to the room in a big house next to the bridge that leads to water treatment facility. Belonged to one of Arena gladiators by the name \"Leon\".", + "664d3de85f2355673b09aed5 Description": "A key to the room in the big house next to the bridge that leads to the water treatment plant. Belonged to one of Arena gladiators by the name \"Leon\".", "664d4b0103ef2c61246afb56 Name": "Dorm overseer key", - "664d4b0103ef2c61246afb56 ShortName": "Dorm over.", - "664d4b0103ef2c61246afb56 Description": "A key to the three-story dormitory with a tag reading \"Dorm overseer\" on it. Appears to be extremely fragile, one-two uses and the key will break apart.", - "664fce7a90294949fe2d81cb Name": "Compromising information on Ref", - "664fce7a90294949fe2d81cb ShortName": "Comprom", + "664d4b0103ef2c61246afb56 ShortName": "Overseer", + "664d4b0103ef2c61246afb56 Description": "A key to the three-story dormitory with a tag reading \"Overseer\" on it. Appears to be extremely fragile, one-two uses and the key will break apart.", + "664fce7a90294949fe2d81cb Name": "Ref dirt", + "664fce7a90294949fe2d81cb ShortName": "Dirt", "664fce7a90294949fe2d81cb Description": "A folder of photos, charts, bank records, e-mail printouts and surveillance diaries of Arena employees.", "66507eabf5ddb0818b085b68 Name": "2A2-(b-TG) stimulant injector", "66507eabf5ddb0818b085b68 ShortName": "2A2-(b-TG)", "66507eabf5ddb0818b085b68 Description": "TerraGroup's next development after the 3-(b-TG) stimulant. The goal of the project was to obtain a drug that would give an advantage in reconnaissance and crossing combat zones far away from supply points. At the same time, the drug is required to be manufacturable in handicraft conditions. The obtained substance allows to keep the CNS in tone for a long period of time, which positively affects the fighter's efficiency to assess the environment, and also enhances their ability to carry equipment. The stimulant’s effective duration is accompanied by increased loss of hydration.", - "6656560053eaaa7a23349c86 Name": "\"Lega\" Medal", + "6655e35b6bc645cb7b059912 Name": "\"The Eye\" mortar strike signaling device", + "6655e35b6bc645cb7b059912 ShortName": "\"The Eye\"", + "6655e35b6bc645cb7b059912 Description": "A special device that utilizes a whole network of detectors, communication systems and satellites. Mechanic built it from the blueprints of a certain someone named Mr. Kerman. Although the device doesn't allow you to connect to digital maps of the area, it can warn you of an impending mortar attack.", + "6656560053eaaa7a23349c86 Name": "Lega Medal", "6656560053eaaa7a23349c86 ShortName": "Lega", - "6656560053eaaa7a23349c86 Description": "A medal with Legendary kill mark. Extremely rare reward for Arena gladiators, which can be earned by winning Arena match or by completing Host's challenges", - "66571bf06a723f7f005a0619 Name": "Locked equipment сrate (Rare)", + "6656560053eaaa7a23349c86 Description": "A medal with the Legendary Kill mark. An extremely rare reward for Arena gladiators, which can be earned by completing Ref's hardest challenges.", + "66571bf06a723f7f005a0619 Name": "Locked equipment crate (Rare)", "66571bf06a723f7f005a0619 ShortName": "Equipment (Rare)", "66571bf06a723f7f005a0619 Description": "A trophy for participating in Arena battles. It contains various equipment to help you survive and kill in the harsh world of Tarkov. But first, you need to find a way to open this box.", - "66572b3f6a723f7f005a066c Name": "Locked weapon сrate (Rare)", + "66572b3f6a723f7f005a066c Name": "Locked weapon crate (Rare)", "66572b3f6a723f7f005a066c ShortName": "Weapons (Rare)", "66572b3f6a723f7f005a066c Description": "A trophy for participating in Arena battles. Contains ammunition, weapon mods, or even weapons if you're lucky. Everything you need to make your enemies respect you. But first, you need to find a way to open this box.", - "66572b88ac60f009f270d1dc Name": "Locked supply сrate (Rare)", + "66572b88ac60f009f270d1dc Name": "Locked supply crate (Rare)", "66572b88ac60f009f270d1dc ShortName": "Supplies (Rare)", "66572b88ac60f009f270d1dc Description": "A trophy for participating in Arena battles. Outside the border, the contents of this box can hardly be considered valuable. However, Tarkov has its own notions of value. But first, you need to find a way to open this box.", "66572b8d80b1cd4b6a67847f Name": "Den figurine", "66572b8d80b1cd4b6a67847f ShortName": "Den", "66572b8d80b1cd4b6a67847f Description": "A limited edition Tarko figurine of a BEAR PMC operator and Ryzhy's battle buddy. Despite all the hardships, his beard looks surprisingly neat.", - "66572bb3ac60f009f270d1df Name": "Locked valuables сrate (Rare)", + "66572bb3ac60f009f270d1df Name": "Locked valuables crate (Rare)", "66572bb3ac60f009f270d1df ShortName": "Valuables (Rare)", "66572bb3ac60f009f270d1df Description": "A trophy for participating in Arena battles. Unlike cash, barter will always be viable, and the contents of this box may be more valuable than a few packs of crunchy paper. But first, you need to find a way to open this box.", "66572be36a723f7f005a066e Name": "Reshala figurine", "66572be36a723f7f005a066e ShortName": "Reshala", - "66572be36a723f7f005a066e Description": "The Tarko collectible figure of Reshala. The unknown craftsman was impressed with the coolness of Reshala and his gang and created this figurine.", + "66572be36a723f7f005a066e Description": "A limited edition Tarko figurine. A lover of expensive watches and golden handguns. Knows how to roundhouse kick. All bark and no bite.", "66572c82ad599021091c6118 Name": "Killa figurine", "66572c82ad599021091c6118 ShortName": "Killa", "66572c82ad599021091c6118 Description": "A limited edition Tarko figurine. Killa loves hardbass, three stripes and is waiting to meet you at the mall. Tarko's swaggiest figure, and whoever said otherwise, has been missing ever since. The figurine is rumored to be made of the same material as his helmet.", "66572cbdad599021091c611a Name": "Tagilla figurine", "66572cbdad599021091c611a ShortName": "Tagilla", "66572cbdad599021091c611a Description": "A limited edition Tarko figurine. As a child, Tagilla fell into a tub of protein. His welding mask protects him not only from bullets, but also from blood spatter. Many parts of the Polikhim factory are rumored to be forged with his hammer.", - "665730fa4de4820934746c48 Name": "Unlocked equipment сrate (Rare)", + "665730fa4de4820934746c48 Name": "Unlocked equipment crate (Rare)", "665730fa4de4820934746c48 ShortName": "Equipment (Rare)", "665730fa4de4820934746c48 Description": "A trophy for participating in Arena battles. It contains various equipment to help you survive and kill in the harsh world of Tarkov. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "665732e7ac60f009f270d1ef Name": "Unlocked weapon сrate (Rare)", + "665732e7ac60f009f270d1ef Name": "Unlocked weapon crate (Rare)", "665732e7ac60f009f270d1ef ShortName": "Weapons (Rare)", "665732e7ac60f009f270d1ef Description": "A trophy for participating in Arena battles. Contains ammunition, weapon mods, or even weapons if you're lucky. Everything you need to make your enemies respect you. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "665732f4464c4b4ba4670fa9 Name": "Unlocked supply сrate (Rare)", + "665732f4464c4b4ba4670fa9 Name": "Unlocked supply crate (Rare)", "665732f4464c4b4ba4670fa9 ShortName": "Supplies (Rare)", "665732f4464c4b4ba4670fa9 Description": "A trophy for participating in Arena battles. Outside the border, the contents of this box can hardly be considered valuable. However, Tarkov has its own notions of value. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "66573310a1657263d816a139 Name": "Unlocked valuables сrate (Rare)", + "66573310a1657263d816a139 Name": "Unlocked valuables crate (Rare)", "66573310a1657263d816a139 ShortName": "Valuables (Rare)", "66573310a1657263d816a139 Description": "A trophy for participating in Arena battles. Unlike cash, barter will always be viable, and the contents of this box may be more valuable than a few packs of crunchy paper. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "6658285190486915542256c4 Name": "Locked equipment сrate (Epic)", + "665745c8a3c672c7b00bb355 Name": "", + "665745c8a3c672c7b00bb355 ShortName": "", + "665745c8a3c672c7b00bb355 Description": "", + "6658285190486915542256c4 Name": "Locked equipment crate (Epic)", "6658285190486915542256c4 ShortName": "Equipment (Epic)", "6658285190486915542256c4 Description": "A trophy for participating in Arena battles. It contains various equipment to help you survive and kill in the harsh world of Tarkov. But first, you need to find a way to open this box.", - "66582889efd94e2d665b14a2 Name": "Locked weapon сrate (Epic)", + "66582889efd94e2d665b14a2 Name": "Locked weapon crate (Epic)", "66582889efd94e2d665b14a2 ShortName": "Weapons (Epic)", "66582889efd94e2d665b14a2 Description": "A trophy for participating in Arena battles. Contains ammunition, weapon mods, or even weapons if you're lucky. Everything you need to make your enemies respect you. But first, you need to find a way to open this box.", - "665828c44de4820934746ce4 Name": "Locked supply сrate (Epic)", + "665828c44de4820934746ce4 Name": "Locked supply crate (Epic)", "665828c44de4820934746ce4 ShortName": "Supplies (Epic)", "665828c44de4820934746ce4 Description": "A trophy for participating in Arena battles. Outside the border, the contents of this box can hardly be considered valuable. However, Tarkov has its own notions of value. But first, you need to find a way to open this box.", - "665828f490486915542256c6 Name": "Locked valuables сrate (Epic)", + "665828f490486915542256c6 Name": "Locked valuables crate (Epic)", "665828f490486915542256c6 ShortName": "Valuables (Epic)", "665828f490486915542256c6 Description": "A trophy for participating in Arena battles. Unlike cash, barter will always be viable, and the contents of this box may be more valuable than a few packs of crunchy paper. But first, you need to find a way to open this box.", - "6658291eefd94e2d665b14a4 Name": "Unlocked equipment сrate (Epic)", + "6658291eefd94e2d665b14a4 Name": "Unlocked equipment crate (Epic)", "6658291eefd94e2d665b14a4 ShortName": "Equipment (Epic)", "6658291eefd94e2d665b14a4 Description": "A trophy for participating in Arena battles. It contains various equipment to help you survive and kill in the harsh world of Tarkov. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "665829424de4820934746ce6 Name": "Unlocked weapon сrate (Epic)", + "665829424de4820934746ce6 Name": "Unlocked weapon crate (Epic)", "665829424de4820934746ce6 ShortName": "Weapons (Epic)", "665829424de4820934746ce6 Description": "A trophy for participating in Arena battles. Contains ammunition, weapon mods, or even weapons if you're lucky. Everything you need to make your enemies respect you. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "66582972ac60f009f270d2aa Name": "Unlocked supply сrate (Epic)", + "66582972ac60f009f270d2aa Name": "Unlocked supply crate (Epic)", "66582972ac60f009f270d2aa ShortName": "Supplies (Epic)", "66582972ac60f009f270d2aa Description": "A trophy for participating in Arena battles. Outside the border, the contents of this box can hardly be considered valuable. However, Tarkov has its own notions of value. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "665829a6efd94e2d665b14a8 Name": "Unlocked valuables сrate (Epic)", + "665829a6efd94e2d665b14a8 Name": "Unlocked valuables crate (Epic)", "665829a6efd94e2d665b14a8 ShortName": "Valuables (Epic)", "665829a6efd94e2d665b14a8 Description": "A trophy for participating in Arena battles. Unlike cash, barter will always be viable, and the contents of this box may be more valuable than a few packs of crunchy paper. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "665886abdaadd1069736c539 Name": "Unlocked valuables сrate (Common)", + "665886abdaadd1069736c539 Name": "Unlocked valuables crate (Common)", "665886abdaadd1069736c539 ShortName": "Valuables (Common)", "665886abdaadd1069736c539 Description": "A trophy for participating in Arena battles. Unlike cash, barter will always be viable, and the contents of this box may be more valuable than a few packs of crunchy paper. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "6658876e146af22739040fad Name": "Unlocked equipment сrate (Common)", + "6658876e146af22739040fad Name": "Unlocked equipment crate (Common)", "6658876e146af22739040fad ShortName": "Equipment (Common)", "6658876e146af22739040fad Description": "A trophy for participating in Arena battles. It contains various equipment to help you survive and kill in the harsh world of Tarkov. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "665888282c4a1b73af576b77 Name": "Unlocked weapon сrate (Common)", + "665888282c4a1b73af576b77 Name": "Unlocked weapon crate (Common)", "665888282c4a1b73af576b77 ShortName": "Weapons (Common)", "665888282c4a1b73af576b77 Description": "A trophy for participating in Arena battles. Contains ammunition, weapon mods, or even weapons if you're lucky. Everything you need to make your enemies respect you. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "6658892e6e007c6f33662002 Name": "Unlocked supply сrate (Common)", + "6658892e6e007c6f33662002 Name": "Unlocked supply crate (Common)", "6658892e6e007c6f33662002 ShortName": "Supplies (Common)", "6658892e6e007c6f33662002 Description": "A trophy for participating in Arena battles. Outside the border, the contents of this box can hardly be considered valuable. However, Tarkov has its own notions of value. The lock has been crudely broken, which means there are no more obstacles between you and the contents of the box.", - "66588b514de4820934746dc6 Name": "Locked equipment сrate (Common)", + "66588b514de4820934746dc6 Name": "Locked equipment crate (Common)", "66588b514de4820934746dc6 ShortName": "Equipment (Common)", "66588b514de4820934746dc6 Description": "A trophy for participating in Arena battles. It contains various equipment to help you survive and kill in the harsh world of Tarkov. But first, you need to find a way to open this box.", - "66588b6dcb48a73e674b2649 Name": "Locked weapon сrate (Common)", + "66588b6dcb48a73e674b2649 Name": "Locked weapon crate (Common)", "66588b6dcb48a73e674b2649 ShortName": "Weapons (Common)", "66588b6dcb48a73e674b2649 Description": "A trophy for participating in Arena battles. Contains ammunition, weapon mods, or even weapons if you're lucky. Everything you need to make your enemies respect you. But first, you need to find a way to open this box.", - "66588ba291f6e93c4c06efef Name": "Locked supply сrate (Common)", + "66588ba291f6e93c4c06efef Name": "Locked supply crate (Common)", "66588ba291f6e93c4c06efef ShortName": "Supplies (Common)", "66588ba291f6e93c4c06efef Description": "A trophy for participating in Arena battles. Outside the border, the contents of this box can hardly be considered valuable. However, Tarkov has its own notions of value. But first, you need to find a way to open this box.", - "66588bb047fbd536a674240e Name": "Locked valuables сrate (Common)", + "66588bb047fbd536a674240e Name": "Locked valuables crate (Common)", "66588bb047fbd536a674240e ShortName": "Valuables (Common)", "66588bb047fbd536a674240e Description": "A trophy for participating in Arena battles. Unlike cash, barter will always be viable, and the contents of this box may be more valuable than a few packs of crunchy paper. But first, you need to find a way to open this box.", "66589a1547fbd536a674249a Name": "USEC Range Specialist", - "66589a1547fbd536a674249a ShortName": "Range Specialist", - "66589a1547fbd536a674249a Description": "", + "66589a1547fbd536a674249a ShortName": "", + "66589a1547fbd536a674249a Description": "Polo shirt", "66589baadaadd1069736c54c Name": "USEC Practical", - "66589baadaadd1069736c54c ShortName": "Practical", - "66589baadaadd1069736c54c Description": "", + "66589baadaadd1069736c54c ShortName": "", + "66589baadaadd1069736c54c Description": "Tactical pants", "66589c2edaadd1069736c54e Name": "USEC Dead Vektor", - "66589c2edaadd1069736c54e ShortName": "Dead Vektor", - "66589c2edaadd1069736c54e Description": "", + "66589c2edaadd1069736c54e ShortName": "", + "66589c2edaadd1069736c54e Description": "T-shirt", "66589cceb00aec5c0278573c Name": "USEC Outdoor Tactical", - "66589cceb00aec5c0278573c ShortName": "Outdoor Tactical", - "66589cceb00aec5c0278573c Description": "", + "66589cceb00aec5c0278573c ShortName": "", + "66589cceb00aec5c0278573c Description": "Tactical pants", "66589eb63733207cb6677dc5 Name": "USEC Troubleshooter", - "66589eb63733207cb6677dc5 ShortName": "Troubleshooter", - "66589eb63733207cb6677dc5 Description": "", + "66589eb63733207cb6677dc5 ShortName": "", + "66589eb63733207cb6677dc5 Description": "Polo shirt", "66589ef5146af22739040fbb Name": "USEC Lowland Green", - "66589ef5146af22739040fbb ShortName": "Lowland Green", - "66589ef5146af22739040fbb Description": "", - "66589f9b2c4a1b73af576b85 Name": "BEAR White collar", - "66589f9b2c4a1b73af576b85 ShortName": "White collar", - "66589f9b2c4a1b73af576b85 Description": "", + "66589ef5146af22739040fbb ShortName": "", + "66589ef5146af22739040fbb Description": "Tactical pants", + "66589f9b2c4a1b73af576b85 Name": "BEAR White Collar", + "66589f9b2c4a1b73af576b85 ShortName": "", + "66589f9b2c4a1b73af576b85 Description": "Shirt", "6658a01e3733207cb6677dc7 Name": "BEAR Rifleman", - "6658a01e3733207cb6677dc7 ShortName": "Rifleman", - "6658a01e3733207cb6677dc7 Description": "", + "6658a01e3733207cb6677dc7 ShortName": "", + "6658a01e3733207cb6677dc7 Description": "Tactical pants", "6658a05f146af22739040fbd Name": "BEAR Polo", - "6658a05f146af22739040fbd ShortName": "Polo", - "6658a05f146af22739040fbd Description": "", - "6658a0ca4de4820934746dd2 Name": "BEAR Wastelander", - "6658a0ca4de4820934746dd2 ShortName": "Wastelander", - "6658a0ca4de4820934746dd2 Description": "", + "6658a05f146af22739040fbd ShortName": "", + "6658a05f146af22739040fbd Description": "Polo shirt", + "6658a0ca4de4820934746dd2 Name": "BEAR Wastelander", + "6658a0ca4de4820934746dd2 ShortName": "", + "6658a0ca4de4820934746dd2 Description": "Tactical pants", "6658a1466e007c6f3366200b Name": "BEAR Gladiator", - "6658a1466e007c6f3366200b ShortName": "Gladiator", - "6658a1466e007c6f3366200b Description": "", + "6658a1466e007c6f3366200b ShortName": "", + "6658a1466e007c6f3366200b Description": "T-shirt", "6658a1d54de4820934746dd4 Name": "BEAR Centurion", - "6658a1d54de4820934746dd4 ShortName": "Centurion", - "6658a1d54de4820934746dd4 Description": "", + "6658a1d54de4820934746dd4 ShortName": "", + "6658a1d54de4820934746dd4 Description": "Tactical pants", + "665d5d9e338229cfd6078da1 Name": "BCM GUNFIGHTER MOD 3 M-LOK foregrip (Black)", + "665d5d9e338229cfd6078da1 ShortName": "GF MLOK", + "665d5d9e338229cfd6078da1 Description": "A lightweight polymer tactical foregrip. Mounted on handguards with M-LOK interface. Manufactured by Bravo Company Manufacturing. Black color version.", + "665edce564fb556f940ab32a Name": "BCM GUNFIGHTER MOD 3 M-LOK foregrip (FDE)", + "665edce564fb556f940ab32a ShortName": "GF MLOK", + "665edce564fb556f940ab32a Description": "A lightweight polymer tactical foregrip. Mounted on handguards with M-LOK interface. Manufactured by Bravo Company Manufacturing. Flat Dark Earth version.", "665ee77ccf2d642e98220bca Name": "Secure container Gamma", "665ee77ccf2d642e98220bca ShortName": "Gamma", "665ee77ccf2d642e98220bca Description": "A unique secure container used only by veteran PMCs formerly deployed in Tarkov. Has a mysterious mark on the side.", + "666073159916667083033cb9 Name": "Battered diary", + "666073159916667083033cb9 ShortName": "Diary", + "666073159916667083033cb9 Description": "A small diary that had been abandoned by its owner a long time ago. The entries are barely legible due to the rough handwriting.", "6662e9aca7e0b43baa3d5f74 Name": "Dogtag BEAR", "6662e9aca7e0b43baa3d5f74 ShortName": "BEAR", "6662e9aca7e0b43baa3d5f74 Description": "Army dogtags serve the purpose of quickly identifying the wounded and deceased in combat. This one belonged to a BEAR PMC operator that went through the Tarkov hell from the very beginning.", @@ -12413,9 +12632,840 @@ "666841a02537107dc508b704 Name": "Cultist jacket", "666841a02537107dc508b704 ShortName": "", "666841a02537107dc508b704 Description": "Jacket", + "666879d498b97e3a8f09f1ae Name": "LEDX Skin Transilluminator (US Version)", + "666879d498b97e3a8f09f1ae ShortName": "LEDX US", + "666879d498b97e3a8f09f1ae Description": "You can argue endlessly that different factories of the same company provide comparable quality, but at the critical moment everyone chooses the original.... Perhaps TerraGroup had special arrangements with the American factory to supply a newer model of LEDX.", + "66687bc89111279d600b5062 Name": "Tarkov City souvenir key", + "66687bc89111279d600b5062 ShortName": "Souvenir", + "66687bc89111279d600b5062 Description": "In the old days, the symbol of power in large cities was a luxurious key the size of a hand. In Tarkov, this tradition was revived, but the key itself was made smaller. Some say that this is the reason why it was lost: someone attached the souvenir to a bunch of keys by mistake and took it away from the town day celebration.", + "666b11055a706400b717cfa5 Name": "Tripwire installation kit", + "666b11055a706400b717cfa5 ShortName": "Tripwire", + "666b11055a706400b717cfa5 Description": "An improvised booby trap kit made of tent pegs and wire with a carabiner. Allows the user to install tripwires on flat surfaces or to conceal explosives on an object.", + "66740c3739b9da6ce402ee65 Name": "", + "66740c3739b9da6ce402ee65 ShortName": "", + "66740c3739b9da6ce402ee65 Description": "", + "66760b3deb51b08bd40c2b08 Name": "Hard drive", + "66760b3deb51b08bd40c2b08 ShortName": "HDD", + "66760b3deb51b08bd40c2b08 Description": "A random access storage device (information storage device), based on the magnetic recording principle. Contains stolen user data.", + "667a8ef464eea5fdef0db135 Name": "Gaming magazine", + "667a8ef464eea5fdef0db135 ShortName": "Magazine", + "667a8ef464eea5fdef0db135 Description": "An issue of a gaming magazine that first wrote about one world-famous shooter game.", + "6680304edadb7aa61d00cef0 Name": "IWI UZI PRO Pistol 9x19 submachine gun", + "6680304edadb7aa61d00cef0 ShortName": "UZI PRO Pistol", + "6680304edadb7aa61d00cef0 Description": "The UZI PRO Pistol (UPP9S) is a fully automatic conversion of the 9x19mm Parabellum submachine gun for law enforcement and military use. This ultra-compact submachine gun is an evolution of the full-size UZI submachine gun, ideal for concealed carry and featuring a high rate of fire. Manufactured by Israel Weapon Industries.", + "668031705014e211b4078046 Name": "UZI PRO 9x19 Pike Arms 114mm threaded barrel", + "668031705014e211b4078046 ShortName": "PA 114mm", + "668031705014e211b4078046 Description": "A threaded 114mm barrel for the UZI PRO. Manufactured by Pike Arms.", + "668031bde3e7eb26e8004cd7 Name": "UZI PRO A3 Tactical M-LOK handguard", + "668031bde3e7eb26e8004cd7 ShortName": "A3 MLOK", + "668031bde3e7eb26e8004cd7 Description": "A handguard for the IWI UZI PRO Pistol, which functions as a foregrip and trigger guard. Equipped with M-LOK interface for attaching additional equipment. Manufactured by A3 Tactical.", + "668031ffe3e7eb26e8004cdd Name": "UZI PRO 9x19 20-round magazine", + "668031ffe3e7eb26e8004cdd ShortName": "UZI PRO", + "668031ffe3e7eb26e8004cdd Description": "A 20-round magazine for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "6680326874b8f2050c0b9178 Name": "UZI PRO dust cover", + "6680326874b8f2050c0b9178 ShortName": "PRO DC", + "6680326874b8f2050c0b9178 Description": "A standard dust cover with a top rail for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "668032ba74b8f2050c0b917d Name": "UZI PRO Stabilizing Brace", + "668032ba74b8f2050c0b917d ShortName": "PRO SB", + "668032ba74b8f2050c0b917d Description": "A foldable pistol brace for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "66866f4ec3d473265104f381 Name": "UZI PRO 9x19 25-round magazine", + "66866f4ec3d473265104f381 ShortName": "UZI PRO", + "66866f4ec3d473265104f381 Description": "A 25-round magazine for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "66866f622a2296a8d9099639 Name": "UZI PRO 9x19 32-round magazine", + "66866f622a2296a8d9099639 ShortName": "UZI PRO", + "66866f622a2296a8d9099639 Description": "A 32-round magazine for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "66866fe776d1a87cd80fd388 Name": "UZI PRO 9x19 114mm barrel", + "66866fe776d1a87cd80fd388 ShortName": "PRO 114mm", + "66866fe776d1a87cd80fd388 Description": "A 114mm barrel for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "6686700a2b934a68630a7fe6 Name": "UZI PRO 9x19 170mm barrel", + "6686700a2b934a68630a7fe6 ShortName": "PRO 170mm", + "6686700a2b934a68630a7fe6 Description": "A 170mm barrel for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "66867023c3d473265104f384 Name": "UZI PRO 9x19 210mm barrel", + "66867023c3d473265104f384 ShortName": "PRO 210mm", + "66867023c3d473265104f384 Description": "A 210mm barrel for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "668670432b934a68630a7fe8 Name": "UZI PRO 9x19 240mm barrel", + "668670432b934a68630a7fe8 ShortName": "PRO 240mm", + "668670432b934a68630a7fe8 Description": "A 240mm barrel for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "668670e3fb75ee4a5e02eb16 Name": "UZI PRO 9x19 barrel retaining nut", + "668670e3fb75ee4a5e02eb16 ShortName": "PRO BRN", + "668670e3fb75ee4a5e02eb16 Description": "A special nut required to install 9x19 barrels on UZI PRO. Manufactured by Israel Weapon Industries.", + "668670f52a2296a8d909963c Name": "UZI PRO 9x19 Masada thread protector", + "668670f52a2296a8d909963c ShortName": "PRO TP", + "668670f52a2296a8d909963c Description": "The Masada thread protector for UZI PRO submachine gun barrels. Manufactured by Israel Weapon Industries.", + "6686717ffb75ee4a5e02eb19 Name": "UZI PRO A3 Tactical Modular Folding Brace", + "6686717ffb75ee4a5e02eb19 ShortName": "A3 MFB", + "6686717ffb75ee4a5e02eb19 Description": "A foldable pistol brace for the UZI PRO submachine gun. Manufactured by A3 Tactical.", + "668672b8c99550c6fd0f0b29 Name": "UZI PRO A3 Tactical Rear Stock Adapter", + "668672b8c99550c6fd0f0b29 ShortName": "A3 RSA", + "668672b8c99550c6fd0f0b29 Description": "A Picatinny adapter designed for installation of various buttstocks on the UZI PRO submachine gun. Manufactured by A3 Tactical.", + "66867310f3734a938b077f79 Name": "UZI PRO SBR buttstock", + "66867310f3734a938b077f79 ShortName": "PRO SBR", + "66867310f3734a938b077f79 Description": "A foldable buttstock for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "66881008f23233ee9a0742e7 Name": "UZI PRO backplate", + "66881008f23233ee9a0742e7 ShortName": "PRO plate", + "66881008f23233ee9a0742e7 Description": "A standard-issue receiver cover plate for the UZI PRO submachine gun. Manufactured by Israel Weapon Industries.", + "668e71a8dadf42204c032ce1 Name": "IWI UZI PRO SMG 9x19 submachine gun", + "668e71a8dadf42204c032ce1 ShortName": "UZI PRO SMG", + "668e71a8dadf42204c032ce1 Description": "The UZI PRO SMG is a submachine gun for law enforcement and military use. This ultra-compact submachine gun is an evolution of the full-size UZI submachine gun, ideal for concealed carry and featuring a high rate of fire. Manufactured by Israel Weapon Industries.", + "668ea3f68117e4968b0cff4a Name": "UZI PRO SMG rail adapter", + "668ea3f68117e4968b0cff4a ShortName": "SMG RA", + "668ea3f68117e4968b0cff4a Description": "A rail adapter for the UZI PRO SMG submachine gun, allows installation of tactical equipment on the sides of the weapon. Manufactured by Israel Weapon Industries.", + "668fe5a998b5ad715703ddd6 Name": "Magnum Research Desert Eagle Mk XIX .50 AE pistol", + "668fe5a998b5ad715703ddd6 ShortName": "Desert Eagle Mk XIX", + "668fe5a998b5ad715703ddd6 Description": "Desert Eagle (Mk XIX) is the third modification of the .50 Action Express caliber sport-hunting pistol. This pistol is huge, heavy and not the most practical in operation, but at the same time it is an absolutely unique short-barreled weapon, which undoubtedly became a frequent visitor in video games for its brutal appearance and impressive size. The Desert Eagle did not win any military approval, but deservedly became one of the most famous pistols in the world. Manufactured by Magnum Research.", + "668fe5c5f35310705d02b696 Name": "Desert Eagle .50 AE 7-round magazine", + "668fe5c5f35310705d02b696 ShortName": "DE", + "668fe5c5f35310705d02b696 Description": "A standard-issue 7-round .50 AE magazine for the Desert Eagle pistol. Manufactured by Magnum Research.", + "668fe5d42a0f85eea407cc16 Name": "Desert Eagle Hogue Rubber Grip", + "668fe5d42a0f85eea407cc16 ShortName": "DE RG", + "668fe5d42a0f85eea407cc16 Description": "A rubberized grip for the Desert Eagle pistol. Manufactured by Hogue.", + "668fe5e1800f0244f9036e46 Name": "Desert Eagle rear sight", + "668fe5e1800f0244f9036e46 ShortName": "DE RS", + "668fe5e1800f0244f9036e46 Description": "A standard-issue rear sight for the Desert Eagle pistol, manufactured by Magnum Research.", + "668fe5ec4315934ba10c6f96 Name": "Desert Eagle front sight", + "668fe5ec4315934ba10c6f96 ShortName": "DE FS", + "668fe5ec4315934ba10c6f96 Description": "A standard-issue front sight for the Desert Eagle pistol, manufactured by Magnum Research.", + "668fe5f62a0f85eea407cc18 Name": "Desert Eagle Mk XIX .50 AE 152mm barrel", + "668fe5f62a0f85eea407cc18 ShortName": "XIX 152mm", + "668fe5f62a0f85eea407cc18 Description": "A Mark XIX 152mm .50 AE barrel for the Desert Eagle pistol, manufactured by Magnum Research.", + "668fe60b56984d93550462c6 Name": "Desert Eagle Mk XIX pistol slide", + "668fe60b56984d93550462c6 ShortName": "XIX slide", + "668fe60b56984d93550462c6 Description": "A Mark XIX slide for the Desert Eagle pistol, manufactured by Magnum Research.", + "668fe62ac62660a5d8071446 Name": ".50 AE FMJ", + "668fe62ac62660a5d8071446 ShortName": "FMJ", + "668fe62ac62660a5d8071446 Description": "A .50 Action Express FMJ cartridge (12.7x33mm) with a 300 grain flat-nose bullet, which provides an enormous stopping power. One of the most powerful unitary pistol cartridges in the world and has a significant lethality.", + "6694f4101ae1778e310f4f8e Name": "Twitch Drops Summer 2024 case (Common)", + "6694f4101ae1778e310f4f8e ShortName": "Twitch", + "6694f4101ae1778e310f4f8e Description": "", + "6694f418c74d8a180f0f78c0 Name": "Twitch Drops Summer 2024 case (Rare)", + "6694f418c74d8a180f0f78c0 ShortName": "Twitch", + "6694f418c74d8a180f0f78c0 Description": "", + "6694f423909d2322a8073151 Name": "Twitch Drops Summer 2024 case (Epic)", + "6694f423909d2322a8073151 ShortName": "Twitch", + "6694f423909d2322a8073151 Description": "", + "6698c89bfbc8142e60024b0e Name": "UZI 238mm threaded 3-lug barrel", + "6698c89bfbc8142e60024b0e ShortName": "UZI 238mm", + "6698c89bfbc8142e60024b0e Description": "A threaded 238mm barrel for the UZI submachine gun, equipped with a 3-lug type adapter for installing muzzle devices.", + "6698c8ab29e062525d0ad8ab Name": "UZI 9x19 259mm barrel", + "6698c8ab29e062525d0ad8ab ShortName": "UZI 259mm", + "6698c8ab29e062525d0ad8ab Description": "A 259mm barrel for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c8b7710a4525fe0e9e55 Name": "UZI 9x19 409mm barrel", + "6698c8b7710a4525fe0e9e55 ShortName": "UZI 409mm", + "6698c8b7710a4525fe0e9e55 Description": "A 409mm barrel for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c8c736ba38d29101770b Name": "UZI polymer handguard", + "6698c8c736ba38d29101770b ShortName": "UZI HG", + "6698c8c736ba38d29101770b Description": "A standard-issue polymer handguard for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c8f4710a4525fe0e9e57 Name": "UZI handguard rail", + "6698c8f4710a4525fe0e9e57 ShortName": "UZI rail", + "6698c8f4710a4525fe0e9e57 Description": "A handguard rail for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c90829e062525d0ad8ad Name": "UZI StormWerkz Scope Mount", + "6698c90829e062525d0ad8ad ShortName": "UZI SW", + "6698c90829e062525d0ad8ad Description": "A rail mount for installing various optics on the UZI submachine gun. Manufactured by StormWerkz.", + "6698c9aa36ba38d29101770f Name": "UZI 9x19 barrel retaining nut", + "6698c9aa36ba38d29101770f ShortName": "UZI BRN", + "6698c9aa36ba38d29101770f Description": "A special nut required to install 9x19 barrels on the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c9ba29e062525d0ad8b1 Name": "UZI 9x19 3-lug barrel retaining nut", + "6698c9ba29e062525d0ad8b1 ShortName": "UZI 3lug", + "6698c9ba29e062525d0ad8b1 Description": "A special 3-lug nut required to install 9x19 barrels on the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c9c636ba38d291017711 Name": "UZI 9x19 3-lug barrel thread protector", + "6698c9c636ba38d291017711 ShortName": "UZI thr.", + "6698c9c636ba38d291017711 Description": "A thread protector for UZI submachine gun 3-lug barrels. Manufactured by Israel Weapon Industries.", + "6698c9e07356874dfe0a0b88 Name": "UZI Type 7 buttstock", + "6698c9e07356874dfe0a0b88 ShortName": "Type 7", + "6698c9e07356874dfe0a0b88 Description": "A polymer buttstock for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6698c9ed36ba38d291017713 Name": "UZI Type 3 buttstock", + "6698c9ed36ba38d291017713 ShortName": "Type 3", + "6698c9ed36ba38d291017713 Description": "A wooden buttstock for the UZI submachine gun. A relic from the 60's, still smells like preservation grease. Manufactured by Israel Weapon Industries.", + "6699249f3c4fda6471005cba Name": "UZI Type 5 buttstock", + "6699249f3c4fda6471005cba ShortName": "Type 5", + "6699249f3c4fda6471005cba Description": "A foldable buttstock for the UZI submachine gun. The most famous variant which has been involved in countless operations, from localized skirmishes on the southern continent, to protecting presidents during assassination attempts. Manufactured by Israel Weapon Industries.\nSlap it HARDER, I know you want it!", + "669924a69950f5f4cd060295 Name": "UZI Type 6 buttstock", + "669924a69950f5f4cd060295 ShortName": "Type 6", + "669924a69950f5f4cd060295 Description": "A wire buttstock for the UZI submachine gun. That's right, it's just like those gangsters from the '80s. Manufactured by Israel Weapon Industries.", + "66992713ae08c5c29e0c4f97 Name": "UZI 9x19 20-round magazine", + "66992713ae08c5c29e0c4f97 ShortName": "UZI", + "66992713ae08c5c29e0c4f97 Description": "A 20-round magazine for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6699271b9950f5f4cd060299 Name": "UZI 9x19 25-round magazine", + "6699271b9950f5f4cd060299 ShortName": "UZI", + "6699271b9950f5f4cd060299 Description": "A 25-round magazine for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "669927203c4fda6471005cbe Name": "UZI 9x19 32-round magazine", + "669927203c4fda6471005cbe ShortName": "UZI", + "669927203c4fda6471005cbe Description": "A 32-round magazine for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "66992725ae08c5c29e0c4f9a Name": "UZI 9x19 40-round magazine", + "66992725ae08c5c29e0c4f9a ShortName": "UZI", + "66992725ae08c5c29e0c4f9a Description": "A 40-round magazine for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6699272a3c4fda6471005cc1 Name": "UZI 9x19 50-round magazine", + "6699272a3c4fda6471005cc1 ShortName": "UZI", + "6699272a3c4fda6471005cc1 Description": "A 50-round magazine for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "66992b349950f5f4cd06029f Name": "IWI UZI 9x19 submachine gun", + "66992b349950f5f4cd06029f ShortName": "UZI", + "66992b349950f5f4cd06029f Description": "An Israeli 9x19mm submachine gun with an open bolt system. A very innovative product of its time which gained great popularity due to its reliability and simplicity of design. Despite being rather outdated, it is still quite popular all over the world.", + "66992f4db9f31ddda10dd1c8 Name": "UZI StormWerkz stock adapter", + "66992f4db9f31ddda10dd1c8 ShortName": "UZI SW", + "66992f4db9f31ddda10dd1c8 Description": "A Picatinny adapter designed for installation of various buttstocks on the UZI submachine gun. Manufactured by StormWerkz.", + "66992f7d9950f5f4cd0602a8 Name": "UZI StormWerkz lower handguard rail", + "66992f7d9950f5f4cd0602a8 ShortName": "UZI SW", + "66992f7d9950f5f4cd0602a8 Description": "A rail designed for installation on the UZI submachine gun handguard. Manufactured by StormWerkz.", + "6699313af74fef4dfd0b04f6 Name": "UZI K-Grip handguard", + "6699313af74fef4dfd0b04f6 ShortName": "K-Grip", + "6699313af74fef4dfd0b04f6 Description": "A handguard with a foregrip for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "66993149558c59581e03c028 Name": "UZI handguard with foregrip", + "66993149558c59581e03c028 ShortName": "UZI FG", + "66993149558c59581e03c028 Description": "A handguard with a vertical foregrip and side rail slots for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "6699370c57df3e2b4e0a0dab Name": "UZI vented barrel shroud", + "6699370c57df3e2b4e0a0dab ShortName": "UZI shroud", + "6699370c57df3e2b4e0a0dab Description": "A vented barrel shroud for the UZI submachine gun, which allows to reduce barrel heat when firing in bursts. Manufactured by Israel Weapon Industries.", + "66993733f74fef4dfd0b04ff Name": "UZI 9x19 sound suppressor", + "66993733f74fef4dfd0b04ff ShortName": "UZI supp.", + "66993733f74fef4dfd0b04ff Description": "A standard-issue sound suppressor for the UZI submachine gun. Manufactured by Israel Weapon Industries.", + "669946c157df3e2b4e0a0dc5 Name": "UZI pistol grip cover", + "669946c157df3e2b4e0a0dc5 ShortName": "UZI PG", + "669946c157df3e2b4e0a0dc5 Description": "A standard cover panel for the UZI submachine gun pistol grip. Manufactured by Israel Weapon Industries.", + "669a6a4a525be1d2d004b8eb Name": "Magpul M-LOK 0.93 inch rail", + "669a6a4a525be1d2d004b8eb ShortName": "M-LOK 0.93\"", + "669a6a4a525be1d2d004b8eb Description": "The Magpul M-LOK 0.93 inch rail allows installation of additional equipment on the handguards equipped with an M-LOK interface.", + "669cf78806768ff39504fc1c Name": "UZI PRO CSM stock adapter", + "669cf78806768ff39504fc1c ShortName": "PRO CSM", + "669cf78806768ff39504fc1c Description": "A Picatinny adapter designed for installation of various buttstocks on the UZI PRO submachine gun. Manufactured by Custom Smith Manufacturing.", + "669fa39b48fc9f8db6035a0c Name": "Magnum Research Desert Eagle L6 .50 AE pistol", + "669fa39b48fc9f8db6035a0c ShortName": "Desert Eagle L6", + "669fa39b48fc9f8db6035a0c Description": "Desert Eagle L6 is the modification of the .50 Action Express caliber sport-hunting pistol. This pistol is huge, heavy and not the most practical in operation, but at the same time it is an absolutely unique short-barreled weapon, which undoubtedly became a frequent visitor in video games for its brutal appearance and impressive size. The Desert Eagle did not win any military approval, but deservedly became one of the most famous pistols in the world. Manufactured by Magnum Research.", + "669fa3d876116c89840b1217 Name": "Magnum Research Desert Eagle L6 .50 AE pistol (WTS)", + "669fa3d876116c89840b1217 ShortName": "Desert Eagle L6", + "669fa3d876116c89840b1217 Description": "Desert Eagle L6 is the modification of the .50 Action Express caliber sport-hunting pistol. This pistol is huge, heavy and not the most practical in operation, but at the same time it is an absolutely unique short-barreled weapon, which undoubtedly became a frequent visitor in video games for its brutal appearance and impressive size. The Desert Eagle did not win any military approval, but deservedly became one of the most famous pistols in the world. Manufactured by Magnum Research. White Tiger Stripes version.", + "669fa3f88abd2662d80eee77 Name": "Magnum Research Desert Eagle L5 .50 AE pistol", + "669fa3f88abd2662d80eee77 ShortName": "Desert Eagle L5", + "669fa3f88abd2662d80eee77 Description": "Desert Eagle L5 is the lightweight modification of the .50 Action Express caliber sport-hunting pistol. This pistol is huge, heavy and not the most practical in operation, but at the same time it is an absolutely unique short-barreled weapon, which undoubtedly became a frequent visitor in video games for its brutal appearance and impressive size. The Desert Eagle did not win any military approval, but deservedly became one of the most famous pistols in the world. Manufactured by Magnum Research.", + "669fa409933e898cce0c2166 Name": "Magnum Research Desert Eagle L5 .357 pistol", + "669fa409933e898cce0c2166 ShortName": "Desert Eagle L5", + "669fa409933e898cce0c2166 Description": "Desert Eagle L5 is the lightweight modification of the .357 Magnum caliber sport-hunting pistol. This pistol is huge, heavy and not the most practical in operation, but at the same time it is an absolutely unique short-barreled weapon, which undoubtedly became a frequent visitor in video games for its brutal appearance and impressive size. The Desert Eagle did not win any military approval, but deservedly became one of the most famous pistols in the world. Manufactured by Magnum Research.", + "669fa435803b94fb5d0e3a76 Name": "Desert Eagle .357 9-round magazine", + "669fa435803b94fb5d0e3a76 ShortName": "DE", + "669fa435803b94fb5d0e3a76 Description": "A standard-issue 9-round .357 Magnum magazine for the Desert Eagle L5 pistol. Manufactured by Magnum Research.", + "669fa47da0bab4e8510d9526 Name": "Desert Eagle L6 .50 AE 152mm barrel", + "669fa47da0bab4e8510d9526 ShortName": "L6 152mm", + "669fa47da0bab4e8510d9526 Description": "An L6 152mm .50 AE barrel for the Desert Eagle pistol, manufactured by Magnum Research.", + "669fa48fa0bab4e8510d952a Name": "Desert Eagle L6 .50 AE 152mm barrel (WTS)", + "669fa48fa0bab4e8510d952a ShortName": "L6 152mm", + "669fa48fa0bab4e8510d952a Description": "An L6 152mm .50 AE barrel for the Desert Eagle pistol, manufactured by Magnum Research. White Tiger Stripes version.", + "669fa4ba1bd4416eaa09b3c6 Name": "Desert Eagle L5 .50 AE 127mm barrel", + "669fa4ba1bd4416eaa09b3c6 ShortName": "L5 127mm", + "669fa4ba1bd4416eaa09b3c6 Description": "An L5 127mm .50 AE barrel for the Desert Eagle pistol, manufactured by Magnum Research.", + "669fa4c61bd4416eaa09b3ca Name": "Desert Eagle L5 .357 127mm barrel", + "669fa4c61bd4416eaa09b3ca ShortName": "L5 127mm", + "669fa4c61bd4416eaa09b3ca Description": "An L5 127mm .357 Magnum barrel for the Desert Eagle pistol, manufactured by Magnum Research.", + "669fa4d97a09bc295603b496 Name": "Desert Eagle L6 pistol slide", + "669fa4d97a09bc295603b496 ShortName": "L6 slide", + "669fa4d97a09bc295603b496 Description": "An L6 slide for the Desert Eagle pistol, manufactured by Magnum Research.", + "669fa5019aa2a422600442f6 Name": "Desert Eagle L5 .50 AE pistol slide", + "669fa5019aa2a422600442f6 ShortName": "L5 .50", + "669fa5019aa2a422600442f6 Description": "An L5 slide for the Desert Eagle pistol chambered in .50 AE, manufactured by Magnum Research.", + "669fa5127a09bc295603b499 Name": "Desert Eagle L5 .357 pistol slide", + "669fa5127a09bc295603b499 ShortName": "L5 .357", + "669fa5127a09bc295603b499 Description": "An L5 slide for the Desert Eagle pistol chambered in .357 Magnum, manufactured by Magnum Research.", + "669fa5271bd4416eaa09b3ce Name": "Desert Eagle L6 pistol slide (WTS)", + "669fa5271bd4416eaa09b3ce ShortName": "L6 slide", + "669fa5271bd4416eaa09b3ce Description": "An L6 slide for the Desert Eagle pistol, manufactured by Magnum Research. White Tiger Stripes version.", + "669fac549b0ce3feae01a137 Name": "Chemical sample", + "669fac549b0ce3feae01a137 ShortName": "Sample", + "669fac549b0ce3feae01a137 Description": "There's no telling what was in the tank container. It looks nasty, and smells even worse. TerraGroup must have used these tanks to store precursors for their research.", + "66a0d1c87d0d369e270bb9de Name": ".50 AE JHP", + "66a0d1c87d0d369e270bb9de ShortName": "JHP", + "66a0d1c87d0d369e270bb9de Description": "A .50 Action Express JHP cartridge (12.7x33mm) with a 300 grain jacketed hollow-point bullet, which provides an enormous stopping power. One of the most powerful unitary pistol cartridges in the world and has a significant lethality.", + "66a0d1e0ed648d72fe064d06 Name": ".50 AE Copper Solid", + "66a0d1e0ed648d72fe064d06 ShortName": "Copper", + "66a0d1e0ed648d72fe064d06 Description": "A .50 Action Express Hawk Copper Solid cartridge (12.7x33mm) with a 400 grain precision bullet, designed to direct a tremendous amount of energy into the target. One of the most powerful unitary pistol cartridges in the world and has a significant lethality.", + "66a0d1f88486c69fce00fdf6 Name": ".50 AE Hawk JSP", + "66a0d1f88486c69fce00fdf6 ShortName": "Hawk JSP", + "66a0d1f88486c69fce00fdf6 Description": "A .50 Action Express Hawk JSP cartridge (12.7x33mm) with a 400 grain jacketed soft point bullet, designed to penetrate and direct a tremendous amount of energy into the target. One of the most powerful unitary pistol cartridges in the world and has a significant lethality.", + "66a0da76b6f47fcfeb025e96 Name": "Desert Eagle Hogue Rubber Grip with finger grooves", + "66a0da76b6f47fcfeb025e96 ShortName": "DE RGFG", + "66a0da76b6f47fcfeb025e96 Description": "A rubberized grip with finger grooves for the Desert Eagle pistol. Manufactured by Hogue.", + "66a0e523e749756c920d02d0 Name": "Chemical container", + "66a0e523e749756c920d02d0 ShortName": "Chemcont", + "66a0e523e749756c920d02d0 Description": "Hermetic container for storing various chemicals.", + "66a0f0926fee20fa70036da6 Name": "Blood sample", + "66a0f0926fee20fa70036da6 ShortName": "Sample", + "66a0f0926fee20fa70036da6 Description": "A blood sample taken from the body of one of the workers at Chemical Plant No. 16. The bodies are clearly not recent, but the blood has not even dried up. Even the texture is the same as fresh blood.", + "66a3896972c8e72507028806 Name": "Twitch Drops Summer 2024 case (Common)", + "66a3896972c8e72507028806 ShortName": "Twitch", + "66a3896972c8e72507028806 Description": "", + "66a3896de45f71bf1009e45a Name": "Twitch Drops Summer 2024 case (Common)", + "66a3896de45f71bf1009e45a ShortName": "Twitch", + "66a3896de45f71bf1009e45a Description": "", + "66a3898c1df2a447cc0d3c35 Name": "Twitch Drops Summer 2024 case (Rare)", + "66a3898c1df2a447cc0d3c35 ShortName": "Twitch", + "66a3898c1df2a447cc0d3c35 Description": "", + "66a3898f0982fc7e4c091c4d Name": "Twitch Drops Summer 2024 case (Rare)", + "66a3898f0982fc7e4c091c4d ShortName": "Twitch", + "66a3898f0982fc7e4c091c4d Description": "", + "66a389c0705adefa710cdeaa Name": "Twitch Drops Summer 2024 case (Epic)", + "66a389c0705adefa710cdeaa ShortName": "Twitch", + "66a389c0705adefa710cdeaa Description": "", + "66a389c60982fc7e4c091c51 Name": "Twitch Drops Summer 2024 case (Epic)", + "66a389c60982fc7e4c091c51 ShortName": "Twitch", + "66a389c60982fc7e4c091c51 Description": "", + "66a8ce418ea1637a3c1b2044 Name": "", + "66a8ce418ea1637a3c1b2044 ShortName": "", + "66a8ce418ea1637a3c1b2044 Description": "", + "66a9f98f3bd5a41b162030f4 Name": "Partisan's bag", + "66a9f98f3bd5a41b162030f4 ShortName": "Partisan", + "66a9f98f3bd5a41b162030f4 Description": "An old used Gorka bag. It seems that Partisan replaced his old Afghan trophies with patches of PMC operatives who were foolish enough to cross him in some way when they came to Tarkov.", + "66aa3a180d6ecb50a21a4e1a Name": "Twitch Drops Summer 2024 case (Common)", + "66aa3a180d6ecb50a21a4e1a ShortName": "Twitch", + "66aa3a180d6ecb50a21a4e1a Description": "", + "66aa3a31efb1b8119f0196c7 Name": "Twitch Drops Summer 2024 case (Rare)", + "66aa3a31efb1b8119f0196c7 ShortName": "Twitch", + "66aa3a31efb1b8119f0196c7 Description": "", + "66aa3a3800b2c42adb07d13e Name": "Twitch Drops Summer 2024 case (Epic)", + "66aa3a3800b2c42adb07d13e ShortName": "Twitch", + "66aa3a3800b2c42adb07d13e Description": "", + "66aa5d36f641b13ad238f8c3 Name": "", + "66aa5d36f641b13ad238f8c3 ShortName": "", + "66aa5d36f641b13ad238f8c3 Description": "", + "66ac9d9740e27931602042d4 Name": "AK skeletonized stock (Customized)", + "66ac9d9740e27931602042d4 ShortName": "Med stock", + "66ac9d9740e27931602042d4 Description": "A metal skeleton stock equipped with a bandage and Esmarch tourniquet, the use of which, when carried this way, has been the subject of much debate and is still in question. A true old school.", + "66acbe49dc61999a6a03d4d6 Name": "", + "66acbe49dc61999a6a03d4d6 ShortName": "", + "66acbe49dc61999a6a03d4d6 Description": "", + "66acd6702b17692df20144c0 Name": "TerraGroup storage room keycard", + "66acd6702b17692df20144c0 ShortName": "Polikhim", + "66acd6702b17692df20144c0 Description": "An access keycard for the TerraGroup storage room, located inside Chemical Plant No. 16.", + "66ace88c46fb07947008645b Name": "", + "66ace88c46fb07947008645b ShortName": "", + "66ace88c46fb07947008645b Description": "", + "66acec1dc94f4bf5bc063a16 Name": "", + "66acec1dc94f4bf5bc063a16 ShortName": "", + "66acec1dc94f4bf5bc063a16 Description": "", + "66acff0a1d8e1083b303f5af Name": "Bank safe", + "66acff0a1d8e1083b303f5af ShortName": "Bank safe", + "66acff0a1d8e1083b303f5af Description": "Bank safe", + "66b22630a6b4e5ec7c02cdb7 Name": "Case with precision tools", + "66b22630a6b4e5ec7c02cdb7 ShortName": "Tools", + "66b22630a6b4e5ec7c02cdb7 Description": "A case containing various expensive precision tools.", + "66b37ea4c5d72b0277488439 Name": "Tamatthi kunai knife replica", + "66b37ea4c5d72b0277488439 ShortName": "Tamatthi", + "66b37ea4c5d72b0277488439 Description": "A replica of the Tamatthi ninja knife.", + "66b37eb4acff495a29492407 Name": "Viibiin sneaker", + "66b37eb4acff495a29492407 ShortName": "Viibiin", + "66b37eb4acff495a29492407 Description": "A single Viibiin brand sneaker. Wonder where the other one is.", + "66b37f114410565a8f6789e2 Name": "Inseq gas pipe wrench", + "66b37f114410565a8f6789e2 ShortName": "Inseq", + "66b37f114410565a8f6789e2 Description": "An Inseq brand plumber's wrench, shiny and colorful.", + "66b4d4ccd9281f8de00c6e02 Name": "", + "66b4d4ccd9281f8de00c6e02 ShortName": "", + "66b4d4ccd9281f8de00c6e02 Description": "", + "66b5f22b78bbc0200425f904 Name": "Camelbak Tri-Zip assault backpack (MultiCam)", + "66b5f22b78bbc0200425f904 ShortName": "Tri-Zip", + "66b5f22b78bbc0200425f904 Description": "A Mid-sized versatile assault pack. Spacious, sturdy and comfortable, this backpack is loved both by military and hikers worldwide. 34L of total space, a hydration system, easy access to side pockets, near-perfect suspension, and a MOLLE attachment system make it a great choice for up to 72 hours of autonomous hiking... or carrying a good load of loot. MultiCam camouflage version.", + "66b5f247af44ca0014063c02 Name": "Vertx Ready Pack backpack (Red)", + "66b5f247af44ca0014063c02 ShortName": "ReadyPack", + "66b5f247af44ca0014063c02 Description": "A tactical (but not overly tactical) everyday carry 20L backpack made by Vertx. Red color version.", + "66b5f65ca7f72d197e70bcd6 Name": "Ballistic Armor Co. Bastion helmet (Armor Black)", + "66b5f65ca7f72d197e70bcd6 ShortName": "BAC Bastion", + "66b5f65ca7f72d197e70bcd6 Description": "The Bastion NIJ level IIIA tactical helmet designed for law enforcement and civilian use. Equipped with M-LOK interface rails for mounting additional equipment. Manufactured by Ballistic Armor Co. Armor Black version.", + "66b5f661af44ca0014063c05 Name": "Ballistic Armor Co. Bastion helmet (OD Green)", + "66b5f661af44ca0014063c05 ShortName": "BAC Bastion", + "66b5f661af44ca0014063c05 Description": "The Bastion NIJ level IIIA tactical helmet designed for law enforcement and civilian use. Equipped with M-LOK interface rails for mounting additional equipment. Manufactured by Ballistic Armor Co. OD Green version.", + "66b5f666cad6f002ab7214c2 Name": "Ballistic Armor Co. Bastion helmet (MultiCam)", + "66b5f666cad6f002ab7214c2 ShortName": "BAC Bastion", + "66b5f666cad6f002ab7214c2 Description": "The Bastion NIJ level IIIA tactical helmet designed for law enforcement and civilian use. Equipped with M-LOK interface rails for mounting additional equipment. Manufactured by Ballistic Armor Co. MultiCam camouflage version.", + "66b5f68de98be930d701c00e Name": "Safariland Liberator HP 2.0 Hearing Protection Headset (FDE)", + "66b5f68de98be930d701c00e ShortName": "Liberator", + "66b5f68de98be930d701c00e Description": "A next generation low-profile active headset, designed to protect the user's hearing from external factors. Manufactured by Safariland. Flat Dark Earth version.", + "66b5f693acff495a294927e3 Name": "Peltor ComTac V headset (OD Green)", + "66b5f693acff495a294927e3 ShortName": "ComTac V", + "66b5f693acff495a294927e3 Description": "A communication headset equipped with a microphone and omnidirectional high-fidelity speakers that are optimized for voice communication and capable of picking up sounds with high sensitivity. Manufactured by 3M Peltor. OD Green color version.", + "66b5f6985891c84aab75ca76 Name": "Peltor ComTac VI headset (Coyote Brown)", + "66b5f6985891c84aab75ca76 ShortName": "ComTac VI", + "66b5f6985891c84aab75ca76 Description": "An improved version of the ComTac V communication headset, equipped with advanced environmental listening settings and an NIB (Natural Interaction Behavior) feature, allowing to communicate with other ComTac VI users in a certain proximity without having to use radios. Manufactured by 3M Peltor. Coyote Brown version.", + "66b5f69ea7f72d197e70bcdb Name": "TW EXFIL Peltor ComTac V headset (OD Green)", + "66b5f69ea7f72d197e70bcdb ShortName": "ComTac V", + "66b5f69ea7f72d197e70bcdb Description": "A communication headset equipped with a microphone and omnidirectional high-fidelity speakers that are optimized for voice communication and capable of picking up sounds with high sensitivity. Equipped with a mount for attaching the headset to Team Wendy EXFIL helmets. Manufactured by 3M Peltor. OD Green color version.", + "66b5f6a28ca68c6461709ed8 Name": "TW EXFIL Peltor ComTac VI headset (Coyote Brown)", + "66b5f6a28ca68c6461709ed8 ShortName": "ComTac VI", + "66b5f6a28ca68c6461709ed8 Description": "An improved version of the ComTac V communication headset, equipped with advanced environmental listening settings and an NIB (Natural Interaction Behavior) feature, allowing to communicate with other ComTac VI users in a certain proximity without having to use radios. Equipped with a mount for attaching the headset to Team Wendy EXFIL helmets. Manufactured by 3M Peltor. Coyote Brown version.", + "66b61ce0c5d72b027748867e Name": "Hybrid composite materials", + "66b61ce0c5d72b027748867e ShortName": "", + "66b61ce0c5d72b027748867e Description": "", + "66b61cfae98be930d701c029 Name": "Hybrid composite materials", + "66b61cfae98be930d701c029 ShortName": "", + "66b61cfae98be930d701c029 Description": "", + "66b6295178bbc0200425f995 Name": "Stich Profi Stich Defense mod.2 plate carrier (MultiCam)", + "66b6295178bbc0200425f995 ShortName": "SD mod.2", + "66b6295178bbc0200425f995 Description": "A plate carrier designed for Granit and SAPI plates, made of heavy-duty materials with IR remission. Equipped with ROC buckles for quick donning and doffing. The inner sides are made of soft fabric and equipped with vent pads for increased comfort. Manufactured by Stich Profi. MultiCam camouflage version.", + "66b6295a8ca68c6461709efa Name": "Tasmanian Tiger Plate Carrier MKIII (Coyote Brown)", + "66b6295a8ca68c6461709efa ShortName": "TT MKIII", + "66b6295a8ca68c6461709efa Description": "A lightweight low-profile plate carrier designed to fit SAPI plates. Manufactured by Tasmanian Tiger. Coyote Brown version.", + "66b6296d7994640992013b17 Name": "Stich Profi Plate Carrier V2 (Black)", + "66b6296d7994640992013b17 ShortName": "SP PC V2", + "66b6296d7994640992013b17 Description": "An improved lightweight version of the standard plate carrier manufactured by Stich Profi. Black color version.", + "66b884eaacff495a29492849 Name": "Aramid insert", + "66b884eaacff495a29492849 ShortName": "", + "66b884eaacff495a29492849 Description": "", + "66b884f4c5d72b02774886eb Name": "Aramid insert", + "66b884f4c5d72b02774886eb ShortName": "", + "66b884f4c5d72b02774886eb Description": "", + "66b884fd7994640992013b37 Name": "Aramid insert", + "66b884fd7994640992013b37 ShortName": "", + "66b884fd7994640992013b37 Description": "", + "66b8851678bbc0200425fa03 Name": "Aramid insert", + "66b8851678bbc0200425fa03 ShortName": "", + "66b8851678bbc0200425fa03 Description": "", + "66b88521a7f72d197e70be3b Name": "Aramid insert", + "66b88521a7f72d197e70be3b ShortName": "", + "66b88521a7f72d197e70be3b Description": "", + "66b8b20c5891c84aab75cb96 Name": "Aramid insert", + "66b8b20c5891c84aab75cb96 ShortName": "", + "66b8b20c5891c84aab75cb96 Description": "", + "66b8b217c5d72b02774887b4 Name": "Aramid insert", + "66b8b217c5d72b02774887b4 ShortName": "", + "66b8b217c5d72b02774887b4 Description": "", + "66b8b223a7f72d197e70bed3 Name": "Aramid insert", + "66b8b223a7f72d197e70bed3 ShortName": "", + "66b8b223a7f72d197e70bed3 Description": "", + "66b8b22b78bbc0200425fb20 Name": "Aramid insert", + "66b8b22b78bbc0200425fb20 ShortName": "", + "66b8b22b78bbc0200425fb20 Description": "", + "66bc98a01a47be227a5e956e Name": "Streamer item case", + "66bc98a01a47be227a5e956e ShortName": "Streamer items", + "66bc98a01a47be227a5e956e Description": "A case for compact storage of those strange souvenirs scattered throughout Tarkov, perfect for collectors.", + "66bcd2c46c8ca126600ccc3f Name": "BEAR Phoenix", + "66bcd2c46c8ca126600ccc3f ShortName": "", + "66bcd2c46c8ca126600ccc3f Description": "Flannel shirt", + "66bcd31f6c8ca126600ccc41 Name": "USEC Legionnaire", + "66bcd31f6c8ca126600ccc41 ShortName": "", + "66bcd31f6c8ca126600ccc41 Description": "Combat shirt", + "66bcd461b544479add01acc6 Name": "USEC Legionnaire", + "66bcd461b544479add01acc6 ShortName": "", + "66bcd461b544479add01acc6 Description": "Combat pants", + "66bcd48714b42ed1dc0af2e0 Name": "BEAR Paladin", + "66bcd48714b42ed1dc0af2e0 ShortName": "", + "66bcd48714b42ed1dc0af2e0 Description": "Tactical pants", + "66bdc28a0b603c26902b2011 Name": "DevTac Ronin ballistic helmet", + "66bdc28a0b603c26902b2011 ShortName": "Ronin", + "66bdc28a0b603c26902b2011 Description": "A Japan-styled tactical helmet, manufactured by DevTac. Not used by any military or special forces. Just somehow happened to be in Tarkov for some frivolous price. Features a full protection of the whole head, but the armor class is not good enough to actually be useful in combat.", + "66bdc2c90b603c26902b2018 Name": "Hybrid composite materials", + "66bdc2c90b603c26902b2018 ShortName": "", + "66bdc2c90b603c26902b2018 Description": "", + "66bdc2d051aa8c345646d03f Name": "Hybrid composite materials", + "66bdc2d051aa8c345646d03f ShortName": "", + "66bdc2d051aa8c345646d03f Description": "", + "66bdc2d9408f1e66eb4fd957 Name": "Hybrid composite materials", + "66bdc2d9408f1e66eb4fd957 ShortName": "", + "66bdc2d9408f1e66eb4fd957 Description": "", + "66bdc2e25f17154509115d1e Name": "Hybrid composite materials", + "66bdc2e25f17154509115d1e ShortName": "", + "66bdc2e25f17154509115d1e Description": "", + "66bdc2ea8cbd597c9c2f9360 Name": "Hybrid composite materials", + "66bdc2ea8cbd597c9c2f9360 ShortName": "", + "66bdc2ea8cbd597c9c2f9360 Description": "", + "66bf6769f08c35734d4940c4 Name": "", + "66bf6769f08c35734d4940c4 ShortName": "", + "66bf6769f08c35734d4940c4 Description": "", + "66bf68d0f08c35734d4940c6 Name": "", + "66bf68d0f08c35734d4940c6 ShortName": "", + "66bf68d0f08c35734d4940c6 Description": "", + "66bf69195d6942454668fd5d Name": "", + "66bf69195d6942454668fd5d ShortName": "", + "66bf69195d6942454668fd5d Description": "", + "66c0b39ca1f68fcc1d0c0cc3 Name": "Lab journal", + "66c0b39ca1f68fcc1d0c0cc3 ShortName": "Journal", + "66c0b39ca1f68fcc1d0c0cc3 Description": "The records in this journal reveal side effects after interacting with TerraGroup's drugs... The factory workers likely were unaware of this \"research\".", + "66c0b90c8398582e4b0c2e27 Name": "Pilot logbook", + "66c0b90c8398582e4b0c2e27 ShortName": "Logbook", + "66c0b90c8398582e4b0c2e27 Description": "A RUAF pilot logbook. It's unclear how it ended up in the cockpit of the foreign AS350 helicopter. Either the USECs ran out of their own logbooks, or the BEARs ran out of helicopters.", + "66d97834d2985e11480d5c1e Name": "Signal flare (Blue)", + "66d97834d2985e11480d5c1e ShortName": "Signal flare (Blue)", + "66d97834d2985e11480d5c1e Description": "Signal flare (Blue)", + "66d98233302686954b0c6f81 Name": "RSP-30 reactive signal cartridge (Blue)", + "66d98233302686954b0c6f81 ShortName": "Blue", + "66d98233302686954b0c6f81 Description": "A reactive signal cartridge for commanding and maintaining squad interaction. Some Scavs use this flare color to send some kinds of signals. The question is, what do these signals mean?", + "66d9f1abb16d9aacf5068468 Name": "RSP-30 reactive signal cartridge (Special Yellow)", + "66d9f1abb16d9aacf5068468 ShortName": "S-Yellow", + "66d9f1abb16d9aacf5068468 Description": "A special cartridge used to signal the right people and collect the special cargo for Prapor.", + "66d9f3047b82b9a9aa055d81 Name": "Signal flare (Special Yellow)", + "66d9f3047b82b9a9aa055d81 ShortName": "Signal flare (Special Yellow)", + "66d9f3047b82b9a9aa055d81 Description": "Signal flare (Special Yellow)", + "66d9f7256916142b3b02276e Name": "Radar station spare parts", + "66d9f7256916142b3b02276e ShortName": "Radar", + "66d9f7256916142b3b02276e Description": "Some spare parts for radar stations. Probably not useful unless you're an advanced radar specialist PMC. Which you probably aren't.", + "66d9f7e7099cf6adcc07a369 Name": "KOSA UAV electronic jamming device", + "66d9f7e7099cf6adcc07a369 ShortName": "KOSA", + "66d9f7e7099cf6adcc07a369 Description": "The device is designed to suppress UAV guidance systems. Helps to reliably protect any facility from airborne attacks.", + "66d9f8744827a77e870ecaf1 Name": "GARY ZONT portable electronic warfare device", + "66d9f8744827a77e870ecaf1 ShortName": "EW unit", + "66d9f8744827a77e870ecaf1 Description": "The device suppresses satellite navigation system signals within a several kilometers radius. Sometimes these “umbrellas” can be more important than good body armor.", + "66da1b49099cf6adcc07a36b Name": "Airdrop technical supply crate", + "66da1b49099cf6adcc07a36b ShortName": "Airdrop technical supply crate", + "66da1b49099cf6adcc07a36b Description": "crate", + "66da1b546916142b3b022777 Name": "Airdrop technical supply crate", + "66da1b546916142b3b022777 ShortName": "Airdrop technical supply crate", + "66da1b546916142b3b022777 Description": "crate", + "66ec2aa6daf127599c0c31f1 Name": "O-832DU Shrapnel", + "66ec2aa6daf127599c0c31f1 ShortName": "O-832DU Shrapnel", + "66ec2aa6daf127599c0c31f1 Description": "O-832DU Shrapnel", + "66fd4372bd170aa3fb012a56 Name": "", + "66fd4372bd170aa3fb012a56 ShortName": "", + "66fd4372bd170aa3fb012a56 Description": "", + "66fd43dfe7690d4e7b0b1516 Name": "", + "66fd43dfe7690d4e7b0b1516 ShortName": "", + "66fd43dfe7690d4e7b0b1516 Description": "", + "66fd4407390606b5e106e016 Name": "", + "66fd4407390606b5e106e016 ShortName": "", + "66fd4407390606b5e106e016 Description": "", + "66ffa9b66e19cc902401c5e8 Name": "MPS Auto Assault-12 Gen 1 12ga automatic shotgun", + "66ffa9b66e19cc902401c5e8 ShortName": "AA-12 Gen 1", + "66ffa9b66e19cc902401c5e8 Description": "The AA-12 (Auto Assault-12) is a reliable full-auto 12-gauge shotgun. The first generation features the high-mounted built-in iron sights. This shotgun is distinguished by its recoil pulse accumulation, which makes the recoil feel smooth without sacrificing fire rate and stopping power. The AA-12 is designed for military and police units. Manufactured by Military Police Systems.", + "66ffaab91f7492c901027bb8 Name": "AA-12 12ga 8-round magazine", + "66ffaab91f7492c901027bb8 ShortName": "AA-12", + "66ffaab91f7492c901027bb8 Description": "An 8-round 12-gauge box magazine for the Auto Assault-12 shotgun.", + "66ffac601f7492c901027bbb Name": "AA-12 12ga 330mm barrel", + "66ffac601f7492c901027bbb ShortName": "AA-12 330mm", + "66ffac601f7492c901027bbb Description": "A 330mm barrel for the Auto Assault-12 12-gauge shotgun.", + "66ffac9e316b08f6840a73e6 Name": "AA-12 stock assembly", + "66ffac9e316b08f6840a73e6 ShortName": "AA-12", + "66ffac9e316b08f6840a73e6 Description": "A standard-issue stock assembly for the Auto Assault-12 shotgun.", + "66ffbfb1a73a7bce3d0b45a8 Name": "FN SCAR Vltor RE-SCAR Stock Adapter", + "66ffbfb1a73a7bce3d0b45a8 ShortName": "RE-SCAR", + "66ffbfb1a73a7bce3d0b45a8 Description": "An adapter with a five-position tube for installing AR buttstocks, designed for FN SCAR rifles. Manufactured by Vltor.", + "66ffc20ba73a7bce3d0b45ab Name": "FN SCAR Vltor RE-SCAR Stock Adapter (Patriot Brown)", + "66ffc20ba73a7bce3d0b45ab ShortName": "RE-SCAR", + "66ffc20ba73a7bce3d0b45ab Description": "An adapter with a five-position tube for installing AR buttstocks, designed for FN SCAR rifles. Manufactured by Vltor. Patriot Brown version.", + "66ffc246a81a4f85e70d4d06 Name": "FN SCAR JMac Customs RSA-SCAR 1913 Adapter", + "66ffc246a81a4f85e70d4d06 ShortName": "RSA-SCAR", + "66ffc246a81a4f85e70d4d06 Description": "An adapter for installing 1913 Picatinny buttstocks, designed for FN SCAR rifles. Manufactured by JMac Customs.", + "66ffc2bd132225f0fe0611d8 Name": "FN SCAR Vltor VSS-11 polymer stock", + "66ffc2bd132225f0fe0611d8 ShortName": "VSS-11", + "66ffc2bd132225f0fe0611d8 Description": "The VSS-11 telescopic polymer buttstock for SCAR series rifles, manufactured by Vltor.", + "66ffc2ecfe9b3825960652f7 Name": "FN SCAR Vltor VSS-11 polymer stock (Patriot Brown)", + "66ffc2ecfe9b3825960652f7 ShortName": "VSS-11", + "66ffc2ecfe9b3825960652f7 Description": "The VSS-11 telescopic polymer buttstock for SCAR series rifles, manufactured by Vltor. Patriot Brown version.", + "66ffc6ceb7ff397142017c3a Name": "FN SCAR Kinetic MREX 6.5 M-LOK rail (FDE)", + "66ffc6ceb7ff397142017c3a ShortName": "MREX 6.5 M-LOK", + "66ffc6ceb7ff397142017c3a Description": "The MREX 6.5 M-LOK rail for SCAR series rifles allows the installation of additional equipment. Manufactured by Kinetic. Flat Dark Earth version.", + "66ffc72082d36dec82030c1f Name": "FN SCAR PMM M-LOK lower rail", + "66ffc72082d36dec82030c1f ShortName": "PMM low", + "66ffc72082d36dec82030c1f Description": "A bottom rail with an M-LOK interface designed for SCAR series rifles. Manufactured by Parker Mountain Machine.", + "66ffc903fe9b382596065304 Name": "FN SCAR PMM M-LOK lower rail (FDE)", + "66ffc903fe9b382596065304 ShortName": "PMM low", + "66ffc903fe9b382596065304 Description": "A bottom rail with an M-LOK interface designed for SCAR series rifles. Manufactured by Parker Mountain Machine. Flat Dark Earth version.", + "66ffe2fbab3336cc0106382b Name": "FN SCAR PMM MRE XL rail extension", + "66ffe2fbab3336cc0106382b ShortName": "MRE XL", + "66ffe2fbab3336cc0106382b Description": "An M-LOK interface rail extension designed for SCAR series rifles. Manufactured by Parker Mountain Machine.", + "66ffe5edfe9b38259606530d Name": "FN SCAR PMM MRE XL rail extension (FDE)", + "66ffe5edfe9b38259606530d ShortName": "MRE XL", + "66ffe5edfe9b38259606530d Description": "An M-LOK interface rail extension designed for SCAR series rifles. Manufactured by Parker Mountain Machine. Flat Dark Earth version.", + "66ffe66a20771d839f0fb4a9 Name": "FN SCAR PMM Rail Elimination Panels", + "66ffe66a20771d839f0fb4a9 ShortName": "PMM REP", + "66ffe66a20771d839f0fb4a9 Description": "Low-profile ergonomic side panels for SCAR series rifles, designed to replace the standard receiver rails. Manufactured by Parker Mountain Machine.", + "66ffe6916f11538c7d0581e1 Name": "FN SCAR PMM Rail Elimination Panels (FDE)", + "66ffe6916f11538c7d0581e1 ShortName": "PMM REP", + "66ffe6916f11538c7d0581e1 Description": "Low-profile ergonomic side panels for SCAR series rifles, designed to replace the standard receiver rails. Manufactured by Parker Mountain Machine. Flat Dark Earth version.", + "66ffe6c36f11538c7d0581e3 Name": "FN SCAR PMM M-LOK side rails", + "66ffe6c36f11538c7d0581e3 ShortName": "PMM side", + "66ffe6c36f11538c7d0581e3 Description": "Side rails for SCAR series rifles, equipped with M-LOK interface and allowing the installation of additional equipment. Manufactured by Parker Mountain Machine.", + "66ffe7bab8da88805e07a03e Name": "FN SCAR PMM M-LOK side rails (FDE)", + "66ffe7bab8da88805e07a03e ShortName": "PMM side", + "66ffe7bab8da88805e07a03e Description": "Side rails for SCAR series rifles, equipped with M-LOK interface and allowing the installation of additional equipment. Manufactured by Parker Mountain Machine. Flat Dark Earth version.", + "66ffe811f5d758d71101e89a Name": "FN SCAR Vltor CASV-SCAR handguard", + "66ffe811f5d758d71101e89a ShortName": "CASV-SCAR", + "66ffe811f5d758d71101e89a Description": "A handguard for SCAR series rifles, manufactured by Vltor.", + "66ffea06132225f0fe061394 Name": "FN SCAR Vltor CASV-SCAR handguard (Patriot Brown)", + "66ffea06132225f0fe061394 ShortName": "CASV-SCAR", + "66ffea06132225f0fe061394 Description": "A handguard for SCAR series rifles, manufactured by Vltor. Patriot Brown version.", + "66ffea456be19fd81e0ef742 Name": "FN SCAR Vltor CASV-SCAR Handguard Extender", + "66ffea456be19fd81e0ef742 ShortName": "CASV-SCAR", + "66ffea456be19fd81e0ef742 Description": "An extension for longer hand grip and installation of additional equipment, designed for the CASV-SCAR handguard. Manufactured by Vltor.", + "66ffeab4ab3336cc01063833 Name": "FN SCAR Vltor CASV-SCAR Handguard Extender (Patriot Brown)", + "66ffeab4ab3336cc01063833 ShortName": "CASV-SCAR", + "66ffeab4ab3336cc01063833 Description": "An extension for longer hand grip and installation of additional equipment, designed for the CASV-SCAR handguard. Manufactured by Vltor. Patriot Brown version.", + "67069c8cee8138ed2f05ad34 Name": "SR-3MP dovetail side rail (Black)", + "67069c8cee8138ed2f05ad34 ShortName": "SR-3MP DT", + "67069c8cee8138ed2f05ad34 Description": "A special mount for installing optics and other accessories to the SR-3MP assault rifle. Manufactured by TsNIITochMash. Black version.", + "67069cbbb29a2cd33803338c Name": "SR-3MP dovetail side rail (Plum)", + "67069cbbb29a2cd33803338c ShortName": "SR-3MP DT", + "67069cbbb29a2cd33803338c Description": "A special mount for installing optics and other accessories to the SR-3MP assault rifle. Manufactured by TsNIITochMash. Made out of plum-colored material, which has earned the nickname \"Sliva\" (Plum).", + "67069cf1af4890b09f0006e8 Name": "SR-3MP side rails (Black)", + "67069cf1af4890b09f0006e8 ShortName": "SR-3MP s.", + "67069cf1af4890b09f0006e8 Description": "Side rails for the SR-3MP assault rifle that allow installation of additional tactical equipment. Manufactured by TsNIITochMash. Black version.", + "67069d02ad91f3a63c0bc2b0 Name": "SR-3MP side rails (Plum)", + "67069d02ad91f3a63c0bc2b0 ShortName": "SR-3MP s.", + "67069d02ad91f3a63c0bc2b0 Description": "Side rails for the SR-3MP assault rifle that allow installation of additional tactical equipment. Manufactured by TsNIITochMash. Made out of plum-colored material, which has earned the nickname \"Sliva\" (Plum).", + "67069d3bb29a2cd338033390 Name": "HK HKey 3 inch rail", + "67069d3bb29a2cd338033390 ShortName": "HKey 3\"", + "67069d3bb29a2cd338033390 Description": "The HKey 3 inch rail allows installation of additional equipment on the handguards equipped with HK's HKey mounting interface.", + "67069d66af4890b09f0006ec Name": "HK G36 KAC Quad Rail handguard", + "67069d66af4890b09f0006ec ShortName": "G36K KAC", + "67069d66af4890b09f0006ec Description": "A quad rail Picatinny handguard for the G36K assault rifle. Manufactured by Knight's Armament Company.", + "67069d8dad91f3a63c0bc2b4 Name": "HK G36 Slim Line HKey Handguard", + "67069d8dad91f3a63c0bc2b4 ShortName": "G36 Slim Line", + "67069d8dad91f3a63c0bc2b4 Description": "A low-profile handguard with an HKey mounting interface for the G36K assault rifle. Manufactured by Heckler & Koch.", + "6706a159c67236b2f703bb95 Name": "HK G36 Tommy Built AR Stock Adapter", + "6706a159c67236b2f703bb95 ShortName": "G36 TB", + "6706a159c67236b2f703bb95 Description": "An adapter for installing AR style buttstocks to the G36 assault rifle. Manufactured by Tommy Built.", + "6707cc67cc1667e49e0f7232 Name": "Infected blood sample", + "6707cc67cc1667e49e0f7232 ShortName": "Infected blood", + "6707cc67cc1667e49e0f7232 Description": "Without proper analysis, you would be unlikely to know how this blood differs from that of a healthy person.", + "6707cd70aab679420007e018 Name": "TG-Vi-24 sample", + "6707cd70aab679420007e018 ShortName": "TG-Vi-24", + "6707cd70aab679420007e018 Description": "Judging by the vial's protection, the substance inside is either very rare or extremely dangerous.", + "6707cef3571b50abc703b64f Name": "V.O. signed diary", + "6707cef3571b50abc703b64f ShortName": "V.O. diary", + "6707cef3571b50abc703b64f Description": "A souvenir diary for private notes. Apparently, TerraGroup used to give them to people when they were promoted to a new position.", + "6707cf827d279daad80fa95f Name": "Vaccine sample IV", + "6707cf827d279daad80fa95f ShortName": "Sample IV", + "6707cf827d279daad80fa95f Description": "One of the vaccine prototypes that Vladimir O. developed in secret from his colleagues.", + "6707d0804e617ec94f0e562f Name": "TG-Vi-24 lethal vaccine", + "6707d0804e617ec94f0e562f ShortName": "Vaccine", + "6707d0804e617ec94f0e562f Description": "This vaccine was developed by Therapist and Sanitar. The lethality of an infected patient is extremely high.", + "6707d0bdaab679420007e01a Name": "TG-Vi-24 true vaccine", + "6707d0bdaab679420007e01a ShortName": "True vaccine", + "6707d0bdaab679420007e01a Description": "A modified version of the vaccine with minimal lethality risk. Looks like Therapist and Sanitar have no intention of sharing it.", + "6707d13e4e617ec94f0e5631 Name": "Flash drive with special software", + "6707d13e4e617ec94f0e5631 ShortName": "Access", + "6707d13e4e617ec94f0e5631 Description": "This thumb drive can be used to set up a remote connection to the TerraGroup local servers for Mechanic.", + "6707d1f9571b50abc703b651 Name": "True vaccine recipe", + "6707d1f9571b50abc703b651 ShortName": "Vaccine recipe", + "6707d1f9571b50abc703b651 Description": "A recipe for a non-lethal vaccine that would drastically reduce the casualties of virus extermination.", + "6709133fa532466d5403fb7c Name": "AA-12 12ga 20-round drum magazine", + "6709133fa532466d5403fb7c ShortName": "AA-12", + "6709133fa532466d5403fb7c Description": "A 20-round 12-gauge drum magazine for the Auto Assault-12 shotgun.", + "670ad7f1ad195290cd00da7a Name": "Infectious strike", + "670ad7f1ad195290cd00da7a ShortName": "Infectious strike", + "670ad7f1ad195290cd00da7a Description": "It's best to avoid letting the infected get too close, as each strike can transmit the virus into your bloodstream.", + "670d125b7ca0004a2a021eae Name": "", + "670d125b7ca0004a2a021eae ShortName": "", + "670d125b7ca0004a2a021eae Description": "", + "670d1749d57ec3c3e20e81a6 Name": "", + "670d1749d57ec3c3e20e81a6 ShortName": "", + "670d1749d57ec3c3e20e81a6 Description": "", + "670d176bb7a8f34fce07fd9d Name": "", + "670d176bb7a8f34fce07fd9d ShortName": "", + "670d176bb7a8f34fce07fd9d Description": "", + "670d17df032591157e0c3538 Name": "", + "670d17df032591157e0c3538 ShortName": "", + "670d17df032591157e0c3538 Description": "", + "670d17f9d2d5ce4514027e83 Name": "", + "670d17f9d2d5ce4514027e83 ShortName": "", + "670d17f9d2d5ce4514027e83 Description": "", + "670d180f0fe9098f0c054642 Name": "", + "670d180f0fe9098f0c054642 ShortName": "", + "670d180f0fe9098f0c054642 Description": "", + "670d18225eef3711b30ace74 Name": "", + "670d18225eef3711b30ace74 ShortName": "", + "670d18225eef3711b30ace74 Description": "", + "670d18320fe9098f0c054644 Name": "", + "670d18320fe9098f0c054644 ShortName": "", + "670d18320fe9098f0c054644 Description": "", + "670d1843186ee334e70ee700 Name": "", + "670d1843186ee334e70ee700 ShortName": "", + "670d1843186ee334e70ee700 Description": "", + "670d1854032591157e0c353a Name": "", + "670d1854032591157e0c353a ShortName": "", + "670d1854032591157e0c353a Description": "", + "670d1862b7a8f34fce07fda7 Name": "", + "670d1862b7a8f34fce07fda7 ShortName": "", + "670d1862b7a8f34fce07fda7 Description": "", + "670d18746f8cc0145f0a0314 Name": "", + "670d18746f8cc0145f0a0314 ShortName": "", + "670d18746f8cc0145f0a0314 Description": "", + "670d18827ca0004a2a022603 Name": "", + "670d18827ca0004a2a022603 ShortName": "", + "670d18827ca0004a2a022603 Description": "", + "670d1892d2d5ce4514027e8a Name": "", + "670d1892d2d5ce4514027e8a ShortName": "", + "670d1892d2d5ce4514027e8a Description": "", + "670d18a3b7a8f34fce07fda9 Name": "", + "670d18a3b7a8f34fce07fda9 ShortName": "", + "670d18a3b7a8f34fce07fda9 Description": "", + "670d18b5032591157e0c353e Name": "", + "670d18b5032591157e0c353e ShortName": "", + "670d18b5032591157e0c353e Description": "", + "670d18e2e002387b88029112 Name": "", + "670d18e2e002387b88029112 ShortName": "", + "670d18e2e002387b88029112 Description": "", + "670d18f87ca0004a2a022606 Name": "", + "670d18f87ca0004a2a022606 ShortName": "", + "670d18f87ca0004a2a022606 Description": "", + "670d1907b7a8f34fce07fdab Name": "", + "670d1907b7a8f34fce07fdab ShortName": "", + "670d1907b7a8f34fce07fdab Description": "", + "670d1928e002387b88029114 Name": "", + "670d1928e002387b88029114 ShortName": "", + "670d1928e002387b88029114 Description": "", + "670d19397ca0004a2a022608 Name": "", + "670d19397ca0004a2a022608 ShortName": "", + "670d19397ca0004a2a022608 Description": "", + "670d19467ca0004a2a02260a Name": "", + "670d19467ca0004a2a02260a ShortName": "", + "670d19467ca0004a2a02260a Description": "", + "670d195519b4a3d9e9057637 Name": "", + "670d195519b4a3d9e9057637 ShortName": "", + "670d195519b4a3d9e9057637 Description": "", + "670d1966186ee334e70ee702 Name": "", + "670d1966186ee334e70ee702 ShortName": "", + "670d1966186ee334e70ee702 Description": "", + "670d197632cadb3aad0a49a5 Name": "", + "670d197632cadb3aad0a49a5 ShortName": "", + "670d197632cadb3aad0a49a5 Description": "", + "670d1989186ee334e70ee8cd Name": "", + "670d1989186ee334e70ee8cd ShortName": "", + "670d1989186ee334e70ee8cd Description": "", + "670d1999d57ec3c3e20e81da Name": "", + "670d1999d57ec3c3e20e81da ShortName": "", + "670d1999d57ec3c3e20e81da Description": "", + "670d19ab42245e21c30eed24 Name": "", + "670d19ab42245e21c30eed24 ShortName": "", + "670d19ab42245e21c30eed24 Description": "", + "670d1a053460753f070bb9b3 Name": "", + "670d1a053460753f070bb9b3 ShortName": "", + "670d1a053460753f070bb9b3 Description": "", + "670d1a13e002387b8802950c Name": "", + "670d1a13e002387b8802950c ShortName": "", + "670d1a13e002387b8802950c Description": "", + "670d1a2be002387b8802950e Name": "", + "670d1a2be002387b8802950e ShortName": "", + "670d1a2be002387b8802950e Description": "", + "670d1a396f8cc0145f0a0742 Name": "", + "670d1a396f8cc0145f0a0742 ShortName": "", + "670d1a396f8cc0145f0a0742 Description": "", + "670d1a4d6f8cc0145f0a0744 Name": "", + "670d1a4d6f8cc0145f0a0744 ShortName": "", + "670d1a4d6f8cc0145f0a0744 Description": "", + "670d1a5cd2d5ce45140289c3 Name": "", + "670d1a5cd2d5ce45140289c3 ShortName": "", + "670d1a5cd2d5ce45140289c3 Description": "", + "670d1a6f3460753f070bc0d9 Name": "", + "670d1a6f3460753f070bc0d9 ShortName": "", + "670d1a6f3460753f070bc0d9 Description": "", + "670d1a81b7a8f34fce080717 Name": "", + "670d1a81b7a8f34fce080717 ShortName": "", + "670d1a81b7a8f34fce080717 Description": "", + "670d1a92d2d5ce4514028b90 Name": "", + "670d1a92d2d5ce4514028b90 ShortName": "", + "670d1a92d2d5ce4514028b90 Description": "", + "670e2af7565b504d2b09371c Name": "", + "670e2af7565b504d2b09371c ShortName": "", + "670e2af7565b504d2b09371c Description": "", + "670e8eab8c1bb0e5a7075acf Name": "PM 9x18PM 90-93 8-round magazine", + "670e8eab8c1bb0e5a7075acf ShortName": "PM", + "670e8eab8c1bb0e5a7075acf Description": "A standard 8-round magazine for IzhMekh-produced Makarov PM pistols. It features a side observation slot for checking the magazine capacity.", + "670fa21e788477a9ce0549f6 Name": "", + "670fa21e788477a9ce0549f6 ShortName": "", + "670fa21e788477a9ce0549f6 Description": "", + "670fa4b08a2b9e2bde05b751 Name": "", + "670fa4b08a2b9e2bde05b751 ShortName": "", + "670fa4b08a2b9e2bde05b751 Description": "", + "670fb704b9e6567c8102cf08 Name": "", + "670fb704b9e6567c8102cf08 ShortName": "", + "670fb704b9e6567c8102cf08 Description": "", + "670fb76578245f17bb00ad85 Name": "", + "670fb76578245f17bb00ad85 ShortName": "", + "670fb76578245f17bb00ad85 Description": "", + "670fb78d5ce1f9ca3b04b6c6 Name": "", + "670fb78d5ce1f9ca3b04b6c6 ShortName": "", + "670fb78d5ce1f9ca3b04b6c6 Description": "", + "670fb7a4e6040a23520aa5d0 Name": "", + "670fb7a4e6040a23520aa5d0 ShortName": "", + "670fb7a4e6040a23520aa5d0 Description": "", + "670fb7bd2e9d3564120e91c7 Name": "", + "670fb7bd2e9d3564120e91c7 ShortName": "", + "670fb7bd2e9d3564120e91c7 Description": "", + "670fb7d425772b9ffb0c7f3a Name": "", + "670fb7d425772b9ffb0c7f3a ShortName": "", + "670fb7d425772b9ffb0c7f3a Description": "", + "670fced86a7e274b1a0964e8 Name": "AA-12 12ga 457mm barrel", + "670fced86a7e274b1a0964e8 ShortName": "AA-12 457mm", + "670fced86a7e274b1a0964e8 Description": "A 457mm barrel for the Auto Assault-12 12-gauge shotgun.", + "670fd03dc424cf758f006946 Name": "AA-12 12ga 342mm threaded barrel", + "670fd03dc424cf758f006946 ShortName": "AA-12 342mm", + "670fd03dc424cf758f006946 Description": "A 342mm threaded barrel for the Auto Assault-12 12-gauge shotgun.", + "670fd0a8d8d4eae4790c8187 Name": "AA-12 12ga 417mm threaded barrel", + "670fd0a8d8d4eae4790c8187 ShortName": "AA-12 417mm", + "670fd0a8d8d4eae4790c8187 Description": "A 417mm threaded barrel for the Auto Assault-12 12-gauge shotgun.", + "670fd0eed8d4eae4790c818a Name": "AA-12 thread protector", + "670fd0eed8d4eae4790c818a ShortName": "AA-12 cap", + "670fd0eed8d4eae4790c818a Description": "A barrel thread protector for the Auto Assault-12 12ga shotgun.", + "670fd1cc95c92bfc8e0bea39 Name": "AA-12 12ga choke", + "670fd1cc95c92bfc8e0bea39 ShortName": "AA-12 c.", + "670fd1cc95c92bfc8e0bea39 Description": "A special muzzle device for the Auto Assault-12 shotgun.", + "670fd23798663bc4b10e911a Name": "AA-12 stock assembly (FDE)", + "670fd23798663bc4b10e911a ShortName": "AA-12", + "670fd23798663bc4b10e911a Description": "A standard-issue stock assembly for the Auto Assault-12 shotgun. Flat Dark Earth version.", + "6710cea62bb09af72f0e6bf8 Name": "Leapers UTG Universal Shotgun Barrel Mount", + "6710cea62bb09af72f0e6bf8 ShortName": "UTG USBM", + "6710cea62bb09af72f0e6bf8 Description": "The UTG Universal Shotgun Barrel Mount is designed for mounting on tubular magazines and barrels with a diameter of 20-25 millimeters. Features 3 rails for attaching additional equipment. Manufactured by Leapers Inc.", + "6711039f9e648049e50b3307 Name": "TerraGroup Labs residential unit keycard ", + "6711039f9e648049e50b3307 ShortName": "Res. unit", + "6711039f9e648049e50b3307 Description": "A keycard to the residential unit in the containment block of TerraGroup Labs.", + "67110d06723c2733410161e8 Name": "HK G36 IDZ adjustable stock", + "67110d06723c2733410161e8 ShortName": "G36 IDZ", + "67110d06723c2733410161e8 Description": "A polymer adjustable buttstock for the G36 assault rifle, manufactured by Heckler & Koch.", + "67110d5ed1758189fc0bd221 Name": "HK G36 IDZ Convex Buttpad", + "67110d5ed1758189fc0bd221 ShortName": "IDZ Conv.", + "67110d5ed1758189fc0bd221 Description": "An extended convex buttpad designed for installation on IDZ stocks for the G36 assault rifle. Manufactured by Heckler & Koch.", + "67110d6fa71d1f123d021cd3 Name": "HK G36 IDZ Concave Buttpad", + "67110d6fa71d1f123d021cd3 ShortName": "IDZ Conc.", + "67110d6fa71d1f123d021cd3 Description": "A concave buttpad designed for installation on IDZ stocks for the G36 assault rifle. Manufactured by Heckler & Koch.", + "67110d8d388bded67304ceb4 Name": "Steyr AUG A3 Vltor 5.56x45 receiver", + "67110d8d388bded67304ceb4 ShortName": "A3 Vltor", + "67110d8d388bded67304ceb4 Description": "A low-profile receiver with built-in tactical equipment rail for AUG A3. Manufactured by Vltor.", + "67110dd41ad01bb88705347b Name": "Steyr AUG A3 Corvus Defensio Receiver Rail MOI 30 Slots", + "67110dd41ad01bb88705347b ShortName": "A3 CD", + "67110dd41ad01bb88705347b Description": "A low-profile sight mount for AUG A3. Manufactured by Corvus Defensio.", + "6711107e1ad01bb88705347e Name": "Steyr AUG Corvus Defensio KeyMod Forward Accessory Rail", + "6711107e1ad01bb88705347e ShortName": "CD KM", + "6711107e1ad01bb88705347e Description": "A KeyMod interface mount that replaces the standard front grip and allows installation of various accessories, designed for the AUG assault rifle. Manufactured by Corvus Defensio.", + "67111094d1758189fc0bd223 Name": "Corvus Defensio KeyMod 1.8 inch rail section", + "67111094d1758189fc0bd223 ShortName": "CD 1.8\"", + "67111094d1758189fc0bd223 Description": "The Corvus Defensio 1.8 inch KeyMod rail allows installation of additional equipment on the handguards equipped with a standard KeyMod interface.", + "6711109e723c2733410161eb Name": "Corvus Defensio KeyMod 6.8 inch rail section", + "6711109e723c2733410161eb ShortName": "CD 6.8\"", + "6711109e723c2733410161eb Description": "The Corvus Defensio 6.8 inch KeyMod rail allows installation of additional equipment on the handguards equipped with a standard KeyMod interface.", + "67112695fe5c8bf33f02476d Name": "Odin Works K-Pod KeyMod bipod adapter", + "67112695fe5c8bf33f02476d ShortName": "K-Pod", + "67112695fe5c8bf33f02476d Description": "A KeyMod interface mount that allows installation of bipods. Manufactured by Odin Works.", + "671126a210d67adb5b08e925 Name": "AI AXMC KeySlot Harris bipod mount", + "671126a210d67adb5b08e925 ShortName": "AI Harris", + "671126a210d67adb5b08e925 Description": "A KeySlot interface adapter that allows installation of Harris bipods to the AXMC precision rifle. Manufactured by Accuracy International.", + "671126b049e181972e0681fa Name": "Magpul M-LOK Bipod Mount", + "671126b049e181972e0681fa ShortName": "M-LOK BP", + "671126b049e181972e0681fa Description": "A mount allows installation of bipods on handguards equipped with a standard M-LOK interface. Manufactured by Magpul.", + "67124dcfa3541f2a1f0e788b Name": "MPS Auto Assault-12 Gen 2 12ga automatic shotgun", + "67124dcfa3541f2a1f0e788b ShortName": "AA-12 Gen 2", + "67124dcfa3541f2a1f0e788b Description": "The AA-12 (Auto Assault-12) is a reliable full-auto 12-gauge shotgun. The second generation features a mount for installing optics. This shotgun is distinguished by its recoil pulse accumulation, which makes the recoil feel smooth without sacrificing fire rate and stopping power. The AA-12 is designed for military and police units. Manufactured by Military Police Systems.", + "6718817435e3cfd9550d2c27 Name": "Steyr AUG A3 5.56x45 assault rifle (Black)", + "6718817435e3cfd9550d2c27 ShortName": "AUG A3", + "6718817435e3cfd9550d2c27 Description": "Steyr AUG A3 is a 5.56x45 bullpup assault rifle, developed by the Austrian company Steyr-Daimler-Puch. AUG is known for good ergonomics, decent accuracy, low recoil and sufficient reliability. The rifle also stands out for its futuristic design. The A3 version features a bolt-catch button. Black version.", + "671883292e2eeb98d406f3b8 Name": "Steyr AUG vertical foregrip (Black)", + "671883292e2eeb98d406f3b8 ShortName": "AUG", + "671883292e2eeb98d406f3b8 Description": "A vertical foregrip for the Steyr AUG assault rifle. Black version.", + "6719023b612cc94b9008e78c Name": "AA-12 stock assembly (TerraGroup)", + "6719023b612cc94b9008e78c ShortName": "AA-12 LABS", + "6719023b612cc94b9008e78c Description": "A standard-issue stock assembly for the Auto Assault-12 shotgun. TerraGroup version.", + "671a406a6d315b526708f103 Name": "Stolen weapon case", + "671a406a6d315b526708f103 ShortName": "Weapon case", + "671a406a6d315b526708f103 Description": "Stolen weapon case.", + "671d85439ae8365d69117ba6 Name": "TT 7.62x25 tt-105 8-round magazine", + "671d85439ae8365d69117ba6 ShortName": "tt-105", + "671d85439ae8365d69117ba6 Description": "A standard late-issue 8-round magazine for the TT pistol. It comes without a lanyard ring.", + "671d8617a3e45c1f5908278c Name": "MP-443 Grach 9x19 18-round magazine", + "671d8617a3e45c1f5908278c ShortName": "MP-443", + "671d8617a3e45c1f5908278c Description": "A standard 18-round 9x19 magazine for the MP-443 pistol.", + "671d8ac8a3e45c1f59082799 Name": "Glock 9x19 19-round magazine (Coyote)", + "671d8ac8a3e45c1f59082799 ShortName": "G19X", + "671d8ac8a3e45c1f59082799 Description": "A 19-round 9x19 magazine for Glock 19X pistols. Coyote version.", + "671d8b38b769f0d88c0950f8 Name": "M1911A1 .45 ACP Wilson Combat 7-round magazine", + "671d8b38b769f0d88c0950f8 ShortName": "Wilson", + "671d8b38b769f0d88c0950f8 Description": "A 7-round .45 ACP magazine with a steel low-profile base pad for Colt M1911 pistols, manufactured by Wilson Combat. Comes as a standard-issue magazine for the M45A1 pistol.", + "671d8b8c0959c721a50ca838 Name": "HK USP Tactical .45 ACP 12-round magazine", + "671d8b8c0959c721a50ca838 ShortName": "USP45T", + "671d8b8c0959c721a50ca838 Description": "A 12-round .45 ACP magazine for the special version of the USP45 pistol - USP45 Tactical.", " V-ex_light": "Road to Military Base V-Ex", " Voip/DisabledForOffline": "VoIP is unavailable in the offline mode", - " kg": " Kg", + " kg": " kg", "#": "#", "(K) Kills": "(K) Kills", "(K/D)": "(K/D)", @@ -12448,7 +13498,7 @@ "65bd1875c443e7fffb006e83": "Tier 1", "65bd187e578fa4a9f503f003": "Tier 2", "65bd1882b7378d56ab0817c3": "Tier 3", - "6617beeaa9cfa777ca915b7c Description": "An Arena host who organizes pit fights across Tarkov.", + "6617beeaa9cfa777ca915b7c Description": "The Arena host who organizes pit fights across Tarkov.", "6617beeaa9cfa777ca915b7c Location": "Tarkov airport", "6617beeaa9cfa777ca915b7c Nickname": "Ref", "7099Kills": "Level 71-99 players killed", @@ -12461,12 +13511,100 @@ "ACTIVE TASKS": "ACTIVE TASKS", "ADD NOTE": "ADD NOTE", "ADD/EDIT CONTAINER TAG": "ADD/EDIT CONTAINER TAG", + "ADDOFFER": "Add offer", "ADDTOFAVORITES": "Display in profile", "AI amount": "AI amount", "AI difficulty": "AI difficulty", "AMD FSR 2.1:": "AMD FSR 2.2:", "AMMO PENETRATION POWER": "Penetration", "AMMO PROJECTILE COUNT": "Projectile count", + "APC/ConfirmDestroyModified": "Are you sure you want to remove the modified equipment?", + "APC/CustomizationTab": "Customization", + "APC/EnterName": "Enter name", + "APC/FastAccess": "Quick access", + "APC/Locked": "Locked", + "APC/PurchasedStatesAll": "All", + "APC/ReadyToUlock": "Unlockable", + "APC/Unlocked": "Unlocked", + "APC/ViewPreset": "View", + "APCBar/Defence": "{0}Defense{1}", + "APCBar/Firepower": "{0}Firepower{1}", + "APCBar/Metascore": "{0}Metascore{1}", + "APCBar/Utility": "{0}Utility{1}", + "APCBar/Weight": "{0}Weight{1}", + "APCFilter/Ammo": "Ammo", + "APCFilter/Armor": "Body armor", + "APCFilter/ArmorePlate": "Ballistic plates", + "APCFilter/ArmoredFaceCover": "Armored masks", + "APCFilter/ArmoredHeadwear": "Armored headwear", + "APCFilter/ArmoredVest": "Armored vests", + "APCFilter/ArmoredVisors": "Ballistic glasses", + "APCFilter/AssaultCarbine": "Assault carbines", + "APCFilter/AssaultRifles": "Assault rifles", + "APCFilter/AssaultScope": "Assault scopes", + "APCFilter/Auxiliary": "Auxiliary parts", + "APCFilter/Barrel": "Barrels", + "APCFilter/Bipod": "Bipods", + "APCFilter/Charge": "Charging handles", + "APCFilter/Collimator": "Reflex sights", + "APCFilter/CompactCollimator": "Compact reflex sights", + "APCFilter/Drugs": "Pills", + "APCFilter/FaceCover": "Facewear", + "APCFilter/FaceShield": "Face shields", + "APCFilter/FlashHiderComensator": "Flash hiders, Muzzle brakes", + "APCFilter/Foregrip": "Foregrips", + "APCFilter/Functional": "Functional parts", + "APCFilter/Gasblock": "Gas systems", + "APCFilter/Gear": "Gear parts", + "APCFilter/GrenadeLauncher": "Grenade launchers", + "APCFilter/Handguard": "Handguards", + "APCFilter/Hats": "Hats", + "APCFilter/Headphones": "Active headsets", + "APCFilter/Headwear": "Headwear", + "APCFilter/IronSight": "Iron sights", + "APCFilter/Laser": "Lasers", + "APCFilter/Launcher": "Underbarrel launchers", + "APCFilter/LightLaser": "Light and laser sights", + "APCFilter/MachineGuns": "Machine guns", + "APCFilter/Magazine": "Magazines", + "APCFilter/MarksmanRifles": "Marksman rifles", + "APCFilter/Master": "Vital parts", + "APCFilter/Medical": "Wound treatment", + "APCFilter/Medkit": "Medkits", + "APCFilter/Melee": "Melee weapons", + "APCFilter/Mount": "Mounts", + "APCFilter/Muzzle": "Muzzle devices", + "APCFilter/MuzzleCombo": "Muzzle adapters", + "APCFilter/OpticScope": "Optics", + "APCFilter/PistolGrip": "Pistol grips", + "APCFilter/Pistols": "Pistols", + "APCFilter/Receiver": "Dust covers, Receivers, Trigger groups", + "APCFilter/SMGs": "Submachine guns", + "APCFilter/Shotguns": "Shotguns", + "APCFilter/Sight": "Sights", + "APCFilter/Silencer": "Suppressors", + "APCFilter/SniperRifles": "Bolt-action rifles", + "APCFilter/SpecialScope": "Special scopes", + "APCFilter/Stimulator": "Injectors", + "APCFilter/Stock": "Buttstocks", + "APCFilter/TacticalCombo": "Combo devices", + "APCFilter/Vest": "Gear rigs", + "APCFilter/Visors": "Eyewear", + "APCFilter/Weapons": "Weapons", + "APCFilters/ArmorPiece": "Armor components", + "APCMetascoreBarDescription/Defence": "Preset defense bar displays the meta score for all armor elements and items with protective properties", + "APCMetascoreBarDescription/Firepower": "Preset firepower bar displays the meta score for your weapon, ammo, and weapon mods", + "APCMetascoreBarDescription/Metascore": "Total potential preset power. Displays the sum of the {0}; {1}; {2} bars", + "APCMetascoreBarDescription/Utility": "Preset utility bar displays the meta score for medicine, gear rigs, and headsets", + "APCMetascoreBarDescription/Weight": "Depending on the weight of the equipment, different debuffs apply.{0}{0}Overweight status applies if you are in the {2}yellow{4} part of the bar:{0}{1}You make more noise{1}Reduced jump height{1}Increased stamina consumption{1}Increased fall damage{1}Reduced movement speed{1}Walking drains stamina{0}{0}Critical status is added to regular Overweight if you are in the {3}red{4} part of the bar:{0}{1}Cannot sprint{1}Reduced max stance height{1}Prone movement consumes stamina{1}Standing stance blocks stamina regain", + "APCTab/Ammo": "Ammo", + "APCTab/Favorite": "Favorites", + "APCTab/Meds": "Meds", + "APCTab/Mods": "Mods", + "APCTab/Weapon": "Weapon", + "APCTab/Wearings": "Gear", + "ARENA/ARMORY/LEVELINGUP": "LEVELING", + "ARENA/ARMORY/LINKS": "LINKS", "ARENA/MERCHANTS/NOEFTBUTTONTEXT": "Transfer to EFT is unavailable", "ARMOR CLASS": "ARMOR CLASS", "ARMOR POINTS": "ARMOR POINTS", @@ -12479,7 +13617,7 @@ "AVAILABLE ON LEVEL {0}": "AVAILABLE AT LEVEL {0}", "Abort": "ABORT", "About half": "About half", - "AcceptFriendsRequest": "Accept Friend Request", + "AcceptFriendsRequest": "Accept friend request", "AcceptInvitation": "Accept invitation", "AcceptScreen/ServerSettingsButton": "Raid settings", "Account is blocked until": "Account is blocked until", @@ -12500,8 +13638,10 @@ "Achievements/Tooltip/Conditions": "Objectives", "Achievements/Tooltip/Task rewards": "Rewards", "Acquire map to review infiltration areas and exfiltration points.": "Acquire a map to review infiltration areas and exfiltration points.", + "ActivateObject": "Plant the device", "Adaprive sharpen:": "Adaptive sharpen:", - "AddTOWISHLIST": "Add to w-list", + "AddOfferButton{0}/{1}": "Add offer {0}/{1}", + "AddTOWISHLIST": "Add to Wishlist", "AddUserToDialog": "{0} joined the chat.", "Adm Basement": "Admin Basement", "Administration Gate": "Administration Gate", @@ -12558,9 +13698,35 @@ "Are you sure you want to insure {0} items?": "Are you sure you want to insure the selected items?", "Are you sure you want to report {0}?": "Are you sure you want to report {0}?", "Arena welcome screen description": "Welcome to Arena!\n\nThis is where your character, an operator of a private military company (PMC), will battle other fighters for glory and cash. \n\nDue to the chaos of the conflict, in the city of Tarkov, Norvinsk region, law and order have taken a back seat. This is the place where rich observers have chosen to organize battles where PMCs will fight each other to the last survivor or work as a team to complete a certain objective - which, of course, they will be set by the Masters. \n\nIf you don't own Escape From Tarkov yet, you can purchase the game and transfer all your progress from the Arena there. \nIf you already own Escape From Tarkov, all progress gained in the Arena (experience and skills) will also count for your character in EFT and vice versa - progress in EFT counts for Arena.", - "Arena/CustomGame/Lobby/cancel invite to friends": "Cancel friends list invite", + "Arena/Apc/ClearHeader": "Deletion", + "Arena/Apc/ClearMessage": "Delete all items?", + "Arena/Apc/CloseHeader": "Confirmation", + "Arena/Apc/CloseMessage": "Save the changes?", + "Arena/Apc/CopyHeader": "Build copy", + "Arena/Apc/CopyMessage": "Loading the selected build will override the current build. Continue?", + "Arena/Apc/LoadHeader": "Reset", + "Arena/Apc/LoadMessage": "Reset the changes?", + "Arena/Apc/SaveHeader": "Preset saving", + "Arena/Apc/SaveMessage": "Save the changes?", + "Arena/Armory/ItemAlreadyUnlockedErrorDescription": "This Armory item is already unlocked", + "Arena/Armory/ItemAlreadyUnlockedErrorHeader": "Item already unlocked", + "Arena/Armory/ItemNotAvailabeToUnlockErrorDescription": "This item is unavailable to unlock", + "Arena/Armory/ItemNotAvailabeToUnlockErrorHeader": "Unlock unavailable", + "Arena/Armory/ItemNotFoundErrorDescription": "This item was not found", + "Arena/Armory/ItemNotFoundErrorHeader": "Item not found", + "Arena/Armory/LevelReward/readyToUlockState": "Ready", + "Arena/Armory/LevelReward/unlockedState": "Ready", + "Arena/BigCustomPurchaseInfo/Blocked": "Blocked", + "Arena/BigCustomPurchaseInfo/NotEnoughMoney": "Not enough money", + "Arena/BigCustomPurchaseInfo/Purchase": "Purchase", + "Arena/BlastGang/AtackGoal": "Attackers", + "Arena/BlastGang/DefenceGoal": "Defenders", + "Arena/BlastGang/ResultScreenOvertime": "Overtime", + "Arena/BlastGang/ResultScreenRoundsProgress": "{0} of {1}", + "Arena/BlastGang/ResultScreenSwapSides": "Switching sides", + "Arena/CustomGame/Lobby/cancel invite to friends": "Cancel friend list invite", "Arena/CustomGame/Lobby/cancel invite to group": "Cancel group invite", - "Arena/CustomGame/Lobby/invite to friends": "Invite to friends list", + "Arena/CustomGame/Lobby/invite to friends": "Invite to friend list", "Arena/CustomGame/Lobby/invite to group": "Invite to group", "Arena/CustomGame/Lobby/kick": "Kick", "Arena/CustomGame/Lobby/move to team": "Move to team", @@ -12575,6 +13741,7 @@ "Arena/CustomGames/Creation/TitleScreen": "Room settings", "Arena/CustomGames/GamesList": "Room list", "Arena/CustomGames/Guests": "Unassigned", + "Arena/CustomGames/LastHeroTitle": "Players", "Arena/CustomGames/Lobby/AdditionalSettings": "Additional settings", "Arena/CustomGames/Lobby/Game": "Game", "Arena/CustomGames/Lobby/ServerSettings": "Server", @@ -12605,16 +13772,31 @@ "Arena/CustomGames/toggle/room name": "Room name", "Arena/CustomGames/toggle/tournament": "Tournament", "Arena/EndMatchNotification": "Match has ended while you were away", + "Arena/EnterPresetName": "Enter preset name", + "Arena/MVP": "MVP", + "Arena/MVP/DamageStatLabel": "Damage dealt to enemies", + "Arena/MVP/DeactivatedBomb": "Deactivated the device", + "Arena/MVP/DeviceInteractLabel": "Devices planted/deactivated", + "Arena/MVP/ExplodedBomb": "Successfully activated the device", + "Arena/MVP/ObjectiveCaptureLabel": "Objectives captured", + "Arena/MVP/PointCaptured": "Captured the objective", + "Arena/MVP/RoundMVPLabel": "Round MVPs received", + "Arena/MVP/TeamDefenseKilled": "Highest kill count", + "Arena/MVP/TeamKilled": "Highest kill count", + "Arena/MVP/TechnicalWin": "For good behavior", + "Arena/MainQuestLabel": "Main task", "Arena/Matching/CustomGames": "Custom games", "Arena/Notification/Selection/Blocked": "Preset purchase blocked", "Arena/OnCancelMatch": "Matching canceled due to loading issues", "Arena/OnCancelMatch/Group": "Matching canceled due to group member having loading issues", "Arena/OnCancelMatch/NoServer": "Could not find an available server. Please try later.", + "Arena/Popup/Quests/FreeRefresh {0}": "Free {0}", + "Arena/Popup/RefreshDailyQuest {0}": "Task replacement / {0}", "Arena/Popups/ReceivePackage": "RECEIVE PACKAGE / TARKOV", "Arena/Popups/TwitchDropsHeader": "Redeem gift", "Arena/Preset/Tooltip/Tab/6": "Various unique collectible presets.", "Arena/Preset/Tooltip/Tab/Assault": "Assault is the most versatile class. Presets of this class have balanced equipment suitable for most combat situations.", - "Arena/Preset/Tooltip/Tab/CQB": "CQB is the most heavily armored class in the Arena. CQBs are characterized by their face shields and increased ammunition for their main weapons. Presets of this class are excellent in defending positions and prolonged firefights.", + "Arena/Preset/Tooltip/Tab/CQB": "Enforcer is the most heavily armored class in the Arena. Enforcers are characterized by their face shields and increased ammunition for their main weapons. Presets of this class are excellent in defending positions and prolonged firefights. ", "Arena/Preset/Tooltip/Tab/Collection": "Presets given for special achievements in the Arena.", "Arena/Preset/Tooltip/Tab/Favorite": "Your favorited set of presets.", "Arena/Preset/Tooltip/Tab/Marksman": "Marksman is a class for long-range combat. Presets of this class often have powerful secondary weapons and reasonable armor protection. This highly specialized class is indispensable in outdoor Arenas.", @@ -12624,6 +13806,7 @@ "Arena/Presets/Tooltips/Ammo": "Ammo", "Arena/Presets/Tooltips/Armor": "Armor", "Arena/Presets/Tooltips/ArmorDamage": "Penetration", + "Arena/Presets/Tooltips/ArmorRate": "Penetration", "Arena/Presets/Tooltips/Bonus/Buffs/Arp": "ARP bonus", "Arena/Presets/Tooltips/Bonus/Buffs/Exp": "Experience bonus", "Arena/Presets/Tooltips/Bonus/Buffs/Rub": "Money bonus", @@ -12675,9 +13858,15 @@ "Arena/Tiers/UnlockedPresets": "Presets unlocked", "Arena/Tooltip/MapSelectedCounter": "Number of selected locations", "Arena/Tooltip/MinMapCount {0}": "Select multiple locations. You need to select at least {0} location(s)", + "Arena/UI/APCItemBuyCaption": "Item unlock", + "Arena/UI/APCItemBuyDescription": "Purchase the item?", + "Arena/UI/APCItemGetDescription": "Receive item?", + "Arena/UI/APCItemNoMoneyDescription": "Not enough money", "Arena/UI/Awaiting-Players": "Waiting for players", + "Arena/UI/BasePreset": "BASE PRESET", "Arena/UI/Confirm-Match": "Confirm", "Arena/UI/CustomMode": "Custom", + "Arena/UI/CustomPreset": "CUSTOM PRESET", "Arena/UI/Disband-Game/Title": "GAME DISBAND", "Arena/UI/Excluded-from-tre-group": "- You will be kicked from your group", "Arena/UI/Game-Found": "Game found", @@ -12699,17 +13888,27 @@ "Arena/UI/Selection/Blocked": "Preset taken", "Arena/UI/Waiting": "Waiting...", "Arena/Ui/ServerFounding": "Looking for server...", + "Arena/Widgets/Event/activating object": "Planting the device", + "Arena/Widgets/Event/can activate object": "Plant the device", + "Arena/Widgets/Event/deactivate object": "Deactivate the device", + "Arena/Widgets/Event/deactivating object": "Deactivating the device", + "Arena/Widgets/Event/defend object": "Defend the device", + "Arena/Widgets/Event/pickup object": "Pick up the device", "Arena/Widgets/Observer/capture point": "Capture the objective", "Arena/Widgets/Observer/contesting point": "Objective contested", "Arena/Widgets/Observer/eliminate team": "Cleanup crew is coming!", "Arena/Widgets/Observer/kill all enemies": "Eliminate the enemy team", "Arena/Widgets/Observer/{0} team capturing point": "Team {0} are capturing the objective", "Arena/Widgets/Observer/{0} team win": "Team {0} won", + "Arena/Widgets/activate object": "Plant the device", "Arena/Widgets/additional time": "Extra time", "Arena/Widgets/ally captured point": "Your team captured the objective", "Arena/Widgets/ally capturing point": "Your team is capturing the objective", "Arena/Widgets/capture point": "Capture the objective", + "Arena/Widgets/capture point hold": "Capture and hold the objectives", "Arena/Widgets/contesting point": "Objective contested", + "Arena/Widgets/deactivate object": "Deactivate the device", + "Arena/Widgets/defend object": "Defend the device", "Arena/Widgets/died": "died", "Arena/Widgets/draw": "Draw", "Arena/Widgets/eliminate team": "Cleanup crew is coming!", @@ -12723,6 +13922,10 @@ "Arena/Widgets/killed himself": "commited suicide", "Arena/Widgets/main time": "Main time", "Arena/Widgets/match": "Match", + "Arena/Widgets/match draw": "Match draw", + "Arena/Widgets/match lose": "Match lost", + "Arena/Widgets/match win": "Match won", + "Arena/Widgets/pickup object": "Pick up the device", "Arena/Widgets/prepare to fight": "Prepare to fight", "Arena/Widgets/ranked": "Ranked mode", "Arena/Widgets/round lose": "Round lost", @@ -12738,8 +13941,18 @@ "Arena/Widgets/{0} team win": "{0} team won", "Arena/popups/leadership for random player": "Leadership will be transferred to a random remaining player", "Arena/popups/you stay leader": "You will stay the group leader", + "Arena/presets/footer/not ready": "NOT READY", + "Arena/presets/footer/ready": "READY", + "ArenaArmoryScreen/TutorialButton": "Tutorial", "ArenaIntoxication": "Strong Poison", "ArenaPostMatchScreen/DailyExpBonus {0}": "Daily first win bonus: {0}", + "ArenaPresetCustomizationScreen/Delete": "Delete preset", + "ArenaPresetCustomizationScreen/DownloadTo": "Load preset as template", + "ArenaPresetCustomizationScreen/Favorite": "Add preset to Favorites", + "ArenaPresetCustomizationScreen/HighlightToggle": "Display item compatibility", + "ArenaPresetCustomizationScreen/Save": "Save preset", + "ArenaPresetCustomizationScreen/StepBack": "Revert changes", + "ArenaPresetCustomizationScreen/TutorialButton": "Tutorial", "ArenaPresetViewScreen/CurrentRankPreset": "Current rank preset", "ArenaPresetViewScreen/base": "Base", "ArenaPresetViewScreen/exp_progress": "Preset EXP progress", @@ -12810,6 +14023,31 @@ "Armor Zone SpineDown": "Lower back", "Armor Zone SpineTop": "Upper back", "ArmorVest": "Body Armor\n", + "ArmoryCondition/ArenaArmoryProgression": "Reach weapon level {0} with:", + "ArmoryCondition/ArenaRank": "Rank", + "ArmoryCondition/CompletedDailyQuests": "Complete daily tasks:", + "ArmoryCondition/CompletedWeeklyQuests": "Complete weekly tasks:", + "ArmoryCondition/HideoutAreaLevel": "Reach Hideout level:", + "ArmoryCondition/ProfileLevel": "Reach level:", + "ArmoryCondition/QuestStatus": "Complete task:", + "ArmoryCondition/Side": "Available only to:", + "ArmoryCondition/TraderLoyaltyLevel": "Reach {0} loyalty level:", + "ArmoryCondition/TraderStanding": "Reach {0} standing:", + "ArmoryCondition/UnlockedAchievements": "Earn achievement:", + "ArmoryCondition/UnlockedArenaArmoryItems": "Unlock item in Armory:", + "ArmoryTutor/Complete": "Finish tutorial", + "ArmoryTutor/LevelsDescription": "When fighting in the Arena, you level up your weapons.\nEach level unlocks weapon attachments that improve the weapon's stats.", + "ArmoryTutor/LevelsTipDescription": "Don't forget to claim your weapon level rewards.", + "ArmoryTutor/LevelsTitle": "Weapon levels", + "ArmoryTutor/LinkedDescription": "Link search will help you explore the connections between items.\nFor weapons, it's attachments, ammo and magazines, and for armor, it's ballistic plates.", + "ArmoryTutor/LinkedTipDescription": "Unlocked attachments are available on any compatible weapon.", + "ArmoryTutor/LinkedTitle": "Links", + "ArmoryTutor/UnlockDescription": "You can buy items for roubles and GP Coins.\nTo buy some items you need to fulfill special conditions,\nsuch as completing daily tasks or reaching a certain profile level.", + "ArmoryTutor/UnlockTipDescription": "GP Coins can be earned for completing operational tasks given by Ref.", + "ArmoryTutor/UnlockTitle": "Unlocking items", + "ArmoryTutor/WelcomeDescription": "This is where you will find all the items to customize your character", + "ArmoryTutor/WelcomeStart": "Start", + "ArmoryTutor/WelcomeTitle": "Welcome to the Armory", "Aspect ratio:": "Aspect ratio:", "Assault": "Assault Rifles", "AssaultCarbine Mastering": "Assault carbine", @@ -12853,6 +14091,7 @@ "BAD_RTT": "Server connection has been closed due to low connection quality", "BEAR": "BEAR", "BEAR Matchmaker": "Begin a raid as your main character, an ex-BEAR PMC operator, and do everything necessary to escape from Tarkov alive.", + "BIPOD RECOIL BUFF": "Mounted recoil buff", "BLEEDING": "BLEEDING", "BTR": "BTR", "BULLET SPEED": "BULLET VELOCITY", @@ -12880,6 +14119,7 @@ "Beyond Fuel Tank": "Passage Between Rocks", "Binaural audio settings will be applied after raid restart.": "Binaural audio settings will be applied after game restart.", "BitcoinFarm": "BITCOIN FARM", + "BlastGangDescription": "A team battle in a 5v5 format. A classic Search and Destroy game mode with one side attacking and the other defending.", "BlindShootAbove": "Overhead blind fire", "BlindShootRight": "Right side blind fire", "Blood": "Blood", @@ -12934,6 +14174,7 @@ "CHANGE TURNING SPEED": "TURN SPEED", "CHECKHIM": "CHECK HIM", "CHECKMAGAZINE": "CHECK MAGAZINE", + "CIRCLEOFCULTISTS": "Cultist Circle", "CLEAR": "CLEAR", "CLONE": "Duplicate", "CLOTHING UNLOCK": "CLOTHING UNLOCK", @@ -12949,6 +14190,7 @@ "CONTACT": "CONTACT", "CONTAINER TYPE": "CONTAINER TYPE", "CONTAINERSIZE": "CONTAINER SIZE", + "CONTINUE": "CONTINUE", "CONTROLS": "CONTROLS", "COOPERATION": "COOPERATE", "COPY": "Copy", @@ -12961,7 +14203,17 @@ "CURRENT NEGATIV BONUSES:": "CURRENT PENALTIES:", "CURRENT RANK": "CURRENT RANK", "CURRENT WEATHER CONDITIONS:": "CURRENT WEATHER CONDITIONS:", - "Caching data...": "Caching data...", + "CUS_TRANSIT_10": "TRANSIT01", + "CUS_TRANSIT_10_COND": " ", + "CUS_TRANSIT_10_DESC": "Transit to Factory", + "CUS_TRANSIT_11": "TRANSIT02", + "CUS_TRANSIT_11_COND": " ", + "CUS_TRANSIT_11_DESC": "Transit to Interchange", + "CUS_TRANSIT_9": "TRANSIT03", + "CUS_TRANSIT_9_COND": " ", + "CUS_TRANSIT_9_DESC": "Transit to Reserve", + "Caching data...": "Caching...", + "Calculated tax {0} real (backend tax) {1}": "Wrong fee: calculated fee is {0}, expected fee is {1}", "Camera Bunker Door": "Camera Bunker Door", "Can't find a place for item": "Can't find a place for the item", "Can't find any appropriate magazine": "No compatible magazines", @@ -12990,19 +14242,19 @@ "Charisma": "Charisma", "CharismaAdditionalDailyQuests": "Adds one more daily operational task", "CharismaBuff1": "Reduces traders' cash prices by [{0:0.#%}]", - "CharismaBuff2": "Increases traders' loyalty rate by [{0:0.#%}]", + "CharismaBuff2": "Increases traders' standing rate by [{0:0.#%}]", "CharismaDailyQuestsRerollDiscount": "Reduces operational task replacement cost by [{0:0.#%}]", "CharismaDescription": "Mastering the art of charisma allows to receive discounts on various services.", "CharismaEliteBuff1": "You are the first to know the latest trading news", "CharismaEliteBuff2": "Increases profit from every transaction by [{0:0.#%}]", "CharismaExfiltrationDiscount": "Reduces paid exfil prices by [{0:0.#%}]", - "CharismaFenceRepPenaltyReduction": "Reduces Fence reputation penalty", + "CharismaFenceRepPenaltyReduction": "Reduces Fence standing penalty", "CharismaHealingDiscount": "Reduces after-raid healing services prices by [{0:0.#%}]", "CharismaInsuranceDiscount": "Reduces insurance services prices by [{0:0.#%}]", "CharismaLevelingUpDescription": "The Charisma skill is improved indirectly by leveling the Attention, Perception, and Intellect skills.", "CharismaScavCaseDiscount": "Adds a discount to Scav Case prices", - "ChatScreen/QuestItemsListHeader": "The following items will be moved to quest item stash:", - "ChatScreen/QuestItemsMoved": "Items successfully moved to quest item stash", + "ChatScreen/QuestItemsListHeader": "The following items will be moved to the task item stash:", + "ChatScreen/QuestItemsMoved": "Items successfully moved to task item stash", "Check your email": "Please check the email you used to register this account. You will receive the Device ID within 5 minues from now.", "CheckAmmo": "Check ammo", "CheckChamber": "Check chamber/Fix malfunction", @@ -13020,6 +14272,7 @@ "Cleanoperationsdescription": "Clean operations", "Clear memory": "Automatic RAM Cleaner", "Clear table": "Clear table", + "Client operation rejected by server": "Operation rejected by server", "Client time de-synchronized with Server time for ~{0} ms": "Client time de-synchronized with Server time for ~{0} ms", "ClientPlayerBlocking/MatchLeave": "Game mode temporarily blocked due to quitting a match", "ClientPlayerBlocking/NotAcceptedMatch": "Game mode temporarily blocked due to failing to accept a match", @@ -13032,12 +14285,15 @@ "ClothingItem/Preview": "Preview", "ClothingItem/Purchase": "Available", "ClothingItem/Unavailable": "Unavailable", + "ClothingPanel/Available_both_games": "Available both in EFT and Arena", + "ClothingPanel/Available_only_arena": "Available only in Arena", "ClothingPanel/ExternalObtain": "Available for purchase on the website", "ClothingPanel/InternalObtain": "Trader purchase conditions:", "ClothingPanel/LoyaltyLevel": "Trader\nLoyalty Level:", "ClothingPanel/PlayerLevel": "Player\nLevel:", + "ClothingPanel/RequiredAchievements": "Achievement:", "ClothingPanel/RequiredPayment": "Required\nPayment:", - "ClothingPanel/RequiredQuest": "Completed\ntask:", + "ClothingPanel/RequiredQuest": "Completed\nTask:", "ClothingPanel/RequiredSkill": "Required\nSkill:", "ClothingPanel/StandingLevel": "Trader\nStanding:", "CloudinessType/Clear": "Clear", @@ -13046,6 +14302,10 @@ "CloudinessType/HeavyCloudCover": "Heavy cloud cover", "CloudinessType/PartlyCloudy": "Partly cloudy", "CloudinessType/Thundercloud": "Thunderclouds", + "CloudsMode/High": "high", + "CloudsMode/Low": "low", + "CloudsMode/Medium": "medium", + "CloudsMode/Ultra": "ultra", "Co-op mode settings": "Practice mode settings", "Coastal_South_road": "Southern Road", "Collider Type Back": "Thorax, Back", @@ -13138,6 +14398,39 @@ "Current attitude:": "Current attitude:", "Current location:": "Current location:", "Custom/Description": "Custom Game\nIn this mode, you can create a match according to your own rules or join an existing room.\nProgress made in this game mode is not saved!", + "CustomPresetsTutor/ClassAssaultDescription": "A versatile class balancing offense and defense", + "CustomPresetsTutor/ClassAssaultTitle": "Assault", + "CustomPresetsTutor/ClassDescription": "Available preset classes:", + "CustomPresetsTutor/ClassInfo": "Each class has different metascore limits. Equip your preset with weapons, \nammunition, armor, and medical supplies so that each of the bars is within the green zone.", + "CustomPresetsTutor/ClassMPHigh": "upper limit", + "CustomPresetsTutor/ClassMPLow": "lower limit", + "CustomPresetsTutor/ClassMPTarget": "permitted meta score", + "CustomPresetsTutor/ClassScoutDescription": "An offensive class with access to armor-piercing ammunition and rapid-fire weapons", + "CustomPresetsTutor/ClassScoutTitle": "Scout", + "CustomPresetsTutor/ClassSniperDescription": "A specialist class that fights at long distances", + "CustomPresetsTutor/ClassSniperTitle": "Marksman", + "CustomPresetsTutor/ClassSqbDescription": "A defensive class with great variability in body and head protection", + "CustomPresetsTutor/ClassSqbTitle": "Enforcer", + "CustomPresetsTutor/ClassTitle": "Class system and preset meta score", + "CustomPresetsTutor/Complete": "Start building", + "CustomPresetsTutor/ConsumeDescription": "Preset utility bar displays the meta score for medicine, gear rigs, and headsets.", + "CustomPresetsTutor/ConsumeTipDescription": "Don't forget to add consumables to the quick access panel.", + "CustomPresetsTutor/ConsumeTitle": "Meta score bars. Utility", + "CustomPresetsTutor/DefenceDescription": "Preset defense bar displays the meta score for all armor elements and items with protective properties. \nYou can swap ballistic plates, and add or remove extra protection attachments from helmets.", + "CustomPresetsTutor/DefenceTipDescription": "You can change the ballistic plates in body armor and plate carriers. Helmets can be equipped with visors.", + "CustomPresetsTutor/DefenceTitle": "Meta score bars. Defense", + "CustomPresetsTutor/FireDescription": "Preset firepower bar displays the meta score for your weapon, ammo, and weapon mods.", + "CustomPresetsTutor/FireTipDescription": "Don't forget to load ammo to your magazines.", + "CustomPresetsTutor/FireTitle": "Meta score bars. Firepower", + "CustomPresetsTutor/MPDescription": "Meta score is a universal performance rating for items in EFT:Arena. \nEach piece of equipment has its own meta score.", + "CustomPresetsTutor/MPTipDescription": "It's best not to skip this tutorial.", + "CustomPresetsTutor/MPTitle": "Meta score", + "CustomPresetsTutor/Skip": "Skip", + "CustomPresetsTutor/TipTitle": "Quick tip!", + "CustomPresetsTutor/WelcomeDescription": "Here you will learn the basic mechanics of creating your own presets \nand how to build the most effective preset for your matches.", + "CustomPresetsTutor/WelcomeStart": "Start", + "CustomPresetsTutor/WelcomeTitle": "Welcome to Custom Presets", + "CustomizationNotExists": "Unavailable clothing in one or more presets", "Customs": "Customs", "DAILY QUESTS": "Operational tasks", "DAMAGE REDUCTION COMMON BUFF": "REDUCES INCOMING DAMAGE (COMMON)", @@ -13167,7 +14460,7 @@ "Daily/Stat/Easy": "Total easy tasks completed", "Daily/Stat/ExpEarned": "Experience earned for task completion", "Daily/Stat/Fails": "Total tasks failed", - "Daily/Stat/FavoriteQuest": "Favorite type of tasks", + "Daily/Stat/FavoriteQuest": "Favorite task type", "Daily/Stat/Hard": "Total hard tasks completed", "Daily/Stat/Header": "Operational tasks", "Daily/Stat/MaxCompleteStreak": "Max streak of completed tasks", @@ -13184,9 +14477,10 @@ "DailyQuestName/Completion": "Find and transfer", "DailyQuestName/Elimination": "Elimination", "DailyQuestName/Exploration": "Exit the location", - "DailyQuestName/PickUp": "Find and extract from the raid", + "DailyQuestName/PickUp": "Find and extract", "DailyQuests": "Operational tasks", "DamageModifier": "Damage taken (except the head)", + "DamageType_Artillery": "82mm mortar round", "DamageType_Barbed": "Barbed wire", "DamageType_Bloodloss": "Bloodloss", "DamageType_Blunt": "Blunt damage", @@ -13209,6 +14503,7 @@ "DamageType_Stimulator": "Stimulant side effect", "DamageType_Undefined": "Previous damage", "Day": "Day", + "DeactivateObject": "Deactivate the device", "Dead": "Dead", "Dead Man's Place": "Dead Man's Place", "DeathInfo/BackHead": "Nape", @@ -13249,7 +14544,7 @@ "DeathInfo/SpineDown": "Lower back", "DeathInfo/SpineTop": "Upper back", "DeathInfo/Stomach": "Stomach", - "DeclineFriendsRequest": "Decline Friend Request", + "DeclineFriendsRequest": "Decline friend request", "DeclineInvitation": "Decline invitation", "Decrease": "Decreases by", "Default": "Default", @@ -13263,6 +14558,7 @@ "Deploying in progress": "Deploying", "Deploying in:": "Deploying in:", "Description": "Description", + "Develop_Right": "Activate", "Dialog is not selected yet": "No chat is selected", "Died": "Died", "Disable": "Disabled", @@ -13273,7 +14569,7 @@ "Disabled": "Disabled", "DisbandGroup": "Disband the group", "DisbandGroup message": "Are you sure you want to disband the group?", - "DiskMipStreamingUsageIntensity: ": "Mip Streaming disk usage limit", + "DiskMipStreamingUsageIntensity: ": "Mip Streaming disk usage limit:", "Dislocation": "Disposition", "Display has changed. Do you want to keep the changes?": "Display settings have changed. Do you want to keep the changes?", "Display offers from": "Display offers from", @@ -13281,6 +14577,7 @@ "Do you really want to delete dialog with user: {0}?": "Are you sure you want to delete the dialog with {0}?", "Dogtag": "DOGTAG", "Don't allow to add me": "Prevent incoming friend requests", + "Donate": "Sacrifice", "Dorms V-Ex": "Dorms V-Ex", "Draw": "Draw", "DrawElite": "Steady aim for the first 3 seconds with any stamina condition", @@ -13294,6 +14591,7 @@ "DropBackpack": "Drop backpack", "DropItem": "Drop Item", "Duck": "Crouch", + "Duplicate": "DUPLICATE", "Dur.": "Dur.", "Duration": "Duration", "E1": "Stylobate Building Elevator", @@ -13312,11 +14610,24 @@ "EAntialiasingMode/None": "Off", "EAntialiasingMode/TAA_High": "TAA High", "EAntialiasingMode/TAA_Low": "TAA", + "EAreaType/CircleOfCultists/Tooltip": "Cultist Circle bonuses\n\nThe value of each sacrificed item is added up. This total determines the value of items received as a Gift from the cultists.\n\nIf the value of a single sacrifice is above a certain threshold, there is a chance to receive items needed for active tasks and unfinished Hideout zones.\n\nThe value of the Gifts is further increased by the bonuses.\n\nThe cultists cannot deliver their Gift while you are in the Hideout.\n\nBonuses:\n— Sacrificing a Sacred Amulet increases the Gift's value by {0}%\n— The Hideout Management skill increases the bonus of Sacred Amulet", + "EAreaType/EquipmentPresetsStand/Tooltip": "The rack can be equipped with any gear. \n\nIn the presets menu, you can equip gear from one of the mannequins or exchange the gear already equipped by your PMC for the mannequin's gear. \n\nPouch items and special slot items do not apply to equipping and exchanging.", "EAreaType/PlaceOfFame/Tooltip": "Gaining bonuses for PMC dogtags.\n\nBonuses are given for dogtags of PMC players who are:\n- Of the opposing faction;\n- Not in your friend list;\n- Not in your group at the time of the kill.\n\nEach dogtag level brings a {0}% bonus\nMaximum bonus for one dogtag is {1}%", - "EArenaPresetsType/Assault": "Assault", - "EArenaPresetsType/CQB": "CQB", - "EArenaPresetsType/Marksman": "Marksman", - "EArenaPresetsType/Scout": "Scout", + "EArenaClothingSortingType/All": "All", + "EArenaClothingSortingType/PurchaseAvailable": "Available for purchase", + "EArenaClothingSortingType/Purchased": "Purchased", + "EArenaClothingSortingType/Unavailable": "Unavailable", + "EArenaPresetClass/Assault": "Assault", + "EArenaPresetClass/CQB": "Enforcer", + "EArenaPresetClass/Marksman": "Marksman", + "EArenaPresetClass/Scout": "Scout", + "EArenaPresetClass/collection": "COLLECTION", + "EArenaPresetsListType/Base": "Standard", + "EArenaPresetsListType/Custom": "Custom", + "EAutoAddToWishlist/AllHideout": "Favorite crafting recipes and Hideout zones", + "EAutoAddToWishlist/Disabled": "Disabled", + "EAutoAddToWishlist/Recipes": "Favorite crafting recipes", + "EAutoAddToWishlist/Zones": "Hideout zone upgrade items", "EAutoVaultingUseMode/Automatic": "Auto", "EAutoVaultingUseMode/Hotkey": "Hotkey", "EBackendErrorCode/CantChangeReadyState": "Error changing ready status", @@ -13326,6 +14637,7 @@ "EBackendErrorCode/GroupSendInviteError": "Error sending group invite", "EBackendErrorCode/ItemHasBeenSold": "Item has already been sold.", "EBackendErrorCode/LimitForPresetsReached": "Equipment kit limit reached", + "EBackendErrorCode/NoArenaSync": "Error connecting to Arena. Please, try again later.", "EBackendErrorCode/OfferSold": "Offer is already sold", "EBackendErrorCode/PlayerAlreadyInGroup": "Player is already in group", "EBackendErrorCode/PlayerAlreadyLookingForGame": "Player is already matching", @@ -13338,6 +14650,8 @@ "EBackendErrorCode/PlayerNotInGroup": "Player is not in group", "EBackendErrorCode/PlayerNotLeader": "Player is not the leader", "EBackendErrorCode/PlayerProfileNotFound": "Player profile not found", + "EBackendErrorCode/PlayerTooManyPartyRequests": "Too many group invites. Please try again later.", + "EBackendErrorCode/RaidConfigurationError": "Game mode configuration error", "EBackendErrorCode/TooManyInviteRequests": "Exceeded the limit of invites sent to one player. Try again in {0} sec.", "EBtrInteractionStatus/Blacklisted": "You are not allowed access to the BTR!", "EBtrInteractionStatus/BusyDoor": "Door is in use!", @@ -13371,6 +14685,11 @@ "EFSR2Mode/Performance": "performance", "EFSR2Mode/Quality": "quality", "EFSR2Mode/UltraPerformance": "ultra performance", + "EFSR3Mode/Balanced": "balanced", + "EFSR3Mode/Off": "off", + "EFSR3Mode/Performance": "performance", + "EFSR3Mode/Quality": "quality", + "EFSR3Mode/UltraPerformance": "ultra performance", "EFSRMode/Balanced": "balanced", "EFSRMode/Off": "off", "EFSRMode/Performance": "performance", @@ -13380,8 +14699,19 @@ "EFT/UI/TRADING/ARENAEFTTRANSFER/ARENANOTPURCHASED": "An active EFT: Arena profile is required to transfer items", "EFT/UI/Trading/ArenaEftTransfer/ArenaEftItemsTransfer": "Items transfer", "EFT/UI/Trading/ArenaEftTransfer/CancelTransfer": "Cancel transfer", + "EFT/UI/Trading/ArenaEftTransfer/CannotTransferToArena": "Unable to transfer to Arena", + "EFT/UI/Trading/ArenaEftTransfer/CommissionTooltip/ArenaNotPurchased": "Arena not purchased", + "EFT/UI/Trading/ArenaEftTransfer/CommissionTooltip/LimitExhausted": "Transfer limit exhausted", + "EFT/UI/Trading/ArenaEftTransfer/CommissionTooltip/NotEnoughMoneyForTax": "Not enough money to cover the fee", + "EFT/UI/Trading/ArenaEftTransfer/CommissionTooltip/ServiceUnavaliable": "Transfer unavailable", + "EFT/UI/Trading/ArenaEftTransfer/NoArenaSyncButtonText": "No connection with Arena! Retry in {0}", "EFT/UI/Trading/ArenaEftTransfer/TimeLetfToCancelTransfer": "Time left to cancel transfer:", "EFT/UI/Trading/ArenaEftTransfer/Transfertoarena": "Transfer to Arena", + "EFT/UI/Trading/ArenaEftTransfer/СommissionTooltip/CharismaBonus": "charisma bonus", + "EFT/UI/Trading/ArenaEftTransfer/СommissionTooltip/Header": "Fee calculation", + "EFT/UI/Trading/ArenaEftTransfer/СommissionTooltip/ItemTransfer": "Item transfer", + "EFT/UI/Trading/ArenaEftTransfer/СommissionTooltip/MoneyTransfer": "Money transfer", + "EFT/UI/Trading/ArenaEftTransfer/СommissionTooltip/StandingBonus": "standing bonus", "EFT/UI/Trading/Arenaefttransfer/Dailytansferlimit": "Daily limit", "EFT/UI/Trading/Arenaefttransfer/Dailytransferlimit": "Daily limit", "EFT/UI/Trading/Arenaefttransfer/Storage": "Stash", @@ -13393,6 +14723,7 @@ "EFenceStandingSource/BossKill": "Penalty for killing Bosses", "EFenceStandingSource/CoopExit": "PMC and Scav co-op exfil", "EFenceStandingSource/ExitStanding": "Successful exfil", + "EFenceStandingSource/PmcBotKill": "Scav assistance", "EFenceStandingSource/ScavKill": "Penalty for killing Scavs", "EFencestandingsource/scavhelp": "Helping Scavs", "EFencestandingsource/traitorKill": "Traitor-Scav kill", @@ -13445,6 +14776,7 @@ "EPressType/Press": "Press", "EPressType/Release": "Release", "EQUIP": "EQUIP", + "EQUIPMENTPRESETSSTAND": "Gear Rack", "EQteActivityType/Gym": "Begin workout", "ERGONOMICS": "ERGONOMICS", "ESSAOMode/ColoredHighestQuality": "colored ultra", @@ -13474,6 +14806,15 @@ "ETraderServiceType/BtrBotCover": "Cover fire", "ETraderServiceType/BtrItemsDelivery": "Move items to stash", "ETraderServiceType/PlayerTaxi": "Take a ride", + "EWishlistGroup/Equipment": "Equipment", + "EWishlistGroup/Hideout": "Hideout", + "EWishlistGroup/Other": "Other", + "EWishlistGroup/Quests": "Tasks", + "EWishlistGroup/Trading": "Barter", + "EWishlistNotificationsType/All": "Enabled", + "EWishlistNotificationsType/Disabled": "Disabled", + "EWishlistNotificationsType/MenuOnly": "In stash only", + "EWishlistNotificationsType/RaidOnly": "In raid only", "EXAMINE": "EXAMINE", "EXAMINE IN PROGRESS": "EXAMINING", "EXAMINE: ": "EXAMINE: ", @@ -13491,8 +14832,8 @@ "EXFIL_CUSTOMS_LEVER": "Turn the power on", "EXFIL_Cooperate_PMC": "Cooperate with a Scav to extract", "EXFIL_Cooperate_Scav": "Cooperate with a PMC to extract", - "EXFIL_DISCOUNT_{0}%_{1}": "Extra {0}% for Fence reputation {1}", - "EXFIL_EXTRA_{0}%_{1}": "Discount {0}% for Fence reputation {1}", + "EXFIL_DISCOUNT_{0}%_{1}": "Extra {0}% for Fence standing {1}", + "EXFIL_EXTRA_{0}%_{1}": "{0}% discount for Fence standing {1}", "EXFIL_INTERCHANGE_HOLE_TIP": "Drop your backpack to fit in", "EXFIL_INTERCHANGE_SAFEROOM_TIP": "You need to lock yourself inside to extract", "EXFIL_Item": "Bring {0}", @@ -13526,7 +14867,7 @@ "Ears": "Ears", "East Gate": "Scav Bunker", "EditMapMarker": "EDIT MARKER", - "Editbuild": "EDIT PRESET", + "Editbuild": "EDIT BUILD", "Effects volume:": "Effects volume:", "EmergencyWall": "Defective Wall", "Empty": "Empty", @@ -13545,7 +14886,7 @@ "EnduranceBuffJumpCostRed": "Reduces jump stamina drain by [{0:0.#%}]", "EnduranceBuffRestorationTimeRed": "Reduces breath recovery time by [{0:0.#%}]", "EnduranceDescription": "Endurance influences the amount of stamina and the rate of exhaustion while running or jumping, as well as holding and recovering breath.", - "EnduranceHands": "Increased hands endurance", + "EnduranceHands": "Increases arm endurance", "EnduranceLevelingUpDescription": "The Endurance skill is improved by sprinting without the overweight status effect, and by working out in the Hideout gym.", "EnergyExpensesUp {0}": "Energy drain increased by {0}", "EnergyRate": "Energy recovery", @@ -13555,6 +14896,7 @@ "Enter player nickname": "Enter player nickname", "Enter your message here": "Enter your message here", "Entry point": "Entry point", + "Equip item has been built": "Equipment saved", "EquipItemWindow/Caption": "Available", "EquipItemWindow/EnterName": "Enter name", "EquipItemWindow/NoItems": "No items available", @@ -13587,6 +14929,7 @@ "Excellent standing": "excellent", "ExceptionItem": "This trader can't repair that item", "Exceptions:": "Exceptions:", + "Exchange": "Exchange", "Exhaustion": "Fatigue", "Exhibition/BlockedMessage": "Not available for current account", "Exit": "EXIT", @@ -13614,6 +14957,15 @@ "Eyes": "Eyes", "Eyewear": "Eyewear", "FACTION": "FACTION", + "FAC_TRANSIT_12": "TRANSIT01", + "FAC_TRANSIT_12_COND": " ", + "FAC_TRANSIT_12_DESC": "Transit to Woods", + "FAC_TRANSIT_13": "TRANSIT02", + "FAC_TRANSIT_13_COND": " ", + "FAC_TRANSIT_13_DESC": "Transit to Customs", + "FAC_TRANSIT_14": "TRANSIT03", + "FAC_TRANSIT_14_COND": "TerraGroup Labs access keycard required (1)", + "FAC_TRANSIT_14_DESC": "Transit to The Lab", "FIND OTHER PLAYERS": "FIND OTHER PLAYERS", "FIND PARTS": "FIND PARTS", "FINDAMMO": "FIND AMMO", @@ -13636,7 +14988,7 @@ "Factory": "Factory", "Factory Far Corner": "Factory Far Corner", "Factory Shacks": "Factory Shacks", - "Factory gate": "Factory Gate (Co-Op)", + "Factory gate": "Friendship Bridge (Co-Op)", "FactoryEnvironmentUiType": "Factory", "Failed to sort item in {0}": "Failed to sort item in {0}", "Fails": "Failures", @@ -13648,6 +15000,7 @@ "FinalRunDescription": "Suicide missions in the famous locations of Tarkov. The task is to complete the mission while defending against waves of scavs and get out of there alive.", "FinalRunDescriptionShort": "LAST MAN STANDING", "FindEp": "Find an extraction point", + "FindLinked": "Find linked", "FirstAid": "First Aid", "FirstAidDescription": "First aid skills make use of first aid kits quicker and more effective.", "FirstPrimaryWeapon": "On Sling", @@ -13669,9 +15022,9 @@ "Freetradingdescription": "Free trading", "Friend invite to {0} was sent succesfully": "A friend request was successfully sent to {0}!", "Friend invite to {0} was sent successfully": "Friend invite to {0} has been sent successfully", - "Friend request from {0} accepted succesfully!": "A friend request from {0} has been accepted!", + "Friend request from {0} accepted succesfully!": "Friend request from {0} accepted successfully!", "Friend request from {0} accepted successfully!": "Friend request from {0} accepted successfully!", - "Friend request from {0} declined succesfully!": "A friend request from {0} has been declined!", + "Friend request from {0} declined succesfully!": "Friend request from {0} declined successfully!", "Friend request from {0} declined successfully!": "Friend request from {0} declined successfully!", "Friendly scavs": "Friendly Scavs", "Friends": "Friends", @@ -13688,6 +15041,7 @@ "GAME CONDITIONS": "GAME TERMS", "GEAR": "GEAR", "GET": "GET", + "GET READY FOR THE MARATHON": "GET READY FOR THE MARATHON", "GET READY!": "GET READY", "GETBACK": "GET BACK", "GETINCOVER": "TAKE COVER", @@ -13709,6 +15063,7 @@ "Gate 3": "Gate 3", "Gate To Factory": "Gate To Factory", "Gate m": "Med Tent Gate", + "Gate_o": "Courtyard Gate", "Gear parts": "Gear mods", "Generator": "GENERATOR", "Get items": "Get items", @@ -13798,9 +15153,19 @@ "HeavyVests": "Heavy Vests", "HeavyVestsDescription": "Heavy body armor wearing skill reduces amount of received penetration health damage, explosive damage to health and armor and improves mobility.", "HeavyVestsLevelingUpDescription": "The Heavy Vests skill is improved by repairing heavy body armor and ballistic plates with repair kits.", + "Hideout/Bestowed": "The Gift is bestowed", + "Hideout/CircleOfCultists": "Cultist Circle", + "Hideout/CircleOfCultists/MaxItemsCount": "Max items: {0}", + "Hideout/CircleOfCultists/TheGiftCantBeBestowed": "Cultists can't bestow their Gift while you're in the Hideout", "Hideout/Craft/ToolMarkerTooltip": "This item will be used as an auxiliary tool. It will return to your stash once production is complete.", + "Hideout/EquipmentPresetsStand/MannequinTab": "MANNEQUIN {0}", "Hideout/Handover window/Caption/All weapons": "All weapons", "Hideout/Handover window/Message/Items in stash selected:": "Items in stash selected:", + "Hideout/Mannequin/Pose/boxing": "Fist Fighter", + "Hideout/Mannequin/Pose/fingerguns": "Cowboy", + "Hideout/Mannequin/Pose/fingerguns2": "Sharpshooter", + "Hideout/Mannequin/Pose/spreadinghands": "Well What Is It", + "Hideout/Mannequin/Pose/standing": "Briefing", "Hideout/Production/Decryption/Fail": "Unsuccessful decryption", "Hideout/Production/Decryption/Success": "Successful decryption", "Hideout/WeaponStand": "Weapon Rack", @@ -13810,6 +15175,8 @@ "Hideout/placeoffame/dogtags": "Dogtags", "Hideout/placeoffame/smalltrophies": "Small trophies", "HideoutExtraSlots": "+2 slots for fuel canisters\n+2 water filter slots\n+2 slots for air filters\n+2 to the storage limit of coins in a bitcoin farm", + "HideoutInteractions/EquipMannequins": "Equip mannequins", + "HideoutInteractions/Sacrifice": "Sacrifice", "HideoutInteractions/TransferItems": "Transfer items", "HideoutManagement": "Hideout Management", "HideoutManagementLevelingUpDescription": "The Hideout Management skill is improved by creating items and upgrading zones in the Hideout.", @@ -13820,6 +15187,7 @@ "Hiding objective {0:F1}": "Hiding objective {0:F1}", "HighQualityColor": "High-quality color", "HighQualityColor setting will be fully applied after the raid restarts": "The setting will be fully applied in the next raid", + "HighQualityFog": "High-quality fog (Test)", "Hold to Aim": "Hold to aim", "Hold to Crouch": "Hold to crouch", "Hold to Lean": "Hold to lean", @@ -13844,6 +15212,12 @@ "INSURED": "INSURED", "INTERACTIONS:": "INTERACTIONS:", "INTHEFRONT": "IN THE FRONT", + "INT_TRANSIT_6": "TRANSIT01", + "INT_TRANSIT_6_COND": " ", + "INT_TRANSIT_6_DESC": "Transit to Customs", + "INT_TRANSIT_7": "TRANSIT02", + "INT_TRANSIT_7_COND": " ", + "INT_TRANSIT_7_DESC": "Transit to Streets of Tarkov", "INVITE": "INVITE", "ITEM IS NOT EXAMINED!": "ITEM HAS NOT BEEN EXAMINED YET!", "Identifier": "Source string", @@ -13857,6 +15231,7 @@ "ImmunityPainKiller": "Increases painkiller action time by [{0:0.#%}]", "ImmunityPoisonBuff": "Reduces poison effect force by [{0:0.#%}]", "ImmunityPoisonChance": "Increases chance to gain immunity to poisons by [{0:0.#%}]", + "ImpossibleInHideout": "Unavailable at the shooting range", "In equipment": "IN EQUIPMENT", "InMenu": "Menu", "InRaid": "Raid", @@ -13933,6 +15308,8 @@ "InventoryError/DiscardLimitForContentReached{0}": "Container \"{0}\" contains items that can't be transferred", "InventoryError/DiscardLimitForStackReached": "Part of the stack can't be transferred", "InventoryError/DiscardLimitReached{0}": "{0} can't be transferred", + "InventoryError/InventoryBlocked": "Inventory is blocked", + "InventoryError/ItemHasRestrictions": "Item has restrictions", "InventoryError/ItemIsBusy": "Cannot interact with the item while it is being used by another player.", "InventoryError/NoCompatibleAmmo": "You don't have any compatible ammo", "InventoryError/NoPossibleActions": "No actions available", @@ -13946,8 +15323,17 @@ "InventoryError/You can't load ammo into this item": "You can't load ammo into this item", "InventoryError/You can't unload ammo from an installed magazine": "You can't unload ammo from an installed magazine", "InventoryError/you can't unload from this item": "You can't unload ammo from this item", - "InventoryErrors/Container/ContentModificationUnavailable": "Unable to replace the weapon", + "InventoryErrors/Container/ContentModificationUnavailable": "Unable to move", "InventoryErrors/MalfunctionError": "You must fix malfunctions first", + "InventoryErrors/MaxItemsCountReached": "Cannot sacrifice more than {0} items", + "InventoryErrors/PinLock/ContainerHasLockedItem{0}": "Container has locked item:\n{0}", + "InventoryErrors/PinLock/ItemAlreadyLocked{0}": "Item {0} is already locked", + "InventoryErrors/PinLock/ItemAlreadyPinned{0}": "Item {0} is already pinned", + "InventoryErrors/PinLock/ItemAlreadyUnlocked{0}": "Item {0} is already unlocked", + "InventoryErrors/PinLock/ItemLockInWrongContainer": "Can't lock items in this container", + "InventoryErrors/PinLock/ItemLocked": "Item is locked", + "InventoryErrors/PinLock/ItemPinInWrongContainer": "Can't pin items in this container", + "InventoryErrors/PinLock/SortingTableLock": "Can't lock items on sorting table", "InventoryScreen/SpecialSlotsHeader": "Special slots", "InventoryWarning/ItemsToBeDestroyed": "Some items will be lost", "InventoryWarning/ItemsWillBeDestroyed": "ATTENTION! Next items will be irrevocably lost:", @@ -13965,16 +15351,16 @@ "It": "Italiano", "Item collected: {0}": "Items have been put in the stash: {0}", "Item examined: ": "Item examined: ", - "Item fits the active {0} quest requirements": "Item fits the active {0} quest requirements", + "Item fits the active {0} quest requirements": "This item fits the objective for the active task {0}", "Item found in raid": "Item found in raid", - "Item is already insured": "This item is already insured.", + "Item is already insured": "This item is already insured", "Item is being examined": "Item is being examined", "Item is not available for insurance": "This item can not be insured.", "Item is not examined": "Unknown Item", "Item is out of stock": "Item is out of stock", - "Item is related to an active {0} quest": "Item is related to an active {0} quest", + "Item is related to an active {0} quest": "This item is related to the active task {0}", "Item successfully repaired to": "Item successfully repaired to", - "Item that has been found in raid for the {0} quest": "The item that has been found in raid for the {0} quest", + "Item that has been found in raid for the {0} quest": "This item has been found in raid for the task {0}", "Item to purchase": "Item to purchase", "Item {0} is not found in stash": "Item ({0}) is not found in stash", "ItemReward/Description": "You will receive this item as a reward", @@ -14043,6 +15429,9 @@ "Km2": "KM²", "Knife": "Melee weapon", "Knock & run": "Knock", + "LAB_TRANSIT_8": "TRANSIT01", + "LAB_TRANSIT_8_COND": " ", + "LAB_TRANSIT_8_DESC": "Transit to Streets of Tarkov", "LATER": "LATER", "LEAVE_BTN": "LEAVE", "LEFT: ": "LEFT: ", @@ -14051,6 +15440,15 @@ "LEVEL": "LEVEL:", "LEVEL {0} UPGRADE REQUIREMENTS": "LEVEL {0} UPGRADE REQUIREMENTS", "LH": "LH", + "LIG_TRANSIT_21": "TRANSIT01", + "LIG_TRANSIT_21_COND": " ", + "LIG_TRANSIT_21_DESC": "Transit to Shoreline", + "LIG_TRANSIT_22": "TRANSIT02", + "LIG_TRANSIT_22_COND": " ", + "LIG_TRANSIT_22_DESC": "Transit to Reserve", + "LIG_TRANSIT_23": "TRANSIT03", + "LIG_TRANSIT_23_COND": " ", + "LIG_TRANSIT_23_DESC": "Transit to Woods", "LL": "LL", "LMG": "Light Machine Guns", "LMGDescription": "Light Machine Gun handling skill improves the overall handling, reduces recoil and reload time of this weapon type.", @@ -14058,6 +15456,7 @@ "LOAD": "LOAD", "LOAD FROM DIRECTORY...": "Load from directory...", "LOAD FROM FILE...": "Load from file...", + "LOCATIONKILLLIST": "LOCATION", "LOCKEDDOOR": "LOCKED DOOR", "LOOT": "LOOT", "LOOT FROM SCAVS": "LOOT FROM SCAVS", @@ -14163,6 +15562,7 @@ "MALFUNCTION PROTECTIONS COMMON BUFF": "REDUCES MALFUNCTION CHANCE (COMMON)", "MALFUNCTION PROTECTIONS RARE BUFF": "REDUCES MALFUNCTION CHANCE (RARE)", "MAP": "MAP", + "MARATHON/TARKOVTITLE": "EFT", "MASTERING": "MASTERING", "MATERIAL": "Material", "MAX AMMO DAMAGE": "Damage", @@ -14194,7 +15594,7 @@ "MOD_MOUNT_002": "MOUNT", "MOD_MUZZLE": "MUZZLE", "MOD_NVG": "SHROUD", - "MOD_PISTOLGRIP": "PISTOL GRIP", + "MOD_PISTOLGRIP": "GRIP", "MOD_PISTOL_GRIP": "PISTOL GRIP", "MOD_PISTOL_GRIP_AKMS": "PISTOL GRIP", "MOD_RECIEVER": "RECEIVER", @@ -14243,6 +15643,14 @@ "Magazine": "Magazine", "Magazine checked: ": "Magazine checked: ", "MainMenu": "MAIN MENU", + "Maintenance/Disconnected": "Lost connection to EFT: Arena network", + "Maintenance/DisconnectedDescription": "Network connection has been lost:\n• Check your Internet connection\n• Make sure you are not using a VPN or other boosters\n• Try restarting your router\n• Check official social networks and platforms for new updates\n• If none of the above has helped, please contact support", + "Maintenance/MaintenanceLabel": "Technical maintenance in progress", + "Maintenance/ReconnectRequired": "Connection restored. Re-authorization required.", + "Maintenance/Reconnected": "Connection to EFT: Arena network has been restored", + "Maintenance/RetryConnection": "Reconnecting to EFT: Arena servers", + "Maintenance/StartMatchButton/Disconnected": "Arena battles are currently unavailable. Re-establishing connection to game servers.", + "Maintenance/StartMatchButton/Maintenance": "Arena battles are currently unavailable. Technical maintenance in progress.", "MakeScreenshot": "Screenshot", "Malfunction/HighChance": "HIGH", "Malfunction/LowChance": "LOW", @@ -14264,6 +15672,10 @@ "MapMarkerType_LockedStuff": "Locked", "MapMarkerType_Loot": "Loot", "MapMarkerType_Other": "Unknown/other", + "Marathon/LocationDescrition": "A marathon mode in which you will need to travel from one location to another to progress.", + "Marathon/MarathonDescription": "A marathon mode in which you will need to\ntravel from one location to another to progress.", + "Marathon/MarathonTitle": "TRANSITION", + "Marathon/TarkovDescrition": "A standard single extraction raid mode.", "MarkerCreate": "Create marker", "MarkerDelete": "Delete marker", "MarkerEdit": "Edit marker", @@ -14318,7 +15730,7 @@ "Min payment:": "Minimum payment: ", "MinCheckLevel": "MIN CHECK LEVEL", "MinutesShort": "MIN", - "MipStreamingBufferSize:": "Mip Streaming buffer size", + "MipStreamingBufferSize:": "Mip Streaming buffer size:", "Misc": "Misc", "MiscDescription": "Miscellaneous weapons handling skills", "MisfireEffect": "Panic attack", @@ -14329,8 +15741,10 @@ "ModeChange/Pve": "PVE ZONE", "ModeChange/Regular": "PVP ZONE", "ModeChange/Unable": "PVE ZONE game mode unavailable", - "ModeChange/Unable/Tooltip": "The Unheard Edition or Edge of Darkness edition is required to access PVE game mode.", + "ModeChange/Unable/Tooltip": "The Unheard Edition or Edge of Darkness Edition is required to access PvE game mode.", "ModeUnavailable": "Mode unavailable", + "Modification/Locked": "Locked", + "Modification/ReadyToUnlock": "Unlockable", "Monitor parameters": "Monitor Parameters", "Most leveled": "Most leveled", "Most recent": "Most recent", @@ -14363,7 +15777,7 @@ "NEEDSNIPER": "NEED SNIPER", "NEEDWEAPON": "NEED WEAPON", "NEGATIVE": "NEGATIVE", - "NEW BUILD": "NEW PRESET", + "NEW BUILD": "NEW BUILD", "NEXT LEVEL UPGRADE REQUIREMENTS": "Construction requirements", "NICKNAME": "NICKNAME", "NO (N)": "NO (N)", @@ -14380,7 +15794,7 @@ "NOT SECURED": "NOT SECURE", "NOTES": "NOTES", "NOTHING": "-", - "NO_EFT_TOOLTIP_LOCALIZATION_KEY": "Transfer condition\nNo \"Escape from Tarkov\" game purchased\nOr the character hasn't been created yet", + "NO_EFT_TOOLTIP_LOCALIZATION_KEY": "Transfer condition\nEscape from Tarkov not purchased\nOr the character hasn't been created yet", "NO_POWER_TIP": "NO POWER", "NVidia Reflex is on. Turn it off to change this parameter.": "NVIDIA Reflex is on. Turn it off to change this parameter.", "NVidia Reflex settings will be applied after restart.": "NVIDIA Reflex settings will be applied after restart.", @@ -14430,11 +15844,13 @@ "NoiseSuppressionLevels/Moderate": "Moderate", "NoiseSuppressionLevels/VeryHigh": "Very high", "Non-authentic": "Non-Authentic", + "NonAllTeammates": "Not all group members are ready to transit", "Not available in alpha": "Not available in the current Beta version.", "Not available in raid": "Not available in raid", "Not enough experience gained. Therefore, you have received the Ran Through exit status.": "You have failed to gain enough experience. Therefore, you have received the Ran Through exit status.", "Not enough place for item": "Not enough space for the item", "Not implemented yet": "Not implemented yet", + "Not in wishlist": "Item is not in Wishlist", "NotEnoughMoney": "Not enough money", "NotEnoughRepairPoints": "Not enough repair points", "NotEqual": "Password doesn't match", @@ -14459,8 +15875,8 @@ "Notifications/NewQuestAvailable": "New operational task available", "Notifications/TraderStandingDecreased{0}{1}": "Standing with {0} decreased by {1}", "Notifications/TraderStandingIncreased{0}{1}": "Standing with {0} increased by {1}", - "NotifierQuestAvailableForFinish": "Quest {0} is ready to be completed", - "NotifierQuestAvailableForStart": "Quest {0} is now available", + "NotifierQuestAvailableForFinish": "Task {0} is ready to be completed", + "NotifierQuestAvailableForStart": "Task {0} is now available", "NotifierQuestFail": "Task {0} objective failed", "OK": "OK", "OMA": "OMA", @@ -14489,6 +15905,7 @@ "OVR": "OVR", "Object LOD quality:": "Object LOD quality:", "Objectives": "Objective(s)", + "Observer": "Spectator", "Offer was sold or out of stock": "Offer was sold out", "Office Window": "Office Window", "Offline raid description": "In this mode, you can practice offline on your own, or immerse yourself in an online cooperative game with friends without the risk of meeting other players. You can use this mode to explore locations, test your weapons, and do other activities before going into an actual fight against live opponents.\nAll game mechanics in the co-op mode (weather, bots, Bosses, etc.) are identical to the online mechanics.", @@ -14543,7 +15960,7 @@ "PRESETS": "PRESETS", "PRODUCTION:": "PRODUCTION:", "PUBLISH ...": "PUBLISH...", - "PVE settings": "PVE settings", + "PVE settings": "AI settings", "Pain": "Pain", "Painkiller": "On painkillers", "PanicEffect": "Chilling horror", @@ -14575,6 +15992,7 @@ "Player {0} has left the group": "User {0} has left the group.", "Player {0} invite you to the group": "Player {0} invites you to the group", "Player {0} was invited to your group": "Player {0} was invited to your group", + "PlayerEquipmentWindow/Caption{0}": "Equipment preview: {0}", "PlayerProfile/Unavailable": "PMC profile hidden", "Players spawn": "Players spawn", "PlayersSpawnPlace/AtTheEndsOfTheMap": "2 teams", @@ -14591,6 +16009,8 @@ "Prepare for Escape": "PREPARE TO ESCAPE", "Preparing the game...": "Preparing the game...", "PresetBonus": "Preset bonus", + "PresetFooter/EditPreset": "Edit", + "PresetFooter/ViewPreset": "View", "PresetManager": "Create new preset", "PresetPenalty": "Preset penalty", "Preset_Unlock": "Unlock", @@ -14643,16 +16063,16 @@ "Protect objective {0:F1}": "Protect objective {0:F1}", "PveFirstTime/Caption": "Game mode: PVE ZONE", "PveFirstTime/Message": "Welcome to the PVE ZONE game mode\n\nIn this mode you can experience the full game with persistent PvE character progression solo or with friends, without worrying about being attacked by other players in a raid. \n\nAll mechanics are identical to the PVP ZONE game mode.\n\nGood luck!", - "QUEST ITEM": "QUEST ITEM", - "QUEST ITEMS": "QUEST ITEMS", + "QUEST ITEM": "TASK ITEM", + "QUEST ITEMS": "TASK ITEMS", "QUICK USE": "QUICK USE", "Quantity of items you need has been redeemed ({0} left)": "Quantity of items you need has been reduced ({0} left)", "QuantumTunnelling": "Tunnel effect", - "Quest fail": "Quest failed", - "Quest items in inventory (in-raid)": "Quest items in inventory (in-raid)", - "Quest items special stash (off-raid)": "Quest item special stash (hideout)", - "Quest start": "Quest started", - "Quest success": "Quest reward", + "Quest fail": "Task failed", + "Quest items in inventory (in-raid)": "Task items on character", + "Quest items special stash (off-raid)": "Task items in stash", + "Quest start": "Task started", + "Quest success": "Task reward", "Quest/Change": "REPLACE", "Quest/Change/Change": "Replace operational task?", "Quest/Change/Price": "Replacement cost:", @@ -14668,6 +16088,10 @@ "QuestCondition/ArenaMatchPlace/Equal{0}": "Claim {0} place", "QuestCondition/ArenaMatchPlace/Win": "Win a match", "QuestCondition/ArenaMatchPlace/WorseThen{0}": "Claim lower than {0} place", + "QuestCondition/ArenaPlayerAction/BombActivated": " by planting the device yourself", + "QuestCondition/ArenaPlayerAction/BombDeactivated": " by deactivating the device yourself", + "QuestCondition/ArenaPlayerAction/BombExploded": " by planting the device yourself and letting it activate", + "QuestCondition/ArenaPlayerAction/PointCapture": " by capturing the objective yourself", "QuestCondition/ArenaPlayerInTeamPlace/BetterThenOrEqual{0}": " while claiming at least {0} place", "QuestCondition/ArenaPlayerInTeamPlace/WorseThen{0}": " while claiming lower than {0} place", "QuestCondition/ArenaPlayerInTeamPlace{0}": " claiming {0} place in the team", @@ -14678,18 +16102,20 @@ "QuestCondition/ArenaRoundPlace/Defeat": "Lose a round", "QuestCondition/ArenaRoundPlace/Win": "Win a round", "QuestCondition/ArenaRoundResult/RoundEndType/Any": " by finishing a round", - "QuestCondition/ArenaRoundResult/RoundEndType/Any/Many{0}": " by finishing a round {0} time(s)", + "QuestCondition/ArenaRoundResult/RoundEndType/BombDeactivated": " by deactivating the device", + "QuestCondition/ArenaRoundResult/RoundEndType/BombExploded": " by letting the device activate", + "QuestCondition/ArenaRoundResult/RoundEndType/Defended": " by protecting the plant site", "QuestCondition/ArenaRoundResult/RoundEndType/PointCaptured": " by capturing the objective", - "QuestCondition/ArenaRoundResult/RoundEndType/PointCaptured/Many{0}": " by capturing the objective {0} time(s)", "QuestCondition/ArenaRoundResult/RoundEndType/TeamKilled": " by eliminating the enemy team", - "QuestCondition/ArenaRoundResult/RoundEndType/TeamKilled/Many{0}": " by eliminating the enemy team {0} time(s)", + "QuestCondition/ArenaRoundResult/RoundEndType/TeamKilledDefense": " by eliminating the defenders", + "QuestCondition/ArenaRoundResult/State/BombTime": " during the device activation timer", "QuestCondition/ArenaRoundResult/State/CleanUpTeam": " after the cleanup crew is released", "QuestCondition/ArenaRoundResult/State/MainTime": " in the main time", - "QuestCondition/ArenaRoundResult/State/PointCapture": " in the overtime", + "QuestCondition/ArenaRoundResult/State/PointCapture": " in the extra time", "QuestCondition/ArenaWinMatch": "{matchPlace}{resetOnConditionFailed{0}}{roundCount}{playerInTeamPlace}{roundResult}{playerPreset}{deathCount}", - "QuestCondition/ArenaWinRound": "{roundPlace}{resetOnConditionFailed{0}}{resetOnSessionEnd}{roundResult}{playerPreset}{deathCount}", + "QuestCondition/ArenaWinRound": "{roundPlace}{resetOnConditionFailed{0}}{resetOnSessionEnd}{roundResult}{playerAction}{playerPreset}{deathCount}", "QuestCondition/Category": "Find items from the category in one raid: {0}", - "QuestCondition/Elimination": "Eliminate{playerPreset}{kill}{zone}{enemyPreset}{resetOnSessionEnd}", + "QuestCondition/Elimination": "Eliminate{kill}{zone}{enemyPreset}{playerPreset}{resetOnSessionEnd}", "QuestCondition/Elimination/Kill": " {target}{botrole}{bodypart}{distance}{weapon}{weapontype}{onesession}", "QuestCondition/Elimination/Kill/BodyPart": " with a {0} shot", "QuestCondition/Elimination/Kill/BodyPart/Chest": "thorax", @@ -14715,6 +16141,7 @@ "QuestCondition/Elimination/Kill/Target/Bear": "BEAR operatives", "QuestCondition/Elimination/Kill/Target/Bot": "cleanup crew", "QuestCondition/Elimination/Kill/Target/Enemy": "enemies", + "QuestCondition/Elimination/Kill/Target/EnemyWithBomb": "the device-carrying enemies", "QuestCondition/Elimination/Kill/Target/Savage": "Scavs", "QuestCondition/Elimination/Kill/Target/Usec": "USEC operatives", "QuestCondition/Elimination/Kill/Weapon": " while using {0}", @@ -14722,23 +16149,22 @@ "QuestCondition/HandoverItem": "Hand over the{onlyfoundinraid} item: \"{item}\"{durability}{durabilitystrict}", "QuestCondition/HandoverItem/Durability": " ({0}% to {1}% durability)", "QuestCondition/HandoverItem/DurabilityStrict": " ({0}% durability)", - "QuestCondition/HandoverItem/OnlyFoundInRaid": " found in raid or crafted", + "QuestCondition/HandoverItem/OnlyFoundInRaid": " found in raid", "QuestCondition/HideoutArea": "{0} level {1}", "QuestCondition/Inventory": "Extract with the items from the category: {0}", + "QuestCondition/Many{0}{1}": "{0} {1} time(s)", "QuestCondition/PickUp": "{equipment}", - "QuestCondition/Preset": "{presetid}{presettype}{presettier}", - "QuestCondition/Preset/632f7afadcb4c7c2c209ba8f": "CQB", + "QuestCondition/Preset": "{presetid}{presettype}", + "QuestCondition/Preset/632f7afadcb4c7c2c209ba8f": "Enforcer", "QuestCondition/Preset/632f8229f6541cacd808452c": "Assault", "QuestCondition/Preset/632f8d94f6541cacd808452d": "Ranked preset", "QuestCondition/Preset/632f8dadbe00240c170aab18": "Scout", "QuestCondition/Preset/632f8e11f6541cacd808452e": "Marksman", "QuestCondition/Preset/64f70b7d6706c3eeaf0ca809": "Collection preset", "QuestCondition/Preset/Enemy/PresetId{0}": " who are playing as the {0} preset", - "QuestCondition/Preset/Enemy/PresetTier{0}": " in {0}", "QuestCondition/Preset/Enemy/PresetType/Any": " who are playing as any preset", "QuestCondition/Preset/Enemy/PresetType{0}": " who are playing as {0}", "QuestCondition/Preset/Player/PresetId{0}": " playing the {0} preset", - "QuestCondition/Preset/Player/PresetTier{0}": " {0}", "QuestCondition/Preset/Player/PresetType/Any": " playing as any preset", "QuestCondition/Preset/Player/PresetType{0}": " playing as {0}", "QuestCondition/SurviveOnLocation": "Survive on {location}{exitName}", @@ -14747,7 +16173,7 @@ "QuestCondition/SurviveOnLocation/Location": "the location", "QuestConditionVariable/EBodyPart/head": "head", "QuestCount/Transfered": "transferred", - "QuestCount/Transferred": "transferred:", + "QuestCount/Transferred": "Eliminated:", "QuestInitialsEquipment": "Initial equipment", "QuestIsNew": "new!", "QuestRecieveRequared": "(click COMPLETE to receive)", @@ -14763,7 +16189,7 @@ "QuestTimeLimit": "time limit:", "QuestTimeLimited": "time limited", "QuestTypeCompletion": "Completion", - "QuestTypeDaily": "Daily Quest", + "QuestTypeDaily": "Daily task", "QuestTypeDiscover": "Discovery", "QuestTypeElimination": "Elimination", "QuestTypeExperience": "Experience", @@ -14776,9 +16202,10 @@ "QuestTypeSkill": "Skill", "QuestTypeStanding": "Standing", "QuestTypeWeaponAssembly": "Parameter-oriented modding", + "QuestWidget/Objectives": "TASKS", "QuestsShowCompleted": "Show сompleted", "QuestsShowLocked": "Show locked", - "Queststatusmarkedasfailed": "Quest failed", + "Queststatusmarkedasfailed": "Task failed", "QuickKnife": "Melee attack", "QuickReloadWeapon": "Emergency weapon reload", "QuickSecondaryWeapon": "Sidearm quick swap", @@ -14793,11 +16220,12 @@ "RECEIVE ALL": "RECEIVE ALL", "RECOIL": "RECOIL", "RECONNECT": "RECONNECT", + "REGIONS": "Regions", "REGROUP": "REGROUP", "RELOAD": "RELOAD", "REMEMBER ACCOUNT": "REMEMBER ACCOUNT", "REMOVEFROMFAVORITES": "Remove from profile", - "REMOVEFROMWISHLIST": "Remove from W-list", + "REMOVEFROMWISHLIST": "Remove from Wishlist", "REMOVES BLOODLOSS": "REMOVES BLOODLOSS", "REMOVES CONTUSION": "REMOVES CONCUSSION", "REMOVES FRACTURE": "REMOVES FRACTURE", @@ -14820,6 +16248,15 @@ "RETURN TIME:": "RETURN TIME: ", "RETURN TO RAID": "RETURN TO RAID", "REVIEW INFIL & EXFIL ON {0}": "REVIEW INFIL & EXFIL ON {0}", + "REZ_TRANSIT_18": "TRANSIT03", + "REZ_TRANSIT_18_COND": " ", + "REZ_TRANSIT_18_DESC": "Transit to Customs", + "REZ_TRANSIT_19": "TRANSIT02", + "REZ_TRANSIT_19_COND": " ", + "REZ_TRANSIT_19_DESC": "Transit to Woods", + "REZ_TRANSIT_20": "TRANSIT01", + "REZ_TRANSIT_20_COND": " ", + "REZ_TRANSIT_20_DESC": "Transit to Lighthouse", "RHigh": "High", "RICOCHET CHANCE": "RICOCHET CHANCE", "RIGHT: ": "RIGHT: ", @@ -14883,12 +16320,18 @@ "Reconnection is not available at this moment due to testing purposes": "Reconnection is not available at this moment due to testing purposes", "RedRebel_alp": "Climber's Trail", "Refill": "Refill", + "RegionsNotification/AllRegionsDisabled": "Automatic region selection was enabled due to high ping on selected servers.", + "RegionsNotification/BadConnection": "Failed to find a suitable server by ping in auto-detection mode. Connection issues may occur.", + "RegionsNotification/SomeRegionsDisabled": "The following regions have been disabled due to high ping: {0}.", + "RegionsTab/BigPing": "You cannot select a region with too high ping.", + "RegionsTab/RegionNotAvailableDueVersion": "This region is unavailable to your game version.", "Registration": "REGISTRATION", "Registration date": "Registration date", "ReloadWeapon": "Reload weapon", "Remove": "Remove", "RemoveAllBuffs": "Removes all buffs", "RemoveBloodLosses": "Stops bleedings", + "RemoveMagazine": "REMOVE MAG", "RemoveNegativeEffects": "Removes negative effects", "RemovePlayer": "Kick player", "RemovePlayer message": "Are you sure you want to remove this player?", @@ -14957,6 +16400,9 @@ "Road to Customs": "Road to Customs", "Rock Passage": "Rock Passage", "Ruined House Fence": "Ruined House Fence", + "SAN_TRANSIT_1": "TRANSIT01", + "SAN_TRANSIT_1_COND": " ", + "SAN_TRANSIT_1_DESC": "Transit to Streets of Tarkov", "SAVAGE": "SCAV", "SAVE AS ...": "SAVE AS...", "SAVE AS...": "Save as...", @@ -14985,6 +16431,9 @@ "SERVICES": "SERVICES", "SETTINGS": "SETTINGS", "SHOWCASE": "SHOWCASE", + "SHO_TRANSIT_24": "TRANSIT01", + "SHO_TRANSIT_24_COND": " ", + "SHO_TRANSIT_24_DESC": "Transit to Lighthouse", "SIDE": "SIDE", "SIGHT CRATE": "Sight magnification", "SILENCE": "SILENCE", @@ -15007,7 +16456,17 @@ "STASH": "STASH", "STATUSKILLLIST": "STATUS", "STOP": "STOP", + "STR_TRANSIT_3": "TRANSIT02", + "STR_TRANSIT_3_COND": " ", + "STR_TRANSIT_3_DESC": "Transit to Ground Zero", + "STR_TRANSIT_4": "TRANSIT01", + "STR_TRANSIT_4_COND": " ", + "STR_TRANSIT_4_DESC": "Transit to Interchange", + "STR_TRANSIT_5": "TRANSIT03", + "STR_TRANSIT_5_COND": "TerraGroup Labs access keycard required (1)", + "STR_TRANSIT_5_DESC": "Transit to The Lab", "SUPPRESS": "SUPPRESS", + "SURVEY": "SURVEY", "Saferoom Exfil": "Saferoom Exfil", "Sales sum with {0} increased by {1}": "Sales sum with {0} increased by {1}", "Sandbox": "Ground Zero", @@ -15036,6 +16495,11 @@ "ScavRole/Marksman": "Sniper", "ScavRole/PmcBot": "Raider", "ScavRole/Sectant": "???", + "ScavRole/infectedAssault": "Infected", + "ScavRole/infectedCivil": "Infected", + "ScavRole/infectedLaborant": "Infected", + "ScavRole/infectedPmc": "Infected", + "ScavRole/infectedTagilla": "Infected", "ScavTimerNotification": "Player {0} will have their Scav character available in {1}", "Scav_Coastal_South": "Southern Road Landslide", "Scav_Hideout_at_the_grotto": "Scav Hideout at the Grotto", @@ -15043,6 +16507,8 @@ "Scavs arrived with loot": "Scavs have arrived with loot", "Scavs has brought you:": "Scavs have brought you:", "Scene loading...": "Loading scene...", + "ScopeZoomIn": "Scope zoom in", + "ScopeZoomOut": "Scope zoom out", "Screen resolution:": "Screen resolution:", "Screen-space effects:": "Screen-space Effects:", "ScreenSettings/Display": "Monitor:", @@ -15052,6 +16518,7 @@ "SearchDescription": "The search skill mastering allows you to search bodies and containers faster and more efficiently.", "SearchDouble": "Search two containers at a time", "SearchLevelingUpDescription": "The Search skill is improved by searching containers.", + "SeasonActivity/ZombieEvent/LocationInfectionCaption": "LOCATION INFECTION LEVEL:", "SecondPrimaryWeapon": "On Back", "SecondaryWeapon": "Sidearm", "SecuredContainer": "Pouch", @@ -15062,7 +16529,14 @@ "Select friends to add:": "Select friends to invite:", "Select pre-saved weapon build": "SELECT A SAVED WEAPON PRESET", "Select to auto fill requirements": "Select to auto-fill requirements", + "SelectPresetButton/AlreadySelectedPreset": "Selected", + "SelectPresetButton/ChangePreset": "Change", + "SelectPresetButton/SelectPreset": "Select", "SelectedPreset": "Selected preset", + "SelectedPreset/CurrentSelected": "Selecting now: {0}", + "SelectedPreset/OnlyMe": "only you", + "SelectedPreset/PresetClassBlocked": "Class already taken", + "SelectedPreset/YouAnd": "You + {0}", "SelectedQuest": "Selected task", "Sells:": "Sells:", "SendFriendsRequest": "Send friend request", @@ -15074,17 +16548,21 @@ "Sessions": "Sessions", "SetAffinityToLogicalCores": "Only use physical cores", "SetMessageResponse": "Response to the message", - "Settings/Control/ResetWarning": "All controls settings have been reset to default.\n\n• Action \"Jump\" has been reassigned to Spacebar on Release.\n• New action \"Vaulting\" has been assigned to Spacebar on Continuous.\n\nPlease try these settings in-game before changing them.", + "Settings/Control/ResetWarning": "All controls settings have been reset to default.\n\n• Action \"Melee weapon\" has been reassigned to \"U\". \"Melee attack\" has been reassigned to \"U\" on Double click.\n• Added a new action \"Mount weapon\" on \"V\". \n• Added a new action \"Toggle bipod\" on \"V+LCtrl\".\n• Added a new action \"Smooth scope zoom adjustment\" on \"Alt + ScrollUp/ScrollDown\".\n\nPlease try these settings in-game before changing them.", "Settings/DoubleClickTimeout": "Double click timeout", "Settings/Game/ConnectionType": "Connection type", + "Settings/Graphics/CloudsQuality": "Clouds quality", + "Settings/Graphics/CloudsQualityTooltip": "Allows you to manually adjust the quality settings of clouds to achieve the desired balance between performance and visual effects.", "Settings/Graphics/DLSSLockThis": "This setting is unavailable while DLSS is on", "Settings/Graphics/DLSSModeTooltip": "NVIDIA DLSS uses AI Super Resolution to provide the highest possible frame rates at maximum graphics settings. DLSS requires an NVIDIA RTX graphics card.", "Settings/Graphics/DLSSNotSupported": "DLSS is not supported on your system", "Settings/Graphics/DLSSWrongSampling": "Disable Resampling to enable DLSS", "Settings/Graphics/FSR2LockThis": "This setting is unavailable while FSR 2.2 is on", - "Settings/Graphics/FSR2ModeTooltip": "AMD FidelityFX Super Resolution 2.2 (FSR) is a newer version of the picture scaling technology that allows you to increase performance with minimal loss of image quality", + "Settings/Graphics/FSR2ModeTooltip": "AMD FidelityFX Super Resolution 2.2 (FSR) is a newer version of the picture scaling technology that allows you to increase performance with minimal loss of image quality.", + "Settings/Graphics/FSR3LockThis": "This setting is unavailable while FSR 3.0 is on", + "Settings/Graphics/FSR3ModeTooltip": "AMD FidelityFX Super Resolution 3.0 (FSR) is a newer version of the picture scaling technology that allows you to increase performance with minimal loss of image quality.", "Settings/Graphics/FSRLockThis": "This setting is unavailable while FSR is on", - "Settings/Graphics/FSRModeTooltip": "AMD FidelityFX Super Resolution (FSR) is a picture scaling technology that allows you to increase performance with minimal loss of image quality", + "Settings/Graphics/FSRModeTooltip": "AMD FidelityFX Super Resolution (FSR) is a picture scaling technology that allows you to increase performance with minimal loss of image quality.", "Settings/Graphics/FSRTooLowResolution": "Screen resolution is too low for this setting", "Settings/Graphics/High": "high", "Settings/Graphics/Low": "low", @@ -15098,7 +16576,12 @@ "Settings/Graphics/VeryHigh": "very high", "Settings/Graphics/VeryLow": "very low", "Settings/NotSet": "Not set", + "Settings/OpticSensitivity": "Scope zoom adjustment sensitivity", "Settings/PressType": "PRESS TYPE", + "Settings/Regions/AutoRegions": "Use automatic server detection", + "Settings/Regions/Name": "Name", + "Settings/Regions/Ping": "Ping", + "Settings/Regions/Region": "Region", "Settings/RevertControl": "REVERT CONTROL", "Settings/RevertControlToDefault": "Revert control settings to default?", "Settings/Settings have been changed": "Some settings have been changed. Do you wish to save them?", @@ -15121,6 +16604,26 @@ "Shadows quality:": "Shadows quality:", "Shaft": "Shaft", "Sharpen:": "Sharpness:", + "ShellingWarningMessage": "Danger! Mortar strike incoming at: unknown sector", + "ShellingWarningMessage/11": "Danger! Mortar strike incoming at: Tarcone", + "ShellingWarningMessage/12": "Danger! Mortar strike incoming at: Bridge", + "ShellingWarningMessage/13": "Danger! Mortar strike incoming at: Scav base", + "ShellingWarningMessage/14": "Danger! Mortar strike incoming at: Dorms", + "ShellingWarningMessage/15": "Danger! Mortar strike incoming at: USEC camp", + "ShellingWarningMessage/21": "Danger! Mortar strike incoming at: Port", + "ShellingWarningMessage/22": "Danger! Mortar strike incoming at: Health Resort", + "ShellingWarningMessage/23": "Danger! Mortar strike incoming at: Smugglers' camp", + "ShellingWarningMessage/24": "Danger! Mortar strike incoming at: Swamp village", + "ShellingWarningMessage/31": "Danger! Mortar strike incoming at: Sawmill", + "ShellingWarningMessage/32": "Danger! Mortar strike incoming at: Road checkpoint", + "ShellingWarningMessage/33": "Danger! Mortar strike incoming at: Emercom base", + "ShellingWarningMessage/34": "Danger! Mortar strike incoming at: Village", + "ShellingWarningMessage/35": "Danger! Mortar strike incoming at: Abandoned village", + "ShellingWarningMessage/41": "Danger! Mortar strike incoming at: Barracks", + "ShellingWarningMessage/42": "Danger! Mortar strike incoming at: Bunker E2", + "ShellingWarningMessage/43": "Danger! Mortar strike incoming at: Garages", + "ShellingWarningMessage/44": "Danger! Mortar strike incoming at: Bunker E1", + "Shellingbusy": "Mortar crew is busy", "Shoot": "Fire", "Shoot with the range": "TRY OUT YOUR WEAPON", "ShootOut": "ShootOut", @@ -15147,6 +16650,8 @@ "Show icons": "Show icons", "Show:": "Show: ", "SightingRange": "SIGHTING RANGE", + "SignalizatorVibrationOff": "Disable vibration", + "SignalizatorVibrationOn": "Enable vibration", "Silent bots": "Silent bots", "SilentOps": "Silent Ops", "SilentOpsDescription": "The skill of staying undetected in all aspects of the raid operation through improved melee speed and reduced volume of doors and looting sounds.", @@ -15237,7 +16742,7 @@ "Stop looking for group": "Stop looking for group", "Strength": "Strength", "StrengthBuffAim": "Reduces stamina drain while aiming by [{0:0.#%}]", - "StrengthBuffElite": "Equipped weapons don't add up to the weight of your character (not including weapons in backpacks)", + "StrengthBuffElite": "Weapons equipped on sling and on back don't count towards total character weight", "StrengthBuffJumpHeightInc": "Increases jump height by [{0:0.#%}]", "StrengthBuffLiftWeightInc": "Increases carrying weight by [{0:0.#%}]", "StrengthBuffMeleeCrits": "Increases chance to deal critical melee damage by [{0:0.#%}]", @@ -15320,6 +16825,12 @@ "SurgeryLevelingUpDescription": "The Surgery skill is improved by using surgical kits on injured body parts.", "SurgeryReducePenalty": "Reduces surgery HP penalty by [{0:0.#%}]", "SurgerySpeed": "Increases surgery speed by [{0:0.#%}]", + "Survey/Completed": "Survey completed\nThank you for your feedback!", + "Survey/HasUncompletedQuestions": "Please answer all questions before submitting", + "Survey/HeaderTitle": "Feedback form", + "Survey/NoAvailableSurvey": "No active surveys available\nStay tuned for updates!", + "Survey/Question": "QUESTION", + "Survey/TextAnswer/InputFieldTitle": "Describe your experience in the form below", "Survival Rate Short": "S/R: {0}%", "SurvivalRate": "Survival rate", "Survived": "Survived", @@ -15356,6 +16867,8 @@ "TYPES OF FIRE": "TYPES OF FIRE", "Tactical": "Toggle tactical devices", "Tactical clothing": "Tactical clothing", + "TacticalInteractionMode/Hold": "Hold", + "TacticalInteractionMode/Press": "Press", "TacticalVest": "Tactical Rig", "Tag": "Tag", "Tagged and Cursed": "Tagged and Cursed", @@ -15364,10 +16877,12 @@ "Tarkov": "Tarkov", "TarkovStreets": "Streets of Tarkov", "Task": "Task", + "Taskbar/Unavailable": "Unavailable", "Taskperformance": "Task Performance", "TeamFight": "TeamFight", "TeamFightDescription": "Team fight 5 against 5. The objective is to eliminate the opposing team sooner than they kill you.", "TeamFightDescriptionShort": "Team deathmatch", + "TeamTab": "Teams", "Teamkills": "Teamkills", "Terrain quality:": "Terrain quality:", "Texture quality settings will be applied after restart.": "Texture quality settings will be applied after game restart.", @@ -15384,7 +16899,7 @@ "The map is available to players from level": "The map is available to players from level {0}", "The map is available to players up to level": "The map is available to players up to level {0}", "TheUnheardEditionEnvironmentUiType": "The Unheard", - "These items will be lost if you do not survive in the next raid. You can move them to a special stash for quest items.": "You can move these items to a special stash for quest items. They will be lost if you do not survive the raid.", + "These items will be lost if you do not survive in the next raid. You can move them to a special stash for quest items.": "These items will be lost if you do not survive the raid. You can move these items to a special task stash.", "This is already equipped": "This is already equipped", "This item is purchased in quantities of {0} pcs. (Max: {1}) limited for you in one restock": "You've purchased this item in quantities of {0} pcs.\n(Max: {1}) limited for you in one restock", "This light level has not been unlocked yet": "This light level has not been unlocked yet", @@ -15411,11 +16926,18 @@ "TimeoutError": "Timeout Error", "Times of day": "Time of day", "To spend": "To spend", + "ToQuestUpdateRemains": "Time until update", + "ToggleBipods": "Toggle bipod", "ToggleGoggles": "Toggle on-head equipment (NVG, face shield)", "ToggleHeadLight": "Toggle helmet tactical device", "ToggleHeadLight:": "", "ToggleInfo": "Icons toggle", "ToggleLauncher": "Toggle Underbarrel Weapon", + "ToggleLockMode": "Toggle item lock mode", + "TogglePinMode": "Toggle item pin mode", + "ToggleTacticalInteraction": "Tactical device activation mode", + "Tooltips/PinLock/LockDescription": "Locked items can't be moved, used, modified, discarded or handed over", + "Tooltips/PinLock/PinDescription": "Pinned items will retain their position after auto-sorting", "Top": "Top", "TopUp": "TOP-UP", "Total": "Total", @@ -15432,7 +16954,7 @@ "Traders are not available now": "Traders are not available now", "Trading": "TRADING", "Trading/AssortmentUpdated": "restocked", - "Trading/Bad standing": "The trader doesn't want to buy it from you because of low reputation", + "Trading/Bad standing": "The trader doesn't want to buy it from you because of low standing", "Trading/Btr/Dialog/AvailableServices/Description": "I can get you where you want to go, I can provide cover fire if you're being tailed. I can also move your stuff to the right place, to your hideout. So, what's it gonna be?", "Trading/Btr/Dialog/AvaliableServices": "So what can you do?", "Trading/Btr/Dialog/Quit": "End conversation", @@ -15443,11 +16965,11 @@ "Trading/Dialog/AvaliableServices": "Can you help me with something?", "Trading/Dialog/Btr/News": "What's the news?", "Trading/Dialog/Btr/News/Next": "Any more news?", - "Trading/Dialog/Btr/News1": "I just don't get it. Why did Skier and Peacekeeper start all this crap and then bail out so quickly without achieving anything substantial?", - "Trading/Dialog/Btr/News2": "I heard the recent commotion started because of some weirdo in a hoodie. Some people saw him on cameras. If you ask me, it's a shady story.", - "Trading/Dialog/Btr/News3": "I've been told that Therapist is trying to get access to the Lab. She's even looking to gather key-cards. What the hell does she want there, I wonder.", - "Trading/Dialog/Btr/News4": "There's a new business emerging in Tarkov: some guides are offering safe routes from one area to another. I can't figure out if these guys are my colleagues or competitors... I'll be keeping an eye on them. And my 30 mil, just in case.", - "Trading/Dialog/Btr/News5": "The weather has been really crazy lately. Did you see that fog the other day? It was thick as milk!", + "Trading/Dialog/Btr/News1": "There was quite a commotion in the city recently! That virus... It's not the first time something like this has happened in Tarkov, but it's never been this bad before. Good thing they managed to get it under control.", + "Trading/Dialog/Btr/News2": "You're probably wondering why the hell I wasn’t around while everyone was shooting the infected. Well, it's simple, I didn't want to get infected, duh. Me and the the guys got on quarantine, haha!", + "Trading/Dialog/Btr/News3": "You know, I’ve got a base too. You know the old depot in the Priozersk protected area? Over there. I heard some trader used to live there, but then he vanished maybe got killed, maybe something else happened. He left a good spot, though.\n\nWhat’s not so good are the punks trying to break in. They’re sneaking in under the train! But no worries, my guys have already started setting up mines around there.", + "Trading/Dialog/Btr/News4": "Lately, the Fence has been going wild. He’s taken control of most of the trade routes and is squeezing money out of honest fighters. I’m already thinking about stopping doing business with him.", + "Trading/Dialog/Btr/News5": "Come see me later, I might have a job for you.", "Trading/Dialog/Btr/NoNews": "I think that's all the news I have.", "Trading/Dialog/Btr/ServicePayoff{0}": "Works for me, yes. (hand over \"{0}\")", "Trading/Dialog/BtrBotCover/Description": "The whole time you're in the BTR, we'll shoot anyone who sticks their noses out. We'll also clear the drop zone and cover you while you get out, but not for long.", @@ -15528,7 +17050,19 @@ "TransferScreen/PriceMessage": "Delivery will cost:", "TransferScreen/TransferFailed": "Failed to purchase service", "TransferScreen/TransferSuccess": "Service purchased!", + "Transit/AccessNotGranted": "Access denied", + "Transit/InactivePoint": "Transit unavailable", + "Transit/Interaction": "Interact", + "Transition in ": "Transition in ", + "Transition in {0:F1}": "Transition in {0:F1}", "Tremor": "Tremor", + "Tripwire/Interaction/Disable": "Disarm", + "Tripwire/Interaction/DisablingText{0:F1}": "Disarming {0:F1}", + "Tripwire/Interaction/MustBeIdle": "Cannot disarm tripwire while moving", + "Tripwire/NoKit": "Tripwire installation kit missing", + "Tripwire/NoPlantFireMode": "Unable to set tripwire with this grenade", + "Tripwire/PlantUnavailable": "Unable to install tripwire", + "Tripwire/PlantUnavailable/Height": "Angle too steep", "TroubleFixing": "Increases troubleshooting speed by [{0:0.#%}]", "TroubleFixingAmmoElite": "Reduces weapon cartridge malfunction chance after fixing a malfunction from the same source by [50%]", "TroubleFixingDurElite": "Reduces weapon durability malfunction chance after fixing a malfunction from the same source by [50%]", @@ -15599,6 +17133,10 @@ "Tutorial_TabTrade_Description": "Here you can see the list of merchants. All of them are based in Tarkov, just like you, and have their own interests. Every one of them has his or her own needs and specifics in the range of items for purchase or on sale. \\n\\nTraders have several levels of loyalty, with every level gives access to new products. Loyalty depends on your reputation with a merchant, your level, and the amount of money spent. \\n\\nOne example is Prapor.", "Tutorial_TabTrade_Title": "Traders", "Type": "Type", + "UI/AddOfferWindow/RefreshPrices": "REFRESH PRICES", + "UI/Arena/Place_-1": "Draw", + "UI/Arena/Place_-2": "Absent from match", + "UI/Arena/Place_-3": "Match invalid", "UI/Arena/Place_1": "1st place", "UI/Arena/Place_10": "10th place", "UI/Arena/Place_11": "11th place", @@ -15624,6 +17162,8 @@ "UI/ArmorPenetration/Medium": "Medium", "UI/ArmorPenetration/VeryHigh": "Very high", "UI/ArmorPenetration/VeryLow": "Very low ", + "UI/Artillery/ArtaManName": "Mortar crew", + "UI/Artillery/ArtilleryWeaponName": "82mm mortar round", "UI/Charisma/Discount/Insurance": "Insurance cost", "UI/Charisma/Discount/PostRaidHealing": "Healing cost", "UI/Charisma/Discount/ScavCase": "Scav Case cost", @@ -15695,14 +17235,25 @@ "UI/OldPrice:": "Old price:", "UI/ProfileStats/Liters": "l", "UI/ProfileStats/Meters": "m", + "UI/Quest/Reward/AdditionalPocketsCaption": "+2 pocket slots", "UI/Quest/Reward/AdditionalStashRowsCaption": "Inventory slot lines in stash", "UI/Quest/Reward/AdditionalStashRowsTooltip": "Your stash will be expanded by the addition of new inventory slot lines.\nThese changes will be applied later on (check our website for details).", + "UI/Quest/Reward/AssortmentUnlockCaption": "Unlocks assortment at {0} Loyalty Level {1}", + "UI/Quest/Reward/CustomizationOfferCaption": "Tactical clothing", + "UI/Quest/Reward/ItemCaption": "Item", + "UI/Quest/Reward/ProductionSchemeCaption": "Crafting recipe at {0} at level {1}", + "UI/Quest/Reward/QuestCaption": "Task", + "UI/Quests/Conditions/ProfileLevel{0}": "Character level: {0}", + "UI/Quests/Conditions/SkillLevel{0}{1}": "{0} skill level: {1}", + "UI/Quests/Conditions/TraderLoyalty{0}{1}": "Loyalty level with {0}: {1}", + "UI/Quests/Conditions/TraderStanding{0}{1}": "Standing with {0}: {1}", "UI/Settings/ArenaWatchTimerAndExits": "Check time and objectives", "UI/Settings/Armory": "Armory", "UI/Settings/Armory/Ammo": "Ammo", "UI/Settings/Armory/Interactions": "Weapon interactions", "UI/Settings/Armory/Other": "Other equipment", "UI/Settings/Armory/Weapons": "Weapons", + "UI/Settings/AutoAddHideout": "Auto add to Wishlist", "UI/Settings/Control/MouseAndKeys": "Keyboard and mouse", "UI/Settings/Control/Phrases": "Phrases", "UI/Settings/Interface": "Interface", @@ -15715,6 +17266,7 @@ "UI/Settings/NotificationType/WebSocket": "Web socket", "UI/Settings/OtherActions": "Other actions", "UI/Settings/Rest": "Other", + "UI/Settings/WishlistNotify": "Wishlist item notifications", "UI/Skills/Charisma/CharismaDiscount": "Charisma skill discount", "UI/Standing:": "Trader standing:", "UI/Trader/TransferLocked": "Unavailable for transfer", @@ -15739,6 +17291,9 @@ "Ui/Settings/AutoVaultingMode": "Vaulting over medium obstacles", "Ui/Settings/BlockGroupInvites": "Block group invites", "Ui/Settings/CantModifyWhenMipStreamingIsOff": "Can't modify the parameter while Mip Streaming is disabled", + "Ui/Settings/ClearAllWishlist": "Clear Wishlist", + "Ui/Settings/ClearAllWishlistMessage1": "Your Wishlist will be cleared.", + "Ui/Settings/ClearAllWishlistMessage2": "All previously saved entries will be deleted. Are you sure?", "Ui/Settings/ColorScheme/GreenToRed": "Polychrome", "Ui/Settings/ColorScheme/WhiteToRed": "Monochrome", "Ui/Settings/EnableHideoutPreload": "Preload Hideout", @@ -15750,7 +17305,7 @@ "Ui/Settings/HighlightScope/None": "Disabled", "Ui/Settings/MalfunctionVisability": "Malfunction notifications", "Ui/Settings/NVidiaReflexNotAvailable": "NVIDIA Reflex is not available on this system.", - "Ui/Settings/NVidiaReflexType": "NVIDIA Reflex Low Latency", + "Ui/Settings/NVidiaReflexType": "NVIDIA Reflex Low Latency:", "Ui/Settings/NotificationTransportType": "Notification channel type", "Ui/Settings/QuickSlotsVisibility": "Quick slots", "Ui/Settings/SelectedMemberCategory": "Profile icon", @@ -15761,6 +17316,7 @@ "Ui/Settings/Visibility/Always": "Always shown", "Ui/Settings/Visibility/Autohide": "Autohide", "Ui/Settings/Visibility/Never": "Always hidden", + "UnavailableDuringMatching": "Unavailable during matching", "Unban": "Unban", "UnbanPlayer": "{0} has been unbanned.", "Uncover": "Cancel insurance", @@ -15790,6 +17346,7 @@ "Use": "USE", "Use only available parts": "Use only available parts", "Used symbols: {0}": "Used symbols: {0}", + "UserCustomPreset": "Custom", "VALIDATE DEVICE ID": "VALIDATE DEVICE ID", "VELOCITY": "MUZZLE VELOCITY", "VIEWMAP": "VIEW", @@ -15821,8 +17378,8 @@ "Voice volume:": "Voice volume:", "Voip/AutoBlockNotification": "Stop spamming push to talk button or you will be blocked from VoIP", "Voip/BlockedMessage": "You have been blocked from using VoIP for system misuse", - "Voip/DenoiseAmount": "Noise reduction", - "Voip/Device": "Device", + "Voip/DenoiseAmount": "Noise reduction:", + "Voip/Device": "Device:", "Voip/DeviceSensitivity": "Microphone volume:", "Voip/DisabledForOffline": "VoIP is unavailable in the offline mode", "Voip/DisabledForRaid": "VoIP was disabled on the server", @@ -15836,13 +17393,13 @@ "Voip/FirstTimeMessageHeader": "VoIP usage rules", "Voip/InitializationFailed": "Microphone initialization failed", "Voip/InitializationFailedTooltip": "Initialization process failed", - "Voip/MicrophoneSensitivity": "Microphone sensitivity", + "Voip/MicrophoneSensitivity": "Microphone sensitivity:", "Voip/PlayersReported": "Your report has been sent", "Voip/VoiceActivationEnable": "Radio voice activation", - "Voip/WalkieTalkieVolume": "Radio volume", + "Voip/WalkieTalkieVolume": "Radio volume:", "Voip/YouAreReported": "Your VoIP misuse has been reported", "WATCHLIST": "WATCHLIST", - "WEAPON BUILDS": "WEAPON PRESETS", + "WEAPON BUILDS": "WEAPON BUILDS", "WEAPON MASTERING (01)": "WEAPON MASTERING (01)", "WEAPON MASTERING (02)": "WEAPON MASTERING (02)", "WEAPON MASTERING (03)": "WEAPON MASTERING (03)", @@ -15853,6 +17410,15 @@ "WEAPONSTANDSECONDARY": "Weapon Rack", "WEAR": "WEAR", "WEIGHT": "WEIGHT", + "WOO_TRANSIT_15": "TRANSIT02", + "WOO_TRANSIT_15_COND": " ", + "WOO_TRANSIT_15_DESC": "Transit to Factory", + "WOO_TRANSIT_16": "TRANSIT01", + "WOO_TRANSIT_16_COND": " ", + "WOO_TRANSIT_16_DESC": "Transit to Reserve", + "WOO_TRANSIT_17": "TRANSIT03", + "WOO_TRANSIT_17_COND": " ", + "WOO_TRANSIT_17_DESC": "Transit to Lighthouse", "Walk": "Walk", "WalkieTalkiePushToTalk": "Use radio", "Warehouse 17": "Warehouse 17", @@ -15882,6 +17448,7 @@ "WeaponJammed": "WEAPON JAMMED", "WeaponModding": "Weapon Modding", "WeaponModdingDescription": "Skill of basic weapon modding on the go increases the mod ergonomics and reduces silencer wear.", + "WeaponMounting": "Mount weapon", "WeaponPunch": "Buttstroke", "WeaponRecoilBuff": "Reduces weapon recoil by [{0:0.#%}]", "WeaponReloadBuff": "Increases reload speed by [{0:0.#%}]", @@ -15894,7 +17461,7 @@ "WearChanceRepairGunsReduceEliteLevel": "Reduces wear chance when using repair kits by [50%]", "Weather conditions": "Weather conditions", "WeightLimit": "Weight limit", - "Welcome screen description": "Welcome to Escape from Tarkov!\nIn this game, you will have to fight for your life and survive the perils of Tarkov, a Russian city in the Norvinsk region on the brink of chaos and collapse. Your character is an operator of a Private Military Company (PMC), caught in a maelstrom of events right after the Contract Wars. The area is sealed off, and your operational command is not responding; previous mission objectives have lost their purpose. Everybody has personal goals now – adapt and survive, escape the blockade or try to save others.\n\nBe prepared to die and lose everything you had with you in every raid you enter.\nKeep in mind that every drop in your internet connection or network hardware malfunction can lead to disconnection from the game with the consecutive death of your character and loss of all the gear you had with you or found within your raid.\n\nYes, you will die, and most probably very often, but remember – this is still a game. Best of luck out there!", + "Welcome screen description": "Welcome to Escape from Tarkov!\nIn this game, you will have to fight for your life and survive the perils of Tarkov, a Russian city in the Norvinsk region on the brink of chaos and collapse. Your character is an operator of a Private Military Company (PMC), caught in a maelstrom of events right after the Contract Wars. The area is sealed off, and your operational command is not responding; previous mission objectives have lost their purpose. Everybody has personal goals now – adapt and survive, escape the blockade or try to save others.\n\nBe prepared to die and lose everything you had with you in every raid you enter.\nKeep in mind that every drop in your internet connection or hardware malfunction can lead to disconnection from the game with the consecutive death of your character and loss of all the gear you had with you or found within your raid.\n\nYes, you will die, and most probably very often, but remember – this is still a game. Best of luck out there!", "West Border": "Eastern Rocks", "West Gate": "West Gate", "When you leave the raid you don’t get anything and also receive Left the Action exit status.": "If you leave the raid, you lose all your loot and also receive the Left the Action exit status.", @@ -15908,6 +17475,12 @@ "WindSpeed/Strong": "Strong wind", "WindSpeed/VeryStrong": "Windstorm", "Windowed": "Windowed", + "Wishlist": "Wishlist", + "Wishlist/AlreadyInWishlist": "Item is already in Wishlist", + "Wishlist/NotInWishlist": "Item is not in Wishlist", + "Wishlist/Notify/Default{0}": "Wishlist item {0} acquired", + "Wishlist/Notify/Purchase{0}": "Wishlist item {0} purchased", + "Wishlist/RemoveFromWishlist": "Remove from Wishlist", "WoodEnvironmentUiType": "Woods", "Woods": "Woods", "Workbench": "WORKBENCH", @@ -15927,18 +17500,21 @@ "You are now the leader of the group": "You are now the group leader.", "You can change your nickname only once": "You can only change your nickname once", "You can recover your password using the website.": "You can recover your password using the website.", + "You can't activate an object here": "You can't plant the device in this spot", + "You can't activate an object while moving": "You can't plant the device while moving", "You can't apply medkit. You're at full HP": "You can't apply a medkit. There is nothing to heal.", + "You can't deactivate an object while moving": "You can't deactivate the device while moving", "You can't disassemble equipped item": "You can't disassemble an equipped item", "You can't do this to this item": "You can't do that to this item", "You can't do this to weapon with internal magazine": "You can't do this to a weapon with internal magazine", - "You can't edit build on equipped weapon": "You can't edit preset on an equipped weapon", + "You can't edit build on equipped weapon": "You can't edit build on an equipped weapon", "You can't edit equipped weapon": "You can't edit an equipped weapon", "You can't enable {0} and {1} at the same time. Turn {1} off?": "You can't enable {0} and {1} at the same time. Would you like to turn {1} off?", "You can't examine two items at the same time": "You can't examine two items at the same time", "You can't fold this item": "You can't fold this item", "You can't open flea market": "You can't open flea market", "You can't plant a beacon while moving": "You can't place a beacon while moving", - "You can't plant quest item while moving": "You can't place an item whilst moving.", + "You can't plant quest item while moving": "You can't place an item while moving", "You can't send message to this user. He is in ignore list.": "You can't send message to this user. He is in your ignore list.", "You can't send message to this user. He is not in your friends list.": "You can't send a message to this user.", "You can't send message to this user. You are in ignore list.": "You have been blacklisted and can't send any messages to this user.", @@ -15956,7 +17532,7 @@ "You in trading": "you", "You need to check chamber in weapon": "You need to check chamber in the weapon", "You need to check the revolver drum": "You need to check the revolver cylinder ", - "You need to survive and exit from the location to save and move these items to a special stash for quest items.": "To save and transfer these items to a special stash for quest items, you must successfully extract from the raid.", + "You need to survive and exit from the location to save and move these items to a special stash for quest items.": "To save and transfer these items to a special task stash, you must successfully extract from the raid.", "You received these rewards: ": "You received these rewards: ", "You still have untransfered items. Are you sure you want to end the transfer? You will be able to return to this process later.": "Not all items have been transferred. Are you sure you want to end this process? You will be able to return to this later.", "You still have untransfered items. Are you sure you want to end the transfer? You will not be able to return to this process later.": "You still have untransfered items. Are you sure you want to end the transfer? You will not be able to return to this process later.", @@ -15975,7 +17551,9 @@ "ZB-1011": "ZB-1011", "ZB-1012": "ZB-1012", "ZeroWeaponDeteriorationOnRepair": "No wear during a repair", + "ZombieInfection": "Virus", "aimdrillsdescription": "Aim drills will increase your aiming speed and will allow to perform aiming quieter.", + "already in this group": "Already in this list", "ammoFound": "Ammo found", "ammoUsed": "Ammo used", "any": "Any location", @@ -15983,6 +17561,8 @@ "anyownertype": "Any", "apply": "APPLY", "arena/AssistShort": "A", + "arena/CapturePointScores": "Score", + "arena/CapturePointScoresОчкиArena/Widgets/capture point hold": "Capture and hold the objectives", "arena/DeathShort": "D", "arena/Exp": "Exp", "arena/KillShort": "K", @@ -16006,11 +17586,29 @@ "arena/RespawnAwaiting": "Awaiting respawn...", "arena/Round": "Round", "arena/anyGameMode": "Any game mode", + "arena/armory/AndOthers": "And more ...", + "arena/armory/ConditionsComleted": "All conditions met", + "arena/armory/ConditionsNotComleted": "Unlock conditions not met", + "arena/armory/ProgressionFirtsTitle": "Progress any weapon to level:", + "arena/armory/unselectedItem": "Item not selected", + "arena/buildEditor/Do you want to save changes?": "Do you want to save the changes?", + "arena/buildEditor/equip item building": "Equipment build", + "arena/buildEditor/missing vital parts": "Unable to save preset. Weapon is missing vital parts.", + "arena/buildEditor/not suitable for class {0}": "Not suitable for {0} class", + "arena/buildEditor/save with missing vital parts": "Save preset with missing vital parts?", + "arena/buildEditor/weapon building": "Weapon build", "arena/button/ArenaBattle": "ARENA BATTLE", + "arena/button/Armory": "Armory", "arena/button/Career": "CAREER", "arena/button/Presets": "PRESETS", "arena/button/QuitGame": "QUIT GAME", "arena/button/Rating": "RATING", + "arena/career/LastHeroStats/title": "LastHero statistics", + "arena/career/blastGangStats/activatedObjects": "Devices planted", + "arena/career/blastGangStats/deactivatedObjects": "Devices deactivated", + "arena/career/blastGangStats/explodedObjectsCoef": "Devices successfully activated, %", + "arena/career/blastGangStats/title": "BlastGang statistics", + "arena/career/checkPointStats/title": "CheckPoint statistics", "arena/career/commonStats/avgGlpPerDay": "Avg ARP per day", "arena/career/commonStats/bestGlp": "Highest ARP", "arena/career/commonStats/bestMatchKillStreak": "Highest match kill streak", @@ -16024,6 +17622,8 @@ "arena/career/commonStats/lastSession": "Last Arena session", "arena/career/commonStats/moneyEarned": "Money earned", "arena/career/commonStats/moneySpent": "Money spent", + "arena/career/commonStats/mvpMatch": "Match MVPs received", + "arena/career/commonStats/mvpRound": "Round MVPs received", "arena/career/commonStats/startDate": "Registration date", "arena/career/commonStats/title": "Overall statistics", "arena/career/commonStats/xpHeal": "Healing XP", @@ -16082,12 +17682,14 @@ "arena/career/shootOutStats/winrat": "Tournament win rate, %", "arena/career/shootOutStats/wins": "Tournaments won", "arena/career/shootOutStats/winsWithFavPreset": "Tournaments won with favorite preset", + "arena/career/skills/bottom": "In order to sustain fair and competitive gameplay, the max level of {0}Skills{1} and {0}Perks{1} is locked at {0}level 30{1}.", + "arena/career/skills/top": "{0}Skills{1} and {0}Weapon mastering{1} are linked between Arena and EFT PVP zone. {0}Levelling{1} them in Arena will also {0}level{1} them in EFT.", "arena/career/tabs/common": "Overall", "arena/career/tabs/health": "Health", "arena/career/tabs/history": "History", "arena/career/tabs/inventory": "Inventory", "arena/career/tabs/pile": "Deck", - "arena/career/tabs/quests/daily": "Daily", + "arena/career/tabs/quests/daily": "Operational", "arena/career/tabs/quests/main": "Main", "arena/career/tabs/skills": "Skills", "arena/career/teamFightStats/assists": "Kill assists", @@ -16113,19 +17715,31 @@ "arena/career/teamFightStats/maxMatchXp": "Highest match XP", "arena/career/teamFightStats/moneyEarned": "Money earned", "arena/career/teamFightStats/moneySpent": "Money spent", + "arena/career/teamFightStats/mvpMatch": "Match MVPs received", + "arena/career/teamFightStats/mvpRound": "Round MVPs received", "arena/career/teamFightStats/overKills": "Overkills", "arena/career/teamFightStats/title": "TeamFight statistics", "arena/career/teamFightStats/winrat": "Win rate, %", "arena/career/teamFightStats/wins": "Victories", "arena/career/teamFightStats/winsWithFavPreset": "Matches won with favorite preset", + "arena/contextInteractions/card/delete": "Delete", + "arena/contextInteractions/card/edit": "Edit", + "arena/contextInteractions/card/inspect default preset": "Inspect", + "arena/customGames/create/gameModeBlastGang": "GAME MODE (BLASTGANG)", + "arena/customGames/create/gameModeCheckPoint": "Game mode (CheckPoint)", + "arena/customGames/create/overtime": "Overtime", "arena/customGames/create/samePresets": "Duplicate presets:", + "arena/customGames/create/setMatchDuration": "Match duration:", + "arena/customGames/create/setOvertime": "Set overtime", "arena/customGames/create/setSamePresets": "Allow duplicate presets", + "arena/customGames/create/setScoresToWinCount": "Points to win:", "arena/customGames/invite/message{0}": "CUSTOM GAME INVITE FROM {0}", "arena/customGames/notify/GameRemoved": "Room has been disbanded", "arena/customgames/errors/notification/gamealreadystarted": "Game has already started", "arena/customgames/popup/refreshdailyquest": "Replace operational task?", "arena/customgames/popups/attemptscountleft:": "Attempts left:", "arena/info/GLP Left": "ARP LEFT", + "arena/info/GP": "GP", "arena/info/KD Ratio": "K/D", "arena/info/Main GLP Scores": "ARP SCORE RATIO", "arena/info/Matches": "MATCHES", @@ -16148,11 +17762,11 @@ "arena/matching/SelectRankedGamemode": "SELECT RANKED GAME MODE", "arena/matching/Type": "TYPE", "arena/matching/UnavailableReason": "Unavailable", - "arena/matching/buyPreset": "BUY PRESET", + "arena/matching/buyPreset": "SELECT PRESET", "arena/matching/presetSelection": "PRESET SELECTION", "arena/matching/readyPlayers0 Ready\\nplayers": "Players ready", "arena/merchants/DayLimitOferflowed": "Daily limit exceeded", - "arena/merchants/NoMoneyForCommission": "Not enough money to pay the commission", + "arena/merchants/NoMoneyForCommission": "Not enough money to pay the fee", "arena/merchants/NoSyncedServerButton": "Service temporarily unavailable", "arena/merchants/NoSyncedServerTooltip": "Service unavailable\n\nSynchronization error\nPlease try again later", "arena/merchants/SynkError": "Synchronization error\nPlease try again later", @@ -16163,6 +17777,13 @@ "arena/merchants/storage": "Stash", "arena/merchants/task": "Tasks", "arena/merchants/to update": "To update", + "arena/merchants/tooltip/commission/CharismaBonus": "charisma bonus", + "arena/merchants/tooltip/commission/Header": "Fee calculation", + "arena/merchants/tooltip/commission/ItemTransfer": "Item transfer", + "arena/merchants/tooltip/commission/MoneyTransfer": "Money transfer", + "arena/merchants/tooltip/commission/NoMoneyForCommission": "Not enough money to pay the transfer and fee", + "arena/merchants/tooltip/commission/StandingBonus": "standing bonus", + "arena/merchants/tooltip/commission/TransferNotAwailable": "Service unavailable", "arena/merchants/transfer": "Transfer", "arena/merchants/transfer amount": "Transfer amount", "arena/merchants/transfer of items": "Item transfer", @@ -16171,6 +17792,8 @@ "arena/merchants/сancellation": "Cancel", "arena/monitors/score": "SCORE", "arena/monitors/style": "STYLE", + "arena/popup/delete preset description": "Are you sure you want to delete this preset?", + "arena/popup/delete preset header": "Preset deletion", "arena/popup/quests/price": "REPLACEMENT COST:", "arena/popup/quests/standing": "TRADER STANDING:", "arena/popup/quests/time": "REMAINING TIME:", @@ -16194,8 +17817,25 @@ "arena/postmatch/preset_modificator": "Modifier", "arena/postmatch/ranked_preset_unlock": "Ranked preset unlocked", "arena/postmatch/reward_panel": "Reward", + "arena/presets/custom/blocked": "locked", + "arena/presets/custom/not enough money": "not enough money", + "arena/presets/custom/not enough money short": "insuf. cash", + "arena/presets/custom/purchase": "purchase", + "arena/presets/custom/requirement level {0}": "Character level: {0}", + "arena/presets/custom/requirement standing {0}": "Ref standing: {0}", + "arena/presets/custom/slot unlock error": "Slot unlock error", + "arena/presets/custom/violations/class imbalance": "Incompatible with class", + "arena/presets/custom/violations/duplicated guns": "Repeating weapons", + "arena/presets/custom/violations/forbidden equipment": "Forbidden equipment", + "arena/presets/custom/violations/incompatible ammo": "Incompatible ammo", + "arena/presets/custom/violations/incompatible mags": "Incompatible magazines", + "arena/presets/custom/violations/malfunction weapon": "Missing ammo", + "arena/presets/custom/violations/total": "Out of meta score limits", + "arena/presets/custom/violations/unclothed equipment": "Unused equipment", + "arena/presets/unlocked slots": "Unlocked", + "arena/presets/unlocked slots count": "slots unlocked:", "arena/questLogTemplate/gameModes": "Game mode(s)", - "arena/questLogTemplate/maps": "Map(s)", + "arena/questLogTemplate/maps": "Location(s)", "arena/selection/gameMode": "game mode", "arena/selection/tiers": "tier", "arena/tab/ASSAULT": "ASSAULT", @@ -16204,7 +17844,7 @@ "arena/tab/MARKSMAN": "MARKSMAN", "arena/tab/RATING": "RATING", "arena/tab/SCOUT": "SCOUT", - "arena/tab/SQB": "CQB", + "arena/tab/SQB": "ENFORCER", "arena/tooltip/GP": "GP Coin. Used to unlock equipment for presets and to purchase gear in EFT. Earned for completing operational tasks in Arena.", "arena/tooltip/OverallMatches": "Total number of ranked and unranked matches played.", "arena/tooltip/Presets": "Presets", @@ -16222,6 +17862,8 @@ "arena/tooltip/sourcesGlp": "Earned ARP sources:", "arena/tooltip/winMatches": "Total number of wins in ranked and unranked matches.", "arena/tooltip/winRate": "Your overall win ratio, calculated from all wins and losses in ranked and unranked matches.", + "arena/widget/ally_capture_point": "Allies captured point", + "arena/widget/enemy_capture_point": "Enemies captured point", "arenaui/presetview/lockedpreset": "Preset unavailable", "arm broke": "You broke your arm!", "assaultKills": "Assault rifle kills", @@ -16317,7 +17959,6 @@ "doubleaction": "Double action", "doublet": "Double-Tap", "drinksUsed": "Drinks consumed", - "earenapresetstype/collection": "COLLECTION", "embedded": "enclosed", "en": "English", "enhancementChance/average": "Medium", @@ -16370,7 +18011,9 @@ "ge": "Deutsch", "glKills": "Grenade launcher kills", "good": "good", + "greanadePlanting": "Tripwire", "grenadeKills": "Grenade kills", + "grenadeThrowing": "Throw", "groin": "GROIN", "groin_back": "GROIN (REAR)", "gym": "Gym", @@ -16416,6 +18059,8 @@ "hideout/Producing": "Producing", "hideout/Replace targets": "Replace targets", "hideout/Requirements are not fulfilled": "Requirements are not fulfilled", + "hideout/RestoreEquipment": "Restore consumables", + "hideout/Sacrificing": "Ritual in progress", "hideout/Stop": "Stop", "hideout/Switched off": "Switched off", "hideout/Take crafted items": "You need to take the items", @@ -16455,6 +18100,10 @@ "hideout_6549f1c405b256642e3e9131": "PMC dogtags", "hideout_6549f1cdde376a2fc737e8a8": "Small trophies", "hideout_6549f1d37d6e4756c83afa77": "Large trophies", + "hideout_6698e6d817b8f677b3077ef0": "Additional mannequins", + "hideout_6698e72c17b8f677b3077ef1": "Additional mannequins", + "hideout_6698e73c0ab2cbb83904ee2a": "Additional mannequins", + "hideout_669fa357d562926a0e01fd65": "Total bonus to the Gift", "hideout_AdditionalSlots": "Additional slots", "hideout_DebuffEndDelay": "Negative effects removal rate", "hideout_EnergyRegeneration": "Energy regeneration rate", @@ -16464,7 +18113,7 @@ "hideout_HydrationRegeneration": "Hydration regeneration rate", "hideout_InsuranceReturnTime": "Insurance return time", "hideout_MaximumEnergyReserve": "Maximum energy reserve", - "hideout_QuestMoneyReward": "Quest money reward boost", + "hideout_QuestMoneyReward": "Task money reward boost", "hideout_RagfairCommission": "Flea market fee", "hideout_ReceiveItemBonus": "Special delivery", "hideout_RepairArmorBonus": "Reduces armor repair cost using repair kits", @@ -16544,6 +18193,14 @@ "hideout_area_24_stage_1_description": "A small weapon rack. Simplifies firearm storage and allows to display weapons in a fancy way.", "hideout_area_24_stage_2_description": "A medium-sized weapon rack. Simplifies firearm storage and allows to display weapons in a fancy way.", "hideout_area_24_stage_3_description": "A large weapon rack. Simplifies firearm storage and allows to display weapons in a fancy way.", + "hideout_area_26_name": "Gear Rack", + "hideout_area_26_stage_0_description": "This place would be good to put a couple of mannequins found at the shopping malls. It just needs a little clean-up.", + "hideout_area_26_stage_1_description": "A mannequin with a weapon rack. Allows you to prepare a set of equipment for the raid.", + "hideout_area_26_stage_2_description": "With two mannequins, you can not only prepare gear for a raid, but also display something cool and rare. Would look great.", + "hideout_area_26_stage_3_description": "Several mannequins with a weapon rack. With a wardrobe like this, it will be easy to store quick access gear for any occasion.", + "hideout_area_27_name": "Cultist Circle", + "hideout_area_27_stage_0_description": "A good place to meet the suspicious hooded persons. Although, you'll have to make contact with them first.", + "hideout_area_27_stage_1_description": "A circle drawn in chalk and cluttered with mysterious symbols. Such circles are used by the cultists for their rituals. One wonders what would happen if you put something in the middle of it...?", "hideout_area_2_name": "Lavatory", "hideout_area_2_stage_1_description": "A primitive toilet. Any amenities are out of the question. Just a bucket and a litter box to maintain basic sanitation in the hideout.", "hideout_area_2_stage_2_description": "A basic bathroom with a wooden outhouse type toilet and a washstand, connected to the water supply system. All this raises the level of cleanliness and hygiene in the hideout.", @@ -16665,6 +18322,7 @@ "loudness": "LOUDNESS", "lowernape": "Lower nape", "m/s": "m/s", + "marathon Name": "Transition", "matching/timeout": "Failed to find a raid. Please try again later.", "matchmaker/health_is_low": "Your character is heavily wounded", "matchmaker/health_is_not_full": "Your character is still wounded", @@ -16676,7 +18334,8 @@ "meters": "meters", "mgKills": "Machine gun kills", "moa": "MOA", - "mod_pistolgrip_000": "Pistol grip", + "mod_pistolgrip_000": "Grip", + "mod_pistolgrip_001": "GRIP", "modsFound": "Mods found", "multiple_locations Name": "multiple locations", "neckback": "Back neck", @@ -16703,6 +18362,7 @@ "purchase all": "PURCHASE ALL", "pushtotalk": "Push-to-talk", "quadKills": "Quad kills", + "quests": "Tasks", "quick secondary weapon": "Sidearm quick swap", "rQualityAverage": "Average", "rQualityExcellent": "Excellent", @@ -16754,7 +18414,7 @@ "ragfair/No offers has been found in {0} category. Select another category.": "No offers have been found in the {0} category. Please select another category.", "ragfair/Not raid barter item notification": "Item must be found in raid", "ragfair/Not raid item notification": "You can't sell an item which was not found in raid", - "ragfair/OFFER ADD": "ADD OFFER", + "ragfair/OFFER ADD": "Offer creation", "ragfair/OR": "OR", "ragfair/Offer": "Offer", "ragfair/Offer with id #{0} has not been found": "Could not find offer ID #{0}", @@ -16768,7 +18428,7 @@ "ragfair/OnlyPrioritized": "Priority offers only", "ragfair/PLACE OFFER": "PLACE OFFER", "ragfair/PURCHASE": "PURCHASE", - "ragfair/PackWarning": "You are going to put several items as a pack. Are you sure?", + "ragfair/PackWarning": "You are going to list several items as one pack. Are you sure?", "ragfair/Price": "Price", "ragfair/PriceFrom": "Min. Price", "ragfair/PriceTo": "Max. Price", @@ -16783,7 +18443,7 @@ "ragfair/Remember selected filter": "Remember selected filter", "ragfair/RemoveBartering": "Exclude bartering offers", "ragfair/RemoveMerchant": "Exclude trader offers", - "ragfair/Require for all items in offer": "Require for all items in offer", + "ragfair/Require for all items in offer": "List as a pack", "ragfair/Require only functional items": "Require only functional items", "ragfair/SHOW MORE": "SHOW MORE", "ragfair/Select item from the Handbook of your known items": "Select item from the Handbook of your known items.", @@ -16793,11 +18453,11 @@ "ragfair/TOTAL:": "Total", "ragfair/This item cannot be placed at ragfair": "This item can't be sold at the Flea Market.", "ragfair/This item will be available at {0} loyalty level. (Yours is {1})": "This item will be available at loyalty level {0}. (Your current level is {1})", - "ragfair/This item will be available with the quest completion": "This item will be available with the quest completion", + "ragfair/This item will be available with the quest completion": "Item will be available with the task completion", "ragfair/TooLittleWarning": "You are going to put the item at a cost much lower than the cheapest existing similar offer. Are you sure?", "ragfair/TooManyItemsSelected": "Too many items", "ragfair/TooMuchWarning": "You are going to place an item at a cost much higher than the most expensive existing similar offer. Are you sure?", - "ragfair/Trader will be unlocked with the quest completion": "Trader will be unlocked with the quest completion", + "ragfair/Trader will be unlocked with the quest completion": "Trader will be unlocked with the task completion", "ragfair/Unable to sell the item that contains": "", "ragfair/Unable to sell the item that contains {0}": "Unable to sell the item that contains \"{0}\"", "ragfair/Unlocked at character LVL {0}": "The ability to create offers as well as to see and buy other players' goods will be unlocked on level {0}.", @@ -16820,6 +18480,7 @@ "ragfair/per pack ({0} items)": "per pack ({0} items)", "ragfair/playerownertype": "Player", "ragfair/prioritized offers": "Priority offers", + "ragfair/restrictionLimits{0}{1}{2}": "This item ({0}) has a listing limit!\nMaximum: {1}, in one pack: {2}", "ragfair/to:": "to:", "ragfair/traderownertype": "Traders", "ragfair/you don't have enough money for the transaction": "You don't have enough money for the transaction", @@ -16916,6 +18577,7 @@ "traders/trader_is_locked": "Trader is locked", "trading/less item {0} than you want. You bought all remaining items ({1})": "The trader has fewer items {0}. You bought all remaining items ({1})", "tripleKills": "Triple kills", + "tripwireKills": "Landmine kills", "tu": "Türkçe", "tunnelvision": "Tunnel vision", "turn off": "TURN OFF", @@ -16935,6 +18597,7 @@ "unpack": "unpack", "usecKills": "USECs killed", "various": "Various", + "various name": "Various", "very bad": "very bad", "very fast": "very fast", "very good": "very good", @@ -16946,6 +18609,7 @@ "weapon name": "Weapon name", "will be available in:": "will be available in:", "will be destroyed after unpacking": "Will be destroyed after unpacking", + "wood_sniper_exit": "Power Line Passage", "you": "You", "you can't transfer item while moving": "You can't transfer items while moving", "you were disconnected for inactivity": "You were disconnected for inactivity", @@ -16986,7 +18650,7 @@ "{0}h{1:00}m": "{0}h{1:00}m", "{0}m": "{0}m", "{0}y{1}d": "{0}y{1}d", - "{resetOnConditionFailed{0}}": " {0} time(s) in a row", + "{resetOnConditionFailed{0}}": " several times in a row", "{resetOnSessionEnd}": " in 1 match", "~ Empty": "~ Empty", "~ Full": "~ Full", @@ -17082,6 +18746,7 @@ "5fe8c7b76c0ea413171b4271": "Season V", "608be809bb51f61f7a7bf504": "", "64b7e7221ed9925548080aea": "Prewipe 13.5 season", + "66c89b3202d36066710f5498": "Summer Twitch Drops event", "5b47574386f77428ca22b2ed": "Energy elements", "5b47574386f77428ca22b2ee": "Building materials", "5b47574386f77428ca22b2ef": "Electronics", @@ -17277,20 +18942,18 @@ "657399489b19e826a721d75c 1": "I moved the stuff where we agreed.", "657399489b19e826a721d75c 2": "Your stuff is at the base.", "6582beba471fa54463010b16 0": "Fighter!\nTravel safely, the Scav bosses and those hooded creeps have crawled out of their holes and are always in their positions. It has happened before, I'm sure you remember. ", + "66cf25c39426aa50850f2980 0": "Thank you for completing the survey! Get a reward.", + "670547bb5fa0b1a7c30d5836 0": "Earned achievement reward.", + "670547bb5fa0b1a7c30d5836 1": "Earned achievement bonus.", + "672dd5b83804f9bc8e0a610e 0": "Survey reward", "Arena/UI/Match_leaving_warning_body 0": "If you leave the match, you'll put your allies at disadvantage./nYou'll lose your reward and rating and could receive a temporary ban.", "Arena/UI/Match_leaving_warning_header 0": "Warning! You are leaving the match.", "5cc084dd14c02e000b0550a3 Name": "Vasilyev", "5cc084dd14c02e000b0550a3 ShortName": "Vasilyev", "5cc084dd14c02e000b0550a3 Description": "Vasilyev", "5cde96047d6c8b20b577f016 Name": "Taylor", - "5cde96047d6c8b20b577f016 ShortName": "Taylor", - "5cde96047d6c8b20b577f016 Description": "Taylor", - "5cdea20c7d6c8b0474535dab Name": "Worn jeans", - "5cdea20c7d6c8b0474535dab ShortName": "", - "5cdea20c7d6c8b0474535dab Description": "", - "5cdea30c7d6c8b04737c2d15 Name": "Work pants", - "5cdea30c7d6c8b04737c2d15 ShortName": "", - "5cdea30c7d6c8b04737c2d15 Description": "", + "5cde96047d6c8b20b577f016 ShortName": "", + "5cde96047d6c8b20b577f016 Description": "", "5fc1221a95572123ae7384a2 Name": "Aleksandr", "5fc1221a95572123ae7384a2 ShortName": " Aleksandr", "5fc1221a95572123ae7384a2 Description": " Aleksandr", @@ -17336,18 +18999,9 @@ "6284d6ab8e4092597733b7a7 Name": "Patrick", "6284d6ab8e4092597733b7a7 ShortName": "Patrick", "6284d6ab8e4092597733b7a7 Description": "Patrick", - "64ad28b54c5754692e078683 Name": "Tikhohod", - "64ad28b54c5754692e078683 ShortName": "", - "64ad28b54c5754692e078683 Description": "", - "64ad296e83edb914bc035f92 Name": "Cultist robe", - "64ad296e83edb914bc035f92 ShortName": "", - "64ad296e83edb914bc035f92 Description": "", - "6543993a620afdbdb0051411 Name": "Rizhy's jacket", - "6543993a620afdbdb0051411 ShortName": "Rizhy", - "6543993a620afdbdb0051411 Description": "Rizhy's jacket", - "65439998155c8a2a1707d298 Name": "Ryzhy's pants", - "65439998155c8a2a1707d298 ShortName": "Ryzhy's", - "65439998155c8a2a1707d298 Description": "Ryzhy's pants", + "668677330ae95580780867c6 Name": "Charlie", + "668677330ae95580780867c6 ShortName": "Charlie", + "668677330ae95580780867c6 Description": "Charlie", "55f2d3fd4bdc2d5f408b4567 Name": "Factory", "55f2d3fd4bdc2d5f408b4567 Description": "The industrial estate and facilities of Chemical Plant No. 16 were rented out illegally to the TerraGroup corporation. During the advent of the Contract Wars, the plant became the scene of numerous firefights between BEAR and USEC that ultimately determined control over the industrial district of Tarkov.\n\nLater on, in the wake of the chaos, the plant facilities became a shelter for the remaining civilians, Scavs, and military operatives, including the scattered remains of the BEAR and USEC contingents.", "56db0b3bd2720bb0678b4567 Name": "Arena", @@ -17407,7 +19061,7 @@ "653e6760052c01c1c805532f Name": "Ground Zero", "653e6760052c01c1c805532f Description": "The business center of Tarkov. This is where TerraGroup was headquartered. This is where it all began.", "65b8d6f5cdde2479cb2a3125 Name": "Ground Zero", - "65b8d6f5cdde2479cb2a3125 Description": "The business center of Tarkov. This is where TerraGroup was headquartered. This is where it all began.", + "65b8d6f5cdde2479cb2a3125 Description": "The business center of Tarkov. This is where TerraGroup was headquartered. This is where it all began. The area has yet again become a hot zone since the early days of the conflict.", "5464e0404bdc2d2a708b4567 Name": "United Security", "5464e0404bdc2d2a708b4567 Description": "The USEC private military company was established in 1999 after the merger of two companies: KerniSEC and Safe Sea. In 2004, an agent of TerraGroup International Holding made contact with USEC, which then consecutively made USEC, essentially, a private army of the holding, with offices all around the world, and over 7500 staff strong.", "5464e0454bdc2d06708b4567 Name": "BEAR", @@ -17430,6 +19084,8 @@ "64c0acf85174e095610734a0 Description": "Sherpas are players who help beginners study the main game features and improve their skills to survive the harsh Tarkov environment. This difficult and honorable task falls on the shoulders of the most friendly, patient, and experienced players.", "64c0ad6af99768b777048f4e Name": "Emissaries", "64c0ad6af99768b777048f4e Description": "Emissaries are volunteers from all over the world who are actively involved in the Escape from Tarkov community and support Battlestate Games. Emissaries create content, make sure every voice in the community is heard, and make official messages clear and accessible to players anywhere in the world.", + "6724cde3b1130abeee0c3db7 Name": "Common Enemy", + "6724cde3b1130abeee0c3db7 Description": "Rumors have spread around Tarkov about a leak from the TerraGroup Laboratory. Residents affected by the substance have shown sudden changes in behavior and bouts of aggression. The number of casualties is rapidly increasing. With this new threat endangering the entire city, conflicts between the factions in Tarkov have significantly decreased. It's possible that the leaders of each side have agreed to a temporary truce.", "579b1eb1d53a0658a154fbe6": "", "579b2068d53a0658a154fbe8": "", "57a39d5024597772b41c2a07": "", @@ -17569,6 +19225,7 @@ "5bd05f1186f774572f181678": "SEALS", "5bdb3ac186f77405f232ad22": "", "5c0a99f186f774457a3f12de": "", + "5c0c1d6586f7743e5335d264": "", "5c0c1dba86f7743e667da897": "AAC SD", "5c0c1dff86f7744dba7a2892": "Carbine", "5c0c1f2b86f77455912eaefc": "Carbine", @@ -17943,12 +19600,120 @@ "66740bace77b296aa9226073": "", "66740ce66756f4498f2efc43": "", "66740dd82b6f3b71be7a1237": "", + "668bb844e551b93a1c2f0715": "", + "668bb8d7f18d791eb2520255": "", + "668bbb0463acb16d63706fe5": "", + "668bbbbfd925aa63b210aaa5": "", + "668bbd15e551b93a1c2f0733": "", + "668bc08e194be70f184279e5": "", + "668bc1e763acb16d63707009": "", + "668bc2697eb38c3c4d586025": "", + "668bc34163acb16d63707029": "", + "668bc46be551b93a1c2f074f": "", + "668bc4d6d925aa63b210aab3": "", + "66b090946f11600e4e48bad5": "", + "66b091116f11600e4e48badd": "", + "66b0916b1516622c22700a30": "", + "66b091a1d7a3ce164221e2cf": "", + "66b09209c84cc7141324eeeb": "", + "66b09220ae030a24a5663808": "", + "66b09282ae030a24a5663815": "", + "66b092dcd7a3ce164221e2dc": "", + "66b09315c5987b623d6e0ea1": "", + "66b0935ad11b1e4a1e1c9c04": "", + "66b09380ed57696ce626c08b": "", + "66b093bfae030a24a566381f": "", + "66b0e484c84cc7141324fd6c": "T.O 2K24", + "66b0e6002fafeb5db478f1f3": "T.O 2K24", + "66b0e7f8c5987b623d6e2e81": "T.O 2K24", + "66b4b264a7f72d197e70bb45": "", + "66b4b293c5d72b02774884f8": "", + "66b4b2a9cad6f002ab720567": "", + "66b4b2e8cad6f002ab720575": "", + "66b4b30519a3ab39b7175ad2": "", + "66b4b372a7f72d197e70bb51": "", + "66b4b38119a3ab39b7175ae0": "", + "66b4b38fcad6f002ab720586": "", + "66b4b3a37994640992013a3b": "", + "66b4b3e2af44ca0014063b8d": "", + "66b4b4085891c84aab75beb1": "", + "66b4b41a5891c84aab75bebe": "", + "66b4b42aa7f72d197e70bb5e": "", + "66b9c41f0b603c26902afd8d": "", + "66b9c53ea7f72d197e70bf83": "", + "66b9c562fd38bf060b4b85a7": "", + "66b9c5db19a3ab39b7175e2b": "", + "66b9c61e0b603c26902afd95": "", + "66b9c65b96edb969cd4f5d7f": "", + "66bc633a6d8d264a821a58af": "", + "66bc674a2cd71f2c3c274464": "", + "66bc6ad809a37d77f1068e00": "", + "66bc74eefd38bf060b4b991c": "", + "66bc7c1c8cbd597c9c2f92d8": "", + "66bc8d410b603c26902b1f86": "", + "66be2e16a572752e3b5e8743": "", + "66c49c0f2e6e23eb7b03f22d": "", + "66c49c9b2e6e23eb7b03f23c": "", + "66e13bef38d19465180059a6": "", + "66e13f7a38d19465180059c4": "", + "66e1415238d19465180059f2": "", + "66e14219e8fd46f7890b4c26": "", + "66e143d8a3ae1661b1043fc5": "", + "66e144b3597dc7f8110cb602": "", + "66e145dba3ae1661b1043fe2": "", + "66e14683e8fd46f7890b4c40": "", + "66e1473d38d1946518005a08": "", + "66e147ac597dc7f8110cb61c": "", + "66e1485b38d1946518005a20": "", + "66e14ab2e8fd46f7890b4c69": "", + "66e14c37597dc7f8110cb626": "", + "66e14de2597dc7f8110cb632": "", + "66e14fb0597dc7f8110cb648": "", + "66e14ff7e8fd46f7890b4c7a": "", + "66e15212a3ae1661b104402b": "", + "66e1530338d1946518005a49": "", + "66e153e7e8fd46f7890b4cb0": "", + "66e1548fa3ae1661b104404c": "", + "66e1552a38d1946518005a51": "", + "66e15637a3ae1661b104405f": "", + "66e156dc38d1946518005a5f": "", + "66e1579e38d1946518005a6f": "", + "66e15d96e8fd46f7890b4cbe": "", + "66e15f35e8fd46f7890b4cd7": "", + "66e16054a3ae1661b1044073": "", + "66e16154597dc7f8110cb660": "", + "66e44c35eeabdac8610613ac": "", + "66e44f938a4bd32fe20dacef": "", + "66f2c02f398a04601e0d4e55": "", + "66f2c18f51101ac89e0e9448": "", + "671a3d97939f4b37710e00f7": "", + "671a3daf0d3ec0f0fe04fad5": "", + "671a3dd46d315b526708f0f6": "", + "671a3dfbe832f41c8d08a336": "", + "671a42343d73dac1360765b9": "", + "671a425a7d49aea42c029b56": "TerraGroup Labs", + "671a42e50d3ec0f0fe04fb7d": "", + "671a4d3d6d315b526708f110": "", + "671b8862d31ac81ddc0aebf6": "", + "671b88704e3838e4370ff5a6": "", + "671b8880d14a58a85b09d833": "", + "671b8897f321d8e485037f46": "", + "671b88a5d31ac81ddc0aec04": "", + "671b88b14e3838e4370ff5b8": "Face", + "671b88c4d14a58a85b09d845": "Face", + "671b88d8f321d8e485037f54": "", + "671b88e7d31ac81ddc0aec16": "", + "671b88f691224852b20c16e6": "", + "671b8907d14a58a85b09d85a": "", + "671b8914f321d8e485037f6a": "", + "671b8926d31ac81ddc0aec2b": "", + "671b89f03d4217059b0c6a26": "", "5936d90786f7742b1420ba5b name": "Debut", "5936d90786f7742b1420ba5b description": "Hello there, soldier. I got a job that's a little too easy for my guys. But you'll do fine. Hey, don't get pissy, I don't know you that well yet to give you a normal job!\n\nThere's a lot of bandit scum roaming the streets. They don't bother me much, but they're still a nuisance. Calm down, say, five of them, and get a couple of MP-133 shotguns off them. I think that'll be enough for you. Dismissed, soldier!", "5936d90786f7742b1420ba5b failMessageText": "", "5936d90786f7742b1420ba5b successMessageText": "So, you got the job done, great. Probably just bought the shotguns off some trader for cheap, huh? Well, whatever, I don't really care. You brought the shotties and that's what matters.", - "5967379186f77463860dadd6": "Eliminate Scavs all over the Tarkov territory", - "596737cb86f77463a8115efd": "Obtain and hand over MP-133 12ga shotguns", + "5967379186f77463860dadd6": "Eliminate Scavs on any location", + "596737cb86f77463a8115efd": "Hand over the item: MP-133 12ga shotgun", "5936d90786f7742b1420ba5b acceptPlayerMessage": "", "5936d90786f7742b1420ba5b declinePlayerMessage": "", "5936d90786f7742b1420ba5b completePlayerMessage": "", @@ -17956,8 +19721,8 @@ "5936da9e86f7742d65037edf description": "How's it going, warrior? I have an errand for you. My comrade Arseny worked at the factory as a tanker driver. His family left during the evacuation while he stayed behind to make some extra money, and perished here. He lived in a three-story dormitory near Polikhim, I don't remember the room.\n\nAnyway, he had a chain watch, a family heirloom. Bragged about it to everyone. Find that watch and bring it to me, I want to send it to his kid. I want the kid to have something to remember his old man by. The watch must be either in his room or in the tanker truck somewhere at the construction site. Arseny always kept the keys in his jacket. Anyway, do the job. So long!", "5936da9e86f7742d65037edf failMessageText": "", "5936da9e86f7742d65037edf successMessageText": "You know what? I didn't think you'd find it. But big thanks to you regardless. This was, you might say, a personal matter. Anyway, here's the reward.", - "5967920f86f77468d219d632": "Hand over the pocket watch", - "5968ec9986f7741ddd6c1012": "Obtain the Bronze pocket watch on a chain on Customs", + "5967920f86f77468d219d632": "Hand over the found item", + "5968ec9986f7741ddd6c1012": "Locate and obtain the bronze pocket watch on Customs", "5975de1f86f7744ca53b7c82": "Obtain the key to the fuel tanker truck", "5936da9e86f7742d65037edf acceptPlayerMessage": "", "5936da9e86f7742d65037edf declinePlayerMessage": "", @@ -17975,7 +19740,7 @@ "59674eb386f774539f14813a failMessageText": "", "59674eb386f774539f14813a successMessageText": "What, success again? Bit of a warrior, eh? The freaking Terror of Tarkov! Hey, don’t get me wrong! Everything’s done right, I owe you one. Important business is taken care of - I feel good. And when I feel good, proper people around me start feeling good as well. Got it?", "59674fe586f7744f4e358aa2": "Stash the package in the break room on the 2nd floor near Gate 3 on Factory", - "5968929e86f7740d121082d3": "Obtain the secure folder in the Tarcone Director's office at the Customs terminal warehouse", + "5968929e86f7740d121082d3": "Locate and obtain the valuable folder in Tarcone director's office on Customs", "5977784486f774285402cf52": "Survive and extract from Factory", "5978b48b86f7746ef62ef859": "", "59674eb386f774539f14813a acceptPlayerMessage": "", @@ -17987,7 +19752,7 @@ "5967530a86f77462ba22226b successMessageText": "Some luck with you there, warrior! Such a treasure to get hold of. That’s worthy of a hefty reward. And a little extra for not leaking it on the side - and my goodwill, which is over any money.", "596762ec86f77426d3687a87": "Survive and extract from the location", "5968941f86f7740d1570bbd2": "Obtain the Portable bunkhouse key", - "5968943f86f7740d137ebfc2": "Obtain Secure Folder 0031 in the bunkhouse on Customs", + "5968943f86f7740d137ebfc2": "Locate and obtain Secure Folder 0031 in one of the bunkhouses on Customs", "5968948986f7740d121082d4": "Hand over the folder", "5a3fbdb086f7745a554f0c31": "Gain access to the locked room in the office hallway on the third floor on Factory", "5967530a86f77462ba22226b acceptPlayerMessage": "", @@ -17997,7 +19762,7 @@ "59675d6c86f7740a842fc482 description": "Hey there, warrior. Still fighting? Good. There is this job, a cakewalk, really. Obviously, not of your caliber, it's gonna be a favor, so to say. I've received an order, they need some 60-rounders for 5.45 AKs. I know there definitely were some in bunkers near the sawmill, my guys stashed some goods there before. But they got driven out of there by those TerraGroup people, who then locked the bunkers with a key of some sort. Well, if you're going for the bunker, you'll need that key, I think it's hidden somewhere in dorms on Customs, people have seen some TerraGroup brass there a couple of times. Anyway, I don't care where you find them, but I need you to get them fresh and untouched by some traders. And hurry up, the order is urgent.", "59675d6c86f7740a842fc482 failMessageText": "", "59675d6c86f7740a842fc482 successMessageText": "Well, they say money can't buy friendship, but I still owe you.", - "59675e1d86f77414b07f137d": "Hand over the magazines", + "59675e1d86f77414b07f137d": "Hand over the items", "5967938c86f77468cf5f9f54": "Find the key to the bunker in the TerraGroup employee's dorm room", "5968ed3186f77420d2328013": "Find AK-74 5.45x39 6L31 60-round magazines in raid", "5a3fbe3a86f77414422e0d9b": "Locate the locked bunker on Woods", @@ -18008,7 +19773,7 @@ "59675ea386f77414b32bded2 description": "Come on in, make yourself at home. How's the life of constant battle? No extra preternatural holes in your hide? Jolly good. No freaking use for them, eh? I’m in a bit of a tight unpleasant spot here. Will you help me out? My messenger vanished. I entrusted a job for this local waste of skin, he played so tough. In short, I’ve sent a little note to Therapist with some proposals for a mutually beneficial cooperation. Nothing special, but nothing outsiders should know either. And so this meat sack went missing, and a little bird told me that this postman got whacked somewhere in the Factory. Why the heck would he go there, that moron? Told him to take the straight path. So anyway, find the body and check it, my scribbles might still be there. And if by some miracle they are, hand them to that medic woman, will ya?", "59675ea386f77414b32bded2 failMessageText": "", "59675ea386f77414b32bded2 successMessageText": "Now that’s what it means to work with proven man! Said, done!", - "596895f986f7740d14064722": "Obtain the letter on the messenger's body on Factory", + "596895f986f7740d14064722": "Locate the dead messenger and obtain his letter on Factory", "5968962686f7740e7266d973": "Survive and extract from the location", "596896c386f7740d1570bbd4": "Hand over the letter to Therapist", "59675ea386f77414b32bded2 acceptPlayerMessage": "", @@ -18022,14 +19787,14 @@ "596760e186f7741e11214d58 acceptPlayerMessage": "", "596760e186f7741e11214d58 declinePlayerMessage": "", "596760e186f7741e11214d58 completePlayerMessage": "", - "5967725e86f774601a446662 name": "Shaking up the Teller", + "5967725e86f774601a446662 name": "Shaking Up the Teller", "5967725e86f774601a446662 description": "Hail, the knave of axe and gun. Some curious info came up recently. Smells like solid profit without running around too much. Ready? Look. There was that wisecrack who ran the stores, lived in a dorm by the factory. And, as usual, sidelined some cash. He lived in room 214. But that's not the point. I don’t think you will find much there if anything at all. Though he swore there’s something. Something else has surfaced: In the same dorm, he owned one more room, 203, but wasn’t babbling about it and, as a matter of fact, used it for storage. Now that’s where he had something of value for sure, more than one of his errand runners perished there. Also, he had a garage. Don’t know the number, but it was certainly two-digit - I have a listing of owners starting with 100, and his name is not there.", "5967725e86f774601a446662 failMessageText": "", "5967725e86f774601a446662 successMessageText": "Impressive indeed! It's almost a nuclear suitcase! No surprise he spared no people trying to pull this out.", - "5968981986f7740d1648df42": "Obtain the valuable item in dorm room 203 on Customs", + "5968981986f7740d1648df42": "Locate and obtain the valuable item in dorm room 203 on Customs", "5968988286f7740d14064724": "Hand over the valuable item", - "5a3fc03286f77414d64f9941": "Gain access to dorm room 214", "59a9287986f77478ad7028d8": "", + "5a3fc03286f77414d64f9941": "Gain access to dorm room 214 on Customs", "5967725e86f774601a446662 acceptPlayerMessage": "", "5967725e86f774601a446662 declinePlayerMessage": "", "5967725e86f774601a446662 completePlayerMessage": "", @@ -18037,7 +19802,7 @@ "5967733e86f774602332fc84 description": "Hello, mercenary. Are you interested in a little part-time work? It's not a difficult task, but it's quite lucrative. Don't forget, you can get both food and drink from me, as well as expert medical care. But first, let's talk about the job.\n\nI require three emergency medical kits. They're called Salewa - the red western ones. I need you to obtain them yourself, not buy them off someone else. Just to prove that we're serious about this. We may know each other, but not enough for me to trust you yet. Are you up for the job?", "5967733e86f774602332fc84 failMessageText": "", "5967733e86f774602332fc84 successMessageText": "Thank you, young man. The first aid kits will be put to good use. I won't tell you any more than that, though.", - "59689eb886f7740d137ebfc3": "Hand over the first aid kits", + "59689eb886f7740d137ebfc3": "Hand over the items", "5968edc086f77420d2328014": "Find Salewa first aid kits in raid", "6394af80e2cb1e6963235128": "Hand over the first aid kits", "5967733e86f774602332fc84 acceptPlayerMessage": "", @@ -18047,10 +19812,10 @@ "59689ee586f7740d1570bbd5 description": "Good afternoon. I have an urgent job for you. It is important for all who still live or, more precisely, exist in our woeful region. Do you know where the chemical factory is? Doesn’t matter now what was produced there and what is happening there now. I mean, who controls it or who tries to secure it. I have a firm suspicion that some sort of poison is leaking from the factory premises into the groundwater. And because of the lack of supplies from the outside, we are all forced to drink this water. Do you understand? Even the filters are no longer effective. If we do not resolve this issue, nobody would need ammo and grenades anymore. To figure it out I need the readings of radio and gas analyzers, which should be in the factory shops next to the water pumps. Look for a small separate room right in the workshops and that's the place where it should be. If you don’t find it there, then look elsewhere, this is no longer my business where exactly you get it from.", "59689ee586f7740d1570bbd5 failMessageText": "", "59689ee586f7740d1570bbd5 successMessageText": "About time. You did an important service to many, if not everyone.", - "59689f7586f7740d14064726": "Hand over the Gas analyzer", + "59689f7586f7740d14064726": "Hand over the items", "5a3fc0ff86f7744d9c2eff86": "Gain access to the locked pumping station on Factory", "5ca6026286f77446d87abec3": "Gain access to the locked pumping station on Factory", - "5cb6f32986f7746ef55e17a0": "Find Gas analyzer in raid", + "5cb6f32986f7746ef55e17a0": "Find a Gas analyzer in raid", "59689ee586f7740d1570bbd5 acceptPlayerMessage": "", "59689ee586f7740d1570bbd5 declinePlayerMessage": "", "59689ee586f7740d1570bbd5 completePlayerMessage": "", @@ -18059,7 +19824,7 @@ "59689fbd86f7740d137ebfc4 failMessageText": "", "59689fbd86f7740d137ebfc4 successMessageText": "How curious! So that's where that water went. Thank you. I will inform my people. Skier certainly would not be happy with me interfering with his interests, but what won’t you do for the sake of the people.", "5968a06486f7740d14064728": "Survive and extract from the location", - "5a3fb73b86f77458e0324376": "Locate the water stockpile hidden inside of the dorms on Customs", + "5a3fb73b86f77458e0324376": "Locate the water stockpile hidden inside one of the dorm rooms on Customs", "59689fbd86f7740d137ebfc4 acceptPlayerMessage": "", "59689fbd86f7740d137ebfc4 declinePlayerMessage": "", "59689fbd86f7740d137ebfc4 completePlayerMessage": "", @@ -18085,8 +19850,8 @@ "5969f9e986f7741dde183a50 description": "I want to ask you for a service. Don't put up that look, of course, it's not for free! In a small dorm, yes, the one inhabited by those bandits, somewhere on the first floor used to live a young paramedic from the factory. Unfortunately, I do not know the room number - when my colleagues and I were his guests on the Medical Worker Day, it was already dark, and in the middle of a party, you see. Well, he was a young specialist, still an intern, but very enthusiastic. Planned to enroll in the Military Medical Academy in St. Petersburg. And in his safe, right there in the room, he kept a case with the particular new medical device. Issued to him by the employer. He tried to get out of town on his blue VAZ 2109 with Saint Petersburg plates. I don't know if he managed to get out or not, but as far as I have heard, he either got stuck near the gas station or apprehended by the military. In any case, I could really put that tool to good use. Come the darkest hour, and you might need it as well. Not that I wish for that to happen, don’t get me wrong, but... I assume you understand everything better than I do. I need you to find it. Oh yes, I almost forgot, we have common interests with Arshavir in this matter. He has a good product for you. After you complete the task, of course.", "5969f9e986f7741dde183a50 failMessageText": "", "5969f9e986f7741dde183a50 successMessageText": "Pleasure doing business with you, young man. I will let Arshavir know about your success. Here's your reward.", - "5969fa4886f7741ddb481544": "Obtain the case containing the device on Customs", - "5969fa8986f7741ddc2d3154": "Hand over the case", + "5969fa4886f7741ddb481544": "Locate and obtain the suitcase with the device on Customs", + "5969fa8986f7741ddc2d3154": "Hand over the suitcase", "5a3fb8f686f7742384533f10": "Locate the paramedic’s car on Customs", "5a3fb92286f77422b46cdb18": "Find a way inside the two-story dorm room 114 on Customs", "5969f9e986f7741dde183a50 acceptPlayerMessage": "", @@ -18096,7 +19861,7 @@ "596a0e1686f7741ddf17dbee description": "Hello, young man. Truly glad to see you. I have a very important assignment, not for everybody to take on. Will you take it? Then listen. Do you know the sawmill in the Woods? So, during the Contract Wars period, it was used as one of the makeshift backup supply bases for TerraGroup. And I am very interested in TerraGroup supply plans in this region. I think they should be somewhere on the territory as well. Try to search for the temporary quarters for workers - there should be a secure case for documents with a special symbol.", "596a0e1686f7741ddf17dbee failMessageText": "Honestly, I did not expect that from you! With these plans, we could've found and sold—... Khm, sent food to civilians, but now all this wealth goes to Skier who'll just vend it all for ten times the price! How could you team up with this scoundrel?", "596a0e1686f7741ddf17dbee successMessageText": "Can’t stop wondering at the reliability of your services. Here is your cut.", - "596a0e7086f7741ddf17dbef": "Obtain Secure Folder 0052 in the sawmill cabin on Woods", + "596a0e7086f7741ddf17dbef": "Locate and obtain Secure Folder 0052 in the sawmill cabin on Woods", "596a0e8086f7741ddd6c104c": "Hand over the folder", "596a0eaf86f774576d4c957f": "Survive and extract from the location", "596a113d86f7741ddd6c104d": "Kind of Sabotage - success", @@ -18107,7 +19872,7 @@ "596a101f86f7741ddb481582 description": "A little bird told me that you want to find some folder and pass it on to the medic girl. We have a business here, and I have my own interest in disrupting her operations, you know. A kind of sabotage, eh? Come on, bring this folder to me, and I’ll treat you right, send some proper cash your way, and there will be more trust for you. The hell do I need it for? Don’t play dumb, take a guess. I’m opening branches here, building up the operation, and quality grub from those who’ve been preparing for all this crap in advance will sell like hotcakes through my channels. But I’m rambling, come on, go on your way, I'll be here packing your cash. Oh, and don't you be gullible to think that this woman is doing all this shit for the good of the people, I'm familiar with her business.", "596a101f86f7741ddb481582 failMessageText": "What a prick you are, for sure. Got a word you gave the folder to that medic after all. Fucking Savior of mankind.", "596a101f86f7741ddb481582 successMessageText": "Well, blah. Nicely done! Take it, as promised. Double-crossing is not for me. See ya, keep in touch.", - "596a10d886f7741ddf17dbf0": "Hand over Secure Folder 0052 to Skier", + "596a10d886f7741ddf17dbf0": "Hand over Secure Folder 0052", "596a117386f7741ddf17dbf1": "Supply Plans - success", "596a101f86f7741ddb481582 acceptPlayerMessage": "", "596a101f86f7741ddb481582 declinePlayerMessage": "", @@ -18125,7 +19890,7 @@ "596a204686f774576d4c95de description": "Hello. Good that you are here. I have a job just for you since you are already familiar with it. Our engineers have successfully neutralized the chemical leak from the factory, but the water is still not fully purified. Although the only remaining pollutants are specific to petroleum products. We assume that this is connected to the TPP fuel oil storage next to the factory. Know these? It’s hard to miss, there's a big pipe there. Technical rooms of fuel oil storage and furnace facility must be nominally equipped with the same radio- and gas analyzers you found in the factory, if, of course, they weren’t stolen yet. Locate and bring them in, and we will solve the water problem in the region, at least for a while.", "596a204686f774576d4c95de failMessageText": "", "596a204686f774576d4c95de successMessageText": "It’s delightful to find was a responsible person who is willing to take risks for the common good.", - "596a20ac86f7741ddf17dbf4": "Hand over the gas analyzers", + "596a20ac86f7741ddf17dbf4": "Hand over the items", "5ec1398886f7561e047757a5": "Find Gas analyzers in raid", "596a204686f774576d4c95de acceptPlayerMessage": "", "596a204686f774576d4c95de declinePlayerMessage": "", @@ -18146,8 +19911,8 @@ "596b36c586f77450d6045ad2 description": "What'chu want, merc? A job? Ha! Looking for a good net salary and a full social package? Alright then, I'll give you a job. \n\nI still barely know you, so let's see what you can do. I'll give you this: find me a white body armor, the one that looks like paper, and one Toz shotty. Gonna gear up my guys a little. But make sure to get the fresh ones, got it? Don't need no haggler shit.\n\nSo anyway, if you do fine, we can talk further about your employment, mister \"operator\".", "596b36c586f77450d6045ad2 failMessageText": "And this idiot said he wanted a job. I don't think we can get along since you can't do shit. Go on, buzz off.", "596b36c586f77450d6045ad2 successMessageText": "Good shit, gonna continue working together. Here's your reward.", - "597867e986f7741b265c6bd3": "Hand over the found in raid BNTI Module-3M body armor", - "5ab8d44c86f7745b2325bd0c": "Hand over the found in raid TOZ-106 shotgun", + "597867e986f7741b265c6bd3": "Hand over the found in raid item: BNTI Module-3M body armor", + "5ab8d44c86f7745b2325bd0c": "Hand over the found in raid item: TOZ-106 20ga bolt-action shotgun", "596b36c586f77450d6045ad2 acceptPlayerMessage": "", "596b36c586f77450d6045ad2 declinePlayerMessage": "", "596b36c586f77450d6045ad2 completePlayerMessage": "", @@ -18155,10 +19920,10 @@ "596b43fb86f77457ca186186 description": "Kinda busy right now! Although... Hang on a sec. There is an urgent matter. There was a firefight about an hour ago in the garages across the river. Just where my errand boy was headed. To hell with him, he was a total moron anyway. But he had with him one particular key. A mighty complex key, I might add. To the door that can be freaking anywhere, you know? This clown was delivering one very valuable thing to me. The bastard hid it somewhere and locked it with this arsetormenting key and came to me to talk up the price. What a bitch! I even raised the pay a little for the smart move, but this wanker still hasn’t told me where it was and went to get it for himself. He was muttering something about a bunkhouse, so I guess he hid the thing there. Although, honestly, there's a shit ton of bunkhouses on Customs. Anyway, I’m almost sure he’s got smoked somewhere at the garages near the RUAF roadblock. Find the key, and then find me that package even if you have to check all doors from the center to the port.", "596b43fb86f77457ca186186 failMessageText": "", "596b43fb86f77457ca186186 successMessageText": "You’re a damn Pinkerton! Helped me out big time! So, you found my idiot errand boy? Well, screw him. If you do something similar, you'll get smoked like him too. Go on, buzz off, I've got some stuff to do.", - "596b44b686f77457cb50ecca": "Obtain the valuable cargo on Customs", + "596b44b686f77457cb50ecca": "Locate and obtain the hidden valuable cargo on Customs", "596b450986f7745a7e510b54": "Hand over the valuable cargo", - "5a3fbab086f77421593d9bf0": "Locate the place where the messenger hid the cargo", - "5a3fbabc86f774231d75afbe": "Locate the messenger's body", + "5a3fbab086f77421593d9bf0": "Locate the place where the messenger hid the cargo on Customs", + "5a3fbabc86f774231d75afbe": "Locate the messenger's body on Customs", "596b43fb86f77457ca186186 acceptPlayerMessage": "", "596b43fb86f77457ca186186 declinePlayerMessage": "", "596b43fb86f77457ca186186 completePlayerMessage": "", @@ -18184,8 +19949,8 @@ "5979eee086f774311955e614 description": "Wanna take a side job in your main specialization? Hehe. What a hypocritical world! I served time for roughing some punk up, and my lingo gets me scoffed at by a nutcase who drops people down in numbers without a trace of remorse! And where is the justice? That’s right. As my prosecutor said, it's there, beyond the wall. And we are all here, as in one big cage. See the point, no? Whatever, I went off on a tangent. Well, this task is easy. A group of Scavs is infesting the factory. And one of their pins is a character who goes by the handle of Uruguay. What a retarded alias to choose. What a shame, who the hell raises such morons? But I digress. The objective is to finish his earthly path. But this is only half the battle. He has a lighter, sort of lucky charm. The gilded Zibbo, fidgets it all the time in his claws. Dropped by my place, and, sure, went on clicking it. And, by the way, he lived in the dorms, room 303. So, I need this light to be carefully dropped off in one safe house for somebody to get properly flabbergasted, and maybe take a hint. Got it? So it goes. That safe house is at the Customs, in a closed bunkhouse next to the trailer parking area. Here is a key to it. Good luck.", "5979eee086f774311955e614 failMessageText": "", "5979eee086f774311955e614 successMessageText": "When the deed is done, go get your fun. Let's see what will come of it.", - "5979ef4586f77431307dc513": "Find the Golden Zibbo lighter on Customs", - "5979ef7986f77431307dc514": "Stash the lighter in the bunkhouse at the trailer parking lot on Customs", + "5979ef4586f77431307dc513": "Locate and obtain the golden Zibbo lighter on Customs", + "5979ef7986f77431307dc514": "Stash the lighter in the bunkhouse at the trailer park on Customs", "5979eee086f774311955e614 acceptPlayerMessage": "", "5979eee086f774311955e614 declinePlayerMessage": "", "5979eee086f774311955e614 completePlayerMessage": "", @@ -18202,21 +19967,21 @@ "5979f9ba86f7740f6c3fe9f2 description": "So, Sherlock, you want a riddle? You’re our pro on these headcrackers, right? Here, look. One lame hobo came around here. Either nuts of just demented, hell if I knew. All in rags, dirty head to toe, and the stench! A walking chemical weapon. Launched one on some vector, and where he goes, everything dies off. Hehe. Oh, damn, laughter through tears. But I digress. Just wanted to dispose of him, a bit farther away so the stink wouldn’t reach us, but one of our boys recognized his former homie in that pile of turd. Imagine that! Horrid things are going on, turning people from normal beings to such rubbish, and all for nothing! But that's not the point. The dude that recognized this heap of rags, said that he was not just a regular prick, but a Deputy Head of Security for two special sensitive zones on the Polikhim! Just imagine what kind of source could he become if he could at least remember his name, not just chew snots and mumble while slapping lips like a madman. What a shame! I don't know what got to him, but here's what I think. All this time that bagger lived somewhere, sleeping on some pissed-through mattresses, right? Right! You should look for that place. Need a hazmat suit? Haha, kidding. But if it comes to it, the hazmat’s on me, and not only it.", "5979f9ba86f7740f6c3fe9f2 failMessageText": "", "5979f9ba86f7740f6c3fe9f2 successMessageText": "How long I live and wonder still. How was he surviving all this time? He can’t put two words together! Whatever. Let's first disinfect all this and wash it with cologne, and then open it and have a look.", - "5979fc2686f77426d702a0f2": "Obtain information about the Deputy Chief’s past life on Customs", - "5979fc5386f77426d702a0f3": "Obtain items that can help with the investigation", + "5979fc2686f77426d702a0f2": "Locate and obtain any information about the deputy chief’s past life on Customs", + "5979fc5386f77426d702a0f3": "Locate and obtain any item that could help with the investigation", "5979fc7e86f77426d702a0f4": "Hand over the information", - "5979fc9286f77426d702a0f5": "Hand over the items", + "5979fc9286f77426d702a0f5": "Hand over the item", "5a3fbbfd86f77459d52a16a8": "Locate the sleeping place of the former Deputy Chief of Security on Customs", "5979f9ba86f7740f6c3fe9f2 acceptPlayerMessage": "", "5979f9ba86f7740f6c3fe9f2 declinePlayerMessage": "", "5979f9ba86f7740f6c3fe9f2 completePlayerMessage": "", "597a0b2986f77426d66c0633 name": "Chemical - Part 2", - "597a0b2986f77426d66c0633 description": "Got tired of waiting for you already. The documents that you got from the den of this tosspot weigh quite a bit. Pretty heavy they are. But this is a damn dangerous stuff. And there is no clarity who will be the best buyer for it. And it's not even so much about the profit, as it is about getting some enormous fuckin' problems if we choose the wrong address. So here's the key that you found there as well, and try to dig up further. My guys said it's from a dorm room. And judging from the documents, our deputy chief was seen on the second floor of the first building, the three-story one. Any info you could find in this room can come in very handy, and the prize will be impressive.", + "597a0b2986f77426d66c0633 description": "Got tired of waiting for you already. The documents that you got from the den of this tosspot weigh quite a bit. Pretty heavy they are. But this is a damn dangerous stuff. And there is no clarity who will be the best buyer for it. And it's not even so much about the profit, as it is about getting some enormous fuckin' problems if we choose the wrong address. So here's the key that you found there as well, and try to dig up further. My guys said it's from a dorm room. \nAnd judging from the documents, our deputy chief was seen on the second floor of the first building, the three-story one. Any info you could find in this room can come in very handy, and the prize will be impressive.", "597a0b2986f77426d66c0633 failMessageText": "", "597a0b2986f77426d66c0633 successMessageText": "It seems this problem is not solved, but only got more complicated. Well, whatever. Come what may.", - "597a0bb486f77426d66c0634": "Find any information that could help with the investigation on Customs", + "597a0bb486f77426d66c0634": "Locate and obtain any information that could help with the investigation on Customs", "597a0bdb86f7742717106d12": "Hand over the info", - "597a0be986f774273b74f673": "Find any evidence that could help with the investigation on Customs", + "597a0be986f774273b74f673": "Locate and obtain any evidence that could help with the investigation on Customs", "597a0bf886f7742717106d13": "Hand over the evidence", "597a0b2986f77426d66c0633 acceptPlayerMessage": "", "597a0b2986f77426d66c0633 declinePlayerMessage": "", @@ -18225,7 +19990,7 @@ "597a0e5786f77426d66c0636 description": "That envelope from the dorm contained some chemical formula. And the flash drive described the reaction process. We found a guy here who’s good with the subject. So he said that they cooked up something like this at Polikhim, experimenting with some blue liquid shit, adding some other shit into it. Sorry, I wasn’t into chemistry at school! All these chemicals, valences, indecent bonds! Fuck that! Hehe. See, I even still remember some words. That was some teaching in schools back then! But whatever. It is necessary to confirm the experiment described there. And then this matter will shine upon us with new colors. This blue shit is abundantly scattered in barrels throughout the region, but nobody knows what it is. And nobody is too eager to figure that out either. But we will take our chance and find out. And make some profits with it. But this requires another stuff, It should be somewhere in the factory. There was a room filled with garbage - they had a laboratory there. Look for a bright yellow sort of syringe, looks like a pen, like a morphine syringe. Well, you get the idea.", "597a0e5786f77426d66c0636 failMessageText": "", "597a0e5786f77426d66c0636 successMessageText": "Well, great. Now it’s time to get as far as possible while they do their experiments. We can have a look later.", - "597a15b386f774799e5cd152": "Obtain the chemical-filled syringe hidden in Factory", + "597a15b386f774799e5cd152": "Locate and obtain the chemical syringe on Factory", "597a15c386f77405ba6887d2": "Hand over the syringe", "597a0e5786f77426d66c0636 acceptPlayerMessage": "", "597a0e5786f77426d66c0636 declinePlayerMessage": "", @@ -18285,8 +20050,8 @@ "59c50c8886f7745fed3193bf description": "My friends were mighty pleased with what you did on Shoreline. And they definitely want some more. More profit in it for you, too. Some extra gear too, so go on, keep doing good things for good people. Ah, almost forgot. They are asking for half-masks, you know, those that Scavs hide their faces with. Grab them from the bodies, they won't need them anymore, but my friends do. No idea what they need them for, probably to make a point or something. One more thing, this time it should be done silently, with a suppressor, so that they don't even know what killed them. To work, soldier.", "59c50c8886f7745fed3193bf failMessageText": "", "59c50c8886f7745fed3193bf successMessageText": "Nailed it, huh? Nice, grab your reward. I bet it's not the last job from my comrades, they really got interested in your Scav extermination.", - "59c50f1686f77412ef2c01e7": "Hand over the half-masks", "59624d5386f77446b872d5f7": "Eliminate Scavs while using a suppressed weapon on Reserve", + "59c50f1686f77412ef2c01e7": "Hand over the half-masks", "5ca5e54186f774456930b9a3": "Find Lower half-masks in raid", "5cb5e2ff86f7746ef64c979b": "Find Lower half-masks in raid", "59c50c8886f7745fed3193bf acceptPlayerMessage": "", @@ -18336,8 +20101,8 @@ "59ca264786f77445a80ed044 description": "Hey, your last Scav cutting was off the chain! People keep coming and asking what the heck is going on. Turns out that my friends somehow negotiated with the local authorities - what’s left of them anyway - to set up some kind of mercenary fights, like gladiator battles. Can you imagine that? We just keep falling back to the Middle Ages with all this shit! In short, for them you are, what’s it called... a game tester, sort of. Whatever they are coming up with, they reevaluate and adjust it according to your actions. Long story short, I don’t really understand shit, but they suggest we continue. This time you will have a way more serious enemy, they want you to decimate PMCs, but you should be kinda disguised as a Scav, so cover your face with a balaclava and put on their jacket, at least. And also, you are supposed to scare off the real Scavs - using a 12 gauge shotgun. It's almost as if they want to start WW3. Stirring shit up and making others turn on each other... Are you in?", "59ca264786f77445a80ed044 failMessageText": "", "59ca264786f77445a80ed044 successMessageText": "Mighty wicked, warrior. Grab your reward. Come back later, my friends have got some more work for you.", - "59ca27f786f77445aa0ddc14": "Eliminate PMC operatives while wearing a balaclava and Scav vest on Lighthouse", "59674d5986f77446b872d5f7": "Eliminate Scavs while using a 12ga shotgun on Lighthouse", + "59ca27f786f77445aa0ddc14": "Eliminate PMC operatives while wearing a balaclava and Scav vest on Lighthouse", "59ca293c86f91445a80ed047": "Find Bars A-2607 95Kh18 knives in raid", "59ca29ab86f77445ab431c86": "Hand over the knives", "59ca264786f77445a80ed044 acceptPlayerMessage": "", @@ -18347,12 +20112,12 @@ "59ca29fb86f77445ab465c87 description": "Masters - as my friends started calling themselves - are moving forward. Now they need the stuff for developing this whole gladiator thing further. Honestly, I’m not too hot on all these moves - I don't like how this keeps spreading chaos. So come on - find everything they need and just hand it over to me, I’ll pass it on to them on your behalf. Well, here's another thing, as proof that you didn't just find it somewhere, the Masters want you to make some noise on the Tarkov outskirts. And not however you like, but dressed in a PACA vest and 6B47 helmet. I do not understand why they need all this masquerade... These people are very shady, but I guess they have their reasons for your appearance.", "59ca29fb86f77445ab465c87 failMessageText": "", "59ca29fb86f77445ab465c87 successMessageText": "Well, I see you found everything. Nicely done. For me, this whole deal reeks of trouble, but as the saying goes, the money does not stink. Grab your reward.", + "59ca293c86f77445a80ed147": "Find any Kalashnikov AK-74 assault rifle in raid", + "59ca29ab86f77445ab133c86": "Hand over the AK-74", + "59ca2bdc86f77445a80ed148": "Find a Colt M4A1 assault rifle in raid", "59ca2c3086f77445aa0ddc15": "Hand over the M4A1", + "59ca2c9e86f77428ea721232": "Find any Makarov PM pistols in raid", "59ca2cbe86f7740fe95c3e52": "Hand over the pistols", - "59ca293c86f77445a80ed147": "Find a Kalashnikov AK-74N assault rifle in raid", - "59ca29ab86f77445ab133c86": "Hand over the AK-74N", - "59ca2bdc86f77445a80ed148": "Find a Colt M4A1 assault rifle in raid", - "59ca2c9e86f77428ea721232": "Find Makarov PM pistols in raid", "5c922dde86f77438500a0fec": "Eliminate PMC operatives while wearing a PACA body armor and 6B47 helmet", "59ca29fb86f77445ab465c87 acceptPlayerMessage": "", "59ca29fb86f77445ab465c87 declinePlayerMessage": "", @@ -18361,11 +20126,11 @@ "59ca2eb686f77445a80ed049 description": "Hello, soldier. I don't know... I want out from these Masters deals. The PMCs are getting closer up their ass... And the thing is, they don’t want to shut them down, but take over instead! In times like these everybody goes a little bonkers, everybody feels the end is nigh. Anyway, that’s my last deal with them, won’t be doing anything for them anymore. Basically, they want the number of PMCs to be heavily reduced throughout the area. Gotta kill everyone indiscriminately: no info on who exactly is trying to be the smartass. The job should be done with an SVD so that the interested people would see who did the job... I don’t like it at all. However, the bounty is very fucking tempting. So it’s up to you. And another thing, these men have their own operation at the chemical plant, so don't go there to do the job, so that there would be no misunderstandings.", "59ca2eb686f77445a80ed049 failMessageText": "Well, no luck at decimating the operators, huh? Okay then, maybe it not worth trying again?", "59ca2eb686f77445a80ed049 successMessageText": "Wasting Scavs is no big deal, they are inhuman anyway. But killing everyone indiscriminately, even your own guys… That's rotten business. Get your cash. This is it. Told them I'm out of it. They know about you, so they'll contact you directly if they need you. Don't know about you, but I really don't like this.", - "59ca2fba86f77445e4732b25": "Eliminate PMC operatives while using an SVD rifle (Excluding Factory)", + "59ca2fba86f77445e4732b25": "Eliminate PMC operatives while using an SVD rifle (excluding Factory)", "5b05468f86f774030379eb74": "Find BEAR PMC dogtags in raid", - "5b0548e686f7740306753506": "Hand over the BEAR dogtags", + "5b0548e686f7740306753506": "Hand over any BEAR dogtags", "5cb3393888a4505d02042061": "Find USEC PMC dogtags in raid", - "5cb3397c88a450159a723d79": "Hand over the USEC dogtags", + "5cb3397c88a450159a723d79": "Hand over any USEC dogtags", "59ca2eb686f77445a80ed049 acceptPlayerMessage": "", "59ca2eb686f77445a80ed049 declinePlayerMessage": "", "59ca2eb686f77445a80ed049 completePlayerMessage": "", @@ -18391,8 +20156,8 @@ "5a03173786f77451cb427172 description": "Good day, my friend. While you were bringing justice, you surely noticed the helicopter standing at the health resort pad. We need to hurry and pick up everything of value that is left in it. For now, it's wide open and dangerous in there. Your task is to mark the helicopter with a beacon and, most importantly, find the safe path to access it with a vehicle, preferably through the woods. Mark it, I mean the path, with a beacon as well. After that, it’s Blue Helmets’ job.", "5a03173786f77451cb427172 failMessageText": "", "5a03173786f77451cb427172 successMessageText": "Good job, now it’s our turn to act. I will send a transport there, let them take whatever they can from that heli.", - "5a0317da86f77451cb427295": "Mark the helicopter at the Health Resort with an MS2000 Marker on Shoreline", - "5a0325f286f7744384509230": "Mark the safe road to the helicopter with an MS2000 Marker on Shoreline", + "5a0317da86f77451cb427295": "Locate and mark the helicopter at the Health Resort with an MS2000 Marker on Shoreline", + "5a0325f286f7744384509230": "Mark the safe passage to the helicopter with an MS2000 Marker on Shoreline", "5a37d80986f774245c063b69": "Survive and extract from the location", "5a03173786f77451cb427172 acceptPlayerMessage": "", "5a03173786f77451cb427172 declinePlayerMessage": "", @@ -18402,13 +20167,13 @@ "5a0327ba86f77456b9154236 failMessageText": "", "5a0327ba86f77456b9154236 successMessageText": "Brilliantly done, the work goes on schedule. Dziękuję, mercenary. Here's your reward.", "5a03282286f77456b91542ef": "Find WD-40 (100ml) in raid", - "5a03289686f7745dbc6c5063": "Hand over the WD-40", + "5a03289686f7745dbc6c5063": "Hand over the found in raid item: WD-40", "5a0328b086f77457a7099ea5": "Find Clin window cleaners in raid", - "5a0328cb86f77456b91543b8": "Hand over the cleaners", + "5a0328cb86f77456b91543b8": "Hand over the found in raid item: Clin window cleaner", "5a0328f586f774580168ced4": "Find Corrugated hoses in raid", - "5a03290586f774584d1594c4": "Hand over the hoses", + "5a03290586f774584d1594c4": "Hand over the found in raid item: Corrugated hose", "5a280b3c86f7741b16366337": "Find Ox bleach in raid", - "5a280b5486f7741f751bfeea": "Hand over the bleach", + "5a280b5486f7741f751bfeea": "Hand over the found in raid item: Ox bleach", "5a0327ba86f77456b9154236 acceptPlayerMessage": "", "5a0327ba86f77456b9154236 declinePlayerMessage": "", "5a0327ba86f77456b9154236 completePlayerMessage": "", @@ -18426,7 +20191,7 @@ "5a0449d586f77474e66227b7 description": "Hello my friend, how are you doing? Not exactly amazing, I know, that’s just how the times are now. My people have run across some really interesting rooms in the health resort, which are, unfortunately, locked tight. It is known that USEC folks were stationed there earlier, and we also learned that they stored the keys at the checkpoint, in a concrete bunker, North-West of the resort. Since they packed in a hurry, there is a chance you may find something there. Bring me the key to the locked rooms.", "5a0449d586f77474e66227b7 failMessageText": "", "5a0449d586f77474e66227b7 successMessageText": "Amazing, great work! So, this means that the key is used for all their rooms... You can go now, mercenary.", - "5a044a6c86f7747370402d91": "Obtain the key to the closed premises of the Sanatorium on Shoreline", + "5a044a6c86f7747370402d91": "Locate and obtain the key to the closed premises of the Health Resort on Shoreline", "5a280f8d86f774141b501756": "Hand over the key", "5a0449d586f77474e66227b7 acceptPlayerMessage": "", "5a0449d586f77474e66227b7 declinePlayerMessage": "", @@ -18435,8 +20200,8 @@ "5a27b75b86f7742e97191958 description": "Good afternoon, mercenary. My name is Peacekeeper, and you were recommended by Skier, as a man who knows his value and the value of loyalty too. Let's not waste time and get straight to business. I need to deliver certain gear to certain people. I'll give you all the stuff I need to be moved, and your job will be to leave it all in a certain spot - on the Shoreline, next to one of the - what’s it called - breakwaters. There is a boat nearby, and that is where you drop the gear. Is the task clear?", "5a27b75b86f7742e97191958 failMessageText": "", "5a27b75b86f7742e97191958 successMessageText": "My contacts received everything they needed. Good job, will be glad to work with you more, mercenary.", - "5a27d81a86f774472a6e0456": "Stash the SV-98 sniper rifle in the boat", - "5a27d85286f77448d82084e7": "Stash the multitool in the boat", + "5a27d81a86f774472a6e0456": "Stash an SV-98 sniper rifle in the boat", + "5a27d85286f77448d82084e7": "Stash a Leatherman Multitool in the boat", "5a3ba11786f7742c9d4f5d29": "Locate the boat hidden next to the breakwater on Shoreline", "5bcf241486f7746a4959344a": "", "5be40b2a88a45079e30e92b5": "", @@ -18484,8 +20249,8 @@ "5a27b87686f77460de0252a8 description": "Our team always works for the good of the people, or at least we try to make it look so. The Blue Helmets peacefully deliver relief supplies to our region, but sometimes, attacks happen on us as well. That’s what happened to two Ural trucks that were carrying UN-marked crates. We wouldn't be upset if not for the delicacy of the cargo, this time crates contained a little help not only for the people but also for the USEC company. You understand that we cannot allow casting a shadow on the United Nations' reputation. Find and wear UN uniform (UNTAR helmet, MF-UNTAR body armor) and teach local scum a lesson. Also, locate the spot where trucks were attacked, mark them with beacons, and bring me several MRE ration packs so I could present them as evidence, just in case. From the intelligence, one of those trucks has to somewhere in the Health Resort area, but there is no info about the other one. I think it's best to look somewhere near the port area, possibly at the construction site.", "5a27b87686f77460de0252a8 failMessageText": "", "5a27b87686f77460de0252a8 successMessageText": "I assume you don't need to be reminded that all this is only between us. If the Blue Helmets' reputation gets tarnished, you will have problems too, mercenary.", - "5a28017786f77452f6318b1b": "Locate and mark the first truck with an MS2000 Marker", - "5a2801f986f774531b679875": "Locate and mark the second truck with an MS2000 Marker", + "5a28017786f77452f6318b1b": "Locate and mark the first UN truck with an MS2000 Marker", + "5a2801f986f774531b679875": "Locate and mark the second UN truck with an MS2000 Marker", "5a28023f86f774528903dd1e": "Hand over the ration packs", "5a3ba47986f7744df8667505": "Locate the first truck that was holding the lost UN cargo on Shoreline", "5a3ba4ba86f7744df759b1e5": "Locate the second truck that was holding the lost UN cargo on Shoreline", @@ -18528,13 +20293,13 @@ "5a27bafb86f7741c73584017 failMessageText": "", "5a27bafb86f7741c73584017 successMessageText": "Fine, let's start.", "5a28151986f77466837984c9": "Find Morphine injectors in raid", - "5a28152b86f7740ab40845fb": "Hand over the injectors", + "5a28152b86f7740ab40845fb": "Hand over the items", "5a28157486f77405822f36c1": "Find Alkaline cleaners for heat exchangers in raid", - "5a28159686f77405710b1e65": "Hand over the cleaners", + "5a28159686f77405710b1e65": "Hand over the items", "5a2815c186f77405822f36ce": "Find Corrugated hoses in raid", - "5a2815d786f774725a5893a6": "Hand over the hoses", + "5a2815d786f774725a5893a6": "Hand over the items", "5a28163686f7740ab4084611": "Find Propane tanks (5L) in raid", - "5a28164786f77405822f36d9": "Hand over the tanks", + "5a28164786f77405822f36d9": "Hand over the items", "5a27bafb86f7741c73584017 acceptPlayerMessage": "", "5a27bafb86f7741c73584017 declinePlayerMessage": "", "5a27bafb86f7741c73584017 completePlayerMessage": "", @@ -18542,7 +20307,7 @@ "5a27bb1e86f7741f27621b7e description": "Good day, today I had the joy of understanding that we have a solid operation running, and it was not without your help. Blue Helmets now have a tight ongoing partnership with locals in all areas of business, and profits keep flowing in. Anyway, business comes first, as your people say. You have already been by the caved tunnel on the Shoreline. TerraGroup attempted to move some cargo through it but failed, and now this cargo is temporarily stored somewhere, whereabouts unknown. Provisional headquarters for coordinating the company’s activities were moved to the resort when the conflict started, but, obviously, they are long gone now. However, I think it’s safe to assume that they couldn’t move out everything, and we can try to get some information there. The computer coordination center was based somewhere on the third floor in the east wing of the resort building. Find any information, if it is there.", "5a27bb1e86f7741f27621b7e failMessageText": "", "5a27bb1e86f7741f27621b7e successMessageText": "Well, show me what you found. Hm, that is a nice laptop, how could they leave such important hardware? I'll send it for decryption.", - "5a28183186f774398675d127": "Obtain the data in the computer room in the east wing of the Health Resort on Shoreline", + "5a28183186f774398675d127": "Locate and obtain the data in Health Resort east wing computer room on Shoreline", "5a28184c86f774376e43772a": "Hand over the retrieved data", "5a27bb1e86f7741f27621b7e acceptPlayerMessage": "", "5a27bb1e86f7741f27621b7e declinePlayerMessage": "", @@ -18597,8 +20362,8 @@ "5a27bc3686f7741c73584026 description": "We have run this Artyom through our database. It seems he lived in the health resort after the conflict and may have been connected to TerraGroup, but it is unconfirmed, no precise info yet. The nature of their joint operation with the fisherman is also not completely clear, but, considering how secretive their meetings were, I'm pretty sure it's some kind of military tech. We need to find where exactly Artyom’s quarters were, the info could be in the list of Health Resort tenants, which has to be in the administration office, if it is still intact, of course. Find those documents and bring them to me.", "5a27bc3686f7741c73584026 failMessageText": "", "5a27bc3686f7741c73584026 successMessageText": "The documents are intact? Good work, my friend. We will check the data for the information we need. Your reward.", - "5a28221e86f7741d5b719624": "Obtain a list of the resort's tenants on Shoreline", - "5a28223786f7741c7a0b5401": "Hand over the list of tenants", + "5a28221e86f7741d5b719624": "Locate and obtain the list of Health Resort tenants on Shoreline", + "5a28223786f7741c7a0b5401": "Hand over the found items", "5a27bc3686f7741c73584026 acceptPlayerMessage": "", "5a27bc3686f7741c73584026 declinePlayerMessage": "", "5a27bc3686f7741c73584026 completePlayerMessage": "", @@ -18607,7 +20372,7 @@ "5a27bc6986f7741c7358402b failMessageText": "", "5a27bc6986f7741c7358402b successMessageText": "A job well done is a job well paid, mercenary. I’ll hand this hard drive to be checked immediately.", "5a2822de86f7740a245249ce": "Hand over the information", - "5a2e958d86f77416be092111": "Obtain information on Artyom’s work on Shoreline", + "5a2e958d86f77416be092111": "Locate and obtain any information on Artyom’s work on Shoreline", "5a27bc6986f7741c7358402b acceptPlayerMessage": "", "5a27bc6986f7741c7358402b declinePlayerMessage": "", "5a27bc6986f7741c7358402b completePlayerMessage": "", @@ -18625,7 +20390,7 @@ "5a27c99a86f7747d2c6bdd8e successMessageText": "Proper work, Rambo, grab your prize. By the way, you dropped some really important brass there. They shit their pants good.\n", "5be0198686f774595412d9c4": "Eliminate USEC PMC operatives", "5ec137962d5b8510d548aef1": "Obtain USEC PMC dogtags", - "5ec137dcc367fc6781104613": "Hand over the dogtags", + "5ec137dcc367fc6781104613": "Hand over any USEC PMC dogtags", "5a27c99a86f7747d2c6bdd8e acceptPlayerMessage": "", "5a27c99a86f7747d2c6bdd8e declinePlayerMessage": "", "5a27c99a86f7747d2c6bdd8e completePlayerMessage": "", @@ -18662,7 +20427,7 @@ "5a68663e86f774501078f78a description": "Thanks for your assistance with the vans. We were just in time, even those Scavs didn't have time to pull them apart. While researching the aftermath of the tunnel collapse, we’ve run across a TerraGroup executive's Geländewagen. It appears that part of the company’s top managers perished there while trying to evacuate. I’m aware that medical research was one of the top priorities for the company, and I'm almost sure that they had no time to evacuate its data and materials in time. Whatever they were doing, I think it can turn out to be very valuable, both for us and for medical science in general. It can earn us a ticket from Tarkov, even more than one. I’ve regularly met up with certain TerraGroup employees to discuss health care issues, so I'm pretty familiar with some of their works. One of my acquaintances, who, by the way, directly reported to that deceased Geländewagen management, used to live in the health resort building. Let me look it up... here it is, room 306. Search it for any documents that could possibly be left behind and bring them to me.", "5a68663e86f774501078f78a failMessageText": "", "5a68663e86f774501078f78a successMessageText": "Do you have the documents? Let me have a look... Indeed, the distinctive doctor’s handwriting. Thank you, young man.", - "5a68760f86f7743cc55d8709": "Search the room in the Health Resort for any documents about TerraGroup's research on Shoreline", + "5a68760f86f7743cc55d8709": "Locate and obtain any info about TerraGroup's research in Health Resort west wing on Shoreline", "5a68763786f77474c33a40a1": "Hand over the retrieved information", "5a68764c86f77474c4269f3c": "Survive and extract from the location", "5a68663e86f774501078f78a acceptPlayerMessage": "", @@ -18771,11 +20536,11 @@ "5ac3460c86f7742880308185 failMessageText": "", "5ac3460c86f7742880308185 successMessageText": "Great, give them here. Hm, should be sufficient for the start, thank you.", "5ac502a786f7740bde1b000c": "Find Power cords in raid", - "5ac5055a86f7745cae22b582": "Hand over the cords", + "5ac5055a86f7745cae22b582": "Hand over the items", "5ac505c386f7740be0424d19": "Find T-Shaped Plugs in raid", - "5ac505e186f7740bdf2ceabe": "Hand over the plugs", + "5ac505e186f7740bdf2ceabe": "Hand over the items", "5ac5061386f77417e429ce7a": "Find Printed circuit boards in raid", - "5ac5062586f774587c327395": "Hand over the PCBs", + "5ac5062586f774587c327395": "Hand over the items", "5acf3b0986f7741bb8378499": "", "5acf3b1286f77418420bf36b": "", "5ac3460c86f7742880308185 acceptPlayerMessage": "", @@ -18798,9 +20563,9 @@ "5ac3464c86f7741d651d6877 failMessageText": "", "5ac3464c86f7741d651d6877 successMessageText": "Ah, you've returned. I'll try to assemble them till nightfall, thanks. I know, it's really hard to find such electronics during these hard times, but I didn't doubt you.", "5ac5081086f7740bde1b002f": "Find Graphics cards in raid", - "5ac5082586f77418804f7d4c": "Hand over the GPUs", + "5ac5082586f77418804f7d4c": "Hand over the items", "5ac5083d86f7740be2744eed": "Find CPU Fans in raid", - "5ac5084d86f7740bde1b0031": "Hand over the CPU Fans", + "5ac5084d86f7740bde1b0031": "Hand over the items", "5acf3b3486f7741ce21f9b06": "", "5acf3b3b86f7741ce21f9b08": "", "5ac3464c86f7741d651d6877 acceptPlayerMessage": "", @@ -18822,10 +20587,10 @@ "5ac346a886f7744e1b083d67 description": "I promised to tell you about that \"monster\" from the other day. It was a failed controller, it flipped out and it sounded as if someone knocked at the door. That's how we create fears for ourselves. Interestingly, if I didn’t go and check what that was, it would be turned off in 15 minutes by the shutdown relay. After that, it would be extremely difficult to determine the source of the night sound. That’s how all those stories from newspapers are born, I assume. I can bypass the signal jammers by reconfiguring their frequency without raising suspicion of their owner as if things are still the same as they were. I need a few electronics for this and I think you can help me with this. The materials must be found silently so no one would get to know about what are we working on, only God knows, who might be involved in this. Here's the list of needed details, you probably know where to find them.", "5ac346a886f7744e1b083d67 failMessageText": "", "5ac346a886f7744e1b083d67 successMessageText": "I’ll manage the assembly soon, not as soon as Electronik, of course, but we won’t bother him for now. Thank you.", - "5ac5e79986f7747398341847": "Hand over the CPUs", - "5ac5e88e86f7741c5804f9db": "Hand over the batteries", - "5ac5e98886f77479bc6ca201": "Hand over the PCBs", - "5ac5ea0586f774609f36280c": "Hand over the phones", + "5ac5e79986f7747398341847": "Hand over the items", + "5ac5e88e86f7741c5804f9db": "Hand over the items", + "5ac5e98886f77479bc6ca201": "Hand over the items", + "5ac5ea0586f774609f36280c": "Hand over the items", "5acf3b7186f774184175301d": "", "5acf3b7886f77418420bf36f": "", "5cb6f81d86f7740e9d452683": "Find PC CPUs in raid", @@ -18861,11 +20626,11 @@ "5ac3475486f7741d6224abd3 failMessageText": "", "5ac3475486f7741d6224abd3 successMessageText": "Great, now I've got something to smoke in my free time. Thank you, mercenary.", "5ac5ee9986f7746e7a509a26": "Find Malboro cigarettes in raid", - "5ac5eee986f77401fd341c9e": "Hand over the Malboro cigarettes", + "5ac5eee986f77401fd341c9e": "Hand over the items", "5ac5ef2a86f7741c5804f9f5": "Find Strike cigarettes in raid", - "5ac5ef5686f77416ca60f644": "Hand over the Strike cigarettes", + "5ac5ef5686f77416ca60f644": "Hand over the items", "5ac5ef9886f7746e7a509a2d": "Find Wilston cigarettes in raid", - "5ac5eff886f7740f43322559": "Hand over the Wilston cigarettes", + "5ac5eff886f7740f43322559": "Hand over the items", "5acf3c3086f77418d851688f": "", "5acf3c3d86f7741ce21f9b1a": "", "5ac3475486f7741d6224abd3 acceptPlayerMessage": "", @@ -18968,11 +20733,11 @@ "5ae448e586f7744dcf0c2a67 description": "You know, brother, I'll tell you what, clothes will always be of value. War or no war, people still buy that stuff. Ultra had a bunch of brand outlets, the ones folks used to hype on, and I could use the things from there now. Do a quick sweep, check if there is anything left if they’re not thrashed yet. Don't worry, I'm not asking you to loot any clothes, I just want you to check if there's anything left in the stores, we will figure everything out later. Just don’t go about rummaging through trash, remember, brand stuff only.", "5ae448e586f7744dcf0c2a67 failMessageText": "", "5ae448e586f7744dcf0c2a67 successMessageText": "Great, awesome, got some stuff to look into. Seems like you scared off those Scavs back then. I'll send my guys, gonna have a new supply.", - "5ae4508386f7741250488337": "Locate and check the AVOKADO store on Interchange", - "5ae450db86f7741250488359": "Locate and check the KOSTIN store on Interchange", - "5ae450ee86f7740f9307859d": "Locate and check the tRend store on Interchange", - "5ae4510786f7740fa614399f": "Locate and check the DINO CLOTHES store on Interchange", - "5ae4511d86f7740ffc31ccb5": "Locate and check the TOP BRAND store on Interchange", + "5ae4508386f7741250488337": "Locate the AVOKADO store on Interchange", + "5ae450db86f7741250488359": "Locate the KOSTIN store on Interchange", + "5ae450ee86f7740f9307859d": "Locate the tRend store on Interchange", + "5ae4510786f7740fa614399f": "Locate the DINO CLOTHES store on Interchange", + "5ae4511d86f7740ffc31ccb5": "Locate the TOP BRAND store on Interchange", "5ae4514986f7740e915d218c": "Survive and extract from the location", "5af4155d86f7745b5e2aba63": "", "5ae448e586f7744dcf0c2a67 acceptPlayerMessage": "", @@ -18982,9 +20747,9 @@ "5ae448f286f77448d73c0131 description": "Hey, got something interesting for you, listen. A certain guy dropped by recently, goes by the name of Mechanic. A tight-lipped type, keeps silent all the time, you must have heard about him. Didn't buy anything but he said he's interested in fuel. And I remember that there were fuel tanks near Ultra, strapped onto the trucks, the ones with the German flag. I want you to go there and mark the fuel tanks with beacons. I’ll send some fuel to Mechanic, he promised to pay well. You'll have your cut too, don't worry.", "5ae448f286f77448d73c0131 failMessageText": "", "5ae448f286f77448d73c0131 successMessageText": "Good, I’ll send some grunts there and let Mechanic know everything is still on. Here, got a little present for you.", - "5ae452c086f774336a397578": "Mark the first fuel tank with an MS2000 Marker on Interchange", - "5ae452de86f77450595c4333": "Mark the second fuel tank with an MS2000 Marker on Interchange", - "5ae452fa86f774336a39758e": "Mark the third fuel tank with an MS2000 Marker on Interchange", + "5ae452c086f774336a397578": "Locate and mark the first fuel tank with an MS2000 Marker on Interchange", + "5ae452de86f77450595c4333": "Locate and mark the second fuel tank with an MS2000 Marker on Interchange", + "5ae452fa86f774336a39758e": "Locate and mark the third fuel tank with an MS2000 Marker on Interchange", "5ae4531986f774177033c3e6": "Survive and extract from the location", "5b50761b88a4507f45121125": "", "5ae448f286f77448d73c0131 acceptPlayerMessage": "", @@ -18994,7 +20759,7 @@ "5ae4490786f7744ca822adcc description": "Good day to you! Everybody’s so stylish nowadays, folks come by asking for things that weren’t much of a hit even back in peaceful times. Doesn’t matter if the thing is hit through by PM like paper, they’ll still take it as long as it makes them stand out. It turns out, people are still having a life, want to party or whatever. Look for different kinds of hats on mannequins or shelves, you know, those like in western movies, and grab our ushankas too.", "5ae4490786f7744ca822adcc failMessageText": "", "5ae4490786f7744ca822adcc successMessageText": "Beauty will save the world, as they say. Thank you, really helped me out, brother. The hats are gonna be sold in just one day, trust me. Here, take this as a reward.", - "5ae4543686f7742dc043c903": "Hand over the ushanka-hats", + "5ae4543686f7742dc043c903": "Hand over the ushankas", "5ae454a086f7742be909a81a": "Hand over the hats", "5af4157f86f7745f696ebd3d": "", "5fd89729a8c881276c560433": "Find Ushanka ear-flap hats in raid", @@ -19006,11 +20771,11 @@ "5ae4493486f7744efa289417 description": "Oh, hey there, brother, I’ve got a nice idea: just imagine how fucking awesome it would be to have info on Ultra’s cargos. What was being shipped, where, and in what amount, you know. I used to work with records like these myself. Don't think there are any manifests for the small shops, plus they most likely were run by slackers, but the larger stores and retail chains definitely kept their records. Check out Goshan and other supermarkets, like OLI and IDEA, the docs must be somewhere in the offices. it would be mighty cool if you found some.", "5ae4493486f7744efa289417 failMessageText": "", "5ae4493486f7744efa289417 successMessageText": "Got all three? Big thanks for that, did a brother a service. These docs could help with so much, you can't even imagine.", - "5ae9b32486f7745bbc72275a": "Obtain the Goshan cargo manifests on Interchange", + "5ae9b32486f7745bbc72275a": "Locate and obtain the Goshan cargo manifests on Interchange", "5ae9b34686f7743129512ccf": "Hand over the Goshan cargo manifests", - "5ae9b36c86f774307c29df04": "Obtain the OLI cargo manifests on Interchange", + "5ae9b36c86f774307c29df04": "Locate and obtain the OLI cargo manifests on Interchange", "5ae9b38a86f77432c81e2ce3": "Hand over the OLI cargo manifests", - "5ae9b3b186f7745bbc722762": "Obtain the IDEA cargo manifests on Interchange", + "5ae9b3b186f7745bbc722762": "Locate and obtain the IDEA cargo manifests on Interchange", "5ae9b3c986f77432c81e2ce6": "Hand over the IDEA cargo manifests", "5af415b286f77407184495dd": "", "5ae4493486f7744efa289417 acceptPlayerMessage": "", @@ -19020,7 +20785,7 @@ "5ae4493d86f7744b8e15aa8f description": "Took a glance at those manifests, I have quite an eye for details! Spotted deficiency in one store right away: some large cargo didn’t make it to OLI and in big quantity. Looks like they carried some batteries, but, apparently, the guys got stuck somewhere. The logistics service usually keeps such things under control. There must be some records on the routes and the last status of the shipping at the OLI logistics offices. Go visit them and try to recover the records. The room is probably closed though, gotta find a key somewhere first. Well, you're a smart dude, you'll figure it out, brother.", "5ae4493d86f7744b8e15aa8f failMessageText": "", "5ae4493d86f7744b8e15aa8f successMessageText": "Found the docs? Big thanks. Hand them over, let's see where our little cargo disappeared.", - "5ae9b5bd86f774307c29df37": "Obtain the OLI cargo route documents on Interchange", + "5ae9b5bd86f774307c29df37": "Locate and obtain the OLI cargo route documents on Interchange", "5ae9b63286f774229110402d": "Hand over the documents", "5af415c386f7745c267423a7": "", "5ae4493d86f7744b8e15aa8f acceptPlayerMessage": "", @@ -19078,9 +20843,9 @@ "5ae4498786f7744bde357695 description": "Good day to you! We already went so far together, you’re like a brother to me. Like family, see, don’t get me wrong. So, like a brother, answer frankly, do you like reading? I devoured books back then, as a kid. But now I need a serious book, for business. A rare bitch for sure, but I know you can get a devil from under the ground if you'd want. Get me the book about designing clothes from special fabrics, all that military stuff has to be made with aramid fabric, which has its own tricks to it. There should be a manual for them, in two volumes. If you can get it, that’d be capital. Should probably check in the book stores, they must be there. ULTRA had, as I remember, the \"Knigoyed\" and \"Museum of History\" stores, so make sure to search them both.", "5ae4498786f7744bde357695 failMessageText": "", "5ae4498786f7744bde357695 successMessageText": "You really found them? Thank you, friend. Don't get any ideas, these books are very important, they'll help me with my business.", - "5ae9c0a686f774703201f143": "Obtain the first book of clothes design on Interchange", + "5ae9c0a686f774703201f143": "Locate and obtain the first book of clothes design on Interchange", "5ae9c0c986f77468ab400f88": "Hand over the first book", - "5ae9c0e186f7746419683c5e": "Obtain the second book of clothes design on Interchange", + "5ae9c0e186f7746419683c5e": "Locate and obtain the second book of clothes design on Interchange", "5ae9c10686f774703201f146": "Hand over the second book", "5af416f086f7745c524a375f": "", "5af4192c86f774297e641027": "", @@ -19197,7 +20962,7 @@ "5b47876e86f7744d1c353205 failMessageText": "", "5b47876e86f7744d1c353205 successMessageText": "Oh, cool, give 'em here. Mechanic asked for it, as you've probably figured. I’ll send it to him today. Thank you, big help.", "5b47884886f7744d1c35327d": "Find Fuel conditioners in raid", - "5b47886986f7744d1a393e65": "Hand over the Fuel conditioners", + "5b47886986f7744d1a393e65": "Hand over the items", "5b4f09c786f77479806f2cf3": "", "5b4f09f586f7744fba15b2dc": "", "5b4f0c7b86f77479ee584ab0": "", @@ -19253,10 +21018,10 @@ "5b478eca86f7744642012254 description": "Ah, it's you... Long time no see. I thought maybe you got whacked, but, as it turns out, you’re a bit of a diehard. Whatever, you're alive and that's good, so listen here. People say there’s a new product on the market, some stuff in fancy chemical containers, like your gun silencer, but a bit larger. What’s inside them, whether it’s new drugs or just some vitamin B, no fucking idea whatsoever. And that’s what we need to find out, I bet that the blue-barrel shit from Polikhim is somehow connected to this, but I don’t know for a fact. These containers were seen at the Health Resort in the west wing first-floor offices, and one pal of mine claims to have seen them with EMERCOM people in the ULTRA mall, but he was in delirium at that time, so maybe it's just his imagination... To cut the long story short, find me a few of those containers, I have a couple of eggheads who might figure out what the fuck is inside.", "5b478eca86f7744642012254 failMessageText": "", "5b478eca86f7744642012254 successMessageText": "Oh, so you actually brought some? Splendid! Hands still intact after touching all these chems? I’ll get the eggheads working then, let them tinker with the stuff.", - "5b478f6886f774464201225a": "Obtain the first chemical container on Shoreline", + "5b478f6886f774464201225a": "Locate and obtain the first chemical container on Shoreline", "5b478f8886f7744d1b23c622": "Hand over the first container", - "5b4c826b86f7743cc87bcee4": "Obtain the second chemical container on Interchange", - "5b4c82cd86f774170c6e4169": "Obtain the third chemical container on Interchange", + "5b4c826b86f7743cc87bcee4": "Locate and obtain the second chemical container on Interchange", + "5b4c82cd86f774170c6e4169": "Locate and obtain the third chemical container on Interchange", "5b4c832686f77419603eb8f0": "Hand over the second container", "5b4c836486f77417063a09dc": "Hand over the third container", "5b4f0b8b86f7747a2910aaa4": "", @@ -19304,6 +21069,8 @@ "5b4c8e6586f77474396a5400": "Obtain the second single-axis fiber optic gyroscope on Shoreline", "5b4f0bca86f7744a6c2b8164": "", "5b4f0bfa86f77453572f54dc": "", + "66d078aadf338e6c13578080": "Obtain the first motor controller on Woods", + "66d07de6c7ef9040fff0b789": "Hand over the first controller", "5b4794cb86f774598100d5d4 acceptPlayerMessage": "", "5b4794cb86f774598100d5d4 declinePlayerMessage": "", "5b4794cb86f774598100d5d4 completePlayerMessage": "", @@ -19401,13 +21168,13 @@ "5c0bbaa886f7746941031d82 description": "So, here's why I called for you. I've caught a mole in my team, this prick was leaking info about my supply channels and points of interest. Of course, I started to wonder what the fuck was going on.\n\nMy men got intel off of him and found out that he was leaking the info to one of the local crews, those that settled by the dorms at the customs area. The thing is, I want to give them some bullshit info on my \"next cargo\", and my men will cut them down when those pricks come for it. But this intel should be delivered with no fuss no muss, as if you were one of them, get it? You will need to stash the Flash drive with the special info, it's planted in the red car's trunk, on the big bridge on Customs. My guys got ambushed at that bridge, so they couldn't hide it anywhere closer to the dorms, sorry. Stash that thumb drive along with an SV-98 and a Roler watch in the dorm, that's how we agreed to do this. And the most important thing: do not smoke any Scavs on Customs and just leave quietly when you're done.", "5c0bbaa886f7746941031d82 failMessageText": "What the fuck, you moron? Why did you shoot them? They won't let us get closer than a mile to the dorms. They'll keep on guard for a long time now... How the fuck do we plant the fake info now, huh? What are you talking about? What bloody \"transmitter\" are you talking about? Fuck outta here!", "5c0bbaa886f7746941031d82 successMessageText": "Looks like everything's cool, my fellas are on the spot, and I think that it's gonna be the last surprise for those fuckers. Thanks for the help.", - "5c0bc32986f7743e4d1002d2": "Stash SV-98 sniper rifle in the trash opposite of stairs on the 3rd floor of the dorm on Customs", - "5c0bc43e86f7744794440ba5": "Stash Roler Submariner gold wrist watch in the trash opposite of stairs on the 3rd floor of the dorm on Customs", - "5c12320586f77437e44bcb15": "Stash the False flash drive in the trash opposite of stairs on the 3rd floor of the dorm on Customs", - "5c1233ac86f77406fa13baea": "You must not kill any Scavs on Customs until the quest is completed", + "5c0bc32986f7743e4d1002d2": "Stash an SV-98 sniper rifle in the trash next to stairs on the 3rd floor of the dorm on Customs", + "5c0bc43e86f7744794440ba5": "Stash a Roler Submariner gold wrist watch in the trash next to stairs on the 3rd floor of the dorm on Customs", + "5c12320586f77437e44bcb15": "Stash the false flash drive in the trash next to stairs on the 3rd floor of the dorm on Customs", + "5c1233ac86f77406fa13baea": "You must not kill any Scavs on Customs while the task is active", "5c17b96486f774331c793f28": "", "5c1fa91586f7740de474cb36": "", - "5c50481c86f77410650e0521": "Obtain the False flash drive from the specified spot on Customs", + "5c50481c86f77410650e0521": "Locate and obtain the false flash drive at the specified spot on Customs", "5c0bbaa886f7746941031d82 acceptPlayerMessage": "", "5c0bbaa886f7746941031d82 declinePlayerMessage": "", "5c0bbaa886f7746941031d82 completePlayerMessage": "", @@ -19426,7 +21193,7 @@ "5c0bd01e86f7747cdd799e56 description": "Good day to you, mercenary. Very soon I will have a night-time meeting on a very important matter. Unfortunately, according to my intelligence in the region, the number of night sorties of your, uh, colleagues has noticeably increased. I feel that these are the same people who do not risk operating in the daytime. I want you to deal with them. These criminals cannot disrupt my work.", "5c0bd01e86f7747cdd799e56 failMessageText": "", "5c0bd01e86f7747cdd799e56 successMessageText": "Good work, my friend! Everything went according to the plan.", - "5c1242fa86f7742aa04fed52": "Eliminate PMC operatives in the time period of 21:00-06:00 (Excluding Factory and The Lab)", + "5c1242fa86f7742aa04fed52": "Eliminate PMC operatives in the time period of 21:00-06:00 (excluding Factory and The Lab)", "5c17d05e86f77430a64c6c66": "", "5c20cd8f86f774337d77b7ef": "", "5c0bd01e86f7747cdd799e56 acceptPlayerMessage": "", @@ -19489,8 +21256,8 @@ "5c0be69086f7743c9c1ecf43": "Hand over the LEDX Skin Transilluminator", "5c1fd1ae86f7742b3b47f064": "", "5c1fd1b586f7742b3a651f74": "", - "5fd892bc37b6e511a4734969": "Find Ophthalmoscope in raid", - "5fd8935b7dd32f724e0fe7ee": "Find LEDX Skin Transilluminator in raid", + "5fd892bc37b6e511a4734969": "Find an Ophthalmoscope in raid", + "5fd8935b7dd32f724e0fe7ee": "Find a LEDX Skin Transilluminator in raid", "5c0be5fc86f774467a116593 acceptPlayerMessage": "", "5c0be5fc86f774467a116593 declinePlayerMessage": "", "5c0be5fc86f774467a116593 completePlayerMessage": "", @@ -19555,13 +21322,13 @@ "5c0d4e61d09282029f53920e description": "Ohh, it’s you? Come on, I have some business for you. Some serious people who are, so to speak, new to the city, need the services of a professional guide who will lead the group to the right place and won’t ask unnecessary questions. They are willing to pay good money for this. Do you think you can handle it? If I see that you are indeed ready, I would recommend you to them, mercenary.", "5c0d4e61d09282029f53920e failMessageText": "Bad luck... I know it's not that easy. That's why I need a competent person, do you understand?", "5c0d4e61d09282029f53920e successMessageText": "Very good work, you will definitely be a good guide! You will be contacted for further instructions later when the clients are ready. For now, here's the prepayment.", + "5c0d4f46d09282029f539216": "You must not die or leave the raid while the task is active (Status: KIA, Left the Action, MIA, Ran Through)", + "5c0e6876d09282029e2fffe0": "Survive and extract from Woods with the \"Survived\" exit status", + "5c0e687ad0928202b25db840": "Survive and extract from Customs with the \"Survived\" exit status", "5c13979886f774251443c1a6": "Survive and extract from Interchange with the \"Survived\" exit status", "5c13982286f774365a69cc4d": "Survive and extract from Shoreline with the \"Survived\" exit status", "5c13989886f7747878361a50": "Survive and extract from Factory with the \"Survived\" exit status", - "5c0d4f46d09282029f539216": "You must not die or leave the raid while the task is active (Status: KIA, Left the Action, MIA, Ran Through)", "5c1931e686f7747ce71bcbea": "Survive and extract from The Lab with the \"Survived\" exit status", - "5c0e6876d09282029e2fffe0": "Survive and extract from Woods with the \"Survived\" exit status", - "5c0e687ad0928202b25db840": "Survive and extract from Customs with the \"Survived\" exit status", "5d0a0e2286f7743a1a74d63b": "", "5d0a111586f7743a1b0d87b1": "", "5dc984ae4b68b15f4825cea5": "Survive and extract from Reserve with the \"Survived\" exit status", @@ -19619,8 +21386,8 @@ "5ca7254e86f7740d424a2043": "Find Antique teapots in raid", "5ca7258986f7740d424a2044": "Find Antique vases in raid", "62a700893e015d7ce1151d90": "Find Axel parrot figurine in raid", - "62a700a37230237f257cac2d": "Find Raven figurines in raid", "62a70094ec21e50cad3b670b": "Hand over the Axel parrot figurine", + "62a700a37230237f257cac2d": "Find Raven figurines in raid", "62a700c2ec21e50cad3b670c": "Hand over the Raven figurines", "5c1141f386f77430ff393792 acceptPlayerMessage": "", "5c1141f386f77430ff393792 declinePlayerMessage": "", @@ -19675,16 +21442,16 @@ "5c51af7086f774423d3f9073": "", "5c51afd786f774423e5e36e5": "", "5c51affc86f774423b4767d4": "", - "5c51bed886f77478bb033461": "Hand over the Battered antique book", - "5c51bf8786f77416a11e5cb2": "Hand over the #FireKlean gun lube", - "5c51bf9a86f77478bf5632aa": "Hand over the Golden rooster", - "5c51bfb186f77478bd516d37": "Hand over the Silver Badge", - "5c51bfc286f77478bc7ae1d9": "Hand over the Deadlyslob's beard oil", - "5c51c03186f7740ada3f2c3d": "Hand over the Golden 1GPhone smartphone", - "5c51c04286f77478be4009f5": "Hand over the Jar of DevilDog mayo", - "5c51c23a86f77478bb033466": "Hand over the Can of sprats", - "5c51c24c86f77416a11e5cb7": "Hand over the Fake mustache", - "5c51c25c86f77478bf5632af": "Hand over the Kotton beanie", + "5c51bed886f77478bb033461": "Hand over the found in raid item: Battered antique book", + "5c51bf8786f77416a11e5cb2": "Hand over the found in raid item: #FireKlean gun lube", + "5c51bf9a86f77478bf5632aa": "Hand over the found in raid item: Golden rooster figurine", + "5c51bfb186f77478bd516d37": "Hand over the found in raid item: Silver Badge", + "5c51bfc286f77478bc7ae1d9": "Hand over the found in raid item: Deadlyslob's beard oil", + "5c51c03186f7740ada3f2c3d": "Hand over the found in raid item: Golden 1GPhone smartphone", + "5c51c04286f77478be4009f5": "Hand over the found in raid item: Jar of DevilDog mayo", + "5c51c23a86f77478bb033466": "Hand over the found in raid item: Can of sprats", + "5c51c24c86f77416a11e5cb7": "Hand over the found in raid item: Fake mustache", + "5c51c25c86f77478bf5632af": "Hand over the found in raid item: Kotton beanie", "5c51db2a86f77478be4009ff": "", "5c52b92e86f77478be400a00": "", "5c52bb0586f774119c51f7f2": "", @@ -19735,13 +21502,13 @@ "5c52cd3386f774469d73a592": "", "5c52ce5486f7742fba438c52": "", "5c52ce6786f7742fb77f6b12": "", - "5c52da1086f7742fbb42a814": "Hand over the Old firesteel", - "5c52da5886f7747364267a14": "Hand over the Antique axe", + "5c52da1086f7742fbb42a814": "Hand over the found in raid item: Old firesteel", + "5c52da5886f7747364267a14": "Hand over the found in raid item: Antique axe", "5cb5ddd386f7746ef72a7e73": "Find Old firesteel in raid", "5cb5dde786f7746ef451bd74": "Find Antique axe in raid", "5cb5de0086f7746ef82c17e4": "Find Battered antique book in raid", "5cb5de1786f7747d215eca04": "Find #FireKlean gun lube in raid", - "5cb5de9c86f7746ef55dbc86": "Find Golden rooster in raid", + "5cb5de9c86f7746ef55dbc86": "Find Golden rooster figurine in raid", "5cb5deae86f7746ef451bd76": "Find Silver Badge in raid", "5cb5debf86f7746ef72a7e78": "Find Deadlyslob's beard oil in raid", "5cb5ded886f7746ef451bd77": "Find Golden 1GPhone smartphone in raid", @@ -19749,30 +21516,30 @@ "5cb5df5586f7746ef82c17e8": "Find Can of sprats in raid", "5cb5df7186f7747d215eca08": "Find Fake mustache in raid", "5cb5df8486f7746ef82c17ea": "Find Kotton beanie in raid", + "5db9aaf46194ab4e69304de8": "", "5de798b233870205123c7f33": "", "5ec798b8254c431289542b90": "Find Raven figurine in raid", - "5ec7998dc1683c0db84484e7": "Hand over the Raven figurine", + "5ec7998dc1683c0db84484e7": "Hand over the found in raid item: Raven figurine", "5ec79aaac1683c0db84484e8": "Find Pestily plague mask in raid", - "5ec79b3ced84ad5ddb58e24c": "Hand over the Pestily plague mask", + "5ec79b3ced84ad5ddb58e24c": "Hand over the found in raid item: Pestily plague mask", "5ec79c2fed84ad5ddb58e24d": "Find Shroud half-mask in raid", - "5ec79c5ac1683c0db84484eb": "Hand over the Shroud half-mask", + "5ec79c5ac1683c0db84484eb": "Hand over the found in raid item: Shroud half-mask", "5ec79f2c82a25876330cb232": "Find Can of Dr. Lupo's coffee beans in raid", - "5ec79fb273279f683254baaa": "Hand over the Can of Dr. Lupo's coffee beans", - "5db9aaf46194ab4e69304de8": "", + "5ec79fb273279f683254baaa": "Hand over the found in raid item: Can of Dr. Lupo's coffee beans", "5f75d3ab0e3df95a7f52b367": "Find 42 Signature Blend English Tea in raid", - "5f75d4558f70ca7a1d684dac": "Hand over the 42 Signature Blend English Tea", + "5f75d4558f70ca7a1d684dac": "Hand over the found in raid item: 42 Signature Blend English Tea", "5f75d4e79a479f5c16331352": "Find Veritas guitar pick in raid", - "5f75d521edb90b73913272a3": "Hand over the Veritas guitar pick", + "5f75d521edb90b73913272a3": "Hand over the found in raid item: Veritas guitar pick", "60cfa1031bdece56c249cbf4": "Find Evasion armband in raid", - "60cfa136f81cc57f471718cb": "Hand over the Evasion armband", + "60cfa136f81cc57f471718cb": "Hand over the found in raid item: Evasion armband", "60d06de320a6283a506aeb67": "Find Can of RatCola soda in raid", - "60d06e921bdece56c249cc0c": "Hand over the Can of RatCola soda", + "60d06e921bdece56c249cc0c": "Hand over the found in raid item: Can of RatCola soda", "60d06eef41fd1e14d71e2323": "Find Loot Lord plushie in raid", - "60d06f3420a6283a506aeb69": "Hand over the Loot Lord plushie", + "60d06f3420a6283a506aeb69": "Hand over the found in raid item: Loot Lord plushie", "60d06f8cac6eb02bc726de99": "Find WZ Wallet in raid", - "60d074211bdece56c249cc13": "Hand over the WZ Wallet", + "60d074211bdece56c249cc13": "Hand over the found in raid item: WZ Wallet", "60d0748820a6283a506aebb1": "Find LVNDMARK's rat poison in raid", - "60d074ef401d874962160aee": "Hand over the LVNDMARK's rat poison", + "60d074ef401d874962160aee": "Hand over the found in raid item: LVNDMARK's rat poison", "60d9a73d9f89812e5b6ac368": "", "60d9a752ac6eb02bc726fcc6": "", "60d9a77141fd1e14d71e2bfc": "", @@ -19785,7 +21552,7 @@ "60d9a7dd401d87496216141f": "", "60d9a80e807141159d0a4e5b": "", "60e827a20c492412897c688e": "Find Smoke balaclava in raid", - "60e827faf09904268a4dbc40": "Hand over the Smoke balaclava", + "60e827faf09904268a4dbc40": "Hand over the found in raid item: Smoke balaclava", "62a6ff004de19a4c3422ea5d": "Hand over the found in raid item: Missam forklift key", "62a6ff141c307729c3264f96": "Hand over the found in raid item: Video cassette with the Cyborg Killer movie", "62a6ff203e015d7ce1151d8a": "Hand over the found in raid item: BakeEzy cook book", @@ -19799,6 +21566,9 @@ "62a6ffb4a9a0ea77981b57d5": "Hand over the found in raid item: Axel parrot figurine", "62a6ffbcec21e50cad3b6708": "Hand over the found in raid item: BEAR Buddy plush toy", "65b10c6a8511b7ef8694e060": "Hand over the found in raid item: Glorious E lightweight armored mask", + "66b4bcc0e6d7bc4faf7f817c": "Hand over the found in raid item: Inseq gas pipe wrench", + "66b4bcec0f6e68013a5f0bac": "Hand over the found in raid item: Viibiin sneaker", + "66b4bd0fe194ef246734689e": "Hand over the found in raid item: Tamatthi kunai knife replica", "5c51aac186f77432ea65c552 acceptPlayerMessage": "", "5c51aac186f77432ea65c552 declinePlayerMessage": "", "5c51aac186f77432ea65c552 completePlayerMessage": "", @@ -19853,7 +21623,7 @@ "5d25bfd086f77442734d3007 description": "Hello there, warrior! My hunt went as planned. You know, the water you prepared for me did really come in handy. By the way, how good are you at handling dehydration? Show me how long PMCs can stay without water.", "5d25bfd086f77442734d3007 failMessageText": "", "5d25bfd086f77442734d3007 successMessageText": "No way you can survive for so long! Impressive. Here you go, drink this, regain your strength.", - "5d25c5a186f77443fe457661": "Survive for 5 minutes while suffering from complete dehydration (Excluding Factory)", + "5d25c5a186f77443fe457661": "Survive for 5 minutes while suffering from complete dehydration (excluding Factory)", "5d9f035086f7741cac4a9713": "Survive and extract from the location", "5dadc98786f7744b0c681e8e": "", "5dadc99686f7744b0f1b1d2a": "", @@ -19875,7 +21645,7 @@ "5d25cf2686f77443e75488d4 failMessageText": "So you failed, huh? Well, will be a lesson for you. Try again, and remember your mistakes.", "5d25cf2686f77443e75488d4 successMessageText": "Successful? Great! Sweat saves the blood! Don't get too ecstatic now, there are some more tasks for you.", "5d25d09286f77444001e284c": "Eliminate Scavs in a single raid without using any medicine on Woods", - "5d25d0d186f7740a22515975": "You must not use any medical supplies until the quest is completed", + "5d25d0d186f7740a22515975": "You must not use any medical supplies while the task is active", "5d9c940886f7742cd41c59c0": "", "5d9c941f86f7743554286958": "", "5d25cf2686f77443e75488d4 acceptPlayerMessage": "", @@ -20192,12 +21962,12 @@ "5e4d4ac186f774264f758336 description": "So, here's another list of the stuff I need. As soon as you have it - bring it here, and make sure it's in good condition. No traders and all, well, you know the deal. I'm thinking about some new outfits for you, something recognizable, warming the Russian heart. I have no idea what's the business between you and the yanks, but these days your life is as shitty as theirs. Shit happens. Anyway, good luck to you.", "5e4d4ac186f774264f758336 failMessageText": "", "5e4d4ac186f774264f758336 successMessageText": "That's exactly what I need! Put it all over there. Lemme measure you... Well, it's gonna be a tough one. Don't worry, you'll love the result, bro.", + "5e4d4ac186f774264f758337": "Find Fleece fabrics in raid", + "5e4d4ac186f774264f758338": "Hand over the fabrics", "5e4d4ac186f774264f758339": "Find Cordura polyamide fabrics in raid", "5e4d4ac186f774264f75833a": "Hand over the fabrics", - "5e4d4ac186f774264f75833c": "Hand over the duct tapes", "5e4d4ac186f774264f75833b": "Find KEKTAPE duct tapes in raid", - "5e4d4ac186f774264f758338": "Hand over the fabrics", - "5e4d4ac186f774264f758337": "Find Fleece fabrics in raid", + "5e4d4ac186f774264f75833c": "Hand over the duct tapes", "5e58db0986f7740bef574f02": "", "5e58db2386f7747c28220302": "", "5e4d4ac186f774264f758336 acceptPlayerMessage": "", @@ -20526,9 +22296,9 @@ "5edabed50880da21347b382e": "", "5edabf0fcc183c769d778bcc": "", "5f039da057a46716b610b577": "Survive and extract from the location", - "5f071b2a8ca6db7f3b41215f": "Mark the medical container at the river pier with an MS2000 Marker on Shoreline", - "5f071ae396d1ae55e476abc4": "Mark the medical container by cottages with an MS2000 Marker on Shoreline", "5f071a9727cec53d5d24fe3b": "Mark the medical container at the Health Resort with an MS2000 Marker on Shoreline", + "5f071ae396d1ae55e476abc4": "Mark the medical container by cottages with an MS2000 Marker on Shoreline", + "5f071b2a8ca6db7f3b41215f": "Mark the medical container at the river pier with an MS2000 Marker on Shoreline", "5edabd13218d181e29451442 acceptPlayerMessage": "", "5edabd13218d181e29451442 declinePlayerMessage": "", "5edabd13218d181e29451442 completePlayerMessage": "", @@ -20562,14 +22332,14 @@ "5edac3f60880da21347b384e": "", "5edac465a0055865214cb5b6": "", "5f046f9825b2ad51bd275800": "Do not kill Sanitar", - "5f07025e27cec53d5d24fe25": "Find TerraGroup Labs access keycards in raid", "5f04935cde3b9e0ecf03d864": "Hand over the keycards", - "5f0702c3d9d49120185e6323": "Obtain TerraGroup Labs keycard (Green)", "5f04944b69ef785df740a8c9": "Hand over the keycard", - "5f070323d57aeb6e09253785": "Find AHF1-M stimulant injector in raid", "5f0495458654d20be3564f4c": "Hand over the injector", - "5f070350f6b5847ad975ceac": "Find 3-(b-TG) stimulant injector in raid", "5f0495b8efefac7f7227de63": "Hand over the injector", + "5f07025e27cec53d5d24fe25": "Find TerraGroup Labs access keycards in raid", + "5f0702c3d9d49120185e6323": "Obtain TerraGroup Labs keycard (Green)", + "5f070323d57aeb6e09253785": "Find AHF1-M stimulant injector in raid", + "5f070350f6b5847ad975ceac": "Find 3-(b-TG) stimulant injector in raid", "5edac34d0bb72a50635c2bfa acceptPlayerMessage": "", "5edac34d0bb72a50635c2bfa declinePlayerMessage": "", "5edac34d0bb72a50635c2bfa completePlayerMessage": "", @@ -20620,9 +22390,9 @@ "5f04886a3937dc337a6b8238 description": "Hey, come on in. Have you heard about some new guy that appeared in the resort area? Calls himself Sanitar. Not a simple man either, definitely worked for TerraGroup when they settled in the health resort. Either a major scientist there or just close to guys who were, no info on that. I've heard he's selling some secret stimulants, this means he understands chemistry quite well. But long story short, he's got some sort of an office or stash in the health resort, and I want you to find that place. I'll send specialists, maybe they'll find some interesting devices there. Just be careful, this man is dangerous.", "5f04886a3937dc337a6b8238 failMessageText": "", "5f04886a3937dc337a6b8238 successMessageText": "So that's how it is, it's right on the first floor? How many times have my people been there and found nothing. Did you get inside the room? Found anything interesting in there? Well, doesn't matter, I'll send my boys to check it out anyway. Here's your reward, you've earned it. Thank you.", + "5f0488c590eea473df674002": "Locate Sanitar's office in the health resort", "5f04983ffbed7a08077b4367": "Survive and extract from the location", "5f0da368ee0d8b5aa14a625f": "", - "5f0488c590eea473df674002": "Locate Sanitar's office in the health resort", "5f04886a3937dc337a6b8238 acceptPlayerMessage": "", "5f04886a3937dc337a6b8238 declinePlayerMessage": "", "5f04886a3937dc337a6b8238 completePlayerMessage": "", @@ -20688,8 +22458,8 @@ "5f75fb988fb5c37ce1766e98 description": "", "5f75fb988fb5c37ce1766e98 failMessageText": "", "5f75fb988fb5c37ce1766e98 successMessageText": "", - "5f97010ace3c6452e951c536": "", "5f75fb988fb5c37ce1766e99": "", + "5f97010ace3c6452e951c536": "", "5f75fb988fb5c37ce1766e98 acceptPlayerMessage": "", "5f75fb988fb5c37ce1766e98 declinePlayerMessage": "", "5f75fb988fb5c37ce1766e98 completePlayerMessage": "", @@ -20722,10 +22492,10 @@ "5fd9fad9c1ce6b1a3b486d00 description": "Greetings, warrior. I have a job for you. Long story short, I lost contact with one of my groups, and it's been quite a while ago. When shit hit the fan, I sent them to Woods to pick up some cargo. I'm afraid they got ambushed, the last time I got through, they reported that the USECs were closing in on them from the hills. Investigate it, check if anyone survived. Their convoy had a BRDM, a Bukhanka van, and a truck of some sort, I do not remember what kind exactly. I think that the USECs must have settled somewhere near there too, so stay sharp. Find my convoy and those USECs' camp, if it is really there. Dismissed.", "5fd9fad9c1ce6b1a3b486d00 failMessageText": "", "5fd9fad9c1ce6b1a3b486d00 successMessageText": "So my guys didn't make it and the transports were looted... Plus a USEC camp nearby, you say? That sucks, the cargo was very important. Well, you've done your part of the deal, so here's the reward. You can buzz off now.", - "5fd9fad9c1ce6b1a3b486d05": "Locate the temporary USEC camp on Woods", + "5fd9fad9c1ce6b1a3b486d02": "", "5fd9fad9c1ce6b1a3b486d03": "Locate Prapor's missing convoy on Woods", + "5fd9fad9c1ce6b1a3b486d05": "Locate the temporary USEC camp on Woods", "5fd9fad9c1ce6b1a3b486d0d": "Survive and extract from the location", - "5fd9fad9c1ce6b1a3b486d02": "", "5fdc862eaf5a054cc9333005": "", "5fd9fad9c1ce6b1a3b486d00 acceptPlayerMessage": "", "5fd9fad9c1ce6b1a3b486d00 declinePlayerMessage": "", @@ -21125,8 +22895,8 @@ "6179ad56c760af5ad2053587 description": "Good afternoon, young man, I have a special assignment for you. Unfortunately, I cannot entrust it to my workers. Knowing your previous feats in searching for data that interests me, you can easily be made into a private investigator! So, there was a person who I had been working closely with, he lived somewhere at the cape Dalniy territory. He always carried a briefcase with him containing his medical studies and research. The issue is that he hasn't been contacting me the last two weeks - I'm starting to worry. If his studies get into the wrong hands, I will have to pay a high price to silence the information spread. Please, mercenary, I am asking you to find my contact's briefcase. He used to drive a red merin sports coupe and was always telling me that he'd love to relax somewhere by the sea, farther away from all the city noise. Are you ready to take on this task, young man?", "6179ad56c760af5ad2053587 failMessageText": "", "6179ad56c760af5ad2053587 successMessageText": "This is brilliant, young man! The data from this laptop can play a high role in my business negotiations!.. Ahem, you can go now, mercenary.", - "617bf2a6f8e6c97ec70878b7": "Find the informant's briefcase on Lighthouse", "617bf29a52e86c73d372a917": "Hand over the found package", + "617bf2a6f8e6c97ec70878b7": "Find the informant's briefcase on Lighthouse", "6179ad56c760af5ad2053587 acceptPlayerMessage": "", "6179ad56c760af5ad2053587 declinePlayerMessage": "", "6179ad56c760af5ad2053587 completePlayerMessage": "", @@ -21153,7 +22923,7 @@ "6179aff8f57fb279792c60a1 description": "Mercenary, there is work for you. According to our intelligence, after the initial conflict, the former base of your USEC comrades, in the cottage area at Cape Dalniy, was abandoned with a lot of valuable equipment and information that could sponsor the Blue Helmets operations. The only problem is that the entire territory is currently under the control of the Scavs, and I would like to get rid of them, or at least scare them out of this zone so that my people can extract all the necessary resources without combat. This is your task, my friend. Naturally, everything that you have just heard will remain strictly between us. I look forward to your report.", "6179aff8f57fb279792c60a1 failMessageText": "", "6179aff8f57fb279792c60a1 successMessageText": "My recon group has already reported your success, mercenary. I think you have earned a generous reward. You're free to go.", - "617bf4e152e86c73d372a95d": "Secure the cottage area from Scavs on Lighthouse", + "617bf4e152e86c73d372a95d": "Eliminate Scavs around the chalet area on Lighthouse", "6179aff8f57fb279792c60a1 acceptPlayerMessage": "", "6179aff8f57fb279792c60a1 declinePlayerMessage": "", "6179aff8f57fb279792c60a1 completePlayerMessage": "", @@ -21174,8 +22944,8 @@ "6179b3bdc7560e13d23eeb8d successMessageText": "So there were some documents? Give'em to me. Let's see ... Stationery delivery, office rent - nothing interesting so far... There it is, chemicals. The \"BLUE ICE\" traces in the water? What is this, some kind of refrigerant? Alright, I'll deal with this, but for now, take yourself a small gift for your efforts. Thanks again, friend.", "617bf6c70cf4a041de5b3972": "Find the data on the water pump operation on Lighthouse", "617bf77a3de8a6689b533a2a": "Hand over the extracted data", - "61951c3e2e2805073c2d29db": "Hand over the extracted data", "61951c30aa0f643f9a0ae1b7": "Find the data on the pumping station operation on Lighthouse", + "61951c3e2e2805073c2d29db": "Hand over the extracted data", "6179b3bdc7560e13d23eeb8d acceptPlayerMessage": "", "6179b3bdc7560e13d23eeb8d declinePlayerMessage": "", "6179b3bdc7560e13d23eeb8d completePlayerMessage": "", @@ -21240,8 +23010,8 @@ "61958c366726521dd96828ec description": "Mercenary, we made a breakthrough! Um, let's retire for a couple of minutes. So, the TerraGroup cargo that you found in a secret wall in the Azure Coast sanatorium does not fully comply with the manifests at our disposal. We guess where the cargo was delivered from the sanatorium, but the information is completely classified for now. However, you, mercenary, still play a large role in this case. Your next task in our operation is to find evidence of the TerraGroup cargo on the territory of Cape Dalniy, in the area of ​​the sandy coast. I suppose it is better to start your search from the collapsed tunnel's side. Keep in touch, my friend.", "61958c366726521dd96828ec failMessageText": "", "61958c366726521dd96828ec successMessageText": "So you found the cargo on the shore, exactly in the place where the TerraGroup transports moored? Okay, so they were shipped straight from the bay... Thank you for your work, mercenary. We will contact you about the next stage of our operation when the time is right.", - "61958d69d14ece31007e2df4": "Survive and extract from the location", "61958d54aa0f643f9a0aed73": "Locate and mark the TerraGroup cargo with an MS2000 Marker on Lighthouse", + "61958d69d14ece31007e2df4": "Survive and extract from the location", "61958c366726521dd96828ec acceptPlayerMessage": "", "61958c366726521dd96828ec declinePlayerMessage": "", "61958c366726521dd96828ec completePlayerMessage": "", @@ -21343,8 +23113,8 @@ "61c1944a7578f770c5341e99": "Locate and visit the Christmas tree on Customs", "61c194d98077ed53c5195a43": "Locate and visit the Christmas tree on Reserve", "61c194f657ba1629dd052a01": "Locate and visit the Christmas tree on Interchange", - "61c1952c2ecf5e52b12f9446": "Locate and visit the Christmas tree on Shoreline", "61c19511fada4f6ce32e2cb4": "Locate and visit the Christmas tree on Lighthouse", + "61c1952c2ecf5e52b12f9446": "Locate and visit the Christmas tree on Shoreline", "61c196fb8077ed53c5195a45": "Locate and visit the Christmas tree on Woods", "61bfa784f4378605ca5598e1 acceptPlayerMessage": "", "61bfa784f4378605ca5598e1 declinePlayerMessage": "", @@ -21437,9 +23207,9 @@ "625d7001c4874104f230c0c5 failMessageText": "", "625d7001c4874104f230c0c5 successMessageText": "Thank you. Lightkeeper has already explained to me how to deliver these stimulants to him. I'll send the package with someone else, because I don't want you to have to do all the courier work as well. I hope we've already proven to Lightkeeper that we're reliable partners.", "6260295faa168e51321d69d9": "Eliminate Raiders in The Lab", - "62602aaff7308432be1d44c9": "Hand over the found in raid SJ1 TGLabs combat stimulant injector", "62602a37c4874104f230c0ca": "Hand over the found in raid SJ6 TGLabs combat stimulant injector", "62602a44e7578c305945c9c5": "Hand over the found in raid SJ9 TGLabs combat stimulant injector", + "62602aaff7308432be1d44c9": "Hand over the found in raid SJ1 TGLabs combat stimulant injector", "625d7001c4874104f230c0c5 acceptPlayerMessage": "", "625d7001c4874104f230c0c5 declinePlayerMessage": "", "625d7001c4874104f230c0c5 completePlayerMessage": "", @@ -21610,9 +23380,9 @@ "636b8864c7ed455bc71e399a": "Eliminate Sanitar while using bolt-action rifles", "636b88ff550cde781e0ac379": "Eliminate Sanitar while using grenade launchers", "636b89dfc0e68626dd2b2ba7": "Eliminate Sanitar while using pistols or revolvers", + "636b8a19c7ed455bc71e399c": "Eliminate Sanitar while using revolvers", "636cc7d546480934981ce1e5": "Eliminate Sanitar while using melee weapons", "636cc91b314c901c6632f716": "Eliminate Sanitar while using throwable weapons", - "636b8a19c7ed455bc71e399c": "Eliminate Sanitar while using revolvers", "636a2f5759cb834f8a5825d6 acceptPlayerMessage": "", "636a2f5759cb834f8a5825d6 declinePlayerMessage": "", "636a2f5759cb834f8a5825d6 completePlayerMessage": "", @@ -21720,8 +23490,8 @@ "639135d89444fb141f4e6eea description": "Good afternoon, mercenary. You're just in time, I have an errand for you. I need to determine how many people have gone missing in the city. To do this, I need a list of all the residents of the city and subtract the already evacuated, the dead, and those who found shelter in the hospital. Your task is to find that list of residents. Bring me the journal from Primorsky District's Housing Department.", "639135d89444fb141f4e6eea failMessageText": "", "639135d89444fb141f4e6eea successMessageText": "Mercenary, you know firsthand how many lives are lost in war. But you have no idea how many die not from a bullet or a knife, but by going missing. Some are buried in the concrete in their own home after the bombing. Someone died in their basement from exhaustion because they couldn't find food. Someone was swallowed by infection because they didn't have the necessary medicine and couldn't get to a hospital because of constant shelling... And there are at least fifteen percent of people like that in this journal.", - "639135d89444fb141f4e6eec": "Hand over the journal", "639135d89444fb141f4e6eeb": "Obtain the journal containing resident details on Streets of Tarkov", + "639135d89444fb141f4e6eec": "Hand over the journal", "639135d89444fb141f4e6eea acceptPlayerMessage": "", "639135d89444fb141f4e6eea declinePlayerMessage": "", "639135d89444fb141f4e6eea completePlayerMessage": "", @@ -21729,8 +23499,8 @@ "639135e0fa894f0a866afde6 description": "Greetings, mercenary. The hospital continues to receive more intoxicated patients. Each day there are more and more of them, and that worries me. It feels like if you destroy one drug den, two new ones appear. We should go another route, try to cure those who are already addicted. In order to do that, I need a sample of the drug for analysis.", "639135e0fa894f0a866afde6 failMessageText": "", "639135e0fa894f0a866afde6 successMessageText": "Thank you for a job well done. Take your reward over there.", - "639135e0fa894f0a866afde8": "Hand over the container", "639135e0fa894f0a866afde7": "Obtain the container with drug samples", + "639135e0fa894f0a866afde8": "Hand over the container", "63a7d64710b7a13eb015961f": "Locate the chemical laboratory on Streets of Tarkov", "639135e0fa894f0a866afde6 acceptPlayerMessage": "", "639135e0fa894f0a866afde6 declinePlayerMessage": "", @@ -21739,8 +23509,8 @@ "639135e8c115f907b14700aa description": "Hello, friend... You know, I wasn't always alone. Loneliness does not bother me, of course, especially since I have a neural net if I want to talk to someone really intelligent... Still, lately it's been weighing on me to think about my relatives. My brother and his wife and kids - will you look them up? The Samoylovs, they lived in Concordia. My brother drove a very recognizable car with a tiger aerography... It might be easier to find them through his car.", "639135e8c115f907b14700aa failMessageText": "", "639135e8c115f907b14700aa successMessageText": "So, this is a recording of the first hour after the events began... There, you see his car? And there's him. Okay, they're getting in the car, driving away... They should have left before the shelling started. What a relief!", - "639135e8c115f907b14700ac": "Hand over the information", "639135e8c115f907b14700ab": "Obtain the data on vehicle movement at the Concordia residential complex parking lot on Streets of Tarkov", + "639135e8c115f907b14700ac": "Hand over the information", "639135e8c115f907b14700aa acceptPlayerMessage": "", "639135e8c115f907b14700aa declinePlayerMessage": "", "639135e8c115f907b14700aa completePlayerMessage": "", @@ -21857,8 +23627,8 @@ "639137709444fb141f4e6ef2 description": "Looking for a job, young man? I think I have something for you. Have you heard that before all these events in Tarkov, people started experiencing strange symptoms? I'd like to find out more about it, maybe the wars that followed had something to do with it. And please, don't divulge my hypothesis to anyone. You'll need to find at least one medical journal that lists the symptoms. Look in the ambulance vehicles, a medical journal might be in any of them. Be careful in your search.", "639137709444fb141f4e6ef2 failMessageText": "", "639137709444fb141f4e6ef2 successMessageText": "Did you find it? Give it to me. That's right, it's the data I needed.", - "639137709444fb141f4e6ef4": "Hand over the journal", "639137709444fb141f4e6ef3": "Obtain the medical observation records on Streets of Tarkov", + "639137709444fb141f4e6ef4": "Hand over the journal", "639137709444fb141f4e6ef2 acceptPlayerMessage": "", "639137709444fb141f4e6ef2 declinePlayerMessage": "", "639137709444fb141f4e6ef2 completePlayerMessage": "", @@ -21877,9 +23647,9 @@ "6391d912f8e5dd32bf4e3ab2 description": "Lightkeeper said he's ready to accept you in again. But the old flash drive doesn't work anymore, so you'll have to find a new one, reflash the transmitter, and give it to me. I'll update your transmitter properly.", "6391d912f8e5dd32bf4e3ab2 failMessageText": "", "6391d912f8e5dd32bf4e3ab2 successMessageText": "Hope all this mess doesn't happen again.", + "6391d9c5f8e5dd32bf4e3ab4": "Obtain the V3 Flash drive on Lighthouse", "6391dc3e744e45201147080b": "Reflash the Radio transmitter", "6391dc554ed9512be67647e1": "Hand over the flash drive", - "6391d9c5f8e5dd32bf4e3ab4": "Obtain the V3 Flash drive on Lighthouse", "63ab7189b4313a7bac606706": "Visit the Lighthouse building", "6391d912f8e5dd32bf4e3ab2 acceptPlayerMessage": "", "6391d912f8e5dd32bf4e3ab2 declinePlayerMessage": "", @@ -21888,9 +23658,9 @@ "6391d9144b15ca31f76bc323 description": "Lightkeeper said he's ready to accept you in again. But the old flash drive doesn't work anymore, so you'll have to find a new one, reflash the transmitter, and give it to me. I'll update your transmitter properly.", "6391d9144b15ca31f76bc323 failMessageText": "", "6391d9144b15ca31f76bc323 successMessageText": "Hope all this mess doesn't happen again.", + "6391d9cffa894f0a866afdea": "Obtain the V3 Flash drive on Lighthouse", "6391dd44e705511c8a4a1b80": "Reflash the Radio transmitter", "6391dd544b15ca31f76bc326": "Hand over the flash drive", - "6391d9cffa894f0a866afdea": "Obtain the V3 Flash drive on Lighthouse", "63ab6f711b5c95746621dd8a": "Visit the Lighthouse building", "6391d9144b15ca31f76bc323 acceptPlayerMessage": "", "6391d9144b15ca31f76bc323 declinePlayerMessage": "", @@ -22115,9 +23885,9 @@ "63a5cf262964a7488f5243ce description": "Greetings! Well, let's get it going, are you excited? The task is quite specific, we need to test the Russian toy for close combat, so that the conditions were the very real combat in urban environment. I have customers who don't believe in the effectiveness of this toy... Can you change their minds?", "63a5cf262964a7488f5243ce failMessageText": "", "63a5cf262964a7488f5243ce successMessageText": "Well? Does it work good? Suitable for close-quarters combat in urban environments?", - "63a5cf262964a7488f5243d1": "Eliminate PMC operatives while using an SR-2M with a suppressor and KP-SR2 sight on Streets of Tarkov", "63a5cf262964a7488f5243cf": "", "63a5cf262964a7488f5243d0": "", + "63a5cf262964a7488f5243d1": "Eliminate PMC operatives while using an SR-2M with a suppressor and KP-SR2 sight on Streets of Tarkov", "63a5cf262964a7488f5243ce acceptPlayerMessage": "", "63a5cf262964a7488f5243ce declinePlayerMessage": "", "63a5cf262964a7488f5243ce completePlayerMessage": "", @@ -22125,11 +23895,11 @@ "63a88045abf76d719f42d715 description": "Оh! Come on in, I've got a job for you! Listen, how long ago have you been in town? Well, I got a job for you. Run through the supermarkets, see if they've been looted. And do the old man a favor and look for the Salt Dog sausage or something like that. Mechanic kindly introduced it to me, and now I'm craving it. It's killing me!", "63a88045abf76d719f42d715 failMessageText": "", "63a88045abf76d719f42d715 successMessageText": "So, how's the situation out there? Nothing left? Bloody looters! But did you find the sausage? Haha, what a miracle! But what about the expiration date?", + "63a98cdf655ec5555b4aa9e6": "Hand over the found in raid Salty Dog beef sausage", "63a98cfbc31b00242d28a95b": "Scout the Shestyorochka store at Nikitskaya street", "63a98d24655ec5555b4aa9e7": "Scout the Sparja store at Primorsky ave", "63a98d39da7999196148ba3a": "Scout the Sparja store in Pinewood hotel", "63a98d60c0f61a5d8731cd9f": "Scout the Goshan store in Concordia", - "63a98cdf655ec5555b4aa9e6": "Hand over the found in raid Salty Dog beef sausage", "63a88045abf76d719f42d715 acceptPlayerMessage": "", "63a88045abf76d719f42d715 declinePlayerMessage": "", "63a88045abf76d719f42d715 completePlayerMessage": "", @@ -22208,9 +23978,9 @@ "647701ba386d446178434b35 description": "", "647701ba386d446178434b35 failMessageText": "", "647701ba386d446178434b35 successMessageText": "", - "64770ae612e67e6d99156c55": "", - "64770a5e748d6446740ef738": "", "64770523eed96526fe1bc0d9": "", + "64770a5e748d6446740ef738": "", + "64770ae612e67e6d99156c55": "", "647701ba386d446178434b35 acceptPlayerMessage": "", "647701ba386d446178434b35 declinePlayerMessage": "", "647701ba386d446178434b35 completePlayerMessage": "", @@ -22218,18 +23988,18 @@ "647710905320c660d91c15a5 description": "All right, mate, come in quick, got work to do. So listen up. Something really fishy's going on. Those big shots and foreign thugs are doing some kind of murky shit at night with some of the locals. I tried to investigate and maybe get my cut, but got fucked over. They didn't cut me in, those muts. Help a brother out, teach those bastards a lesson, show them who's the real deal in this town, so that it doesn't happen again.", "647710905320c660d91c15a5 failMessageText": "", "647710905320c660d91c15a5 successMessageText": "What hoods? What marks? What foreigners? Are you high or something? Why the fuck did you kill them?! Well, whatever, job's done, and that's that. Others will get the hint, I imagine.", - "64771f62a243be48547d6b98": "Locate and neutralize Priest", - "64771f2ded3a9d1ca43cbfe9": "Eliminate Rogues", - "64771ee4ed3a9d1ca43cbfe7": "Eliminate Raiders", - "64771eb49ff5e21611764717": "Locate and neutralize Tagilla", - "64771e7ded3a9d1ca43cbfe5": "Locate and neutralize Sanitar", - "64771d529ff5e21611764715": "Locate and neutralize Birdeye", - "64771cab5320c660d91c15ab": "Locate and neutralize Big Pipe", - "64771c884ae7f12905177ce9": "Locate and neutralize Knight", - "64771c555320c660d91c15a9": "Locate and neutralize Shturman", - "64771bca4ae7f12905177ce7": "Locate and neutralize Killa", - "647712e35320c660d91c15a7": "Locate and neutralize Glukhar", "647712cf4ae7f12905177ce5": "Locate and neutralize Reshala", + "647712e35320c660d91c15a7": "Locate and neutralize Glukhar", + "64771bca4ae7f12905177ce7": "Locate and neutralize Killa", + "64771c555320c660d91c15a9": "Locate and neutralize Shturman", + "64771c884ae7f12905177ce9": "Locate and neutralize Knight", + "64771cab5320c660d91c15ab": "Locate and neutralize Big Pipe", + "64771d529ff5e21611764715": "Locate and neutralize Birdeye", + "64771e7ded3a9d1ca43cbfe5": "Locate and neutralize Sanitar", + "64771eb49ff5e21611764717": "Locate and neutralize Tagilla", + "64771ee4ed3a9d1ca43cbfe7": "Eliminate Raiders", + "64771f2ded3a9d1ca43cbfe9": "Eliminate Rogues", + "64771f62a243be48547d6b98": "Locate and neutralize Priest", "647710905320c660d91c15a5 acceptPlayerMessage": "", "647710905320c660d91c15a5 declinePlayerMessage": "", "647710905320c660d91c15a5 completePlayerMessage": "", @@ -22246,12 +24016,12 @@ "649567f359eab30d1b7c9585 description": "Hello mercenary! Heard what happened at the Lighthouse? My sources tell me the local crime lords have had a big dispute with the Rogues, and they're looking all over the city and the outskirts for them. The task is to help these Rogues. Because disturbing the peace and order on my watch is forbidden. Understood?", "649567f359eab30d1b7c9585 failMessageText": "", "649567f359eab30d1b7c9585 successMessageText": "A job well done. The city may sleep safe now.", - "649569e81bb4d158bc4d0165": "Locate and neutralize Tagilla in a single raid", - "649569c15d1d966bd1060567": "Locate and neutralize Sanitar in a single raid", - "649568f159eab30d1b7c9588": "Locate and neutralize Shturman in a single raid", - "649568dc38fcd34cc8485927": "Locate and neutralize Killa in a single raid", - "649568377d39c528e1532716": "Locate and neutralize Glukhar in a single raid", "6495682b38fcd34cc8485925": "Locate and neutralize Reshala in a single raid", + "649568377d39c528e1532716": "Locate and neutralize Glukhar in a single raid", + "649568dc38fcd34cc8485927": "Locate and neutralize Killa in a single raid", + "649568f159eab30d1b7c9588": "Locate and neutralize Shturman in a single raid", + "649569c15d1d966bd1060567": "Locate and neutralize Sanitar in a single raid", + "649569e81bb4d158bc4d0165": "Locate and neutralize Tagilla in a single raid", "64956b888e277d6c87532da5": "Survive and extract from the location", "649567f359eab30d1b7c9585 acceptPlayerMessage": "", "649567f359eab30d1b7c9585 declinePlayerMessage": "", @@ -22326,26 +24096,26 @@ "64edbe9926cfa02c506f893f": "Locate and obtain clock dial painting #1", "64edbeae9878a0569d6ec747": "Hand over the painting", "64edce2d1a5f313cb144bf83": "Locate and obtain clock dial painting #2", - "64edce90403fc9681a4b7d5e": "Locate and obtain clock dial painting #3", - "64edcea1b63b74469b6c131a": "Locate and obtain clock dial painting #4", - "64edcebb496db64f9b7a442d": "Locate and obtain clock dial painting #5", - "64edcecd1a5f313cb144bf84": "Locate and obtain clock dial painting #6", - "64edcee01180874bb93e857e": "Locate and obtain clock dial painting #7", - "64edcf0039e45b527a7c3fed": "Locate and obtain clock dial painting #8", - "64edcf27bf4c727e9c7bdb94": "Locate and obtain clock dial painting #9", - "64edcf48b63b74469b6c131b": "Locate and obtain clock dial painting #10", - "64edcf5c496db64f9b7a442e": "Locate and obtain clock dial painting #11", - "64edcf711a5f313cb144bf85": "Locate and obtain clock dial painting #12", "64edce599878a0569d6ec749": "Hand over the painting", "64edce82496db64f9b7a442c": "Hand over the painting", + "64edce90403fc9681a4b7d5e": "Locate and obtain clock dial painting #3", + "64edcea1b63b74469b6c131a": "Locate and obtain clock dial painting #4", "64edceac67e11a7c6206dcd7": "Hand over the painting", + "64edcebb496db64f9b7a442d": "Locate and obtain clock dial painting #5", "64edcec4a2a5bb727b61c25e": "Hand over the painting", + "64edcecd1a5f313cb144bf84": "Locate and obtain clock dial painting #6", "64edced69878a0569d6ec74a": "Hand over the painting", + "64edcee01180874bb93e857e": "Locate and obtain clock dial painting #7", "64edcee7403fc9681a4b7d5f": "Hand over the painting", + "64edcf0039e45b527a7c3fed": "Locate and obtain clock dial painting #8", "64edcf0932bed22c3e0c741d": "Hand over the painting", + "64edcf27bf4c727e9c7bdb94": "Locate and obtain clock dial painting #9", "64edcf2f9a4f905106514fbe": "Hand over the painting", + "64edcf48b63b74469b6c131b": "Locate and obtain clock dial painting #10", "64edcf5067e11a7c6206dcd8": "Hand over the painting", + "64edcf5c496db64f9b7a442e": "Locate and obtain clock dial painting #11", "64edcf62a2a5bb727b61c25f": "Hand over the painting", + "64edcf711a5f313cb144bf85": "Locate and obtain clock dial painting #12", "64edcf7b496db64f9b7a442f": "Hand over the painting", "64edbb1317ab941a6f7cc247 acceptPlayerMessage": "", "64edbb1317ab941a6f7cc247 declinePlayerMessage": "", @@ -22376,12 +24146,12 @@ "64f1cc571a5f313cb144bf90 description": "My colleagues are asking for a favor, and strangely enough, they recommend you, mercenary. Apparently, I'm not the only one who's heard of your deeds. So here's the deal: you're going to eliminate the local leaders of all the primitive gangs that have set sails all over Tarkov. The details aren't important for you to know. As a reward, they say they'll leave a valuable souvenir for you. Now, go on, soldier. I'll be waiting for your return.", "64f1cc571a5f313cb144bf90 failMessageText": "", "64f1cc571a5f313cb144bf90 successMessageText": "Excellent. Now, your souvenir is waiting for you at Ragman's place, he's already received instructions from our friends.", - "64f1cc571a5f313cb144bf9b": "Locate and neutralize Tagilla", - "64f1cc571a5f313cb144bf99": "Locate and neutralize Sanitar", - "64f1cc571a5f313cb144bf97": "Locate and neutralize Shturman", - "64f1cc571a5f313cb144bf95": "Locate and neutralize Killa", - "64f1cc571a5f313cb144bf93": "Locate and neutralize Glukhar", "64f1cc571a5f313cb144bf91": "Locate and neutralize Reshala", + "64f1cc571a5f313cb144bf93": "Locate and neutralize Glukhar", + "64f1cc571a5f313cb144bf95": "Locate and neutralize Killa", + "64f1cc571a5f313cb144bf97": "Locate and neutralize Shturman", + "64f1cc571a5f313cb144bf99": "Locate and neutralize Sanitar", + "64f1cc571a5f313cb144bf9b": "Locate and neutralize Tagilla", "64f1cc571a5f313cb144bf9d": "Survive and extract from the location", "64f1cc571a5f313cb144bf90 acceptPlayerMessage": "", "64f1cc571a5f313cb144bf90 declinePlayerMessage": "", @@ -22408,8 +24178,8 @@ "64f5aac4b63b74469b6c14c2 description": "No, I don't believe Oleg's gone. So we keep looking. The last time we were in touch, he said he got a new job, eyes sparkling. But then we were distracted by another topic, and being drunk didn't help... Anyway, I don't know where he got a job, but if he was so excited, it must have had something to do with everything Soviet. That's what we'll be looking for. Find this place and search it clean. I don't want to lose my comrade.", "64f5aac4b63b74469b6c14c2 failMessageText": "", "64f5aac4b63b74469b6c14c2 successMessageText": "No sign of Oleg again? Oh, the journal, huh? We'll look into it. Thank you, soldier.", - "64f5aac4b63b74469b6c14c9": "Survive and extract from the location", "64f5aac4b63b74469b6c14c7": "Locate the place of work of Prapor's friend on Streets of Tarkov", + "64f5aac4b63b74469b6c14c9": "Survive and extract from the location", "64f5b876a2a5bb727b61c5ad": "Obtain any information on the fate of Prapor's friend", "64f5bbc967e11a7c6206e00e": "Hand over the found data", "64f5aac4b63b74469b6c14c2 acceptPlayerMessage": "", @@ -22479,8 +24249,8 @@ "655e427b64d09b4122018228 description": "You're finally in touch, mercenary. I was just approached by a man who calls himself a Master. He asked to find you, because from his words you understand the essence of the matter and deserve Their respect.\nThe master asked me to tell you that there is a new job for you. It is necessary to eliminate experienced colleagues throughout Tarkov. I will give you the necessary equipment to complete the task.\nLet me be honest with you, my friend. I do not approve Master's methods, but the benefits offered are very attractive. I can't tell you everything, but I can give you some advice: special times are coming, save your ammunition if you want to survive. Our work with you is very productive, and I would not like you to die in this massacre.", "655e427b64d09b4122018228 failMessageText": "", "655e427b64d09b4122018228 successMessageText": "Well, you completed the task, mercenary. The master has prepared an appropriate reward for you. Wait for a message, it seems that he is ready to offer a job in, so to speak, a specific place.", - "655e49e942913d55e050376b": " Hand over level 25+ dogtags", "655e483da3ee7d4c56241e17": "Eliminate PMC operatives", + "655e49e942913d55e050376b": " Hand over level 25+ dogtags", "655e427b64d09b4122018228 acceptPlayerMessage": "", "655e427b64d09b4122018228 declinePlayerMessage": "", "655e427b64d09b4122018228 completePlayerMessage": "", @@ -22536,9 +24306,9 @@ "657315e1dccd301f1301416a description": "Hey! You did well on the first job, but it's not enough to make me happy. You're gonna have to do a little more legwork, soldier. \n\nI need to find a bottle of wine. I myself am more of a hard drinker, but I know a man who collects wine. And not just any kind, but the rarest kind! I want to give him a bottle as a gesture of goodwill. Nowadays in Tarkov, any connections with reputable people are worth their weight in gold, you know?\n\nThere was a liquor store in the city center. They used to sell booze three times the price, for the elite folks. I'm sure there's some left. Go there and search the place and get me a good bottle of some French wine! And don't even try to slip me some fake shit.", "657315e1dccd301f1301416a failMessageText": "You've become too experienced for this kind of job, warrior. We'll leave the fetch tasks to the greens.", "657315e1dccd301f1301416a successMessageText": "O-ho, that's a beautiful bottle! The man is gonna love it. Here's your reward, well deserved.", + "6575aa67197bd678a0c3f552": "Locate the liquor store on Ground Zero", "65817cabba2ba6ef71fc72ca": "Locate and obtain the wine bottle in the store", "65817cd2881a7e07b3ec1249": "Hand over the wine bottle", - "6575aa67197bd678a0c3f552": "Locate the liquor store on Ground Zero", "657315e1dccd301f1301416a acceptPlayerMessage": "", "657315e1dccd301f1301416a declinePlayerMessage": "", "657315e1dccd301f1301416a completePlayerMessage": "", @@ -22554,11 +24324,11 @@ "657315e4a6af4ab4b50f3459 description": "Hello, mercenary. I'm Mechanic. I was told you wanted to meet me. We could arrange that, but there's a matter to be settled first.\n\nTerraGroup sent a USEC task force after one of their employees. He was accused of leaking information and they wanted him removed. I don't know if they succeeded or not, which is why you need to investigate this. Check the TerraGroup complex in the city center, look for traces of both the squad and the employee. I used to work with him, so I'm interested in what eventually happened. He almost always carried a drive with his important data on it, so if you find it, bring it to me.", "657315e4a6af4ab4b50f3459 failMessageText": "I'm canceling the task. You obviously need something more substantial than that.", "657315e4a6af4ab4b50f3459 successMessageText": "They killed him? Well, that's sad, but expected. TerraGroup was desperate to cover their tracks. You've done a good job, I think we can continue this partnership. And thanks for the data drive.", - "65817fbbb454159976c91917": "Locate and obtain the scientist's hard drive", - "65817fc99a039ed2e97896e4": "Hand over the hard drive", "6575a524a39d2be74e620546": "Locate the USEC PMC group at the parking lot of the TerraGroup complex on Ground Zero", "6575a62a62028c6d5cb43cb7": "Locate the lab scientist on Ground Zero", "6575a64d3fc09bdfb38b713d": "Access the scientist's office", + "65817fbbb454159976c91917": "Locate and obtain the scientist's hard drive", + "65817fc99a039ed2e97896e4": "Hand over the hard drive", "657315e4a6af4ab4b50f3459 acceptPlayerMessage": "", "657315e4a6af4ab4b50f3459 declinePlayerMessage": "", "657315e4a6af4ab4b50f3459 completePlayerMessage": "", @@ -22643,8 +24413,8 @@ "6578eb36e5020875d64645cd description": "Come on in, have a seat. I need to talk to you.\n\nWe need to keep cleaning up Tarkov. Next up is an ex-cop named Kollontay. He's been nothing but trouble in peacetime, and he's even more so now. Find him and deal with him. They say he's holed up at the MVD academy in the city.", "6578eb36e5020875d64645cd failMessageText": "", "6578eb36e5020875d64645cd successMessageText": "Is it done? That's good to hear. A little less filth in our city. Here's your reward.", - "6580130847df99b0741919f0": "Eliminate Kollontay's guards", "6578eb36e5020875d64645d0": "Locate and neutralize Kollontay", + "6580130847df99b0741919f0": "Eliminate Kollontay's guards", "6582b05dc992d6dcc0a40c75": "Hand over the found in raid Kollontay's police baton", "6578eb36e5020875d64645cd acceptPlayerMessage": "", "6578eb36e5020875d64645cd declinePlayerMessage": "", @@ -22709,11 +24479,11 @@ "660411197eb22f375205b649 description": "Hello, friend. You got the flash drive? Good. You don't have to tell me what to do. Skier already sent his goons over. I told them it was gonna be a problem, but they obviously didn't follow. Decryption doesn't just happen by itself. It takes equipment, and that equipment takes power. I've got the main hardware, but I need more parts. Bring them, please. I'll give you a list.", "660411197eb22f375205b649 failMessageText": "", "660411197eb22f375205b649 successMessageText": "Wow, nice pieces. That should be enough power now. I'll contact you when the flash drive's ready for pickup.", - "660c3a3b74ce823ff63adf61": "Hand over the encrypted flash drive", "660411197eb22f375205b64c": "Find PC CPU in raid", "660411197eb22f375205b64d": "Hand over the CPUs", "660411dfff338cb1fdd8ffee": "Find RAM in raid", "660411ec9827739137229db8": "Hand over the RAM", + "660c3a3b74ce823ff63adf61": "Hand over the encrypted flash drive", "660ebbdd1aebb7c23de8aed6": "Find SSD drive in raid", "660ebbed8e61ec0d3590fd69": "Hand over the SSD", "660411197eb22f375205b649 acceptPlayerMessage": "", @@ -22723,8 +24493,8 @@ "6604128c0e8e4148260fde55 description": "Hi. I realize time is tight, but I'm having trouble with this flash drive. I'm gonna need some tools. You can't just find them in Tarkov, you have to know certain people. One of them needs a military gyrotachometer, so we'll barter. Take it and plant it on the Reserve base at the radar station, inside the dome. The sooner you do it, the better. ", "6604128c0e8e4148260fde55 failMessageText": "", "6604128c0e8e4148260fde55 successMessageText": "That was fast. Thank you. Here, this is for your help.", - "660bf9b67af98c04f78d944d": "Launch a signal flare at the roof of the radar station on Reserve", "660422dc628231b3f69f1570": "Stash a Military gyrotachometer at the designated place on Reserve", + "660bf9b67af98c04f78d944d": "Launch a signal flare at the roof of the radar station on Reserve", "6604128c0e8e4148260fde55 acceptPlayerMessage": "", "6604128c0e8e4148260fde55 declinePlayerMessage": "", "6604128c0e8e4148260fde55 completePlayerMessage": "", @@ -22872,8 +24642,8 @@ "66058cc208308761cf390993 description": "You're under my wing from now on, brother. I'll make sure you get progress good, but you're gonna have to get your ass in gear more often.\n\nLet's start with the basics. The Arena's in Tarkov, but the biggest sponsors are overseas. They watch every game, place bets, throw money at the favorites. And you need to get some of those big shots interested. Get their attention, show them you're worthy. Make a name for yourself. One win alone isn't enough to do it. Show them you can make a thrilling performance!", "66058cc208308761cf390993 failMessageText": "", "66058cc208308761cf390993 successMessageText": "I see the progress you're making! They're starting to talk about you overseas. People are interested. It's a sign that you're doing the right thing!", + "662ba78e19c86d3199ae0a93": "Win a match in ranked mode in Arena", "662ba7b942dc438835a2760d": "Reach 1700 ARP rating", - "662ba78e19c86d3199ae0a93": "Win a match in ranked TeamFight mode in Arena", "66058cc208308761cf390993 acceptPlayerMessage": "", "66058cc208308761cf390993 declinePlayerMessage": "", "66058cc208308761cf390993 completePlayerMessage": "", @@ -22889,9 +24659,9 @@ "66058cc72cee99303f1ba069 description": "How's the mood? Battle-ready? Ready to shine in the Arena once more? Ready to shred some motherfuckers? The odds are still stacked against you, so don't let the audience down!\n\nSpeaking of that. You got some money? You gotta bet on yourself and then win six times. You'll make tons of cash, and you'll be famous. Bring the money, I'll organize everything. Just be warned: if you lose five times, you start again.", "66058cc72cee99303f1ba069 failMessageText": "Oh man, you almost did it. Try again, the audience still seems to favor you.", "66058cc72cee99303f1ba069 successMessageText": "Here's your paycheck. I deducted all my services from it straight away: bribing opponents, fees, and all that. What, you thought I work for free?", - "6633a85e347a2a2b4051a26b": "Hand over Roubles from the EFT balance", - "662bb23200ae352a6d5a415d": "Win 6 matches out of 10 in ranked TeamFight mode in Arena", + "662bb23200ae352a6d5a415d": "Win 6 matches out of 10 in ranked mode in Arena", "662bb24b3d34cd5e19206e63": "Failure condition: Lose 5 matches", + "6633a85e347a2a2b4051a26b": "Hand over Roubles from the EFT balance", "665490bf7177a91368ff628a": "", "665493a649bd17856482ba77": "Failure Condition: Lose 5 matches", "66058cc72cee99303f1ba069 acceptPlayerMessage": "", @@ -23059,8 +24829,8 @@ "660ab96ef50cbdad7906e080 description": "You want to earn my trust? Did you figure out who's unhappy with Skier, or did you just point your finger at the sky? Doesn't matter. Sell weapons to Skier so he can understand that he's forgiven. And get me the cell phone that his men were stashing at the dorms. Let's find out what so many people died for.", "660ab96ef50cbdad7906e080 failMessageText": "", "660ab96ef50cbdad7906e080 successMessageText": "The phone is a fake. Someone really wanted Skier and his men focused on it. Looks like the game has a new player. We'll look into it.", - "660ac159205fdc5a2afb1665": "Locate and obtain The Unheard's phone on Customs", "660ab9c4fcef83ea40e29efe": "Hand over the phone", + "660ac159205fdc5a2afb1665": "Locate and obtain The Unheard's phone on Customs", "663b3c931a6c808fd4041d0c": "", "663b6f2e01248a081e0a6c6c": "Sell any weapon to Skier", "660ab96ef50cbdad7906e080 acceptPlayerMessage": "", @@ -23164,8 +24934,8 @@ "660ad1902392822f6e0dc0bd description": "So you're here to earn my trust? You're beginning to understand Tarkov. That's commendable.\n\nSell our foreign friend some weapons. That way he'll realize that the sanctions have been lifted and he's made amends. Then bring me the laptop that his men have left at the Health Resort, and I'll look into what he was after.", "660ad1902392822f6e0dc0bd failMessageText": "", "660ad1902392822f6e0dc0bd successMessageText": "This laptop is a fake. Someone made this whole story up on purpose. I'd say Peacekeeper should think about who might have set him up, but I think the whole of Tarkov was the target.", - "660ad1902392822f6e0dc0c0": "Hand over the laptop", "660ad1902392822f6e0dc0bf": "Locate and obtain The Unheard's laptop on Shoreline", + "660ad1902392822f6e0dc0c0": "Hand over the laptop", "663b6e8c53b8fd3ae8652d21": "Sell any weapon to Peacekeeper", "660ad1902392822f6e0dc0bd acceptPlayerMessage": "", "660ad1902392822f6e0dc0bd declinePlayerMessage": "", @@ -23236,9 +25006,9 @@ "6616a9fdfd94e03533038da8 description": "Hey! Got an update on that locked room. Rumor has it the ex-USECs have been seen around there for a while. Maybe they know how to open the doors. The other question is, what happened to whoever was inside? Either they escaped or they are already dead. We should find out. See if you can find anything interesting there while you're at it.", "6616a9fdfd94e03533038da8 failMessageText": "", "6616a9fdfd94e03533038da8 successMessageText": "So it's empty inside. That's good: if there are no bodies, chances are the refugees are alive. You know about the superposition principle, right?\nAll right, back to the point. I looked through the drive. There was a password [bmV3ZGF3bi4u] with \"important\" written on it. I think you can figure it out.", - "662687519751e32101a0a744": "", "6616a9fdfd94e03533038dab": "Locate and obtain the hard drive inside the cottage hideout on Lighthouse", "6616a9fdfd94e03533038dac": "Hand over the hard drive", + "662687519751e32101a0a744": "", "663b763025d88834a5bb15fc": "Locate and obtain the hard drive inside the cottage hideout on Lighthouse", "6616a9fdfd94e03533038da8 acceptPlayerMessage": "", "6616a9fdfd94e03533038da8 declinePlayerMessage": "", @@ -23277,12 +25047,12 @@ "66588c0c98194a5d26010197 description": "Hello mercenary! Heard what happened at the Lighthouse? My sources tell me the local crime lords have had a big dispute with the Rogues, and they're looking all over the city and the outskirts for them. The task is to help these Rogues. Because disturbing the peace and order on my watch is forbidden. Understood?", "66588c0c98194a5d26010197 failMessageText": "", "66588c0c98194a5d26010197 successMessageText": "A job well done. The city may sleep safe now.", - "66588c0c98194a5d260101a2": "Locate and neutralize Tagilla in a single raid", - "66588c0c98194a5d260101a0": "Locate and neutralize Sanitar in a single raid", - "66588c0c98194a5d2601019e": "Locate and neutralize Shturman in a single raid", - "66588c0c98194a5d2601019c": "Locate and neutralize Killa in a single raid", - "66588c0c98194a5d2601019a": "Locate and neutralize Glukhar in a single raid", "66588c0c98194a5d26010198": "Locate and neutralize Reshala in a single raid", + "66588c0c98194a5d2601019a": "Locate and neutralize Glukhar in a single raid", + "66588c0c98194a5d2601019c": "Locate and neutralize Killa in a single raid", + "66588c0c98194a5d2601019e": "Locate and neutralize Shturman in a single raid", + "66588c0c98194a5d260101a0": "Locate and neutralize Sanitar in a single raid", + "66588c0c98194a5d260101a2": "Locate and neutralize Tagilla in a single raid", "66588c0c98194a5d260101a4": "Survive and extract from the location", "66588c0c98194a5d26010197 acceptPlayerMessage": "", "66588c0c98194a5d26010197 declinePlayerMessage": "", @@ -23291,147 +25061,1232 @@ "6658a15615cbb1b2c6014d5b description": "Come on in, kid. Heard the news yet?\n\nLooks like all manner of folk are paying social calls to that health resort now. Everybody wants a piece of action. The dimwits spooked them off of there. My hounds are telling me that they saw that group of misfits moving towards old reserve base. So now you gotta hurry there. Who knows when will this window of opportunity close.", "6658a15615cbb1b2c6014d5b failMessageText": "", "6658a15615cbb1b2c6014d5b successMessageText": "Did you chop off all the heads of the hydra in one fell swoop? They did a good job on gathering like that, no doubt about it. Tarkov will be forever grateful to you.\nAnd I keep my word: here is the promised reward.", - "6658a15615cbb1b2c6014d72": "Locate and neutralize Priest", - "6658a15615cbb1b2c6014d70": "Eliminate Rogues", - "6658a15615cbb1b2c6014d6e": "Eliminate Raiders", - "6658a15615cbb1b2c6014d6c": "Locate and neutralize Tagilla on Reserve", - "6658a15615cbb1b2c6014d6a": "Locate and neutralize Sanitar on Reserve", - "6658a15615cbb1b2c6014d68": "Locate and neutralize Birdeye on Reserve", - "6658a15615cbb1b2c6014d66": "Locate and neutralize Big Pipe on Reserve", - "6658a15615cbb1b2c6014d64": "Locate and neutralize Knight on Reserve", - "6658a15615cbb1b2c6014d62": "Locate and neutralize Shturman on Reserve", - "6658a15615cbb1b2c6014d60": "Locate and neutralize Killa on Reserve", - "6658a15615cbb1b2c6014d5e": "Locate and neutralize Glukhar on Reserve", "6658a15615cbb1b2c6014d5c": "Locate and neutralize Reshala on Reserve", + "6658a15615cbb1b2c6014d5e": "Locate and neutralize Glukhar on Reserve", + "6658a15615cbb1b2c6014d60": "Locate and neutralize Killa on Reserve", + "6658a15615cbb1b2c6014d62": "Locate and neutralize Shturman on Reserve", + "6658a15615cbb1b2c6014d64": "Locate and neutralize Knight on Reserve", + "6658a15615cbb1b2c6014d66": "Locate and neutralize Big Pipe on Reserve", + "6658a15615cbb1b2c6014d68": "Locate and neutralize Birdeye on Reserve", + "6658a15615cbb1b2c6014d6a": "Locate and neutralize Sanitar on Reserve", + "6658a15615cbb1b2c6014d6c": "Locate and neutralize Tagilla on Reserve", + "6658a15615cbb1b2c6014d6e": "Eliminate Raiders", + "6658a15615cbb1b2c6014d70": "Eliminate Rogues", + "6658a15615cbb1b2c6014d72": "Locate and neutralize Priest", "6658a220a4dc74f102c355ce": "Locate and neutralize Kaban on Reserve", "6658a2387aed962d75700786": "Locate and neutralize Kollontay on Reserve", "6658a15615cbb1b2c6014d5b acceptPlayerMessage": "", "6658a15615cbb1b2c6014d5b declinePlayerMessage": "", "6658a15615cbb1b2c6014d5b completePlayerMessage": "", + "665eeacf5d86b6c8aa03c79b name": "Thirsty - Hounds", + "665eeacf5d86b6c8aa03c79b description": "We need to talk. Sanitar's goons have been prowling the shore area at nights. Obviously looking for something. Can't let it go unchecked. Scare them off while I try to find out what they're up to.", + "665eeacf5d86b6c8aa03c79b failMessageText": "", + "665eeacf5d86b6c8aa03c79b successMessageText": "You fought them off? Excellent! I found out they're looking for Thirsty's hideout. He was the guy who used to always bring a double supply of water with him. I haven't seen him in a while, right after he mixed up with Skier. I guess it led to a bad end for him.", + "665eed28bdbf7b1f92394ecb": "Eliminate Scavs in the time period of 22:00-07:00 on Shoreline", + "665eeacf5d86b6c8aa03c79b acceptPlayerMessage": "", + "665eeacf5d86b6c8aa03c79b declinePlayerMessage": "", + "665eeacf5d86b6c8aa03c79b completePlayerMessage": "", + "665eec1f5e47a79f8605565a name": "Thirsty - Breadwinner", + "665eec1f5e47a79f8605565a description": "The Thirsty dude? You too?! Why are you all bringing him up all of a sudden?\n\nYeah, I worked with this guy. Сouldn't last five minutes without a drink. We made some good money with him back then. Always brought good loot, that guy. My respect to him. But he's been out of the game for a long time, at least in Tarkov.\n\nI can give you a tip on where he dumped his extra supplies, but not for free. I'm looking for two tanks of propane right now. Why don't you find it for me, and then we'll talk about your guy?", + "665eec1f5e47a79f8605565a failMessageText": "", + "665eec1f5e47a79f8605565a successMessageText": "You got it? That's a good start. Now we can talk about Thirsty.", + "665ef4d93bd11acd294ac48c": "Find Propane tanks (5L) in raid", + "665ef4f08f3a505364a8ab09": "Hand over the items", + "665eec1f5e47a79f8605565a acceptPlayerMessage": "", + "665eec1f5e47a79f8605565a declinePlayerMessage": "", + "665eec1f5e47a79f8605565a completePlayerMessage": "", + "665eec4a4dfc83b0ed0a9dca name": "Thirsty - Delivery", + "665eec4a4dfc83b0ed0a9dca description": "So, I keep my word. Before you, Sanitar was sniffing around that guy, too. But his business proposition was shite, so I didn't tell him anything. I'll tell you, but a bit later.\n\nHere are some nice propane tanks for you. Yeah, the ones you brought. Now you have to stash them. One in the nature reserve, in the Scav bunker with the radio tower. The other at the Customs area, in the little store by the crossroads. Just make sure to not shoot the tanks, okay? If you finish the job, you'll get more info.", + "665eec4a4dfc83b0ed0a9dca failMessageText": "", + "665eec4a4dfc83b0ed0a9dca successMessageText": "You done? Very well. I'll give you a bonus for not bitching about the job. So, anyway, Thirsty used to hang around in the west wing of the Health Resort, in the basement. That was a long time ago, before the junkies got there. We cleaned that place out a long time ago, but maybe there's something left, I don't know. Check it out for yourself.", + "666057c94381b34642e07f09": "Найти место закладки на локации Лес", + "6660594cff21054286135d35": "Заложить Балон пропана (5л)", + "66605b4a933179c4e3393fd5": "Найти место закладки балона на локации Таможня", + "66605b6f46d32cc9188e07aa": "Заложить Балон пропана (5л)", + "6661a14545909ae2e92ca2d5": "Locate the specified stash spot on Woods", + "6661a170945719c63f28d9c6": "Stash the first Propane tank (5L)", + "6661a18a12e8457716d59f5d": "Locate the specified stash spot on Customs", + "6661a1a1b1953d6c96da8f0e": "Stash the second Propane tank (5L)", + "665eec4a4dfc83b0ed0a9dca acceptPlayerMessage": "", + "665eec4a4dfc83b0ed0a9dca declinePlayerMessage": "", + "665eec4a4dfc83b0ed0a9dca completePlayerMessage": "", + "665eeca45d86b6c8aa03c79d name": "Thirsty - Echo", + "665eeca45d86b6c8aa03c79d description": "Thank you for reaching out. I know you're investigating a certain person called Thirsty. Sanitar is investigating him as well, for a specific reason. He's always hunting for any information on TerraGroup's activities. Surely it's all connected.\n\nIf you can intercept the data first, bring it to me, I'll pay you handsomely. Besides, in my hands, it won't cause another disaster.", + "665eeca45d86b6c8aa03c79d failMessageText": "", + "665eeca45d86b6c8aa03c79d successMessageText": "Just a diary, nothing but that? Well, it could still prove valuable... That handwriting is terrible! It'll take a while to read it. Here's your reward.", + "6660785fc37356435d193ae4": "Locate any information about Thirsty on Shoreline", + "66607896f2ea02201517c203": "Obtain the information in Thirsty's hideout", + "666078bee6ed30ab2294f593": "Hand over the found information", + "665eeca45d86b6c8aa03c79d acceptPlayerMessage": "", + "665eeca45d86b6c8aa03c79d declinePlayerMessage": "", + "665eeca45d86b6c8aa03c79d completePlayerMessage": "", + "665eeca92f7aedcc900b0437 name": "Thirsty - Secrets", + "665eeca92f7aedcc900b0437 description": "Hello again. I was able to extract some scraps of information about a certain drug from the diary you brought. The owner of the diary used it frequently. It's some sort of combat stimulant, I think you might be interested in it.\n\nI can provide you with samples if you help me reproduce and test it. Here's a list of the items you'll need.", + "665eeca92f7aedcc900b0437 failMessageText": "", + "665eeca92f7aedcc900b0437 successMessageText": "I was sure you'd be interested in this! Here are the results of the work.", + "6661a28be2cdba6a469447c7": "Hand over the found in raid item: Adrenaline injector", + "6661a2ae387c59056c822add": "Hand over the found in raid item: Bottle of OLOLO Multivitamins", + "6661a2bf4846fd2b6ba30f90": "Hand over the found in raid item: Bottle of saline solution", + "665eeca92f7aedcc900b0437 acceptPlayerMessage": "", + "665eeca92f7aedcc900b0437 declinePlayerMessage": "", + "665eeca92f7aedcc900b0437 completePlayerMessage": "", + "66631489acf8442f8b05319f name": "Friend Among Strangers", + "66631489acf8442f8b05319f description": "You've made a name for yourself, and I may have an assignment for someone like you. But before I do, I want to make sure you can tell who's an asset and who's a threat. It's simple, shoot the PMCs, but don't hurt my people. Understood?", + "66631489acf8442f8b05319f failMessageText": "Doesn't seem like you're trying to keep my people safe. Turns out you're more of a liability than a benefit. If you want to work with me, you have to prove your worth.", + "66631489acf8442f8b05319f successMessageText": "Here's your reward.", + "6667193a41b0135d2df10fd9": "Eliminate PMC operatives without killing Scavs", + "66631489acf8442f8b05319f acceptPlayerMessage": "", + "66631489acf8442f8b05319f declinePlayerMessage": "", + "66631489acf8442f8b05319f completePlayerMessage": "", + "6663148ca9290f9e0806cca1 name": "Immunity", + "6663148ca9290f9e0806cca1 description": "Well, you've proven you won't shoot indiscriminately. Recently, one of my men was poisoned on a mission and didn't even make it to the extraction point. We couldn't figure out what toxin caused his death. The guy went on a scouting trip to the white chalk circles. I need a more fresh sample and a tough employee who can survive the poisoning and make it back from the raid.", + "6663148ca9290f9e0806cca1 failMessageText": "", + "6663148ca9290f9e0806cca1 successMessageText": "You survived the poisoning? Now I'll try to get some information from your blood samples and get in touch with the right people. Either way, you've already earned your reward.", + "666719fc7c5ae40e6adcf43e": "Extract from the location with the \"Unknown toxin\" status effect", + "6663148ca9290f9e0806cca1 acceptPlayerMessage": "", + "6663148ca9290f9e0806cca1 declinePlayerMessage": "", + "6663148ca9290f9e0806cca1 completePlayerMessage": "", + "6663148ed7f171c4c20226c1 name": "Small Business - Part 1", + "6663148ed7f171c4c20226c1 description": "Hello. I have an errand for you. One of our people decided he could use my distribution lines on his own. It looks like our \"entrepreneur\" is marketing to cultists with souvenir figurines. Find them and bring them back, and I'll examine their insides.", + "6663148ed7f171c4c20226c1 failMessageText": "", + "6663148ed7f171c4c20226c1 successMessageText": "Thanks. My suspicions have been confirmed. I hope you understand this job is not to be talked about.", + "666729738d4b7a9182ad4a89": "Find a Ded Moroz figurine in raid", + "66672a1a928cfea6db3ff6cb": "Hand over the item", + "66672a99bf7a7a1fcee35af0": "Find a Politician Mutkevich figurine in raid", + "66672a9e351098ce6dee9d3e": "Hand over the item", + "66672b010cf940754acb3a83": "Find a Killa figurine in raid", + "66672b18eba38faad31d29c3": "Hand over the item", + "66672b3330d5ad1d58cc1e95": "Find a Reshala figurine in raid", + "66672b47d515c72d9075fe64": "Hand over the item", + "66672b7dd70d15a60bb41e04": "Find a Ryzhy figurine in raid", + "66672b88a8236f9caf29c39e": "Hand over the item", + "6667306ec19fb654f22fa05a": "Find a Scav figurine in raid", + "6667308a456e86f33c87437c": "Hand over the item", + "666730b475bbbbfd5049b7da": "Find a Tagilla figurine in raid", + "666730d6386cf75012a431f2": "Hand over the item", + "666730f88db8c7927a859959": "Find a Cultist figurine in raid", + "6667310584936a1238607d39": "Hand over the item", + "66673136b23cfc3ecab865d6": "Find a Den figurine in raid", + "6667314ae24cc783e69ad784": "Hand over the item", + "6663148ed7f171c4c20226c1 acceptPlayerMessage": "", + "6663148ed7f171c4c20226c1 declinePlayerMessage": "", + "6663148ed7f171c4c20226c1 completePlayerMessage": "", + "6663149196a9349baa021baa name": "Small Business - Part 2", + "6663149196a9349baa021baa description": "You remember my \"entrepreneur\"? I found him, he's one of the local gang bosses. Who? You don't need to know that. Your job is to go to each of them and remind them that my trade routes are mine alone. Don't touch the chiefs themselves, they're more useful alive. But their guards should be cut down for a clear show of force.", + "6663149196a9349baa021baa failMessageText": "I told you not to touch the bosses themselves! I need to intimidate them, not take them out.", + "6663149196a9349baa021baa successMessageText": "Done? Good, now everyone will think twice before getting into my sales network.", + "666732298477f79f3f6ea229": "Eliminate any Scav Boss guards without killing the Bosses", + "6663149196a9349baa021baa acceptPlayerMessage": "", + "6663149196a9349baa021baa declinePlayerMessage": "", + "6663149196a9349baa021baa completePlayerMessage": "", + "66631493312343839d032d22 name": "Small Business - Part 3", + "66631493312343839d032d22 description": "The \"entrepreneur\" was dealt with, but there are still people in town who bought my product bypassing me. Remember the toxin cultists? That's them. Leave the fanatics a message from me. Let them know there's only one Fence in this city. You do that, and I'll make sure you receive something special.", + "66631493312343839d032d22 failMessageText": "", + "66631493312343839d032d22 successMessageText": "You found all their circles? After a job like that, you've definitely proven you can be trusted. Here you go.", + "666733e0c62a5c652f3c4b45": "Stash a Cultist knife at the sunken village marked circle on Shoreline", + "666733e3f2c2969cf600991b": "Stash a Cultist knife at the Health Resort east wing marked circle on Shoreline", + "666733e565831d5bafa18bbb": "Stash a Cultist knife at the river village marked circle on Woods", + "666733e7430c8972d6a5f438": "Stash a Cultist knife at the sawmill marked circle on Woods", + "66631493312343839d032d22 acceptPlayerMessage": "", + "66631493312343839d032d22 declinePlayerMessage": "", + "66631493312343839d032d22 completePlayerMessage": "", + "6663149cfd5ca9577902e037 name": "The Invisible Hand", + "6663149cfd5ca9577902e037 description": "Hey, bro. My friendly competitors are poaching my customers. If they want to declare a trade war on me, then my answer has to be very serious. I found out how they transport their goods. They hire guys with big backpacks. Take care of those mules, will you?", + "6663149cfd5ca9577902e037 failMessageText": "", + "6663149cfd5ca9577902e037 successMessageText": "Sick! That's how trade issues should always be dealt with.", + "66696cd3997231debad40d19": "Eliminate any target that is using a 20+ container size backpack", + "6663149cfd5ca9577902e037 acceptPlayerMessage": "", + "6663149cfd5ca9577902e037 declinePlayerMessage": "", + "6663149cfd5ca9577902e037 completePlayerMessage": "", + "6663149f1d3ec95634095e75 name": "Circulate", + "6663149f1d3ec95634095e75 description": "You really gave me a hand with those mules back then. Now everything seems to be ready for retail, but there's not enough momentum to revitalize our economy. Let's show this town how to market!", + "6663149f1d3ec95634095e75 failMessageText": "", + "6663149f1d3ec95634095e75 successMessageText": "Now that's more like it! Thank you, brother.", + "666973ee1d80fbbbfeaf46c9": "Sell Ragman any backpacks or tactical rigs", + "6663149f1d3ec95634095e75 acceptPlayerMessage": "", + "6663149f1d3ec95634095e75 declinePlayerMessage": "", + "6663149f1d3ec95634095e75 completePlayerMessage": "", + "666314a1920800278d0f6746 name": "Special Offer", + "666314a1920800278d0f6746 description": "Got another job for you, brother! I see the demand for backpacks, can't lose profit now. I've only got basic backpacks, so I need to bring in some exclusive items. That'll bring in more customers. You know what I mean, right? If you get some really rare rigs and backpacks, I'll be in your debt!", + "666314a1920800278d0f6746 failMessageText": "", + "666314a1920800278d0f6746 successMessageText": "You know what? These thingies are so good I'm gonna measure them and produce them myself. They're gonna sell out instantly!", + "666976536518781b9feb2f28": "Find Sanitar's bag in raid", + "6669766290442b8d8e0688b3": "Hand over the equipment", + "6669769ff0cb253ff7649f27": "Find the Crye Precision AVS plate carrier (Tagilla Edition) in raid", + "666976ab1a6ef5fa7b813883": "Hand over the equipment", + "6669773b93557c1520f725dc": "", + "66697748053e5fe6051b1680": "", + "66697774640ec1284ed1621f": "Find the LBT-1961A Load Bearing Chest Rig (Goons Edition) in raid", + "666977849154974010adb5ec": "Hand over the equipment", + "666977bfe975ac480a8f914e": "Find the Mystery Ranch NICE COMM 3 BVS frame system (Coyote) in raid", + "666977ca5fa54985173f8e2c": "Hand over the equipment", + "666977f2dd6e511e9f33005a": "Find the Crye Precision CPC plate carrier (Goons Edition) in raid", + "666978023255d2720cbdf76d": "Hand over the equipment", + "6669785411eddc83c3374c7b": "", + "6669786105acfed6df00b46a": "", + "666314a1920800278d0f6746 acceptPlayerMessage": "", + "666314a1920800278d0f6746 declinePlayerMessage": "", + "666314a1920800278d0f6746 completePlayerMessage": "", + "666314a31cd52e3d040a2e76 name": "Combat Proven", + "666314a31cd52e3d040a2e76 description": "Look what my guys made! The rigs look like a perfect match, but they still need to be tested. If you can beat the local hotshots with them, then it's a good product.", + "666314a31cd52e3d040a2e76 failMessageText": "", + "666314a31cd52e3d040a2e76 successMessageText": "So, how was it? No stiffness, no tearing? Then maybe I can increase the price a bit... Oh, right, here's your reward, you're a life saver!", + "6669abb8dac5788ebd0ff74a": "Locate and neutralize any Boss (excluding The Goons and Partisan) while using any Goons Edition tactical rig", + "666314a31cd52e3d040a2e76 acceptPlayerMessage": "", + "666314a31cd52e3d040a2e76 declinePlayerMessage": "", + "666314a31cd52e3d040a2e76 completePlayerMessage": "", + "666314a50aa5c7436c00908a name": "Old Patterns", + "666314a50aa5c7436c00908a description": "We did a great work together with the new gear line! Just like back in the old days when business was booming and cash was rolling in. By the way, I got an idea for a special cut to make pants pockets bigger. You want me to try it out on yours? Then you'll have to pay for them. The patterns are pretty old and expensive. You can't do that from memory!", + "666314a50aa5c7436c00908a failMessageText": "", + "666314a50aa5c7436c00908a successMessageText": "Beautiful. Alright, pants off right now, time for an upgrade!", + "6669acb8c4d34bd547a4d2ac": "Hand over Physical Bitcoin", + "666314a50aa5c7436c00908a acceptPlayerMessage": "", + "666314a50aa5c7436c00908a declinePlayerMessage": "", + "666314a50aa5c7436c00908a completePlayerMessage": "", + "666314b0acf8442f8b0531a1 name": "Hell on Earth - Part 1", + "666314b0acf8442f8b0531a1 description": "What's up, warrior. I've been talking to my nephew about some video game where you shoot demons. I thought I'd give him a little present. \n\nAnyway, here's the task: get me a double-barrelled shotgun like in that game, and make it look real nasty! Oh, and make the barrel shorter.", + "666314b0acf8442f8b0531a1 failMessageText": "", + "666314b0acf8442f8b0531a1 successMessageText": "It really is a beast! Even I'm now interested in seeing this game...", + "66632cf3fbd7dedfa6153a9f": "Modify an MP-43-1C shotgun to comply with the given specifications", + "666314b0acf8442f8b0531a1 acceptPlayerMessage": "", + "666314b0acf8442f8b0531a1 declinePlayerMessage": "", + "666314b0acf8442f8b0531a1 completePlayerMessage": "", + "666314b2a9290f9e0806cca3 name": "Hell on Earth - Part 2", + "666314b2a9290f9e0806cca3 description": "Warrior! Remember the DB you were building? I couldn't deliver it past the border. That's a bummer, the shotty is gorgeous. Speaking of, we've got plenty of demons of our own in Tarkov. \n\nCan't even take a shit in the woods at night! Why don't you take this gun out for a spin and deal with those devils?", + "666314b2a9290f9e0806cca3 failMessageText": "", + "666314b2a9290f9e0806cca3 successMessageText": "How'd it go? We really should add something like that to the inventory... I think it's gonna be a big hit!", + "66632deea5607d352f3aa844": "Eliminate the hooded men while using the double barrel shotgun", + "666314b2a9290f9e0806cca3 acceptPlayerMessage": "", + "666314b2a9290f9e0806cca3 declinePlayerMessage": "", + "666314b2a9290f9e0806cca3 completePlayerMessage": "", + "666314b4d7f171c4c20226c3 name": "The Good Times - Part 1", + "666314b4d7f171c4c20226c3 description": "Hello again! Remember the good old time when all the major fighting took place at Polikhim? People were buying tons of gear from me back then. There was a kit, the most popular among PMCs. \n\nI was wondering how it performs in the field nowadays. Check it out for me and tell me how it is, yea?", + "666314b4d7f171c4c20226c3 failMessageText": "", + "666314b4d7f171c4c20226c3 successMessageText": "Thanks for your help, soldier! Nowadays, there's battles all over the city, and everyone's got their own different equipment. It's an arms race, I'll tell you that!", + "666333e93962787efd64004a": "Eliminate PMC operatives while using Colt M4A1, 6B43 body armor, and Kiver-M helmet on Factory", + "666314b4d7f171c4c20226c3 acceptPlayerMessage": "", + "666314b4d7f171c4c20226c3 declinePlayerMessage": "", + "666314b4d7f171c4c20226c3 completePlayerMessage": "", + "666314b696a9349baa021bac name": "Quality Standard", + "666314b696a9349baa021bac description": "Good afternoon. I've learned that сomrade Prapor has become nostalgic lately. Although I can't find time for such things myself, your and Prapor's affairs have brought me to a good idea. \n\nWhen the locals found out about TerraGroup's underground laboratory, there was quite a stir! It was a breakthrough for my business, the lab is where I got my unique equipment from. \n\nWell, there may still be some original American leftover LEDX from back then. Can you get me one of those? It would really help our cause.", + "666314b696a9349baa021bac failMessageText": "", + "666314b696a9349baa021bac successMessageText": "My thanks to you. I don't know what we'd do if the lab wasn't accessible to people like you.", + "6672e47f25ab92726912c3e5": "Locate and obtain the special version of the LEDX Skin Transilluminator in The Lab", + "6672e49679243c500ec02c2e": "Hand over the found item", + "666314b696a9349baa021bac acceptPlayerMessage": "", + "666314b696a9349baa021bac declinePlayerMessage": "", + "666314b696a9349baa021bac completePlayerMessage": "", + "666314b8312343839d032d24 name": "Airmail", + "666314b8312343839d032d24 description": "Hello, friend! You know how even small changes affect our isolated Tarkov world. Take, for example, the arrival of the humanitarian aid that's being dropped from airplanes. \n\nEven I couldn't get some of the components for my work before. But now you can find real treasures in these crates! \n\nBy the way, I'd like to arrange for a new package. To do this, I need to make sure that the pilots work as instructed, give a drop right after the launch of the red flare. Can you help me with that?", + "666314b8312343839d032d24 failMessageText": "", + "666314b8312343839d032d24 successMessageText": "It worked, right? Thanks, friend. Our airmail comes in so handy!", + "6672edebec0c3e2ad7d4e489": "Launch a red signal flare at the old sawmill on Woods", + "666314b8312343839d032d24 acceptPlayerMessage": "", + "666314b8312343839d032d24 declinePlayerMessage": "", + "666314b8312343839d032d24 completePlayerMessage": "", + "666314bafd5ca9577902e03a name": "The Good Times - Part 2", + "666314bafd5ca9577902e03a description": "The factory run was amazing, your stories made my memory come flooding back! The gunfights are one thing, but when the bandits' leaders showed up, that's when it got real hot. \n\nReshala was the first to show up, always bragging about his gold TT. Back then, everyone wanted one of these in their holster. \n\nBut now, for some reason, the demand for TTs is going down. Can you remind everyone what kind of weapons real men fight with?", + "666314bafd5ca9577902e03a failMessageText": "", + "666314bafd5ca9577902e03a successMessageText": "Older models always have a kind of personality to them. And this one, the gilding, the grip... Something about it just feels right, doesn't it?", + "6663389aa257916ad3c89529": "Eliminate any target while using the golden TT-33 pistol", + "666314bafd5ca9577902e03a acceptPlayerMessage": "", + "666314bafd5ca9577902e03a declinePlayerMessage": "", + "666314bafd5ca9577902e03a completePlayerMessage": "", + "666314bc1d3ec95634095e77 name": "Minute of Fame", + "666314bc1d3ec95634095e77 description": "Sup, bandit! How's life? A little birdie told me there's a special magazine in the Ultra mall at the Interchange. They wrote about our Russian video game, which is recognized all over the world! I guess the guys really came up with a great concept!", + "666314bc1d3ec95634095e77 failMessageText": "", + "666314bc1d3ec95634095e77 successMessageText": "Now this is a victory! The magazine hit the jackpot! Looks like real historical shit.", + "6667570298ab2c873b4cc004": "", + "667a958eb30fe2e2938a6387": "Locate and obtain the special edition of the gaming magazine on Interchange", + "667a95972740eaeca1ecda21": "Hand over the found item", + "666314bc1d3ec95634095e77 acceptPlayerMessage": "", + "666314bc1d3ec95634095e77 declinePlayerMessage": "", + "666314bc1d3ec95634095e77 completePlayerMessage": "", + "666314bd920800278d0f6748 name": "Viewer", + "666314bd920800278d0f6748 description": "Hello, soldier. I've met some rookies recently, here in Tarkov. They say people don't watch everything on tape anymore, they watch it live! Programs, stories, and some even show their everyday life non-stop. \n\nThey even said a bunch of civilians are watching Tarkov's activities live! It seems that the whole world is interested in our city!\n\nI don't understand how they organized the broadcast to the outside world, but I wouldn't mind a second pair of eyes. It's a simple task - organize surveillance in some spots, and I'll return the favor.", + "666314bd920800278d0f6748 failMessageText": "", + "666314bd920800278d0f6748 successMessageText": "I think I'm beginning to understand why people watch these \"live streams\". It's addictive!", + "6667579086472aaf0bf7bef5": "Передать жесткий диск с утечкой", + "666757c530b9b77ff2d9ac58": "Найти жесткий диск с утечкой в покосившемся доме на локации Берег", + "6674430a82468886a4aebb30": "", + "667570c2d4f68aeef0cae9a5": "", + "667570e8a855902e9311cfdd": "", + "667bf8370849ce7edf2b124e": "Install a WI-FI Camera on the mountain ledge on Woods", + "667bf840981b1c594af358ce": "Install a WI-FI Camera at the pier tower on Shoreline", + "667bf845dc371ee9869f185e": "Install a WI-FI Camera at the office corridor on Factory", + "66d07fa69d373d977f437fe0": " Install a WI-FI Camera at the office corridor on Factory", + "666314bd920800278d0f6748 acceptPlayerMessage": "", + "666314bd920800278d0f6748 declinePlayerMessage": "", + "666314bd920800278d0f6748 completePlayerMessage": "", + "666314bf1cd52e3d040a2e78 name": "Serious Allegations", + "666314bf1cd52e3d040a2e78 description": "Hey! Remember the client with the game magazine? I have a new order. I need a data disk, it's all related to the same game. Some scam artist said that the people who created the game had stolen user data from 2 million accounts! And as proof he showed a hard drive to everyone, allegedly with this leak. But the publishers are serious guys, they would not allow such bullshit. So the client is looking for the drive to clarify the situation.\n\nMy guys said the drive should be in an old wooden house near the health resort, there is a toilet on the left and a rag above the entrance.", + "666314bf1cd52e3d040a2e78 failMessageText": "", + "666314bf1cd52e3d040a2e78 successMessageText": "Lemme see. Ha, it's a blank! Yeah, the publishers turned out to be smooth guys, and trust me, this allegations kid will be forgotten by everyone.", + "666759ec97f6cdd83434764e": "Передать жесткий диск с утечкой", + "666759f6742e5c250f2065fe": "Найти жесткий диск с утечкой в покосившемся доме на локации Берег", + "667571ad6889d3af44af7be2": "Locate and obtain the hard drive at the old house on Shoreline", + "667571cb7620e3041bad913c": "Hand over the found item", + "666314bf1cd52e3d040a2e78 acceptPlayerMessage": "", + "666314bf1cd52e3d040a2e78 declinePlayerMessage": "", + "666314bf1cd52e3d040a2e78 completePlayerMessage": "", + "666314c10aa5c7436c00908c name": "Camera, Action!", + "666314c10aa5c7436c00908c description": "Hello there. I know some people, a documentary crew. They want to make a movie about Tarkov. They're risk-takers, but I can't change their minds. So I figured I'd better help them get it done quickly and stay alive. \n\nEquipment for them was also dropped from the airplane you called in, but the hardware is fragile and was partially damaged during the landing. Can you help me find replacement parts?", + "666314c10aa5c7436c00908c failMessageText": "", + "666314c10aa5c7436c00908c successMessageText": "Great, thanks for your help! The cameramen said they've already come up with a title for the movie — \"Raid\". Sounds good, don't you think?", + "66675a4567c0cf0989946e12": "Hand over the found in raid item: SSD drive", + "66675a50f15c3daac1fcb57d": "Hand over the found in raid item: USB Adapter", + "66675a5b89c89dbbf90361d5": "Hand over the found in raid item: Portable Powerbank", + "66675a66e7b6dbc6ff88de91": "Hand over the found in raid item: Rechargeable battery", + "667c252898eab887725ef789": "Hand over the found in raid item: PC CPU", + "667c25452c353b0176f883d1": "Hand over the found in raid item: Electronic components", + "667c257562774a862480925c": "Hand over the found in raid item: Bundle of wires", + "667c25970b2c3c93bfc0f204": "Hand over the found in raid item: Capacitors", + "667c25a8b3d49a2e3f4bd05c": "Hand over the found in raid item: NIXXOR lens", + "667c25b7b4419ddadbe352be": "Hand over the found in raid item: RAM stick", + "667c25eeb3fba3b8f07b9193": "Hand over the found in raid item: Working LCD", + "667c26159bd3d32fb565578e": "Hand over the found in raid item: Light bulb", + "666314c10aa5c7436c00908c acceptPlayerMessage": "", + "666314c10aa5c7436c00908c declinePlayerMessage": "", + "666314c10aa5c7436c00908c completePlayerMessage": "", + "666314c3acf8442f8b0531a3 name": "Proper Comeback", + "666314c3acf8442f8b0531a3 description": "You're a good guy, I'll tell you that. I wouldn't trust another man to do this, but you're an experienced fellow, you understand what I'm saying. I heard that Prapor is now into modern technology, and he's got cameras everywhere, watching everything from his man cave. \n\nAnd recently he ruined one of my deals, started yelling like a damn rooster, something about the rules of trade and military order... We have to show him what a motherfucker he's become. Oops, sorry for the offensive language. Hope it doesn't disrespect your community guidelines.", + "666314c3acf8442f8b0531a3 failMessageText": "", + "666314c3acf8442f8b0531a3 successMessageText": "Well done! They say that even the outside world found out about our little move, haha!", + "667442da875be5fb415df535": "Stash a Golden rooster figurine at Prapor's WI-FI Camera on Woods", + "6675741838e8f9096619562d": "", + "6675742aa69b94e13df80e0b": "", + "6682873d755938fa4cb73073": "Stash a Golden rooster figurine at Prapor's WI-FI Camera on Shoreline", + "66828746efaecf435dde20ca": "Stash a Golden rooster figurine at Prapor's WI-FI Camera on Factory", + "66d080533a3c33d823a3477d": "Stash a Golden rooster figurine at Prapor's WI-FI Camera on Factory", + "666314c3acf8442f8b0531a3 acceptPlayerMessage": "", + "666314c3acf8442f8b0531a3 declinePlayerMessage": "", + "666314c3acf8442f8b0531a3 completePlayerMessage": "", + "666314c5a9290f9e0806cca5 name": "Key to the City", + "666314c5a9290f9e0806cca5 description": "How's it going, brother? I heard the city's stirring up, collecting souvenirs, reminiscing over old times. And I just got a lead on something like this. They keep these things in museums. \n\nIn the old days, each city had its own key, which the governor received at the time of establishment. I even saw one on a tour when I was a kid!\n\nThey don't do that anymore, but Tarkov does have its own key, apparently! When the city was laid out, they made one for historical reference. And I know where to find it! If you bring it back, we'll make a fortune.", + "666314c5a9290f9e0806cca5 failMessageText": "", + "666314c5a9290f9e0806cca5 successMessageText": "You got it? Nice! What do those numbers mean? Only the bright minds who know about Tarkov's history will understand that, probably. ", + "66675ab84ae46ba8cb5f8f5d": "передать Ключ от города", + "66675abf3763d2d5e42654b4": "Найти Ключ от города на локации улицы Таркова", + "6679884cef969161e3e9d64d": "Locate and obtain the souvenir key to the city on Streets of Tarkov", + "667988545af9f7082798b67d": "Hand over the found item", + "666314c5a9290f9e0806cca5 acceptPlayerMessage": "", + "666314c5a9290f9e0806cca5 declinePlayerMessage": "", + "666314c5a9290f9e0806cca5 completePlayerMessage": "", + "6672d9def1c88688a707d042 name": "Establish Contact", + "6672d9def1c88688a707d042 description": "Hello, mercenary. You want to take our cooperation to the next level? You know the greater the responsibility, the more important the trust. Prove your dependability.", + "6672d9def1c88688a707d042 failMessageText": "", + "6672d9def1c88688a707d042 successMessageText": "Well, now we can talk about your job.", + "6672dab64f4c15050e5cfef3": "Reach 5.0 standing with Fence", + "66813c01decf4560581ca0c0": "Reach 5.0 standing with Fence", + "6672d9def1c88688a707d042 acceptPlayerMessage": "", + "6672d9def1c88688a707d042 declinePlayerMessage": "", + "6672d9def1c88688a707d042 completePlayerMessage": "", "6672ec2a2b6f3b71be794cc5 name": "A Key to Salvation", "6672ec2a2b6f3b71be794cc5 description": "Good afternoon. I desperately need the staff keycards from the TerraGroup laboratory, and you know full well how impossible it is to get even one of those. I heard that Mechanic is willing to trade the cards for some military equipment, but I lack the manpower to gather it currently. This is a matter of life and death. Will you help?", "6672ec2a2b6f3b71be794cc5 failMessageText": "", "6672ec2a2b6f3b71be794cc5 successMessageText": "Thank you! I don't know how or where you got them, but now I can get the equipment that will surely delight my cust— Ahem, patients, of course. These cards are the key to salvation no less!", - "66742f90653d4d410e6908ea": "Hand over a TerraGroup Labs access keycard", - "66742f71f4a5f593020a5554": "Hand over a TerraGroup Labs keycard (Violet)", - "66742f60da136c794ff6df0c": "Hand over a TerraGroup Labs keycard (Yellow)", - "66742efcb6a664c20e32cc11": "Hand over a TerraGroup Labs keycard (Red)", - "66742ebfbe505da164e5068d": "Hand over a TerraGroup Labs keycard (Green)", - "66742eb113141dd347c1515f": "Hand over a TerraGroup Labs keycard (Blue)", "66742e9871a1ea849356d1a1": "Hand over a TerraGroup Labs keycard (Black)", + "66742eb113141dd347c1515f": "Hand over a TerraGroup Labs keycard (Blue)", + "66742ebfbe505da164e5068d": "Hand over a TerraGroup Labs keycard (Green)", + "66742efcb6a664c20e32cc11": "Hand over a TerraGroup Labs keycard (Red)", + "66742f60da136c794ff6df0c": "Hand over a TerraGroup Labs keycard (Yellow)", + "66742f71f4a5f593020a5554": "Hand over a TerraGroup Labs keycard (Violet)", + "66742f90653d4d410e6908ea": "Hand over a TerraGroup Labs access keycard", "6672ec2a2b6f3b71be794cc5 acceptPlayerMessage": "", "6672ec2a2b6f3b71be794cc5 declinePlayerMessage": "", "6672ec2a2b6f3b71be794cc5 completePlayerMessage": "", - "616041eb031af660100c9967 startedMessageText 5935c25fb3acc3127c3d8cd9 0": " ", - "616041eb031af660100c9967 failMessageText 5935c25fb3acc3127c3d8cd9 0": " ", - "616041eb031af660100c9967 successMessageText 5935c25fb3acc3127c3d8cd9 0": "Good, good. You've done well, mercenary. You're free to go.", - "616041eb031af660100c9967 description 5935c25fb3acc3127c3d8cd9 0": "Ah, mercenary, do you want to do a good deed? My clients are asking to ensure a safe area to conduct a specific secret operation. I would like to appoint you for this, as you are the most competent of the local workers. You will have to survey the area and report back to me. Good luck, mercenary.", - "616041eb031af660100c9967 changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", - "616041eb031af660100c9967 startedMessageText 5c0647fdd443bc2504c2d371 0": " ", - "616041eb031af660100c9967 failMessageText 5c0647fdd443bc2504c2d371 0": " ", - "616041eb031af660100c9967 successMessageText 5c0647fdd443bc2504c2d371 0": "Well, guess it’s time to head out then. Thank you, kid.", - "616041eb031af660100c9967 description 5c0647fdd443bc2504c2d371 0": "Come on in for some tea, kid. I'm preparing to go hunting today, and could use some scouting in the area. Can you go check it out? I'd be grateful.", - "616041eb031af660100c9967 changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I've already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", + "668bc79ef18d791eb2520279 name": "", + "668bc79ef18d791eb2520279 description": "", + "668bc79ef18d791eb2520279 failMessageText": "", + "668bc79ef18d791eb2520279 successMessageText": "", + "668bc79ef18d791eb2520279 acceptPlayerMessage": "", + "668bc79ef18d791eb2520279 declinePlayerMessage": "", + "668bc79ef18d791eb2520279 completePlayerMessage": "", + "668bcccc167d507eb01a268b name": "Import Сontrol", + "668bcccc167d507eb01a268b description": "Hello, I'll bring you up to speed. Apparently Peacekeeper and comrade Prapor are trying to re-divide the weapon market. They're both dumping to win customers from each other. Rings a bell, doesn't it? History always repeats itself, and we are in yet another page of the book with this arms race...\n\nWell, whatever, no point in rambling now, plus this situation could prove beneficial to me. I was just about to restock my supply of imported weapons. I heard that even the Scavs at Polikhim have tuned western guns now! Can you get me some of those? I don't think anyone will mourn these bandits.", + "668bcccc167d507eb01a268b failMessageText": "", + "668bcccc167d507eb01a268b successMessageText": "Hmm, that's odd... I thought Peacekeeper only sold quality product. The condition of these guns would make many people consider switching to another seller.", + "668bceb012b42f685164674c": "Eliminate Scavs on Factory", + "668bcf4e734d42388944ccf5": "Hand over the found in raid western Scav weapons", + "668bcccc167d507eb01a268b acceptPlayerMessage": "", + "668bcccc167d507eb01a268b declinePlayerMessage": "", + "668bcccc167d507eb01a268b completePlayerMessage": "", + "668bccf963acb16d63707043 name": "What’s Your Evidence?", + "668bccf963acb16d63707043 description": "Hello, my friend. You've likely already heard rumors about my merchandise, yes? My guess is this Russian prick just can't stand the fact that the customers are choosing me over him. Or perhaps there's a new player trying to join the competition. \n\nIn any case, this reputational damage must be dealt with immediately. Bring me some of this \"poor-quality merchandise\", and I'll look into it.", + "668bccf963acb16d63707043 failMessageText": "", + "668bccf963acb16d63707043 successMessageText": "What the kurwa is this... That's not my product! Well, thank you for your work anyway. Now I have several leads, but we need to figure out where these weapons came from.", + "668bd013696575b3bbc846ec": "Hand over the western Scav weapons with very low durability", + "668bccf963acb16d63707043 acceptPlayerMessage": "", + "668bccf963acb16d63707043 declinePlayerMessage": "", + "668bccf963acb16d63707043 completePlayerMessage": "", + "668bcd1b194be70f18427a00 name": "Caught Red-Handed", + "668bcd1b194be70f18427a00 description": "Oh yes yes my friend, you are just in time! I conducted an investigation and found the source of the faulty weapons. Turns out Prapor had nothing to do with this. The imported guns in this condition and quantity are only available to those ex-USEC bandits. It seems they've decided to join the market themselves. \n\nHowever, they can't sell their goods on their own for obvious reasons, meaning they must have accomplices... You need to set up surveillance at their base so we can find their dealers.", + "668bcd1b194be70f18427a00 failMessageText": "", + "668bcd1b194be70f18427a00 successMessageText": "Great! Now I'm gonna track down the dealers who have been discrediting me. After that, I'll contact you for your next job.", + "668be8a88b5800f44b533e21": "Install a WI-FI Camera to watch the first water treatment plant building entrance on Lighthouse", + "668be8dfd906438a21fc839c": "Install a WI-FI Camera to watch the second water treatment plant building entrance on Lighthouse", + "668be8e5ed860032551c901f": "Install a WI-FI Camera to watch the third water treatment plant building entrance on Lighthouse", + "668bcd1b194be70f18427a00 acceptPlayerMessage": "", + "668bcd1b194be70f18427a00 declinePlayerMessage": "", + "668bcd1b194be70f18427a00 completePlayerMessage": "", + "668bcd253e2c5f65cc64d7da name": "Risks of Small Business", + "668bcd253e2c5f65cc64d7da description": "So, the cameras worked just right. The ex-USECs are receiving help from the Svavs, and my man was able to ID them. They're two of Kaban's men, Gus and Basmach. I'm not certain if their boss knows about this side gig, but now is not the time to look into it. \n\nThe reputational damage is already too high, and I need to take these two fucks down, ASAP. An old rival of mine has decided to take advantage of the situation, so we have to work fast!", + "668bcd253e2c5f65cc64d7da failMessageText": "So you're refusing to help me? Protecting these Scavs on Prapor's orders? I won't forget this, mercenary.", + "668bcd253e2c5f65cc64d7da successMessageText": "Excellent work. These two flew too close to the sun, am I right? Well, time to restore my good name.", + "668bd044fd212b5f7ca0d830": "Eliminate Basmach on Streets of Tarkov", + "668bd0c04fd3b3f3aa50c893": "Eliminate Gus on Streets of Tarkov", + "668bcd253e2c5f65cc64d7da acceptPlayerMessage": "", + "668bcd253e2c5f65cc64d7da declinePlayerMessage": "", + "668bcd253e2c5f65cc64d7da completePlayerMessage": "", + "668bcd367eb38c3c4d58603c name": "Protection of Interests", + "668bcd367eb38c3c4d58603c description": "Heyo, warrior! I heard about our western colleague and his so-called \"investigation\". The USEC deserters decided to sell used guns and got in touch with the Scavs. They say it were Kaban's boys who set Peacekeeper up. Trouble for him, but huge profit for me! \n\nThe only problem is that he found out about Gus and Basmach, and now he wants to take them out. Listen, I don't really like those thugs, but they're very useful to my business. Be a good lad, go help those boys out, will you?", + "668bcd367eb38c3c4d58603c failMessageText": "You're sabotaging my operation here, kid. Was it import jeans or fucking soda you sold out for?", + "668bcd367eb38c3c4d58603c successMessageText": "PK didn't spare resources to get those two, didn't he? But you've done well. I knew you'd help me out. After such an embarrassment, the tourist will take a long time to recover. The two boys seem to have good ambition, they'll go far, I'm telling you! All they need is to get out from under Kaban.", + "668be97f77ef4d66357d6393": "Eliminate PMC operatives on Streets of Tarkov", + "668be9bfd999e5485ead4306": "You must not kill Gus or Basmach while the task is active", + "668f9ec2f575f0ed515f8cc6": "Do not kill Gus or Basmach while the quest is active", + "668bcd367eb38c3c4d58603c acceptPlayerMessage": "", + "668bcd367eb38c3c4d58603c declinePlayerMessage": "", + "668bcd367eb38c3c4d58603c completePlayerMessage": "", + "668bcd6c3e2c5f65cc64d7dc name": "Time-Tested", + "668bcd6c3e2c5f65cc64d7dc description": "This is it, warrior! It's time for the decisive breakthrough in this arms race! Peacekeeper is in a vulnerable position, so we have to take him down for good. Show that there's nothing in Tarkov that's better than our domestic guns. I think you know full well how to demonstrate the quality of Russian weapons.", + "668bcd6c3e2c5f65cc64d7dc failMessageText": "", + "668bcd6c3e2c5f65cc64d7dc successMessageText": "You really showed them! Now everyone knows who to buy a reliable weapon from. I wonder how Gus and Basmach will fare from now on.", + "668bd364b3a107338354ae8f": "Eliminate as many targets as possible while using Russian weapons", + "668bcd6c3e2c5f65cc64d7dc acceptPlayerMessage": "", + "668bcd6c3e2c5f65cc64d7dc declinePlayerMessage": "", + "668bcd6c3e2c5f65cc64d7dc completePlayerMessage": "", + "668bcd7459a35c28386482d0 name": "Western Quality Standards", + "668bcd7459a35c28386482d0 description": "Good day to you! So, we have dealt with the cause of the negative rumors, but rumors still run through the city. And then there's that old soldier still campaigning his business. He thinks he can beat me in this fight. \n\nLet's prove to him that he can't. The advantages of imported weapons are obvious, and you must demonstrate them in action. It's time for a good show, my friend! ", + "668bcd7459a35c28386482d0 failMessageText": "", + "668bcd7459a35c28386482d0 successMessageText": "Spectacular. Once again you've proven that you work for result. Now everyone knows who to visit for the highest quality and innovative products.", + "668bd3adf0ede1e7c0a18eb5": "Eliminate as many targets as possible while using Western weapons", + "668bcd7459a35c28386482d0 acceptPlayerMessage": "", + "668bcd7459a35c28386482d0 declinePlayerMessage": "", + "668bcd7459a35c28386482d0 completePlayerMessage": "", + "669f9584e749756c920d02c6 name": "", + "669f9584e749756c920d02c6 description": "", + "669f9584e749756c920d02c6 failMessageText": "", + "669f9584e749756c920d02c6 successMessageText": "", + "669f9584e749756c920d02c6 acceptPlayerMessage": "", + "669f9584e749756c920d02c6 declinePlayerMessage": "", + "669f9584e749756c920d02c6 completePlayerMessage": "", + "669fa38fad7f1eac2607ed46 name": "One Less Loose End", + "669fa38fad7f1eac2607ed46 description": "Hello, dear friend. There's an important job just for someone like you. You need to pick up a journal from the TerraGroup field lab at the Polikhim factory and drop it off at a specified location. It's at an old sawmill in Priozersk nature reserve. Leave the package at the house with transformers. \n\nI don't want to upset my influential customer, so I can't trust a random person with the job.", + "669fa38fad7f1eac2607ed46 failMessageText": "Are you sure you did the right thing, mercenary? My client won't stand for it, and I'd recommend you look over your shoulder more often from now on. Don't count on me for protection.", + "669fa38fad7f1eac2607ed46 successMessageText": "Great! You know the saying \"What happens in Vegas, stays in Vegas\"? Everyone has their secrets, and prying into those secrets might be too dangerous...", + "669faeb6a6e02d00c47ad812": "Locate and obtain the lab journal on Factory", + "669faecceb01bf6324de66c4": "Stash the journal at the old sawmill on Woods", + "669fa38fad7f1eac2607ed46 acceptPlayerMessage": "", + "669fa38fad7f1eac2607ed46 declinePlayerMessage": "", + "669fa38fad7f1eac2607ed46 completePlayerMessage": "", + "669fa3910c828825de06d69f name": "A Healthy Alternative", + "669fa3910c828825de06d69f description": "Hello. I understand that you were tasked with finding the laboratory log from the polychemical plant. Apparently, TerraGroup is willing to pay handsomely for the extraction of their documents. \n\nI urge you to reconsider. If the corporation cares so much about this material, it must be hiding something valuable! Obviously, I mean valuable to the city and its citizens. Just leave the journal in my care.", + "669fa3910c828825de06d69f failMessageText": "You've decided to return the journal to the corp? You don't seem to care much for the people of this town. I'm disappointed in your choice.", + "669fa3910c828825de06d69f successMessageText": "You picked the right side! This journal will be very useful to my acquaintance in his experiments.... I mean, research! This way we can alleviate the suffering of the Tarkov citizens who are still in the city.", + "669faef62c68a5925a36fccc": "Hand over the lab journal", + "669fa3910c828825de06d69f acceptPlayerMessage": "", + "669fa3910c828825de06d69f declinePlayerMessage": "", + "669fa3910c828825de06d69f completePlayerMessage": "", + "669fa394e0c9f9fafa082897 name": "Forklift Certified", + "669fa394e0c9f9fafa082897 description": "Hello, friend! How are you doing? Things are going well for me here. Sometimes it even seems too good to be true. Well, can't complain though!\n\nI can't play Tetriz in the old warehouse anymore, so I've found a new, bigger playground. But there's no machinery! \n\nI want to build myself a forklift from what's left in the factory. There should be enough surviving parts for one. You don't have to collect parts, just route my men through all the forklifts.", + "669fa394e0c9f9fafa082897 failMessageText": "", + "669fa394e0c9f9fafa082897 successMessageText": "I didn't realize there were so many forklifts at the plant! I remember the times I spent all day with my father in the garage working on his Volga...", + "669faf99963982aef42a5ba4": "Locate the first forklift on Factory", + "669fafa09a13dcb8bf66e6bd": "Locate the second forklift on Factory", + "669fafa1d0fe63abcf15fac8": "Locate the third forklift on Factory", + "669fafa2394f7353883ffd8d": "Locate the fourth forklift on Factory", + "669fafa49bf4b277e24f3681": "Locate the fifth forklift on Factory", + "669fafa5f597899ad6bc55bb": "Locate the sixth forklift on Factory", + "669fafa76172f63531f6e74d": "Locate the seventh forklift on Factory", + "669fafa9299830ffe78e937d": "Locate the eighth forklift on Factory", + "66a80f20fe47046136f14c8b": "Locate the ninth forklift on Factory", + "66bd67615936a4753b7345be": "Locate the tenth forklift on Factory", + "66bd6765b9e77d3672edfeee": "Locate the eleventh forklift on Factory", + "66c2331d75e8aa67fbf65930": "Locate the twelfth forklift on Factory", + "669fa394e0c9f9fafa082897 acceptPlayerMessage": "", + "669fa394e0c9f9fafa082897 declinePlayerMessage": "", + "669fa394e0c9f9fafa082897 completePlayerMessage": "", + "669fa395c4c5c04798002497 name": "Exit Here", + "669fa395c4c5c04798002497 description": "Hey, so I've noticed that more and more people are sneaking around at the chemical plant, it's getting a little crowded for my taste... That's why I need you to scout out a new exit route in case shit goes down, you know. If you do that, you can count on a magnificent reward, trust!", + "669fa395c4c5c04798002497 failMessageText": "", + "669fa395c4c5c04798002497 successMessageText": "In the backyard, huh? A lot of people tried to go through there before, but they got blown up by tripwires too often. But you're telling me there's not a single old mine left? \n\nWell that's good! Just don't talk about our new hidey hole too much, okay? By the time the suckers find out about this exit, we'll have looted the factory clean!", + "669fb12eb01ceef19a5b4ebc": "Survive and extract from Factory through the main exit", + "669fa395c4c5c04798002497 acceptPlayerMessage": "", + "669fa395c4c5c04798002497 declinePlayerMessage": "", + "669fa395c4c5c04798002497 completePlayerMessage": "", + "669fa3979b0ce3feae01a130 name": "Claustrophobia", + "669fa3979b0ce3feae01a130 description": "Haven't seen you in a while. I was just talking about you with my friend, talking about clever youth...\n\nHe told me a story about some amateur soldiers who went raiding into the old tunnels. One got spooked by a noise and started shooting everywhere, another one threw a bad grenade and killed everyone in their group. Turns out my comrade didn't even need a tripwire in the end. Disappointing, he said.\n\nIf you don't want to find yourself in a similar situation, take a shotgun and go to those tunnels at the chemical plant. If you can handle the enemy in such conditions, then cramped space will become your ally.", + "669fa3979b0ce3feae01a130 failMessageText": "", + "669fa3979b0ce3feae01a130 successMessageText": "Alive and well, I see? Well, now you're the apex predator in those dungeons.", + "669fb1ffe34e78d618792b41": "Eliminate any target in the old cellars while using a shotgun on Factory", + "669fa3979b0ce3feae01a130 acceptPlayerMessage": "", + "669fa3979b0ce3feae01a130 declinePlayerMessage": "", + "669fa3979b0ce3feae01a130 completePlayerMessage": "", + "669fa399033a3ce9870338a8 name": "Possessor", + "669fa399033a3ce9870338a8 description": "Hey, warrior! You've probably seen a crashed chopper at the factory before, yeah? I wonder when and how it ended up there. But I know one thing for sure: they never sent helis to Tarkov to pick up anyone, neither before nor now. We should find out who was on that helicopter and what was their mission.\n\nYou should go scout that heli. There's gotta be a logbook or something.", + "669fa399033a3ce9870338a8 failMessageText": "", + "669fa399033a3ce9870338a8 successMessageText": "Haha! I knew you were the right merc for the job. The helicopter doesn't appear to be Russian, but that's only at first glance. It looks like our undercover operatives infiltrated the USECs and captured one of them!\n\nIf there are no bodies near the helicopter, it means that the boys managed to escape, and the task was accomplished.", + "669fb4a56e66d3d79183a5c9": "Locate and obtain the helicopter logbook on Factory", + "669fb4b21f2e5268651cc96a": "Hand over the found information", + "669fa399033a3ce9870338a8 acceptPlayerMessage": "", + "669fa399033a3ce9870338a8 declinePlayerMessage": "", + "669fa399033a3ce9870338a8 completePlayerMessage": "", + "669fa39b91b0a8c9680fc467 name": "Black Swan", + "669fa39b91b0a8c9680fc467 description": "I don't understand why nobody notices the obvious patterns in the platinum price change. We're facing a total crisis but I'm the one they're calling pessimistic! Well, let's see how they buy up platinum at the overprice.\n\nBy the way, we have old heat exchangers under the plant, they have those old corrugated tubes from Soviet times with platinum inserts in them. At times like this, you always want to be prepared for a possible crisis.\n\nCan you help me stock up? Just mark the heat exchangers with strobes.", + "669fa39b91b0a8c9680fc467 failMessageText": "", + "669fa39b91b0a8c9680fc467 successMessageText": "You sure you didn't miss any? Alright, good. Still, it's a shame that complacency prevents some investors from seeing real change. \n\nEveryone will then say that the platinum crisis took everyone by surprise and could not have been predicted... Yeah, right.", + "669fb647a5be751be095da27": "Locate and mark the first heat exchanger with an MS2000 Marker on Factory", + "669fb64aa7e974b27a9c7e1f": "Locate and mark the second heat exchanger with an MS2000 Marker on Factory", + "669fb64b5150ba5196dae347": "Locate and mark the third heat exchanger with an MS2000 Marker on Factory", + "669fa39b91b0a8c9680fc467 acceptPlayerMessage": "", + "669fa39b91b0a8c9680fc467 declinePlayerMessage": "", + "669fa39b91b0a8c9680fc467 completePlayerMessage": "", + "669fa39c64ea11e84c0642a6 name": "The Walls Have Eyes", + "669fa39c64ea11e84c0642a6 description": "You got here just in time, man! I remember you helped me a hell of a lot with surveillance in the suburbs. \n\nAnd now there's all this commotion at the chemical plant, I bet you're well aware of it! Be a true pal, arrange some eyes for me there too, yea?\n\nI've seen some cranes there, they would be a perfect place for a camera. Alright, chop chop.", + "669fa39c64ea11e84c0642a6 failMessageText": "", + "669fa39c64ea11e84c0642a6 successMessageText": "Awesome, thanks for the help.", + "669fb5c58c03e61e1a33ddf0": "Install a WI-FI Camera in the first crane's cockpit on Factory", + "669fb5c7d5fbaaa7b285e83d": "Install a WI-FI Camera in the second crane's cockpit on Factory", + "669fb5c9d798aa41b9bd60b5": "Install a WI-FI Camera in the third crane's cockpit on Factory", + "669fa39c64ea11e84c0642a6 acceptPlayerMessage": "", + "669fa39c64ea11e84c0642a6 declinePlayerMessage": "", + "669fa39c64ea11e84c0642a6 completePlayerMessage": "", + "669fa39ee749756c920d02c8 name": "All Is Revealed", + "669fa39ee749756c920d02c8 description": "Hello, young man. I've received information that one of the tank containers at the Polikhim chemical plant has been damaged. Judging by the description of the liquid inside, it doesn't look like any of the emulsions declared in the official documents.\n\nI think the substance in the tank could be hazardous, so I'm asking you to get me a sample as soon as possible. This is the only way we can be sure of our assessment of chemical safety in Tarkov.", + "669fa39ee749756c920d02c8 failMessageText": "", + "669fa39ee749756c920d02c8 successMessageText": "Excellent! I've already found a specialist to look into this subject. Your contribution to the safety of the city is invaluable!", + "669fb6c859bdae826f7325d4": "Take a sample of the chemicals from the damaged tank container on Factory", + "66a7eebed6bac3ecc16f7d6b": "Hand over the collected sample", + "669fa39ee749756c920d02c8 acceptPlayerMessage": "", + "669fa39ee749756c920d02c8 declinePlayerMessage": "", + "669fa39ee749756c920d02c8 completePlayerMessage": "", + "669fa3a08b4a64b332041ff7 name": "Dragnet", + "669fa3a08b4a64b332041ff7 description": "Hello, soldier. Everyone seems to be flocking to Polikhim, running around looking for secrets... I found out something interesting, too. It turns out that the TerraGroup fucks had their own warehouse in the basement for extra important cargo, and there's a vial of some rare nasty stuff in there.\n\nYou know what's gonna happen when people find out about this. One will ask to retrieve it, another will try to intercept it. Now imagine it falls into the wrong hands. It's best if you and I take this stuff before anyone else and keep it under wraps. The job's important. Will you help me?", + "669fa3a08b4a64b332041ff7 failMessageText": "", + "669fa3a08b4a64b332041ff7 successMessageText": "You're a good kid. My comrade will find a good stash spot for this thingie where no one will ever find it.", + "66a0e692281e56a89b717b7d": "Locate and obtain the chemical container at the TerraGroup warehouse on Factory", + "66a0e69ec03c2dad1a84993a": "Hand over the chemical container", + "669fa3a08b4a64b332041ff7 acceptPlayerMessage": "", + "669fa3a08b4a64b332041ff7 declinePlayerMessage": "", + "669fa3a08b4a64b332041ff7 completePlayerMessage": "", + "669fa3a1c26f13bd04030f37 name": "Capacity Check", + "669fa3a1c26f13bd04030f37 description": "Hey. I have partners who are interested in the condition of the equipment at the Factory. Not just any TerraGroup equipment, but ordinary reactor mixers, of all things! Guess the guys have found some use for them. I trust them and would like to help them. Let them at least try to carry out their plan. \n\nAccording to my information, the mixers themselves are intact, but the engines above are probably out of service. I know you're capable of doing this, and you've come to my rescue many times. So will you help me again?", + "669fa3a1c26f13bd04030f37 failMessageText": "", + "669fa3a1c26f13bd04030f37 successMessageText": "Is everything working now? Great, I'll pass the news on to my, uh, mechanics.", + "66a0e7581ad4ff329a13ebc8": "Fix the first reactor mixer with a Toolset on Factory", + "66a0e75bd9cb07ea69e018c7": "Fix the second reactor mixer with a Toolset on Factory", + "66a0e75df6e0911101eed474": "Fix the third reactor mixer with a Toolset on Factory", + "669fa3a1c26f13bd04030f37 acceptPlayerMessage": "", + "669fa3a1c26f13bd04030f37 declinePlayerMessage": "", + "669fa3a1c26f13bd04030f37 completePlayerMessage": "", + "669fa3a3ad7f1eac2607ed48 name": "Health Care Privacy - Part 6", + "669fa3a3ad7f1eac2607ed48 description": "Together with you we have come a long way on the trail of the mysteriously deceased inhabitants of Tarkov. \nNow I have new information.\n\nThe bodies of workers at the factory were found without signs of violence. It could be a symptom of poisoning or worse... Blood samples would help shed light on the mystery of these workers' deaths. We can't take that chance.\n\nYou already have good experience in collecting samples, so I'd like to entrust this case to you. ", + "669fa3a3ad7f1eac2607ed48 failMessageText": "", + "669fa3a3ad7f1eac2607ed48 successMessageText": "Do you have the samples? All right, let's carefully move them over here... There seems to be no connection to epidemiological risks. But the blood texture is quite different than expected, so this must be somehow influenced by TerraGroup!", + "66a0f37f04fb80a0bfdbaf60": "Hand over the blood sample", + "66a0f391676953651bd8b796": "Locate the dead worker and take their blood sample on Factory", + "669fa3a3ad7f1eac2607ed48 acceptPlayerMessage": "", + "669fa3a3ad7f1eac2607ed48 declinePlayerMessage": "", + "669fa3a3ad7f1eac2607ed48 completePlayerMessage": "", + "669fa3a40c828825de06d6a1 name": "Test Drive - Part 5", + "669fa3a40c828825de06d6a1 description": "Here you are, warrior! It's been a while since you and I did some good old gun testing, huh?\n\nI got a new one, albeit imported. Lightweight, easy to handle. That's something our guns sometimes lack.\n\nWe need to test this beast in close quarters within kissing distance, hehe. Factory would be perfect for this. Let me know how it goes.", + "669fa3a40c828825de06d6a1 failMessageText": "", + "669fa3a40c828825de06d6a1 successMessageText": "How's it feel, easy to aim? Does the silencer get in the way? Okay, I'm convinced. Only a fool would turn down a good weapon.", + "66a0f5a7f9eae6761253114c": "Eliminate any target while using an UZI PRO with 240mm barrel, SBR stock, and BOSS Xe reflex sight on Factory", + "669fa3a40c828825de06d6a1 acceptPlayerMessage": "", + "669fa3a40c828825de06d6a1 declinePlayerMessage": "", + "669fa3a40c828825de06d6a1 completePlayerMessage": "", + "66a1a806bd092031693a6e25 name": "Bad Feeling", + "66a1a806bd092031693a6e25 description": "Hello. So looks like a group of Scavs managed to enter that underground lab people have been talking about. Apparently, they were looking for some secret room, but the Raiders stopped them. Now everybody's searching this Lab for that room, and somebody even unlocked the main entrance to the facility.\n\nAnd I'll tell you this: if the room was hidden even from their own staff, then there was definitely something incredibly dangerous going on there. I have a really bad feeling about this, so I ask you to stop the curious bandits. There are many other places to scavenge, right?", + "66a1a806bd092031693a6e25 failMessageText": "", + "66a1a806bd092031693a6e25 successMessageText": "I knew I could count on you. You saved the city from another conflict. We shouldn't be digging into the shady dealings of these \"scientists\", nothing good comes out of it.", + "66a1a89b9944dffe44a21072": "Eliminate Raiders in The Lab", + "66a1a8db0b2909ec8990395a": "Eliminate PMC operatives in The Lab", + "66a1a806bd092031693a6e25 acceptPlayerMessage": "", + "66a1a806bd092031693a6e25 declinePlayerMessage": "", + "66a1a806bd092031693a6e25 completePlayerMessage": "", + "66a74c628410476dd65543be name": "Gunsmith - Special Order", + "66a74c628410476dd65543be description": "Hello, friend. Things have been a little bumpy for me lately. I will be temporarily raising the prices of my products and services from today until I can solve some pressing matters. A mercenary friend of mine is putting together a team to raid the underground lab, and he needs reliable firepower. Can you help? I see you know as much about the ARs as I do, so I thought I'd entrust this to you. I need an M4A1 with no more than 300 total recoil and ergonomics no less than 70. Not easy, I know. Now, be sure to put an EOTech XPS 3-0 on it, since the client refuses to use any other scope.", + "66a74c628410476dd65543be failMessageText": "", + "66a74c628410476dd65543be successMessageText": "Many thanks. I think this will keep me on track for some time.", + "66a74c628410476dd65543bf": "", + "66a74c628410476dd65543c1": "", + "66a74c628410476dd65543c2": "Modify an M4A1 to comply with the given specifications", + "66a74c628410476dd65543be acceptPlayerMessage": "", + "66a74c628410476dd65543be declinePlayerMessage": "", + "66a74c628410476dd65543be completePlayerMessage": "", + "66a75b44243a6548ff5e5ff9 name": "Gun Connoisseur", + "66a75b44243a6548ff5e5ff9 description": "Thanks for the help with the M4, you really helped me out. Unfortunately, this mercenary never transferred the payment he promised me. I trusted him because of old acquaintances, but the guy went straight to the lab as soon as he received the weapon, and so far there is no word from him. Got too greedy, that's my guess... Well anyway, I can deal with this matter later, but I also have something else on my mind.\nI'm collecting feedback on my services, looking for a fresh perspective, you know? I've decided not only to do individual orders, but to sell guns in sets, fully loaded out of the box. Test it out properly, ask your colleagues maybe. Every little detail and view point is important! And be sure to check the weapons in action, I'm sure you know how....", + "66a75b44243a6548ff5e5ff9 failMessageText": "", + "66a75b44243a6548ff5e5ff9 successMessageText": "Hmm, I see. Pretty much what I expected, of course. Yet I still need more feedback... Anyway, I'll be in touch.", + "66a76d45acbbf739afad1fea": "Eliminate any target while using 5.56x45 caliber weapons", + "66a76d693cda803a9788be30": "Eliminate any target while using 5.45x39 caliber weapons", + "66a76daa3a883f3481e56b96": "Eliminate any target while using 7.62x39 caliber weapons", + "66a76efbe0a0eb89847ac586": "Eliminate any target while using 7.62x54R caliber weapons", + "66a76fb52a58ea63fbb62d67": "Eliminate any target while using 9x19 caliber weapons", + "66a76fc57a265a8879856491": "Eliminate any target while using 9x39 caliber weapons", + "66a75b44243a6548ff5e5ff9 acceptPlayerMessage": "", + "66a75b44243a6548ff5e5ff9 declinePlayerMessage": "", + "66a75b44243a6548ff5e5ff9 completePlayerMessage": "", + "66a77394243a6548ff5e601d name": "Customer Communication", + "66a77394243a6548ff5e601d description": "I've talked to other mercs and sketched out the general picture for future sales. Thanks for your opinion, too. Unfortunately, the problems aren't diminishing. Just a couple days ago, some drifters cut off my long distance communication channels to my suppliers. I'm gonna need some wire, mainly power cables. I'm willing to buy them from you right away.", + "66a77394243a6548ff5e601d failMessageText": "", + "66a77394243a6548ff5e601d successMessageText": "Excellent, I'll never forget this! I'll send your colleagues to fix my cables. Things are getting better, aren't they? Here, another present for you.", + "66a77394243a6548ff5e6021": "Find a Military cable in raid", + "66a77394243a6548ff5e6022": "Find Power cords in raid", + "66a77394243a6548ff5e6023": "Hand over the item", + "66a77394243a6548ff5e6024": "Hand over the items", + "66a7763955ff26e1599f23e7": "Find LCD displays in raid", + "66a77688f2d282a4946547b0": "Hand over the items", + "66a77394243a6548ff5e601d acceptPlayerMessage": "", + "66a77394243a6548ff5e601d declinePlayerMessage": "", + "66a77394243a6548ff5e601d completePlayerMessage": "", + "66a78dada472ad7f845b71f7 name": "Supply and Demand", + "66a78dada472ad7f845b71f7 description": "Judging by the latest news, the situation in Tarkov cannot be called stable. We have to make do with what we have. However, I have a unique proposition for you. A new phase of the conflict is about to develop. History repeats itself in cycles, and my predictions never fail me. I have just received a good shipment of all kinds of stuff, and thanks to you, I can finally breathe freely. I've decided to invest in a major market research. Just like the last time, I need you to use your favorite weapon, but now you'll be wearing a special tracker that will help us stay in touch. I've recruited some of your other colleagues to do the same. The most popular weapons will be put on sale. If it works out well, I'll even try to get a discount on the rest of the stuff. So, you in?", + "66a78dada472ad7f845b71f7 failMessageText": "", + "66a78dada472ad7f845b71f7 successMessageText": "Thank you, man. Stay in touch.", + "66a794ca1b3fe087d0a96ea3": "Eliminate PMCs with your favorite weapon", + "66a78dada472ad7f845b71f7 acceptPlayerMessage": "", + "66a78dada472ad7f845b71f7 declinePlayerMessage": "", + "66a78dada472ad7f845b71f7 completePlayerMessage": "", + "66aa58245ab22944110db6e9 name": "New Day, New Paths", + "66aa58245ab22944110db6e9 description": "Greetings, mercenary. My partners desperately need to transport something important through the center of the city. You know how isolated the neighborhoods are and how dangerous the main roads are. You'll need to scout the route from the TerraGroup headquarters to the Rodina movie theater.\n\nMy men have recently seen the Scavs who found a shortcut between the neighborhoods. It appears to be an old route used by USEC units during the Contract Wars. It was used for most of the supply runs, the soldiers even called it the Suez Canal amongst each other.\n\nThis path will allow you to visit several different locations in one raid. Find it and make sure it's safe.", + "66aa58245ab22944110db6e9 failMessageText": "", + "66aa58245ab22944110db6e9 successMessageText": "Amazing, you've found it! Hopefully it'll be just as safe by the time the convoy leaves.\n\nHowever, I don't understand how they were able to restore the road. The road was blocked by the collapsed Paradigm Shipping building, which is when supplies were cut off. Few people have the resources to clear such a wreck.\n\nApparently, someone is very interested in organizing easy routes...", + "66aa5b2cecad9c067780924b": "Scout the intersection of Mira Ave and the overpass on Ground Zero (In one raid)", + "66aa5bb281dff8466b076894": "Locate the passage leading to Streets of Tarkov on Ground Zero (In one raid)", + "66aa5be8035c6a410dc570b2": "Use the transit from Ground Zero to Streets of Tarkov (In one raid)", + "66aa5c88c085db7d8158db4a": "Scout the road on Primorsky Ave on Streets of Tarkov (In one raid)", + "66aa5c8ba8c36eaef492ef92": "Survive and extract from Streets of Tarkov (or transit to the next location)", + "66b0e57eddc25d8d17e3e3c0": "Scout the area round the Rodina cinema on Streets of Tarkov (In one raid)", + "66aa58245ab22944110db6e9 acceptPlayerMessage": "", + "66aa58245ab22944110db6e9 declinePlayerMessage": "", + "66aa58245ab22944110db6e9 completePlayerMessage": "", + "66aa61663aa37705c5024277 name": "Know Your Place!", + "66aa61663aa37705c5024277 description": "Came here just when I needed you! I found a new delivery route across the city. Well, not exactly found it, per se. Someone moved a package from the city center to Ultra twice as fast as usual.\n\nThese guys must have found a veteran guide who's been here before all the electronics were shut down... Maybe even someone like this crazy guerilla mushroom guy, you heard of him? He'd show up out of nowhere, even been taken captive. But he always found a way to get out and lose his pursuers.\n\nEither way, we need to take control of the route. Find the place where those smugglers emerge from, and show everyone that this is now Ragman's route! So yeah, go ahead and scare everyone off in the city and near Ultra.", + "66aa61663aa37705c5024277 failMessageText": "", + "66aa61663aa37705c5024277 successMessageText": "I think we got the wrong guys, man. Someone came by and told me that this route is used by some very important people. Should've thought this through...", + "66aa61663aa37705c5024278": "Eliminate any target on Streets of Tarkov (In one raid)", + "66aa61663aa37705c502427c": "Use the transit from Streets of Tarkov to Interchange (In one raid)", + "66aa61663aa37705c502427e": "Eliminate any target on Interchange (In one raid)", + "66aa61663aa37705c5024277 acceptPlayerMessage": "", + "66aa61663aa37705c5024277 declinePlayerMessage": "", + "66aa61663aa37705c5024277 completePlayerMessage": "", + "66aa74571e5e199ecd094f18 name": "Secrets of Polikhim", + "66aa74571e5e199ecd094f18 description": "Been waiting for you, friend. My workers found a rare ultrasonic thickness gauge at the customs warehouse, along with some equally useful equipment. There's nothing better that can give me that kind of precision in my measurements!\n\nI can't risk it, so I'm trusting you with this recovery mission. Pick up the package at Customs and deliver it to the designated point at Polikhim. There's something I've been wanting to test for a while... Wait, you didn't know about the industrial area shortcut?\n\nI used it back when I worked at Polikhim. It was the only way to get equipment to the plant that would otherwise be stuck in customs for months. \n\nA fellow forester showed me this path. He said that people were afraid to pick mushrooms near the plant, so it was always full of good pickings.", + "66aa74571e5e199ecd094f18 failMessageText": "", + "66aa74571e5e199ecd094f18 successMessageText": "You didn't lose anything along the way, correct? All right, then it's time to send the engineers out to do some measurements, we're about to find out what these factory walls are hiding. Thanks for your help, friend.", + "66aa74571e5e199ecd094f1b": "Use the transit from Customs to Factory (In one raid)", + "66aa74571e5e199ecd094f1e": "Eliminate Scavs on Factory (In one raid)", + "66aa748cbc69671b0b82ece6": "", + "66aa7532f3dab453f440e251": "", + "66aa7546e08f4372a95fad5d": "", + "66ab94c517859714e68eea8e": "", + "66ab95264a978766aeb9e684": "", + "66ab9543c94ccd538ca48af0": "", + "66ab962edbab188ccbff7916": "", + "66ab965162eb0c47875ceb3c": "", + "66ab97a5c74ce045d6c32578": "Locate and obtain the precision tools package in the laboratory on Customs", + "66ab97d56cb6e3bfd7c79fbc": "Stash the package at the laboratory storage room on Factory", + "66aa74571e5e199ecd094f18 acceptPlayerMessage": "", + "66aa74571e5e199ecd094f18 declinePlayerMessage": "", + "66aa74571e5e199ecd094f18 completePlayerMessage": "", + "66ab970848ddbe9d4a0c49a8 name": "Special Comms", + "66ab970848ddbe9d4a0c49a8 description": "Salutations! An important assignment has just come from the high-ups. Top priority and all that jazz. There's a path from Priozersk to the Reserve base, and our guys need communication in those parts urgently.\n\nThe path? Ah well, I'll share it with you, but make sure nobody else knows about it! When the Contract Wars were in full swing, some artisan managed to lay a path parallel to our road. We tracked the guy down and started interrogating him on who he was working for, what kind of mission he was on, you know the drill. \n\nWe thought we'd captured a spy! Yet he kept calling himself a mushroom picker and grinning like a moron. We wanted to send him to headquarters. But at night our mushroom picker disappeared, no one saw him again after that.\n\nSo, with your help, we'll build a communication line along this path, and you'll be responsible for the equipment. You'll deliver a part of it to the place, go to the Reserve base, and leave the second part there.", + "66ab970848ddbe9d4a0c49a8 failMessageText": "", + "66ab970848ddbe9d4a0c49a8 successMessageText": "Your country will be proud of you, soldier! \n\nBut the fact that the Scavs started roaming around this path worries me a bit... Someone must be scouting for all the forgotten shortcut routes on Tarkov's map.", + "66ab970848ddbe9d4a0c49ab": "Use the transit from Woods to Reserve", + "66ab9c5c60199cdb0902f8cc": "Stash a Military cable at the boulder next to RUAF gate on Woods", + "66ab9c78e192b852d889e2bf": "Stash a Bulbex cable cutter at the boulder next to RUAF gate on Woods", + "66ab9c7ea3a7219e87d4b75e": "Stash a Bulbex cable cutter at the sandbags next to LAV III above the storage warehouse on Reserve", + "66ab9c914a7cba3ea786ce58": "Stash a Military cable at the sandbags next to LAV III above the storage warehouse on Reserve", + "66ab970848ddbe9d4a0c49a8 acceptPlayerMessage": "", + "66ab970848ddbe9d4a0c49a8 declinePlayerMessage": "", + "66ab970848ddbe9d4a0c49a8 completePlayerMessage": "", + "66ab9da7eb102b9bcd08591c name": "Forester's Duty", + "66ab9da7eb102b9bcd08591c description": "Hello. I used to walk many a footpath myself, but time has bested me. The looters have cleaned out all the popular places, and now they're heading into the forests. \n\nI saw some of those Scavs the other day. They were dragging something through the swamp near Azure Coast. Even before the war, people used to call this place a death trap. Only I and my mushroom picker friend knew how to cross it in one piece and survive.\n\nWould you scare those bandits away? Make them know the forests are not for them to ravage. Make sure you cross that path I mentioned too, clean it for good.", + "66ab9da7eb102b9bcd08591c failMessageText": "", + "66ab9da7eb102b9bcd08591c successMessageText": "The forest likes quiet, we can't let them destroy such places. \n\nI don't know how they could have found out about this trail... My friend has never shown his paths to bad people.", + "66ab9da7eb102b9bcd08591d": "Eliminate Scavs at the village on Lighthouse (In one raid)", + "66ab9da7eb102b9bcd08591f": "Use the transit from Lighthouse to Shoreline (In one raid)", + "66ab9da7eb102b9bcd085922": "Eliminate Scavs at the village on Shoreline (In one raid)", + "66ab9da7eb102b9bcd08591c acceptPlayerMessage": "", + "66ab9da7eb102b9bcd08591c declinePlayerMessage": "", + "66ab9da7eb102b9bcd08591c completePlayerMessage": "", + "66aba85403e0ee3101042877 name": "Beneath The Streets", + "66aba85403e0ee3101042877 description": "Good afternoon. I have received information that somewhere under the city there is an abandoned entrance to the Laboratory. \n\nApparently, TerraGroup has converted one of the old bomb shelters into an emergency exit from their lab. This presents us with a unique opportunity to acquire all the precious equipment we need with minimal risk! \n\nHowever, I cannot send my people out without reconnaissance, it would be too dangerous. It's better to have someone experienced check this passage first and make sure the areas of interest are secure. Will you help us?", + "66aba85403e0ee3101042877 failMessageText": "", + "66aba85403e0ee3101042877 successMessageText": "So you have found it indeed. Excellent! How's the passage, is it safe? In a state of disrepair, you say? Well, it seems like this opportunity won't be with us for long. I'll send my men as soon as possible.", + "66aba85403e0ee3101042878": "Locate the passage leading to The Lab on Streets of Tarkov (In one raid)", + "66aba85403e0ee310104287a": "Use the transit from Streets of Tarkov to The Lab (In one raid)", + "66aba96e18a4a43b2a990b4e": "", + "66aba97b1000025218c82ea8": "Locate the passage leading to Streets of Tarkov in The Lab (In one raid)", + "66aba9b0b3712c785ccb2647": "", + "66aba9ec70e169fe1a10c85f": "", + "66aba9f5e1c9b85bc70eaf3b": "", + "66b090f5723e7bbe8b518ca8": "Scout the server room in The Lab (In one raid)", + "66b0910951c5294b9d213918": "Scout the hazard dome in The Lab (In one raid)", + "66b10eef0951e90ec383850b": "Scout the control room in The Lab (In one raid)", + "66aba85403e0ee3101042877 acceptPlayerMessage": "", + "66aba85403e0ee3101042877 declinePlayerMessage": "", + "66aba85403e0ee3101042877 completePlayerMessage": "", + "66abb019f5ca239a1006258b name": "Marathon - Sightseeing", + "66abb019f5ca239a1006258b description": "Hello my brother in crime! We got some real action coming up, you hear about the new trails? Mister Fence is planning to set up a real network, and he needs a little help from our end.\n\nHere's the plan: I'll give you the locations, you mark them. Think of it as strolling around the city and enjoying the beautiful places.\n\nYou, however, will take the less known paths. Nobody's been there since the Contract Wars, probably. You'll be thanking me after such a trip!", + "66abb019f5ca239a1006258b failMessageText": "", + "66abb019f5ca239a1006258b successMessageText": "You done with the sightseeing? Fucking great, mate! Oh, by the way... Is it true what they say about this mushroom picker wandering through the swamp at night?", + "66abb07983e00cd68c493b93": "Mark the passage to Streets of Tarkov with an MS2000 Marker on Ground Zero", + "66abb07f5186167dc936b545": "Mark the passage to Interchange with an MS2000 Marker on Streets of Tarkov", + "66abb081f95aebc762e59c21": "Mark the passage to Streets of Tarkov with an MS2000 Marker in The Lab", + "66abb0869dfc42f39dae135b": "Mark the passage to Customs with an MS2000 Marker on Interchange", + "66abb087ce20f2d428c52435": "Mark the passage to Factory with an MS2000 Marker on Customs", + "66abb0895ffee6d7968d3f4c": "Mark the passage to Woods with an MS2000 Marker on Factory", + "66abb08bf51ed35fd1af9b6f": "Mark the passage to Reserve with an MS2000 Marker on Woods", + "66abb08f50fe485b45cb5d6e": "Mark the passage to Lighthouse with an MS2000 Marker on Reserve", + "66abb0918d26bf2c9da1507e": "Mark the passage to Shoreline with an MS2000 Marker on Lighthouse", + "66b0fc1ee4b718b3f29d2e49": "Mark the passage to The Lab with an MS2000 Marker on Streets of Tarkov", + "66abb019f5ca239a1006258b acceptPlayerMessage": "", + "66abb019f5ca239a1006258b declinePlayerMessage": "", + "66abb019f5ca239a1006258b completePlayerMessage": "", + "66abb32aeb102b9bcd088d5f name": "Marathon - From Beginning To End", + "66abb32aeb102b9bcd088d5f description": "Hello, mercenary. You must have heard about the \"new\" routes between the city and its suburbs. \n\nIn reality, they've been around since the Contract Wars. All we had to do was validate and network them. Later on, I'll open it up to the public: less people will want to get their hands on my goods in popular places.\n\nBut right now, I need to move one shipment across the city, pronto. You'll lead the way to secure the path for my men in dangerous areas. \n\nI've already got some of the routes under my people's control, so they can transfer your things to your Hideout.", + "66abb32aeb102b9bcd088d5f failMessageText": "", + "66abb32aeb102b9bcd088d5f successMessageText": "The buyer has told me everything is in place. You've earned your reward, and you can expect my men to help you on the new trails.", + "66abb32aeb102b9bcd088d62": "Use the transit from Ground Zero to Streets of Tarkov", + "66abb39bf1d97b9b55390a79": "Use the transit from Streets of Tarkov to Interchange", + "66abb3a52d8bf81df0ec6156": "", + "66abb3aae25c1c539ab84870": "Use the transit from Interchange to Customs", + "66abb3ac416b26ade4a1446c": "Use the transit from Customs to Factory", + "66abb3bf228ace5ca9f3d745": "Use the transit from Factory to Woods", + "66abb3c546296c1d3abd4ec5": "Use the transit from Woods to Reserve", + "66abb3ca1925053c0493f8b0": "Use the transit from Reserve to Lighthouse", + "66abb3d0b87953519dc5e04b": "Use the transit from Lighthouse to Shoreline", + "66b2165e67c60d029fd20ec8": "Survive and extract from Shoreline", + "66abb32aeb102b9bcd088d5f acceptPlayerMessage": "", + "66abb32aeb102b9bcd088d5f declinePlayerMessage": "", + "66abb32aeb102b9bcd088d5f completePlayerMessage": "", + "66b38c7bf85b8bf7250f9cb6 name": "Rough Tarkov", + "66b38c7bf85b8bf7250f9cb6 description": "Hello there. I see you've become very confident in your survival skills. That's what gets people killed. Overconfidence weakens your senses, and Tarkov doesn't tolerate it. \n\nI was talking to an old comrade of mine, and let me tell you, tripwires are the ultimate test of alertness. Partisan has driven a great many bastards out of existence, and most of the time it was only a matter of catching the enemy inattentive. Yes, his methods are extreme, he's been like that since Afghanistan.\n\nEven if you're on my friend's good side, there are still plenty of \"gifts\" in Tarkov even without him. Not just in the woods, too. Sometimes even a random room can come with an explosive surprise. That's why I advise you to cut down on your eagerness and take a closer look at such places. \n\nYou'll live longer if you learn to recognize mortal danger.", + "66b38c7bf85b8bf7250f9cb6 failMessageText": "", + "66b38c7bf85b8bf7250f9cb6 successMessageText": "Would you look at that, you're alive! While you were gone, I've prepped this little thingie for you, so you can learn the secrets of booby trapping on your own. Consider it a homework assignment, but just make sure to not blow yourself up.", + "66b38c7bf85b8bf7250f9cb7": "Locate the heavily mined area on Woods", + "66b38de6a97d8cbafd711846": "Locate the Claymore mine on Ground Zero", + "66b38c7bf85b8bf7250f9cb6 acceptPlayerMessage": "", + "66b38c7bf85b8bf7250f9cb6 declinePlayerMessage": "", + "66b38c7bf85b8bf7250f9cb6 completePlayerMessage": "", + "66b38e144f2ab7cc530c3fe7 name": "Every Hunter Knows This", + "66b38e144f2ab7cc530c3fe7 description": "Come on in. So, how's your tripwire business going? No luck? Figures. This isn't like mindlessly shooting everyone. You've got to have a sense of intuition and know where the prey's gonna be. If you were a hunter, you'd understand.\n\nTry watching where the bandits hang out. Think about where your wire would catch the bastard off guard and how to conceal it. Take your time, use your best judgment. \n\nOnly then will your hunt be fruitful. Come back when you find at least a couple good spots. I wouldn't be so quick to set these tripwires around, otherwise you'll kill some of your teammates by accident.", + "66b38e144f2ab7cc530c3fe7 failMessageText": "", + "66b38e144f2ab7cc530c3fe7 successMessageText": "Good job, you found some decent spots. Tripwires demand a specific approach, and now you're starting to get the hang of it. Come back if you need another tripwire kit.\n\nBe careful, though! You're not the only one who knows how to set a tripwire, which means every bush, every room, and every rock can kill you. Remember that well.", + "66b38e144f2ab7cc530c3fe8": "Locate a good tripwire installation spot on Factory", + "66b38e144f2ab7cc530c3fea": "Locate a good tripwire installation spot on Customs", + "66b38e144f2ab7cc530c3fe7 acceptPlayerMessage": "", + "66b38e144f2ab7cc530c3fe7 declinePlayerMessage": "", + "66b38e144f2ab7cc530c3fe7 completePlayerMessage": "", + "66d9cbb67b491f9d5304f6e6 name": "Is This a Reference?", + "66d9cbb67b491f9d5304f6e6 description": "Hello, merc. Do you ever find yourself thinking that certain places in Tarkov look suspiciously similar to something you've already seen before?\n\nOne of my outside contacts has proven to be an avid admirer of such coincidences. Well, now I need someone to set up surveillance on these listed locations.\n\nOh, one more thing. The client asked me to tell whoever takes the job to do this with “maximum effort” and something about “207 bones in the human body”, whatever that means. Looks like this comedian is bored out of his mind and doesn't know what to do with himself.", + "66d9cbb67b491f9d5304f6e6 failMessageText": "", + "66d9cbb67b491f9d5304f6e6 successMessageText": "Well would you look at this. The customer is very pleased with the material. He even said that he himself would fit in well with the local culture with his blades and pistols.\n\nWe really don't need any more katana lovers in leather suits around here... I hope his interest in Tarkov passes as quickly as it arose.", + "66d9cbb67b491f9d5304f6e9": "Install a WI-FI Camera at the amphibian pizza lovers' hideout on Streets of Tarkov", + "66d9cbb67b491f9d5304f6ea": "Install a WI-FI Camera at the burned girl's sickroom on Streets of Tarkov", + "66d9cbb67b491f9d5304f6eb": "Install a WI-FI Camera at the barbed wire body on Streets of Tarkov", + "66dacf2a88c7001436a67390": "Install a WI-FI Camera at the really scary hole in the wall on Streets of Tarkov", + "66dad1d7811532f53e472c13": "Install a WI-FI Camera at the high rise where one die-hard guy kicked ass on Ground Zero", + "66dad1d941756590432b0eaa": "Install a WI-FI Camera at the computer with a joke for programmers on Ground Zero", + "66dad1dbb16caebe0e214d89": "Install a WI-FI Camera at the little chair surrounded by big black chairs on Ground Zero", + "66dad1ddec53b0df3b10a1b9": "Install a WI-FI Camera by your friend Wilson on Lighthouse", + "66dad1de93c8fcffd5790d89": "Install a WI-FI Camera at the kindled rest place on Lighthouse", + "66dad1e0703b718902451ee4": "Install a WI-FI Camera at the ominous welcome sign on Lighthouse", + "66dad1e21e7ef28d17a69a93": "Install a WI-FI Camera at the megagenius scientist's seat on Lighthouse", + "66dad1e607181e2f78a3a0a2": "Install a WI-FI Camera at the place where conscripts did a very important task on Reserve", + "66dad1e843a718561db0fdd3": "Install a WI-FI Camera at the two chair riddle on Reserve", + "66dad1ebc5c8e6cd26dd1d31": "Install a WI-FI Camera at every tank driver's first videogame on Reserve", + "66dad1edbc4fdd0c6eb38c5e": "Install a WI-FI Camera at the bucket-head villain on Customs", + "66dad1f00e049ac7abb6d801": "Install a WI-FI Camera at Anvil 3-4 crew member's execution site on Customs", + "66dad1f22edc2103eb176de8": "Install a WI-FI Camera at every indie developer's worst nightmare on Customs", + "66db1f8d7539f4b4eb640aff": "Install a WI-FI Camera in the room where the firefighter burned the books to become happy on Factory", + "66db1f8f564045697071d934": "Install a WI-FI Camera at the place where some valve technicians couldn't finish their third project on Factory", + "66db1f928d59a9fe511dfc25": "Install a WI-FI Camera at the dangerous Russian chocolate beauty on Factory", + "66db1f94a147d9840ec0dfba": "Install a WI-FI Camera in the conspiracy theorist's room on Factory", + "66db1f98b8e22a92437fe5c6": "Install a WI-FI Camera near where someone thought he'd get transported to the magic school on Factory", + "66db1f9b4f7bf01d937eb150": "Install a WI-FI Camera at the mother of all strategy games on Factory", + "66db1ff798d52a5a8e4ed1f8": "Install a WI-FI Camera at the stairway to the skies on Factory", + "66debf2b9e4ce2ef233ee5b7": "Install a WI-FI Camera at the bear who sat into a flaming car on Woods", + "66debf2e1e254957b82711ff": "Install a WI-FI Camera at the upside-down chair on Shoreline", + "66debf30802386a45d0adb60": "Install a WI-FI Camera at the not-so-lonely bathroom on Shoreline", + "66debf32dbb19129c35938d2": "", + "66d9cbb67b491f9d5304f6e6 acceptPlayerMessage": "", + "66d9cbb67b491f9d5304f6e6 declinePlayerMessage": "", + "66d9cbb67b491f9d5304f6e6 completePlayerMessage": "", + "66e01aca214f88109006a4b5 name": "Into the Inferno", + "66e01aca214f88109006a4b5 description": "The soldier of fortune has come for his new task! Rumors have it that Tarkov has become even more dangerous. Who would've thought, right? Someone's started targeting certain areas with mortar fire. \n\nYou better go and see what's going on. And yes, this means going right into the middle of those mortar strike areas. Yup. Alright, so we've noticed the bombardments in the nature reserve, the military base, the customs office, and the coast line. Off you go then.", + "66e01aca214f88109006a4b5 failMessageText": "", + "66e01aca214f88109006a4b5 successMessageText": "Alive and well, that's great. So let's see what we're working with here. Somebody stole the mortars and now they're hitting various locations right before the airdrop supplies come in. \n\nVery suspicious. These local powdermen sure couldn't have secured communications with the outside world, could they? Either way, all we can do for now is watch.", + "66e01df1af891d3886705427": "", + "66e04e2f282e96cb6f2e50d1": "", + "66e19b019f1774a3038c0c67": "Visit an active mortar strike area on any specified location (Shoreline, Woods, Reserve, Customs)", + "66e01aca214f88109006a4b5 acceptPlayerMessage": "", + "66e01aca214f88109006a4b5 declinePlayerMessage": "", + "66e01aca214f88109006a4b5 completePlayerMessage": "", + "66e01ad15a8890455a0d9eea name": "In and Out", + "66e01ad15a8890455a0d9eea description": "New mission, soldier. I want whatever it is that comes in those crates. According to the intel, there's valuable military equipment inside. Oh and yeah, don't forget to take out the competition to make sure they don't steal anything important.\n\nBy the way, I got a package I thought you might need. It's a gift from a mutual friend of ours. Don't look at me like that, I'm talking about the four-eyes.", + "66e01ad15a8890455a0d9eea failMessageText": "", + "66e01ad15a8890455a0d9eea successMessageText": "Good work! Now, what do we have here? Bingo, It's radar parts. It'll come in handy in the future. I think I know who might be interested. \n\nWhat? You wanna know too? It's not a soldier's job to ask questions. On your way, merc.", + "66e01e5c807dd6f2b14da31b": "Eliminate PMC operatives on any location that has mortar strikes (Shoreline, Woods, Reserve, Customs)", + "66e01ef8c2c37ef8fe110ba9": "Hand over the found in raid item: Radar station spare parts", + "66e01ad15a8890455a0d9eea acceptPlayerMessage": "", + "66e01ad15a8890455a0d9eea declinePlayerMessage": "", + "66e01ad15a8890455a0d9eea completePlayerMessage": "", + "66e01ad6835f78499f049180 name": "Ours by Right", + "66e01ad6835f78499f049180 description": "Okay, I got word of a major fuck-up. It may not be your fault, but that's beside the point. The assholes at the water treatment plant intercepted a bunch of these crates with portable EW equipment in them. \n\nThey're obviously useless at this point, but I'm not gonna let them steal government property like this. \n\nFor a warrior like you, the task is feasible. Go to the WTP and get me those EW thingies. And yes, those rats need to be put down. \n\nThe EWs themselves have probably already been handed over to their commanders, so you're guaranteed to get this equipment from them. Assuming you don't die, I suppose.", + "66e01ad6835f78499f049180 failMessageText": "", + "66e01ad6835f78499f049180 successMessageText": "Splendid, the new toys have arrived. My guys are gonna love these. You need to be ready for anything these days, and such protection is definitely not superfluous.", + "66e0209ecec5c782dbd0f024": "", + "66e020ca3c3a0fe53346e455": "", + "66e0215028e22e7ef3c9aa2f": "", + "66e0218bab09a83519b09872": "", + "66e021c69099a9be779a1728": "", + "66e19f1821f233c7928e32dc": "Hand over the found in raid item: GARY ZONT portable electronic warfare device", + "66e19f359fee1e54e0e01f7c": "Eliminate Rogues", + "66e19f7d534a8ff2bb7e9f89": "Locate and neutralize Big Pipe", + "66e19fb429e9c0617af804a8": "Locate and neutralize Birdeye", + "66e19ff1d9a36fb31bc2b96a": "Locate and neutralize Knight", + "66e01ad6835f78499f049180 acceptPlayerMessage": "", + "66e01ad6835f78499f049180 declinePlayerMessage": "", + "66e01ad6835f78499f049180 completePlayerMessage": "", + "66e01adbd3d014f3ae061c12 name": "Provide Cover", + "66e01adbd3d014f3ae061c12 description": "This whole trader thing is going pretty well for me, wouldn't you say? You know, If I didn't have my wits about me, I'd be dead in this hellhole a long time ago. Anyway, I'll deal with the reports later, not the first time. \n\nRight now, I need to equip the guys posted outside my territory. Bring them this new equipment we found. I'll give you a part of it, but the rest you need to get yourself - you already know where to look. No, you won't meet them face to face. Just stash the items in the designated spot.", + "66e01adbd3d014f3ae061c12 failMessageText": "", + "66e01adbd3d014f3ae061c12 successMessageText": "Good, now that they're safe from airborne threats, their combat mission will be accomplished with no problem.", + "66e062d886157640d5db6eb8": "", + "66e063a790b9dd1d882ec236": "", + "66e06bef25097c1088d27459": "", + "66e06c7a4220aba55b7ce4d1": "", + "66e070d21022d2c195b847aa": "Stash the GARY ZONT portable electronic warfare device inside the sunken church on Woods", + "66e071c8a9e80c3f25bb1bad": "Stash the Radar station spare parts inside the old sawmill hangar on Woods", + "66e0735089627301d900ef1d": "Stash the GARY ZONT portable electronic warfare device inside the weather station tower on Shoreline", + "66e073bb328d35f5dcb8f0cc": "Stash the GARY ZONT portable electronic warfare device inside the chairman's house on Shoreline", + "66e01adbd3d014f3ae061c12 acceptPlayerMessage": "", + "66e01adbd3d014f3ae061c12 declinePlayerMessage": "", + "66e01adbd3d014f3ae061c12 completePlayerMessage": "", + "66e01ae0c391e4c94903d220 name": "Cream of the Crop", + "66e01ae0c391e4c94903d220 description": "Good of you to drop by! Got a job for you, cargos again. It seems someone has figured out that some of the equipment has fallen into the wrong hands. But that is not the problem. \n\nWe got word of an important airdrop they will target immediately if they see it. We're gonna have to work hard to get it. Keep it as confidential as possible. The key is to make sure you don't get spotted with the package. \n\nGet a special yellow RSP flare at the coast. They're stashed at high elevations, like roofs and towers. Then find a spot somewhere out of the way and shoot it.\n\nThe necessary people will recognize it and send the package. Wait for it and take whatever's in it. Then, run to stash the devices at the designated spots at the Lighthouse. Go straight from the coast, it'll be quicker.\n\nDo it all in one go, don't get killed or go back to your bunker until you've finished the job. Oh, and avoid shelling, obviously. This equipment can't be wasted. Serious people are interested in this matter, and mister Lightkeeper expects to hear from me when the task is completed.", + "66e01ae0c391e4c94903d220 failMessageText": "", + "66e01ae0c391e4c94903d220 successMessageText": "The task was difficult, but you did it perfectly, soldier! Now all that remains is to find out who brought such rare tools to Tarkov and for what purpose. But that's my concern, you don't need to get involved.\n\nI've got a good reward for you. My guys intercepted some Scavs, they had some special RSP flares on them. Should be useful!", + "66e0864adb7c624eb1ebfc85": "Find the KOSA UAV electronic jamming device in raid", + "66e086a04a164106f15e5f3f": "Stash the KOSA device on the second floor of the yacht club cottage on Lighthouse", + "66e086e294bc96e5460ca731": "Stash the KOSA device inside the abandoned house near Lightkeeper's bridge on Lighthouse", + "66e2c832596e2895181e1bd4": "Use the transit from Shoreline to Lighthouse", + "66e01ae0c391e4c94903d220 acceptPlayerMessage": "", + "66e01ae0c391e4c94903d220 declinePlayerMessage": "", + "66e01ae0c391e4c94903d220 completePlayerMessage": "", + "66e01c4c475acf7e0102d296 name": "Before the Rain", + "66e01c4c475acf7e0102d296 description": "Come on in. The airdrops keep coming in, and our job is to hold on to whatever we can intercept. If these assholes have mastered mortars, they'll be unstoppable with EWs and spare parts for them.\n\nBring me everything you can get. I'll prepare a good reward.", + "66e01c4c475acf7e0102d296 failMessageText": "", + "66e01c4c475acf7e0102d296 successMessageText": "I think we salvaged most of it, that's good. Now we wait.", + "66e079a0fdf3ab1d92995bdf": "Hand over the found in raid item: Radar station spare parts", + "66e079f0f08b6243434eb622": "Hand over the found in raid item: GARY ZONT portable electronic warfare device", + "66e01c4c475acf7e0102d296 acceptPlayerMessage": "", + "66e01c4c475acf7e0102d296 declinePlayerMessage": "", + "66e01c4c475acf7e0102d296 completePlayerMessage": "", + "66e3e2ee2136472d220bcb36 name": "Night of The Cult", + "66e3e2ee2136472d220bcb36 description": "About time you stopped by. You've noticed those night devils coming out of everywhere too, haven't you? They're arming themselves a lot better, huh. It's like someone's actually working with them. From above, you know?\n\nWe should look into what those bastards are up to. Besides, all the better if you can reduce their numbers. Just be careful. \n\nThere's a rumor among the scavengers that you can run into an invincible beast at night. They say it hunts and devours humans. \n\nI remember an Eastern story about such a demon, its nickname was, uh... “The Oni”. I wouldn't have brought these stories up before. But now something's definitely brewing, and dark thoughts just keep creeping into my head.", + "66e3e2ee2136472d220bcb36 failMessageText": "", + "66e3e2ee2136472d220bcb36 successMessageText": "So, what'd you find? I didn't sit idle either while you were gone, I met with Partisan. He says they're preparing a special ritual, and that's why they're coming out of their dens. They're all mentioning some kind of “Night of The Cult”.\n\nI don't know what's this about, but it's definitely bad news for Tarkov. And something tells me there's somebody who's orchestrating the whole thing. That demon didn't just show up in our parts for no reason. \n\nI saw something myself last night, though. His face was red, like it was burning. I grabbed my gun and aimed, but just as I blinked, there was no one there. Old man hallucinations, perhaps...", + "66e3e3482636168958243a09": "", + "66e3e780e4dbb01803c493f4": "Eliminate the hooded night people", + "66e3e2ee2136472d220bcb36 acceptPlayerMessage": "", + "66e3e2ee2136472d220bcb36 declinePlayerMessage": "", + "66e3e2ee2136472d220bcb36 completePlayerMessage": "", + "66e3e2fcb26de0e0790d3fe6 name": "The Graven Image", + "66e3e2fcb26de0e0790d3fe6 description": "Alright, I've got good news for you. \nPartisan managed to eavesdrop on the cultists' conversation before the tripwire killed them.\n\nThe Harbinger, as they call him, is in charge of this whole terror parade. He promised them that if they did what he told them, they'd receive the new Gift of the Unheard. What the hell? I have no idea what this means. But I'm certain that if you let them perform the damn ritual, there'll be countless victims amongst the decent folk. People have started fleeing the Streets, they say a ghost is hunting for souls.\n\nWe don't know the details of this mystery, but it's definitely connected to the whole thing! And we know who's behind it. We need to take out the Harbinger, and if you find any creepy crap near him, try to bury it deep in the ground. Maybe that'll keep the cultists in line.", + "66e3e2fcb26de0e0790d3fe6 failMessageText": "", + "66e3e2fcb26de0e0790d3fe6 successMessageText": "The bastards are taken care of? Damn things belong in hell anyway. Hopefully, the rest of the cultists will back off and go back to their dens. \n\nFunny thing is, Zryachiy's been absent lately, too. I wonder if he came down from the Lighthouse to finish the ritual and let those demons out into the light of day.", + "66e3e43cf8becfe5cc6a9938": "", + "66e3e492d9326ab109c70089": "", + "66e3e4c45e55183329f46c4d": "", + "66e3eb3592c6be7be7fdc2e5": "Locate and neutralize the Oni", + "66e3eb4c4a5359f2db0be81a": "Locate and neutralize the Harbinger", + "66e3eb65e385f94b38f061d7": "Locate and neutralize the Ghost", + "66e3e2fcb26de0e0790d3fe6 acceptPlayerMessage": "", + "66e3e2fcb26de0e0790d3fe6 declinePlayerMessage": "", + "66e3e2fcb26de0e0790d3fe6 completePlayerMessage": "", + "66e3e3027804a21d860755d6 name": "Until Dawn", + "66e3e3027804a21d860755d6 description": "I reckon you can see what's going on now that you're back. Not only have those brutes not dispersed, but they've begun to organize their preparations even more vigorously! \n\nI just got word that the poor kid Ryzhy has been captured by Zryachiy himself. They say he'll be the main sacrifice. That means we're running out of time!\n\nPartisan is still in the forest hunting for cultists, but even he can't do it alone. Now it's up to us to clean up the scum with our own hands. If there's nobody to carry out the ritual, maybe it'll be over.", + "66e3e3027804a21d860755d6 failMessageText": "", + "66e3e3027804a21d860755d6 successMessageText": "Freeze, you vermin! Oh, it's you. They're starting to show up in my neck of the woods now, too. I've had a few of those visitors just before you.\n\nYou say you've cleansed Tarkov of the cultists? Well, with losses like that, they won't be able to do anything anytime soon. They'll forget all about the Harbinger. However, I don't know if I'll be able to sleep easy for a while.\n\nThanks for your help. Couldn't have done it without you.", + "66e3e57fe7f565222935089e": "", + "66e3e6663bb29f616cf844de": "", + "66e3e8d323cf1fe67c0bed75": "", + "66e3e9b4218d34e0cce29dfc": "Eliminate the hooded night people on Ground Zero", + "66e3ec28ecbe7102342ea56a": "Eliminate the hooded night people on Lighthouse", + "66e3ecad063ef452798d369d": "Eliminate the hooded night people on Shoreline", + "66e3ecdc80b51f15f1043595": "Eliminate the hooded night people on Streets of Tarkov", + "66e3ed0e637221ba629e2c14": "Eliminate the hooded night people on Woods", + "66e3ed3a01f926ac4c2c3c94": "Eliminate the hooded night people on Customs", + "66e3ef4c458485a487458eed": "Eliminate the hooded night people on night-time Factory", + "66e3e3027804a21d860755d6 acceptPlayerMessage": "", + "66e3e3027804a21d860755d6 declinePlayerMessage": "", + "66e3e3027804a21d860755d6 completePlayerMessage": "", + "670404a2ea1caa8f2e0be106 name": "Don’t Believe Your Eyes", + "670404a2ea1caa8f2e0be106 description": "Hello. Tell me, are you feeling healthy? There's been talk of some kind of disease, either from the Lab or somewhere else. I even had a “witness” come in, clearly gone mental. \n\nHe told me about the living dead who bleed themselves and hunt people. I tell you what, I've heard many such tales before.\n\nYet the man's grayed hair and that look in his eyes... He's definitely seen something sinister. Maybe some looters mutilated a corpse for fun, or some poor bastard spilled acid on himself. \n\nIn any case, I think you should look into that story. You know how panic spreads around this place.", + "670404a2ea1caa8f2e0be106 failMessageText": "", + "670404a2ea1caa8f2e0be106 successMessageText": "I cannot believe it! So the madman was telling the truth? If it's connected to TerraGroup and their experiments, it's bad news.\n\nIt seems that someone has opened the Lab from the inside, disrupted all the security, and now anyone can get in and out of there.\n\nTake care of yourself and get ready for some serious footwork. Tarkov is in great danger.", + "67040502c599a240aeb7fc94": "Eliminate the infected on any location", + "671b9af6038f464a253ff93c": "Locate the source of rumors of the living dead in The Lab", + "671b9d4ef32cf95e65e0d54b": "Find a way inside the quarantined section in The Lab", + "670404a2ea1caa8f2e0be106 acceptPlayerMessage": "", + "670404a2ea1caa8f2e0be106 declinePlayerMessage": "", + "670404a2ea1caa8f2e0be106 completePlayerMessage": "", + "67040b3d10b18d153a08f636 name": "Dirty Blood", + "67040b3d10b18d153a08f636 description": "I don't ever want to stand in the same room with that bitch, but looks like we don't have much of a choice... At this point, our survival depends on whether or not we can defeat this infection.\n\nCollect blood samples from the infected and bring them to me. I'll go to Therapist and tell her what's going on. \n\nI think she'd be willing to help the city in the face of such a threat, even if there's no money in it for her.", + "67040b3d10b18d153a08f636 failMessageText": "", + "67040b3d10b18d153a08f636 successMessageText": "Okay, good. I'm glad you're still in one piece. Don't get caught by those bastards, I still need your help.", + "67040f4c53184e7f6641add6": "Locate and obtain the infected blood sample in The Lab", + "67040f56ff76cf3a5cea93bd": "Hand over the found item", + "67040b3d10b18d153a08f636 acceptPlayerMessage": "", + "67040b3d10b18d153a08f636 declinePlayerMessage": "", + "67040b3d10b18d153a08f636 completePlayerMessage": "", + "67040b6c45eaf70db10dbec6 name": "Burn It Down", + "67040b6c45eaf70db10dbec6 description": "So I went to see this \"friend\" of ours. She says she needs time. That's exactly what we don't have right now! The contagion is spreading quickly, the sick have already been seen above ground.\n\nWe must forget about the old problems for a while and put all our energies into killing the scourge. Take plenty of ammunition and don't let them surround you. \n\nUntil we have a cure, our only option is to kill as many as possible.", + "67040b6c45eaf70db10dbec6 failMessageText": "", + "67040b6c45eaf70db10dbec6 successMessageText": "Oh, that's you. Are you absolutely certain you're not infected? They say the first symptom is itching and fever.\n\nBut if you've killed so many of them and haven't gotten sick yourself, then I'm sure you're still able to help. You can go for now, and I'll make some lemon tea with honey. To keep my immune system strong, you know?", + "67040b6c45eaf70db10dbec9": "Eliminate the infected on any location", + "67040b6c45eaf70db10dbec6 acceptPlayerMessage": "", + "67040b6c45eaf70db10dbec6 declinePlayerMessage": "", + "67040b6c45eaf70db10dbec6 completePlayerMessage": "", + "67040ba4578a46e44a05c0a8 name": "The Root Cause", + "67040ba4578a46e44a05c0a8 description": "Greetings. I figure you're already aware of the recent situation, granted you've found the blood samples Jaeger brought me. I've analyzed them, but it's not sufficient.\n\nIn order to get started, I need a sample of the virus itself. This is extremely dangerous, so use every precaution during the mission!\n\nCome and see me as soon as you find it. This is to minimize the time the virus is out in the open.", + "67040ba4578a46e44a05c0a8 failMessageText": "", + "67040ba4578a46e44a05c0a8 successMessageText": "Only when you know what you're up against can you make an effective remedy.\n\nBut that will take time. The information that may have been stored on some TerraGroup devices would help speed up the process. \n\nI have contacted Mechanic. If he finds anything useful, he will contact you himself.", + "670410d1b4843ee4b8830049": "Locate and obtain the virus sample in The Lab", + "670410e1eccf320a037c030b": "Hand over the found item", + "67040ba4578a46e44a05c0a8 acceptPlayerMessage": "", + "67040ba4578a46e44a05c0a8 declinePlayerMessage": "", + "67040ba4578a46e44a05c0a8 completePlayerMessage": "", + "67040c22cc1f3752720376e9 name": "Matter of Technique", + "67040c22cc1f3752720376e9 description": "Tough times are upon us, huh? TerraGroup is one big box of mysteries.\n\nWhat could be crazier than turning a man into the living dead? I doubt Tarkov will survive this blow if we can't stand up to it.\n\nAt Therapist's request, I did some research and found a working computer that might have some useful data left on it. But now we need you.\n\nPrepare the thumb drive exactly as instructed, get to TerraGroup's computer in their office in the city, and leave it there. You'll have to stay at the PC to make sure the connection is established. \n\nOnce you've done your part, our mutual acquaintance and I will do the rest - all a matter of technique.", + "67040c22cc1f3752720376e9 failMessageText": "", + "67040c22cc1f3752720376e9 successMessageText": "Okay, I see the connection, so you did everything right... Oh, they're DDoS-proofed. But what if we access it from here, you assholes? Hm, that's where Mr. Kerman comes in.\n\nAre you still here? I'm sorry, I don't have time to chitchat anymore. Kerman just sent over his data, said he's not gonna let TerraGroup's projects ruin our city. \n\nWhile he takes down the security, I have to format the drives to give Therapist everything we can find out.", + "670411a2cded018840f5b599": "Locate the required computer at TerraGroup's Cardinal office on Streets of Tarkov", + "670411d819aafd130ebc4bb8": "Install the flash drive at the computer to download the files", + "670411f392f504013a1c89fe": "", + "67041205106aa148ad4ac0d7": "", + "67040c22cc1f3752720376e9 acceptPlayerMessage": "", + "67040c22cc1f3752720376e9 declinePlayerMessage": "", + "67040c22cc1f3752720376e9 completePlayerMessage": "", + "67040c43ce929d6ee506c7c7 name": "Find the Source", + "67040c43ce929d6ee506c7c7 description": "It's good you're back. The TerraGroup information was useful, but still not enough to create a working antidote. However, I did find an important lead.\n\nThe project to create this virus was highly classified, but Mechanic matched the virus codes with TerraGroup's internal division indexes. And we found an overlap.\n\nOne of the key employees, not officially assigned to any open project, was a certain Vladimir O. I'm sure that a specialist of such importance kept everything important on his person, so as not to risk the spread of information.\n\nYou need to thoroughly check the territory of the Laboratory, especially in the area of the block where the virus was developed. If my hunch is correct, you may find Vladimir's records there.", + "67040c43ce929d6ee506c7c7 failMessageText": "", + "67040c43ce929d6ee506c7c7 successMessageText": "Good! I'll get to work right away and contact Mechanic. \n\nThe diary is probably encrypted, so our friend's love of complex riddles will come in handy.", + "6706893e6451790d64465e12": "Access the sealed room with the virus in The Lab", + "6706896497a1fabc16e68de4": "Locate and obtain the diary inside the room", + "6706896f9f1291bdecc69c30": "Hand over the found item", + "67040c43ce929d6ee506c7c7 acceptPlayerMessage": "", + "67040c43ce929d6ee506c7c7 declinePlayerMessage": "", + "67040c43ce929d6ee506c7c7 completePlayerMessage": "", + "67040c5b4ac6d9c18c0ade26 name": "Gloves Off", + "67040c5b4ac6d9c18c0ade26 description": "So, any progress on creating a cure for the infection? I hope Therapist is truly engaged in this and not just looking for a good buyer for this diary.\n\nWe still can't cure Tarkov once and for all, so let's at least clean it up while we can. I've heard that the easiest way to kill these creatures is to shoot them in the head. In that sense, it's still the same as with humans. I'd take something more powerful to make sure their faces get shredded for sure. Right, take a shotgun with you!\n\nAlright, time for work. Get in the fight and help this city. Oh, and grab some of my honey tea to help your body fight off the sickness.", + "67040c5b4ac6d9c18c0ade26 failMessageText": "", + "67040c5b4ac6d9c18c0ade26 successMessageText": "Well done, kid! We're short of manpower right now, but together we're at least buying time to create a cure. \n\nAnd if we lose, at least we'll leave it cleaner. Just have to do what has to be done.", + "67040c5b4ac6d9c18c0ade29": "Eliminate the infected with a headshot while using a shotgun on any location", + "67040c5b4ac6d9c18c0ade26 acceptPlayerMessage": "", + "67040c5b4ac6d9c18c0ade26 declinePlayerMessage": "", + "67040c5b4ac6d9c18c0ade26 completePlayerMessage": "", + "67040c78bf4be8a4ef041a65 name": "Sample IV - A New Hope", + "67040c78bf4be8a4ef041a65 description": "We have managed to decipher the diary! This Vladimir was a true man of science, and realized in time that they were creating something terrifying.\n\nHe secretly began to develop an antidote all by himself. The work was in its final stages, he even synthesized several prototypes!\n\nIt seems he made one mistake in estimating the length of the virus' incubation period... That is what probably made him the first victim of a project he himself had been involved in.\n\nWe have reason to believe there's a sample of antidote number 4 in the sealed section. With it, we can recreate the vaccine formula and synthesize more.\n\nWe can't lose that sample. That's why I had to arrange a deal with that car service mobster to deliver the sample to my group. You'll need to cross from the Lab to the city, and then leave the vaccine at his, uh, workstation.", + "67040c78bf4be8a4ef041a65 failMessageText": "", + "67040c78bf4be8a4ef041a65 successMessageText": "Your contribution to saving the city is invaluable! However, I can't do a full analysis of the sample on my own.\n\nBut I know someone who can be involved in the process. An expert of the highest caliber... I will get back to you with the results very soon.", + "67068b5263a6a9dd703a29f2": "Locate and obtain the vaccine vial in The Lab", + "67068b5c3d3d44305f177281": "Hand over the found item", + "67262b4023c03479138728fa": "Use the transit from The Lab to Streets of Tarkov", + "67262ba531b7021ec5cfc7e8": "Stash the vaccine under Kaban's office on Streets of Tarkov", + "67040c78bf4be8a4ef041a65 acceptPlayerMessage": "", + "67040c78bf4be8a4ef041a65 declinePlayerMessage": "", + "67040c78bf4be8a4ef041a65 completePlayerMessage": "", + "67040c92bf4be8a4ef041a6c name": "Darkest Hour Is Just Before Dawn", + "67040c92bf4be8a4ef041a6c description": "You doing alright? Even though I can hardly stand on my feet, I went to see my mushroom picker friend and give him some of my tea. \n\nAnd you know what, the old man's keeping strong and healthy! That means we can't get discouraged either. The infected are everywhere now, but there are survivors too.\n\nSo, it's time to roll up our sleeves and do some dirty work. Go to every corner of Tarkov and eradicate the monsters - we'll do our best to save the few who haven't been infected yet.", + "67040c92bf4be8a4ef041a6c failMessageText": "", + "67040c92bf4be8a4ef041a6c successMessageText": "Glad you're still with us. It's getting better, even if it's only for a short while. \n\nWe can take a short break and regain our strength for now, as long as it's calm. Hopefully the medic hag will give us some results soon.", + "67040c92bf4be8a4ef041a6f": "Eliminate the infected on Ground Zero", + "670696ab3907c9db5b4612e9": "Eliminate the infected on Streets of Tarkov", + "6706a2843e88aef2615f9233": "Eliminate the infected on Interchange", + "6706a2a80af75b50e90dc89b": "Eliminate the infected on Reserve", + "6706a2cccd98cc18afe9cbb0": "Eliminate the infected in The Lab", + "6706a3e18e9193128de9c265": "Eliminate the infected on Lighthouse", + "6706a3fdf0c39b9d7b8657c5": "Eliminate the infected on Factory", + "6706a41aee82de6b3df6e35f": "Eliminate the infected on Shoreline", + "6706a4332cbd3d14ed928bbd": "Eliminate the infected on Customs", + "6706a44c4c287a29e432f182": "Eliminate the infected on Woods", + "67040c92bf4be8a4ef041a6c acceptPlayerMessage": "", + "67040c92bf4be8a4ef041a6c declinePlayerMessage": "", + "67040c92bf4be8a4ef041a6c completePlayerMessage": "", + "67040cae4ac6d9c18c0ade2c name": "Radical Treatment", + "67040cae4ac6d9c18c0ade2c description": "The vaccine you found is a real treasure! With the help of my former TerraGroup colleague, we managed to finalize the formula.\n\nUnfortunately, administering the drug is fatal along with neutralizing the virus. \n\nThis is the only way we can save those who have not yet been affected by this terrible disease... The best place to distribute the drug is in the water supply.\n\nDissolve it at the designated points and come back. I'll give you the recipe in case something happens to the doses you're receiving now.", + "67040cae4ac6d9c18c0ade2c failMessageText": "How dare you! My colleague made a critical contribution to saving the city and did not deserve this fate! I don't know how I can trust you after such outrageous actions.", + "67040cae4ac6d9c18c0ade2c successMessageText": "You made the right choice. I know Jaeger tried to trick you into harming my colleague.\n\nBut I assure you that this version of the drug was the safest way to cleanse the city of the virus...", + "6706a4ddec997e861c3f6f04": "Spread the vaccine on Lighthouse", + "6706a50277a97bdaa930c5f1": "", + "6706a504c00fb0d1f430a249": "Spread the vaccine on Shoreline", + "6706a51fa60dfe2fb85275ed": "Spread the vaccine on Woods", + "6706a52083168d9e8ed303d8": "Spread the vaccine on Customs", + "6706a61a5fb5eedf15ec6234": "Spread the vaccine on Factory", + "6706a634a92aee702eee4bb5": "", + "67091272fbf6f41d103a3216": "Spread the vaccine in The Lab", + "67040cae4ac6d9c18c0ade2c acceptPlayerMessage": "", + "67040cae4ac6d9c18c0ade2c declinePlayerMessage": "", + "67040cae4ac6d9c18c0ade2c completePlayerMessage": "", + "67040ccdcc1f3752720376ef name": "Forgotten Oaths", + "67040ccdcc1f3752720376ef description": "Wait! Did you also not know that she developed this “cure” with Sanitar? \n\nI bet they made a simplified version so they could just kill all the sick people without blinking an eye, yeah? I'm not going to let this happen.\n\nI know her nature... She definitely developed a less lethal version of the drug for her own use, or for sale. \n\nBut if she worked on it with this punk, that means he's the one who's keeping it! Punish the bastard and get the real version of the drug. \n\nIf not the drug itself, at least find the recipe... We'll figure it out from there, probably!", + "67040ccdcc1f3752720376ef failMessageText": "How stupid do you have to be to believe her, even after I literally spilled the truth? The blood of those who die from this vaccine will be on your hands, kid. \n\nWhen they come to you in your dreams, you'll realize what you've done.", + "67040ccdcc1f3752720376ef successMessageText": "All done, right? We've really rubbed it in these \"businessmen's\" noses!\n\nThis should remind the hag that she swore the Hippocratic Oath.", + "6706af584478a43e95ee1c5c": "", + "6706af5b05a230144c1ba1bc": "", + "6706af5d397d407f643268f8": "", + "6706af5f7a932b3fd9e703ae": "", + "6706af6171fdcfc5d912a647": "", + "6706af6cf1cdc7ba44665711": "Locate and obtain the true vaccine in Sanitar's office on Shoreline", + "6706afe3be5e96d75c2d01b9": "", + "6707e758f847ab10fd857441": "Locate and neutralize Sanitar", + "6719135cfab45272c32a8c01": "Hand over the found item", + "67040ccdcc1f3752720376ef acceptPlayerMessage": "", + "67040ccdcc1f3752720376ef declinePlayerMessage": "", + "67040ccdcc1f3752720376ef completePlayerMessage": "", + "6707e6614e617ec94f0e63dc name": "Clear Conscience", + "6707e6614e617ec94f0e63dc description": "You got it? Haha, I knew it! What kind of person would keep a cure for himself in times of plague?\n\nNow we must make the remedy strictly according to the instructions, so be careful. The entire success of our plan depends on your actions!\n\nWhile you were running for the recipe, I discussed the distribution issue with Mechanic. \n\nOnce you've made the vaccine, you need to distribute it through the water, just like the old times. Only now instead of a well, there'll be stations and pipes.", + "6707e6614e617ec94f0e63dc failMessageText": "", + "6707e6614e617ec94f0e63dc successMessageText": "Well, perhaps now it's finally over! All that matters is that you chose the right side, kid, and your conscience is clear.\n\nThe cure should certainly work if they made it for themselves, we just have to wait a little longer.", + "6707e6614e617ec94f0e63e0": "Spread the true vaccine on Lighthouse", + "6707e6614e617ec94f0e63e1": "", + "6707e6614e617ec94f0e63e2": "Spread the true vaccine on Shoreline", + "6707e6614e617ec94f0e63e3": "Spread the true vaccine on Woods", + "6707e6614e617ec94f0e63e4": "Spread the true vaccine on Customs", + "6707e6614e617ec94f0e63e5": "Spread the true vaccine on Factory", + "6709251bd1347df18467acee": "Spread the true vaccine in The Lab", + "6707e6614e617ec94f0e63dc acceptPlayerMessage": "", + "6707e6614e617ec94f0e63dc declinePlayerMessage": "", + "6707e6614e617ec94f0e63dc completePlayerMessage": "", + "67165d59a9c06627040a9094 name": "Forced measure", + "67165d59a9c06627040a9094 description": "I know that everyone has put aside their former concerns for the sake of survival. But whatever is happening at the Laboratory is beyond anything that can be tolerated!\n\nThere are so many infected there that the danger of new dangerous drugs spreading is extremely high. The sick are evidently losing their minds, and don't realize the risks when they smash the chemical flasks or break the rare equipment...\n\nWe must take back control of the Laboratory. We're the closest we've ever been to saving the city, and we can't allow another disaster. Tarkov won’t survive it. Sadly, there’s no saving those already infected—eliminate as many as possible using any means at your disposal. The safety of Tarkov is at stake.\n", + "67165d59a9c06627040a9094 failMessageText": "", + "67165d59a9c06627040a9094 successMessageText": "So many lives have been lost. But, you do realize that it had to be done, don't you? We can't let this virus spread all over Tarkov again.", + "67165d59a9c06627040a9097": "Eliminate the infected in The Lab", + "67165d59a9c06627040a9094 acceptPlayerMessage": "", + "67165d59a9c06627040a9094 declinePlayerMessage": "", + "67165d59a9c06627040a9094 completePlayerMessage": "", + "67190f157b0991dc22064755 name": "Foreign Support", + "67190f157b0991dc22064755 description": "How are you doing, mercenary? If you're still able to operate, you can help me with an important matter. We need assistance in the city. \n\nAccording to my information, right now there is a large number of infected in the central area. The West already knows what's happening and doesn't want to stay aside. \n\nHowever, the convoy that was sent to contain the situation has been destroyed. I have no more men left to spare, but the task must be accomplished. And we need to do it in a way that makes our partners' involvement obvious. \n", + "67190f157b0991dc22064755 failMessageText": "", + "67190f157b0991dc22064755 successMessageText": "You're back, and I've already received the necessary reports. It looks authentic enough that I don't think our partners will have any questions. You've earned your reward.", + "67190f157b0991dc22064758": "Eliminate the infected while wearing a UN uniform (UNTAR helmet, MF-UNTAR body armor, M4A1 rifle) on Streets of Tarkov", + "67190f157b0991dc22064755 acceptPlayerMessage": "", + "67190f157b0991dc22064755 declinePlayerMessage": "", + "67190f157b0991dc22064755 completePlayerMessage": "", + "67190f6c1b3f4964d90d71e9 name": "Global Threat", + "67190f6c1b3f4964d90d71e9 description": "I'm getting reports from the terminal near Azure Coast, my people say there are more and more infected every day. Even if one sick person makes it into the harbor area, chaos will ensue. \n\nPeople will panic, try to use water transportation to leave. In that case, the disaster could go beyond the borders of Norvinsk region and even Russia.\n\nThe port security needs help. If you help reduce the number of infected over there, I'll make sure you get a reward from my Western partners.", + "67190f6c1b3f4964d90d71e9 failMessageText": "", + "67190f6c1b3f4964d90d71e9 successMessageText": "You did it! The terminal is still secure, which means we've managed to keep the disaster within Tarkov's borders. As agreed, here's the reward from my partners.", + "67190f6c1b3f4964d90d71ec": "Eliminate the infected on Shoreline", + "67190f6c1b3f4964d90d71e9 acceptPlayerMessage": "", + "67190f6c1b3f4964d90d71e9 declinePlayerMessage": "", + "67190f6c1b3f4964d90d71e9 completePlayerMessage": "", + "67190f9c7b0991dc22064766 name": "Watch the Watcher", + "67190f9c7b0991dc22064766 description": "Greetings. I'm not sure if you have a good understanding of the balance of power in Tarkov, but currently it doesn't matter.\n\nOne of the key figures in this city is at the Lighthouse. You may not know him, but he sure knows all about you. \n\nThe person is well protected, but his guards could use some help. Due to the huge losses, I cannot provide any of my own manpower resources, but this could be a lucrative job for you.\n\nWho knows, maybe you'll get some credit for it later. Either way, this loss will cost Tarkov too much if you don't do anything about it.", + "67190f9c7b0991dc22064766 failMessageText": "", + "67190f9c7b0991dc22064766 successMessageText": "I've been told that the Lighthouse area is calmer and will not be needing our support for some time. You protected an important person in a difficult time, and you deserve your reward.", + "67190f9c7b0991dc22064769": "Eliminate the infected on Lighthouse", + "67190f9c7b0991dc22064766 acceptPlayerMessage": "", + "67190f9c7b0991dc22064766 declinePlayerMessage": "", + "67190f9c7b0991dc22064766 completePlayerMessage": "", + "67190febcce4a5fdf605d4f8 name": "Not a Step Back!", + "67190febcce4a5fdf605d4f8 description": "Times are hard, but you are a real warrior! Who else but you to defend our country from these monsters?\n\nI keep receiving reports of numerous enemy breakthroughs, and the least defended location is the nature reserve. You'll have to move into the area and kill as many of those freaks as you can.\n\nAnd yes, bring tons of ammo and stay on the high ground, you'll need it.\n\nAnd remember to stay at a distance, shoot them on the approach! Don't let them get too close to you.", + "67190febcce4a5fdf605d4f8 failMessageText": "", + "67190febcce4a5fdf605d4f8 successMessageText": "So many? Man, normally we'd just artillery the fuck out of them...\n\nBut you gave them a hell of a beating. If any of my soldiers managed to hide somewhere, now's the time to get out. I'm gonna go check the frequency.", + "67190febcce4a5fdf605d4fb": "Eliminate the infected from over 70 meters away on Reserve", + "67190febcce4a5fdf605d4f8 acceptPlayerMessage": "", + "67190febcce4a5fdf605d4f8 declinePlayerMessage": "", + "67190febcce4a5fdf605d4f8 completePlayerMessage": "", + "6719101deddf081d340d4c60 name": "Spread the Damage", + "6719101deddf081d340d4c60 description": "Good thing you stopped by, warrior. The city center got pretty tough. But I did some digging at our stockpiles and found some explosives.\n\nThat's what we've been missing! The only problem is, there's no one to deliver this package to those freaks.\n\nHelp us out, soldier! Now is not the time to save your supplies. We've got to use everything we have. Go out there and blow those bastards up. We've got to stop them.", + "6719101deddf081d340d4c60 failMessageText": "", + "6719101deddf081d340d4c60 successMessageText": "You are the truest of all warriors! Thanks to your assault, I even managed to pull one of my groups out of the encirclement.", + "6719101deddf081d340d4c63": "Eliminate the infected while using grenades or grenade launchers on Ground Zero", + "6719101deddf081d340d4c60 acceptPlayerMessage": "", + "6719101deddf081d340d4c60 declinePlayerMessage": "", + "6719101deddf081d340d4c60 completePlayerMessage": "", + "67191048eddf081d340d4c6e name": "Pressured by Circumstances", + "67191048eddf081d340d4c6e description": "It's tough everywhere right now, I know. Have you ever been fascinated by this human ability to adapt to any condition?\n\nI think it's what made man the pinnacle of evolution. But to feel like you're slowly getting used to the crowds of infected people in your hometown... It makes me sick.\n\nThe demand for firearms has increased tremendously, and I'm thinking that if this epidemic drags on, there will be only handguns left in the stockpiles. Can you test to see how effective they are in the current environment?", + "67191048eddf081d340d4c6e failMessageText": "", + "67191048eddf081d340d4c6e successMessageText": "It turns out you can survive even with a weapon like this, if you have the skills. But I'm not sure there's enough shooters of your caliber in the city. \n\nI hope we don't need your proven tactics. But it's best to prepare for the worst-case scenario.", + "67191048eddf081d340d4c71": "Eliminate the infected while using pistols or revolvers on Factory", + "67191048eddf081d340d4c6e acceptPlayerMessage": "", + "67191048eddf081d340d4c6e declinePlayerMessage": "", + "67191048eddf081d340d4c6e completePlayerMessage": "", + "671910d5dbd4354ac10e9784 name": "Conservation Area", + "671910d5dbd4354ac10e9784 description": "Hello again. Still feeling strong? Well, keep it that way. We're not going to get much rest any time soon.\n\nWhatever's going on with the treatment of this disease, there's still a lot of sick people all over the city! That's why I once again ask for your support.\n\nThe infected have been seen in our forest, and we can't let that go unnoticed. What if this virus stays in the soil? Is this what we'd leave behind?\n\nWe can't let them roam the nature reserve, we have to drive them away. Try hunting them at night and see how they behave... It might make things easier.", + "671910d5dbd4354ac10e9784 failMessageText": "", + "671910d5dbd4354ac10e9784 successMessageText": "So the infected are deadly at night, too? Even the fiercest beast needs rest too, I thought...\n\nAfter this, I don't know if we can truly cure them. It's getting harder and harder to see them as human beings with each passing day...", + "671910d5dbd4354ac10e9787": "Eliminate the infected on night-time Woods", + "671910d5dbd4354ac10e9784 acceptPlayerMessage": "", + "671910d5dbd4354ac10e9784 declinePlayerMessage": "", + "671910d5dbd4354ac10e9784 completePlayerMessage": "", + "6719116460f6f081570d05f7 name": "Every Man for Himself", + "6719116460f6f081570d05f7 description": "\"This is some fucked up shit, isn't it? Watching zombie movies was way cooler than actually seeing them in person.\n\nObviously, it's every man for himself now and all that, but... I got a lil' stash at Customs, and if I lose it, it's over for me. And not just for me, but for my boys too!\n\nNot giving you the details, sorry for that. But if you help me clean up the dorms, I'll send my guys up to pick up the cargo.\n\nI'll pay you big bucks for your professional services though!\"", + "6719116460f6f081570d05f7 failMessageText": "", + "6719116460f6f081570d05f7 successMessageText": "So, did you take care of the infected? You know, it sucks that I'm not friends with the medic woman. Her equipment would be great right now. Masks, gloves, all that stuff... Whatever, as long as I get the package. Here's the dough.", + "6719116460f6f081570d05fa": "Eliminate the infected at the dorms area on Customs", + "6719116460f6f081570d05f7 acceptPlayerMessage": "", + "6719116460f6f081570d05f7 declinePlayerMessage": "", + "6719116460f6f081570d05f7 completePlayerMessage": "", + "671911bbcee3738f8502d401 name": "Reduce the Distance", + "671911bbcee3738f8502d401 description": "Come on in. How long do you think this will last? Anyway, our job is to survive for as long as we can. Take as many of the infected with us as we can if we can't cure them.\n\nAs long as we still have ammunition. What happens when we're out of firepower? That's right. It's either us or them.\n\nA lot of people have already died with no ammo, left with only a knife against crowds of infected. But my point is, even they have a weakness, we just need to find it.\n\nCan you help with that? I can't trust anyone else to do this, they'll get themselves killed for nothing. Study their tactics and find a way to defeat the infected in close combat. There's a lot of them near the Ultra shopping mall now, so go there.", + "671911bbcee3738f8502d401 failMessageText": "", + "671911bbcee3738f8502d401 successMessageText": "I wasn't sure you'd come back. But now that you're here, I know we can win even a hand-to-hand fight with them. \n\nNow get some rest and double-check all your cuts and scrapes. I'd rather get bit by a viper than let that virus get into my bloodstream.", + "671911bbcee3738f8502d404": "Eliminate the infected while using melee weapons on Interchange", + "671911bbcee3738f8502d401 acceptPlayerMessage": "", + "671911bbcee3738f8502d401 declinePlayerMessage": "", + "671911bbcee3738f8502d401 completePlayerMessage": "", + "671a49f77d49aea42c029b5f name": "Irresistible", + "671a49f77d49aea42c029b5f description": "I got word from my buddy that there's a special merchandise in town. You like movies? Then you'll certainly recognize this gun!\n\nThere's only one little issue. The cargo went missing near the Ultra mall, I think somebody snatched it up. But man do I need these shotguns. It's a damn exclusive, you know what I'm saying?\n\nAnyway, why don't you take a little trip to Ultra and find this weapon crate there? If you get it, I'll pay you real good.", + "671a49f77d49aea42c029b5f failMessageText": "", + "671a49f77d49aea42c029b5f successMessageText": "Atta boy! It'll sell real good real quick, I'm telling you! Not many guns can boast such a flashy advertisement...", + "671a5941cb557f8656561a12": "Locate and obtain the lost weapon crate on Interchange", + "671a598e596272a846fa862a": "Hand over the retrieved cargo", + "671a49f77d49aea42c029b5f acceptPlayerMessage": "", + "671a49f77d49aea42c029b5f declinePlayerMessage": "", + "671a49f77d49aea42c029b5f completePlayerMessage": "", + "671a59e43d73dac1360765cc name": "Dangerous Props", + "671a59e43d73dac1360765cc description": "You're just in time. My expectations were too high, I guess. Things are so brutal around here, and people still won't buy these shotguns. One guy even told me he would never buy this \"janky movie prop\". Unbelievable!\n\nWe gotta show everybody that this gun is well worth the money. Let's put on a real show in Tarkov, so that everyone knows that my shotguns aren't just for movies!", + "671a59e43d73dac1360765cc failMessageText": "", + "671a59e43d73dac1360765cc successMessageText": "Now we're talking... The orders are rolling in, so it's a total success! Here's your share, fair and square.", + "671ac68e30609eb2c7e9a7f7": "Eliminate any target while using the MPS Auto Assault-12 shotgun", + "671a59e43d73dac1360765cc acceptPlayerMessage": "", + "671a59e43d73dac1360765cc declinePlayerMessage": "", + "671a59e43d73dac1360765cc completePlayerMessage": "", + "6727ef2c6015b7cc540ea754 name": "Contagious Beast", + "6727ef2c6015b7cc540ea754 description": "I never thought we'd have so much on our plate. Did you hear that the infected have gotten to Tagilla? He was already furious before, and now even more so. With such an active carrier of contagion, we'll soon run out of healthy people.\n\nHe must be stopped. Sure, there are tons of infected everywhere now, but none of them are as dangerous as Tagilla. So I'm asking you to put everything on hold and find the bastard. And don't leave until his body stops twitching.\n\nAfter everything that's happened, it wouldn't surprise me if Tagilla survives several magazines and then gets up as if nothing had happened... And hey, be careful out there.", + "6727ef2c6015b7cc540ea754 failMessageText": "", + "6727ef2c6015b7cc540ea754 successMessageText": "You made sure this demon is out of commission, yes? Well, let's hope we've dealt with this threat for good.\n\nConserve your ammo and check back soon, it's important we all work together right now.", + "6727f18974e5bdcd3778dc54": "Locate and neutralize infected Tagilla", + "6727f338415cfa0beb19c5be": "Survive and extract", + "6727ef2c6015b7cc540ea754 acceptPlayerMessage": "", + "6727ef2c6015b7cc540ea754 declinePlayerMessage": "", + "6727ef2c6015b7cc540ea754 completePlayerMessage": "", "616041eb031af660100c9967 startedMessageText 54cb50c76803fa8b248b4571 0": " ", "616041eb031af660100c9967 failMessageText 54cb50c76803fa8b248b4571 0": " ", "616041eb031af660100c9967 successMessageText 54cb50c76803fa8b248b4571 0": "All clear, you say? Good work then, soldier.", "616041eb031af660100c9967 description 54cb50c76803fa8b248b4571 0": "Ah, warrior. Listen, I need some help with scouting a location - need to walk around a couple of places, check out the situation there, maybe find escape routes. Not for free - you'll get rewarded, of course. Alright, pack up, we'll be waiting for your news.", "616041eb031af660100c9967 changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", - "616041eb031af660100c9967 startedMessageText 5a7c2eca46aef81a7ca2145d 0": " ", - "616041eb031af660100c9967 failMessageText 5a7c2eca46aef81a7ca2145d 0": " ", - "616041eb031af660100c9967 successMessageText 5a7c2eca46aef81a7ca2145d 0": "Alright, here's my map, show me what you found. Good, I'll let the clients know. Thank you, friend.", - "616041eb031af660100c9967 description 5a7c2eca46aef81a7ca2145d 0": "Mercenary, do you have a minute? I've prepared an order for the clients, but they need a guarantee that the way to the meeting spot is safe. If you aren't busy, can you find a route for them? Find a safe passage, a way to leave safely, you get me. Thank you, I’ll owe you one.", - "616041eb031af660100c9967 changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "A pity, certainly. I wanted to ask you specifically to do this job… I really started to like working with you. Don’t rush to refuse though, okay? Maybe things will change.", + "616041eb031af660100c9967 startedMessageText 54cb57776803fa99248b456e 0": " ", + "616041eb031af660100c9967 failMessageText 54cb57776803fa99248b456e 0": " ", + "616041eb031af660100c9967 successMessageText 54cb57776803fa99248b456e 0": "Marvelous, young man. Thank you for the work.", + "616041eb031af660100c9967 description 54cb57776803fa99248b456e 0": "Greetings, young man. My workers have to deliver several batches of valuable medicine, but I am too cautious to send them alone without making sure the path is safe. If you are available, then please help us, for the good of all civilians. You only have to scout the area and ensure a safe passage. Are you interested?", + "616041eb031af660100c9967 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "616041eb031af660100c9967 startedMessageText 58330581ace78e27b8b10cee 0": " ", "616041eb031af660100c9967 failMessageText 58330581ace78e27b8b10cee 0": " ", "616041eb031af660100c9967 successMessageText 58330581ace78e27b8b10cee 0": "So, how's the situation? Good, all going well then.", "616041eb031af660100c9967 description 58330581ace78e27b8b10cee 0": "C'mere, mister operator, let's talk. How are you doing, lad, busy? Not busy then. I need to scout an area so that my things go smoothly. Go check it out, alright? I don’t want my men to get into any fights. So yeah, come back to me when you're done. I'll be here.", "616041eb031af660100c9967 changeQuestMessageText 58330581ace78e27b8b10cee 0": "What, pussied out? I knew you wouldn’t have the balls for this. Alright, since you’re so sissy about it, I’ll give you another job.", + "616041eb031af660100c9967 startedMessageText 5935c25fb3acc3127c3d8cd9 0": " ", + "616041eb031af660100c9967 failMessageText 5935c25fb3acc3127c3d8cd9 0": " ", + "616041eb031af660100c9967 successMessageText 5935c25fb3acc3127c3d8cd9 0": "Good, good. You've done well, mercenary. You're free to go.", + "616041eb031af660100c9967 description 5935c25fb3acc3127c3d8cd9 0": "Ah, mercenary, do you want to do a good deed? My clients are asking to ensure a safe area to conduct a specific secret operation. I would like to appoint you for this, as you are the most competent of the local workers. You will have to survey the area and report back to me. Good luck, mercenary.", + "616041eb031af660100c9967 changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", + "616041eb031af660100c9967 startedMessageText 5a7c2eca46aef81a7ca2145d 0": " ", + "616041eb031af660100c9967 failMessageText 5a7c2eca46aef81a7ca2145d 0": " ", + "616041eb031af660100c9967 successMessageText 5a7c2eca46aef81a7ca2145d 0": "Alright, here's my map, show me what you found. Good, I'll let the clients know. Thank you, friend.", + "616041eb031af660100c9967 description 5a7c2eca46aef81a7ca2145d 0": "Mercenary, do you have a minute? I've prepared an order for the clients, but they need a guarantee that the way to the meeting spot is safe. If you aren't busy, can you find a route for them? Find a safe passage, a way to leave safely, you get me. Thank you, I’ll owe you one.", + "616041eb031af660100c9967 changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "A pity, certainly. I wanted to ask you specifically to do this job… I really started to like working with you. Don’t rush to refuse though, okay? Maybe things will change.", "616041eb031af660100c9967 startedMessageText 5ac3b934156ae10c4430e83c 0": " ", "616041eb031af660100c9967 failMessageText 5ac3b934156ae10c4430e83c 0": " ", "616041eb031af660100c9967 successMessageText 5ac3b934156ae10c4430e83c 0": "Awesome, brother, I won’t forget this!", "616041eb031af660100c9967 description 5ac3b934156ae10c4430e83c 0": "Hey there, brother, I have some stuff to deal with. There are a couple of guys with whom I really-really want to meet and discuss a couple of things, but these guys are very shy and won't get into any mess. Can you help me out with this matter? Just look around for any safe route for them so that nobody bothers them. Alright?", "616041eb031af660100c9967 changeQuestMessageText 5ac3b934156ae10c4430e83c 0": "Look how picky this guy is. “This one I’ll do, this one I won’t”. Earlier you were eager to do any of my “find and give” tasks. Yo, don’t even look at me as if I’m lying right now! ", - "616041eb031af660100c9967 startedMessageText 54cb57776803fa99248b456e 0": " ", - "616041eb031af660100c9967 failMessageText 54cb57776803fa99248b456e 0": " ", - "616041eb031af660100c9967 successMessageText 54cb57776803fa99248b456e 0": "Marvelous, young man. Thank you for the work.", - "616041eb031af660100c9967 description 54cb57776803fa99248b456e 0": "Greetings, young man. My workers have to deliver several batches of valuable medicine, but I am too cautious to send them alone without making sure the path is safe. If you are available, then please help us, for the good of all civilians. You only have to scout the area and ensure a safe passage. Are you interested?", - "616041eb031af660100c9967 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", + "616041eb031af660100c9967 startedMessageText 5c0647fdd443bc2504c2d371 0": " ", + "616041eb031af660100c9967 failMessageText 5c0647fdd443bc2504c2d371 0": " ", + "616041eb031af660100c9967 successMessageText 5c0647fdd443bc2504c2d371 0": "Well, guess it’s time to head out then. Thank you, kid.", + "616041eb031af660100c9967 description 5c0647fdd443bc2504c2d371 0": "Come on in for some tea, kid. I'm preparing to go hunting today, and could use some scouting in the area. Can you go check it out? I'd be grateful.", + "616041eb031af660100c9967 changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I've already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", "61604635c725987e815b1a46 startedMessageText 54cb50c76803fa8b248b4571 0": "test", "61604635c725987e815b1a46 failMessageText 54cb50c76803fa8b248b4571 0": " ", "61604635c725987e815b1a46 successMessageText 54cb50c76803fa8b248b4571 0": "There you are! You got everything? Good stuff.", "61604635c725987e815b1a46 description 54cb50c76803fa8b248b4571 0": "Hey there, come on in. Do you by any chance know of any magical place where you can always find whatever you need? There's an order for some supplies, and I've got no clue where to find them right now. Wanna help me out? For a reward, of course.", "61604635c725987e815b1a46 changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "61604635c725987e815b1a46 startedMessageText 54cb57776803fa99248b456e 0": " ", + "61604635c725987e815b1a46 failMessageText 54cb57776803fa99248b456e 0": " ", + "61604635c725987e815b1a46 successMessageText 54cb57776803fa99248b456e 0": "You've done a good deed, mercenary.", + "61604635c725987e815b1a46 description 54cb57776803fa99248b456e 0": "Good afternoon, young man. In our troubling times, it's hard to remain in abundance, you have to agree. I've received an order for a batch of specific resources, but I am unable to acquire them. Will you help us, mercenary? Here is a list of all needed items.", + "61604635c725987e815b1a46 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", + "61604635c725987e815b1a46 startedMessageText 58330581ace78e27b8b10cee 0": " ", + "61604635c725987e815b1a46 failMessageText 58330581ace78e27b8b10cee 0": " ", + "61604635c725987e815b1a46 successMessageText 58330581ace78e27b8b10cee 0": "Here's our errand boy. You've done good, mate.", + "61604635c725987e815b1a46 description 58330581ace78e27b8b10cee 0": "Hey, wanna look for some goodies? I need to find some stuff, but my lads are all busy with the more important stuff. You, however, look like you're eager to help a friend out! C'mere, I'll draw you your shopping list. Off you go then.", + "61604635c725987e815b1a46 changeQuestMessageText 58330581ace78e27b8b10cee 0": "What, pussied out? I knew you wouldn’t have the balls for this. Alright, since you’re so sissy about it, I’ll give you another job.", "61604635c725987e815b1a46 startedMessageText 5935c25fb3acc3127c3d8cd9 0": " ", "61604635c725987e815b1a46 failMessageText 5935c25fb3acc3127c3d8cd9 0": " ", "61604635c725987e815b1a46 successMessageText 5935c25fb3acc3127c3d8cd9 0": "Marvelous, my friend. You have our thanks.", "61604635c725987e815b1a46 description 5935c25fb3acc3127c3d8cd9 0": "Good afternoon. I have an order for specific goods that the Blue Helmets would not be able to obtain. However, we have you, mercenary, and with your skills, it will be a breeze for you. Here is the list of the required items. Don't let me down.", "61604635c725987e815b1a46 changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", - "61604635c725987e815b1a46 startedMessageText 5c0647fdd443bc2504c2d371 0": " ", - "61604635c725987e815b1a46 failMessageText 5c0647fdd443bc2504c2d371 0": " ", - "61604635c725987e815b1a46 successMessageText 5c0647fdd443bc2504c2d371 0": "Thank you, kid, good job. Here, that’s for the trouble.", - "61604635c725987e815b1a46 description 5c0647fdd443bc2504c2d371 0": "Hey there, kid. I'm running low on some of the supplies, some for my store, some for me. Can you help me out? Wait here, I'll make a list. Thank you.", - "61604635c725987e815b1a46 changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", "61604635c725987e815b1a46 startedMessageText 5a7c2eca46aef81a7ca2145d 0": " ", "61604635c725987e815b1a46 failMessageText 5a7c2eca46aef81a7ca2145d 0": " ", "61604635c725987e815b1a46 successMessageText 5a7c2eca46aef81a7ca2145d 0": "Good work, mercenary. I owe you one.", "61604635c725987e815b1a46 description 5a7c2eca46aef81a7ca2145d 0": "Hello, mercenary. Listen, I've got an order for various supplies, but I don't have some of them in stock for the moment. I'd be extremely grateful if you found them for me. Here's the list, all info is in there. Thank you.", "61604635c725987e815b1a46 changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "A pity, certainly. I wanted to ask you specifically to do this job… I really started to like working with you. Don’t rush to refuse though, okay? Maybe things will change.", - "61604635c725987e815b1a46 startedMessageText 58330581ace78e27b8b10cee 0": " ", - "61604635c725987e815b1a46 failMessageText 58330581ace78e27b8b10cee 0": " ", - "61604635c725987e815b1a46 successMessageText 58330581ace78e27b8b10cee 0": "Here's our errand boy. You've done good, mate.", - "61604635c725987e815b1a46 description 58330581ace78e27b8b10cee 0": "Hey, wanna look for some goodies? I need to find some stuff, but my lads are all busy with the more important stuff. You, however, look like you're eager to help a friend out! C'mere, I'll draw you your shopping list. Off you go then.", - "61604635c725987e815b1a46 changeQuestMessageText 58330581ace78e27b8b10cee 0": "What, pussied out? I knew you wouldn’t have the balls for this. Alright, since you’re so sissy about it, I’ll give you another job.", "61604635c725987e815b1a46 startedMessageText 5ac3b934156ae10c4430e83c 0": " ", "61604635c725987e815b1a46 failMessageText 5ac3b934156ae10c4430e83c 0": " ", "61604635c725987e815b1a46 successMessageText 5ac3b934156ae10c4430e83c 0": "Ah, such a player, always helps a brother out!", "61604635c725987e815b1a46 description 5ac3b934156ae10c4430e83c 0": "Hey, brother. I've got a big full-packed list of special goods for delivery, and the clients are still waiting. Can you go look for the needed stuff to help your best bro Arshavir?", "61604635c725987e815b1a46 changeQuestMessageText 5ac3b934156ae10c4430e83c 0": "Look how picky this guy is. “This one I’ll do, this one I won’t”. Earlier you were eager to do any of my “find and give” tasks. Yo, don’t even look at me as if I’m lying right now!", - "61604635c725987e815b1a46 startedMessageText 54cb57776803fa99248b456e 0": " ", - "61604635c725987e815b1a46 failMessageText 54cb57776803fa99248b456e 0": " ", - "61604635c725987e815b1a46 successMessageText 54cb57776803fa99248b456e 0": "You've done a good deed, mercenary.", - "61604635c725987e815b1a46 description 54cb57776803fa99248b456e 0": "Good afternoon, young man. In our troubling times, it's hard to remain in abundance, you have to agree. I've received an order for a batch of specific resources, but I am unable to acquire them. Will you help us, mercenary? Here is a list of all needed items.", - "61604635c725987e815b1a46 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", - "616051e63f96cc089c1cf37f startedMessageText 5935c25fb3acc3127c3d8cd9 0": " ", - "616051e63f96cc089c1cf37f failMessageText 5935c25fb3acc3127c3d8cd9 0": " ", - "616051e63f96cc089c1cf37f successMessageText 5935c25fb3acc3127c3d8cd9 0": "Good work, my friend! Here’s your reward.", - "616051e63f96cc089c1cf37f description 5935c25fb3acc3127c3d8cd9 0": "Mercenary, there is a task for you. The Blue Helmets will be grateful if you, so to say, strengthen our relationships. There is a list of specific people without whom our business would be much easier. Get rid of them and report to me when you're done.", - "616051e63f96cc089c1cf37f changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", - "616051e63f96cc089c1cf37f startedMessageText 5c0647fdd443bc2504c2d371 0": " ", - "616051e63f96cc089c1cf37f failMessageText 5c0647fdd443bc2504c2d371 0": " ", - "616051e63f96cc089c1cf37f successMessageText 5c0647fdd443bc2504c2d371 0": "So the only thing they want is to shoot each other. That’s just wrong. Well, kid, I know you at least tried.", - "616051e63f96cc089c1cf37f description 5c0647fdd443bc2504c2d371 0": "You know, we cannot rid Tarkov of the all-destroying parasites by ourselves. But what we can do is teach them a lesson and let them realize their mistakes however inhumane they were. And if those bandits don't want to talk - then to hell is the only road for them.", - "616051e63f96cc089c1cf37f changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", + "61604635c725987e815b1a46 startedMessageText 5c0647fdd443bc2504c2d371 0": " ", + "61604635c725987e815b1a46 failMessageText 5c0647fdd443bc2504c2d371 0": " ", + "61604635c725987e815b1a46 successMessageText 5c0647fdd443bc2504c2d371 0": "Thank you, kid, good job. Here, that’s for the trouble.", + "61604635c725987e815b1a46 description 5c0647fdd443bc2504c2d371 0": "Hey there, kid. I'm running low on some of the supplies, some for my store, some for me. Can you help me out? Wait here, I'll make a list. Thank you.", + "61604635c725987e815b1a46 changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", "616051e63f96cc089c1cf37f startedMessageText 54cb50c76803fa8b248b4571 0": " ", "616051e63f96cc089c1cf37f failMessageText 54cb50c76803fa8b248b4571 0": " ", "616051e63f96cc089c1cf37f successMessageText 54cb50c76803fa8b248b4571 0": "You got the bastards? Good, here's your prize.", "616051e63f96cc089c1cf37f description 54cb50c76803fa8b248b4571 0": "Greetings, soldier, I have a job for you. I've got some morons who I really don't want to deal with anymore. A type of work just for you. Can you help me out? Deal with those idiots, lemme give you the list of targets.", "616051e63f96cc089c1cf37f changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", - "616051e63f96cc089c1cf37f startedMessageText 5a7c2eca46aef81a7ca2145d 0": "", - "616051e63f96cc089c1cf37f failMessageText 5a7c2eca46aef81a7ca2145d 0": "", - "616051e63f96cc089c1cf37f successMessageText 5a7c2eca46aef81a7ca2145d 0": "", - "616051e63f96cc089c1cf37f description 5a7c2eca46aef81a7ca2145d 0": "", - "616051e63f96cc089c1cf37f changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "", + "616051e63f96cc089c1cf37f startedMessageText 54cb57776803fa99248b456e 0": " ", + "616051e63f96cc089c1cf37f failMessageText 54cb57776803fa99248b456e 0": " ", + "616051e63f96cc089c1cf37f successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", + "616051e63f96cc089c1cf37f description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", + "616051e63f96cc089c1cf37f changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "616051e63f96cc089c1cf37f startedMessageText 58330581ace78e27b8b10cee 0": " ", "616051e63f96cc089c1cf37f failMessageText 58330581ace78e27b8b10cee 0": " ", "616051e63f96cc089c1cf37f successMessageText 58330581ace78e27b8b10cee 0": "A damn beast you are, hehe. Good work, here's your share.", "616051e63f96cc089c1cf37f description 58330581ace78e27b8b10cee 0": "Here he is, the one and only! Listen, brother, we're friends, right? And friends need to help each other out! So go help me out - I need to pop some morons, no questions asked, alright? You in?", "616051e63f96cc089c1cf37f changeQuestMessageText 58330581ace78e27b8b10cee 0": "What, pussied out? I knew you wouldn’t have the balls for this. Alright, since you’re so sissy about it, I’ll give you another job.", + "616051e63f96cc089c1cf37f startedMessageText 5935c25fb3acc3127c3d8cd9 0": " ", + "616051e63f96cc089c1cf37f failMessageText 5935c25fb3acc3127c3d8cd9 0": " ", + "616051e63f96cc089c1cf37f successMessageText 5935c25fb3acc3127c3d8cd9 0": "Good work, my friend! Here’s your reward.", + "616051e63f96cc089c1cf37f description 5935c25fb3acc3127c3d8cd9 0": "Mercenary, there is a task for you. The Blue Helmets will be grateful if you, so to say, strengthen our relationships. There is a list of specific people without whom our business would be much easier. Get rid of them and report to me when you're done.", + "616051e63f96cc089c1cf37f changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", + "616051e63f96cc089c1cf37f startedMessageText 5a7c2eca46aef81a7ca2145d 0": "", + "616051e63f96cc089c1cf37f failMessageText 5a7c2eca46aef81a7ca2145d 0": "", + "616051e63f96cc089c1cf37f successMessageText 5a7c2eca46aef81a7ca2145d 0": "", + "616051e63f96cc089c1cf37f description 5a7c2eca46aef81a7ca2145d 0": "", + "616051e63f96cc089c1cf37f changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "", "616051e63f96cc089c1cf37f startedMessageText 5ac3b934156ae10c4430e83c 0": " ", "616051e63f96cc089c1cf37f failMessageText 5ac3b934156ae10c4430e83c 0": " ", "616051e63f96cc089c1cf37f successMessageText 5ac3b934156ae10c4430e83c 0": "Nice, nice. Here, take this, a little thank you gift.", "616051e63f96cc089c1cf37f description 5ac3b934156ae10c4430e83c 0": "Gotta do something... Ah, salam, brother. Listen, can you help a brother out? My boys ran into some morons and as always, there was a big mess. Many good guys died, but what’s even worse is that those assholes stole all our looted clothes! Can't leave those fuckers unpunished, right? Go and pop those bitches.", "616051e63f96cc089c1cf37f changeQuestMessageText 5ac3b934156ae10c4430e83c 0": "Look how picky this guy is. “This one I’ll do, this one I won’t”. Earlier you were eager to do any of my “find and give” tasks. Yo, don’t even look at me as if I’m lying right now!", - "616051e63f96cc089c1cf37f startedMessageText 54cb57776803fa99248b456e 0": " ", - "616051e63f96cc089c1cf37f failMessageText 54cb57776803fa99248b456e 0": " ", - "616051e63f96cc089c1cf37f successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", - "616051e63f96cc089c1cf37f description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", - "616051e63f96cc089c1cf37f changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", + "616051e63f96cc089c1cf37f startedMessageText 5c0647fdd443bc2504c2d371 0": " ", + "616051e63f96cc089c1cf37f failMessageText 5c0647fdd443bc2504c2d371 0": " ", + "616051e63f96cc089c1cf37f successMessageText 5c0647fdd443bc2504c2d371 0": "So the only thing they want is to shoot each other. That’s just wrong. Well, kid, I know you at least tried.", + "616051e63f96cc089c1cf37f description 5c0647fdd443bc2504c2d371 0": "You know, we cannot rid Tarkov of the all-destroying parasites by ourselves. But what we can do is teach them a lesson and let them realize their mistakes however inhumane they were. And if those bandits don't want to talk - then to hell is the only road for them.", + "616051e63f96cc089c1cf37f changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", "616052ea3054fc0e2c24ce6e startedMessageText 54cb50c76803fa8b248b4571 0": " ", "616052ea3054fc0e2c24ce6e failMessageText 54cb50c76803fa8b248b4571 0": " ", "616052ea3054fc0e2c24ce6e successMessageText 54cb50c76803fa8b248b4571 0": "You got the bastards? Good, here's your prize.", "616052ea3054fc0e2c24ce6e description 54cb50c76803fa8b248b4571 0": "Greetings, soldier, I have a job for you. I've got some morons who I really don't want to deal with anymore. A type of work just for you. Can you help me out? Deal with those idiots, lemme give you the list of targets.", "616052ea3054fc0e2c24ce6e changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "616052ea3054fc0e2c24ce6e startedMessageText 54cb57776803fa99248b456e 0": " ", + "616052ea3054fc0e2c24ce6e failMessageText 54cb57776803fa99248b456e 0": " ", + "616052ea3054fc0e2c24ce6e successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", + "616052ea3054fc0e2c24ce6e description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", + "616052ea3054fc0e2c24ce6e changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "616052ea3054fc0e2c24ce6e startedMessageText 58330581ace78e27b8b10cee 0": " ", "616052ea3054fc0e2c24ce6e failMessageText 58330581ace78e27b8b10cee 0": " ", "616052ea3054fc0e2c24ce6e successMessageText 58330581ace78e27b8b10cee 0": "A damn beast you are, hehe. Good work, here's your share.", @@ -23452,16 +26307,16 @@ "616052ea3054fc0e2c24ce6e successMessageText 5c0647fdd443bc2504c2d371 0": "So the only thing they want is to shoot each other. That’s just wrong. Well, kid, I know you at least tried.", "616052ea3054fc0e2c24ce6e description 5c0647fdd443bc2504c2d371 0": "You know, we cannot rid Tarkov of the all-destroying parasites by ourselves. But what we can do is teach them a lesson and let them realize their mistakes however inhumane they were. And if those bandits don't want to talk - then to hell is the only road for them.", "616052ea3054fc0e2c24ce6e changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "616052ea3054fc0e2c24ce6e startedMessageText 54cb57776803fa99248b456e 0": " ", - "616052ea3054fc0e2c24ce6e failMessageText 54cb57776803fa99248b456e 0": " ", - "616052ea3054fc0e2c24ce6e successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", - "616052ea3054fc0e2c24ce6e description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", - "616052ea3054fc0e2c24ce6e changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6160538a5b5c163161503c11 startedMessageText 54cb50c76803fa8b248b4571 0": " ", "6160538a5b5c163161503c11 failMessageText 54cb50c76803fa8b248b4571 0": " ", "6160538a5b5c163161503c11 successMessageText 54cb50c76803fa8b248b4571 0": "You got the bastards? Good, here's your prize.", "6160538a5b5c163161503c11 description 54cb50c76803fa8b248b4571 0": "Greetings, soldier, I have a job for you. I've got some morons who I really don't want to deal with anymore. A type of work just for you. Can you help me out? Deal with those idiots, lemme give you the list of targets.", "6160538a5b5c163161503c11 changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6160538a5b5c163161503c11 startedMessageText 54cb57776803fa99248b456e 0": " ", + "6160538a5b5c163161503c11 failMessageText 54cb57776803fa99248b456e 0": " ", + "6160538a5b5c163161503c11 successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", + "6160538a5b5c163161503c11 description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", + "6160538a5b5c163161503c11 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6160538a5b5c163161503c11 startedMessageText 58330581ace78e27b8b10cee 0": " ", "6160538a5b5c163161503c11 failMessageText 58330581ace78e27b8b10cee 0": " ", "6160538a5b5c163161503c11 successMessageText 58330581ace78e27b8b10cee 0": "A damn beast you are, hehe. Good work, here's your share.", @@ -23482,16 +26337,16 @@ "6160538a5b5c163161503c11 successMessageText 5c0647fdd443bc2504c2d371 0": "So the only thing they want is to shoot each other. That’s just wrong. Well, kid, I know you at least tried.", "6160538a5b5c163161503c11 description 5c0647fdd443bc2504c2d371 0": "You know, we cannot rid Tarkov of the all-destroying parasites by ourselves. But what we can do is teach them a lesson and let them realize their mistakes however inhumane they were. And if those bandits don't want to talk - then to hell is the only road for them.", "6160538a5b5c163161503c11 changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6160538a5b5c163161503c11 startedMessageText 54cb57776803fa99248b456e 0": " ", - "6160538a5b5c163161503c11 failMessageText 54cb57776803fa99248b456e 0": " ", - "6160538a5b5c163161503c11 successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", - "6160538a5b5c163161503c11 description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", - "6160538a5b5c163161503c11 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "61605529dd634525033424da startedMessageText 54cb50c76803fa8b248b4571 0": " ", "61605529dd634525033424da failMessageText 54cb50c76803fa8b248b4571 0": " ", "61605529dd634525033424da successMessageText 54cb50c76803fa8b248b4571 0": "You got the bastards? Good, here's your prize.", "61605529dd634525033424da description 54cb50c76803fa8b248b4571 0": "Greetings, soldier, I have a job for you. I've got some morons who I really don't want to deal with anymore. A type of work just for you. Can you help me out? Deal with those idiots, lemme give you the list of targets.", "61605529dd634525033424da changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "61605529dd634525033424da startedMessageText 54cb57776803fa99248b456e 0": " ", + "61605529dd634525033424da failMessageText 54cb57776803fa99248b456e 0": " ", + "61605529dd634525033424da successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", + "61605529dd634525033424da description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", + "61605529dd634525033424da changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "61605529dd634525033424da startedMessageText 58330581ace78e27b8b10cee 0": " ", "61605529dd634525033424da failMessageText 58330581ace78e27b8b10cee 0": " ", "61605529dd634525033424da successMessageText 58330581ace78e27b8b10cee 0": "A damn beast you are, hehe. Good work, here's your share.", @@ -23512,16 +26367,16 @@ "61605529dd634525033424da successMessageText 5c0647fdd443bc2504c2d371 0": "So the only thing they want is to shoot each other. That’s just wrong. Well, kid, I know you at least tried.", "61605529dd634525033424da description 5c0647fdd443bc2504c2d371 0": "You know, we cannot rid Tarkov of the all-destroying parasites by ourselves. But what we can do is teach them a lesson and let them realize their mistakes however inhumane they were. And if those bandits don't want to talk - then to hell is the only road for them.", "61605529dd634525033424da changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "61605529dd634525033424da startedMessageText 54cb57776803fa99248b456e 0": " ", - "61605529dd634525033424da failMessageText 54cb57776803fa99248b456e 0": " ", - "61605529dd634525033424da successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", - "61605529dd634525033424da description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", - "61605529dd634525033424da changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "616055d58d1c6b29be3f382b startedMessageText 54cb50c76803fa8b248b4571 0": " ", "616055d58d1c6b29be3f382b failMessageText 54cb50c76803fa8b248b4571 0": " ", "616055d58d1c6b29be3f382b successMessageText 54cb50c76803fa8b248b4571 0": "You got the bastards? Good, here's your prize.", "616055d58d1c6b29be3f382b description 54cb50c76803fa8b248b4571 0": "Greetings, soldier, I have a job for you. I've got some morons who I really don't want to deal with anymore. A type of work just for you. Can you help me out? Deal with those idiots, lemme give you the list of targets.", "616055d58d1c6b29be3f382b changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "616055d58d1c6b29be3f382b startedMessageText 54cb57776803fa99248b456e 0": " ", + "616055d58d1c6b29be3f382b failMessageText 54cb57776803fa99248b456e 0": " ", + "616055d58d1c6b29be3f382b successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", + "616055d58d1c6b29be3f382b description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", + "616055d58d1c6b29be3f382b changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "616055d58d1c6b29be3f382b startedMessageText 58330581ace78e27b8b10cee 0": " ", "616055d58d1c6b29be3f382b failMessageText 58330581ace78e27b8b10cee 0": " ", "616055d58d1c6b29be3f382b successMessageText 58330581ace78e27b8b10cee 0": "A damn beast you are, hehe. Good work, here's your share.", @@ -23542,26 +26397,26 @@ "616055d58d1c6b29be3f382b successMessageText 5c0647fdd443bc2504c2d371 0": "So the only thing they want is to shoot each other. That’s just wrong. Well, kid, I know you at least tried.", "616055d58d1c6b29be3f382b description 5c0647fdd443bc2504c2d371 0": "You know, we cannot rid Tarkov of the all-destroying parasites by ourselves. But what we can do is teach them a lesson and let them realize their mistakes however inhumane they were. And if those bandits don't want to talk - then to hell is the only road for them.", "616055d58d1c6b29be3f382b changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "616055d58d1c6b29be3f382b startedMessageText 54cb57776803fa99248b456e 0": " ", - "616055d58d1c6b29be3f382b failMessageText 54cb57776803fa99248b456e 0": " ", - "616055d58d1c6b29be3f382b successMessageText 54cb57776803fa99248b456e 0": "Is the job done? Good, then here is your reward.", - "616055d58d1c6b29be3f382b description 54cb57776803fa99248b456e 0": "Mercenary, you are just in time. We need help in eliminating a group of bandits who are interfering with our humanitarian operations. If you are not busy, then I will entrust this to you. All details are included.", - "616055d58d1c6b29be3f382b changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", - "6180385770bf5a029372b9aa startedMessageText 5935c25fb3acc3127c3d8cd9 0": "", - "6180385770bf5a029372b9aa failMessageText 5935c25fb3acc3127c3d8cd9 0": "", - "6180385770bf5a029372b9aa successMessageText 5935c25fb3acc3127c3d8cd9 0": "A great report, mercenary. Good work.", - "6180385770bf5a029372b9aa description 5935c25fb3acc3127c3d8cd9 0": "Hello, soldier! Are you ready to help the people? Big goals start small. Please survey the marked location and find extraction points, this will help save dozens of lives.", - "6180385770bf5a029372b9aa changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", "6180385770bf5a029372b9aa startedMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9aa failMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9aa successMessageText 54cb50c76803fa8b248b4571 0": "So, how is it? Got it. Here’s your reward then.", "6180385770bf5a029372b9aa description 54cb50c76803fa8b248b4571 0": "Welcome, soldier! Can you help me out with a thing? Need to run around a place, check out the situation and escape routes. For what? Ain't you a nosy one. If I’m asking, it means I need it. The quicker you do it, the better.", "6180385770bf5a029372b9aa changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6180385770bf5a029372b9aa startedMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9aa failMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9aa successMessageText 54cb57776803fa99248b456e 0": "Thank you for your work. You have helped to save several lives.", + "6180385770bf5a029372b9aa description 54cb57776803fa99248b456e 0": "Good afternoon, young man. Are you able to help us? We’re stationing several seriously injured patients, and we won’t be able to extract them with our forces alone. We have to transfer them from the city, and there they will be taken away and taken to the hospital. Come again? No, you will not have to carry them yourself. You’ll only have to scout the area, the route along which my assistants will evacuate the injured.", + "6180385770bf5a029372b9aa changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9aa startedMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9aa failMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9aa successMessageText 58330581ace78e27b8b10cee 0": "Good one, what can I say.", "6180385770bf5a029372b9aa description 58330581ace78e27b8b10cee 0": "Alright, listen up, mate, straight to the point. I need you to stroll somewhere and check out if the place is safe and all that.", "6180385770bf5a029372b9aa changeQuestMessageText 58330581ace78e27b8b10cee 0": "What, pussied out? I knew you wouldn’t have the balls for this. Alright, since you’re so sissy about it, I’ll give you another job.", + "6180385770bf5a029372b9aa startedMessageText 5935c25fb3acc3127c3d8cd9 0": "", + "6180385770bf5a029372b9aa failMessageText 5935c25fb3acc3127c3d8cd9 0": "", + "6180385770bf5a029372b9aa successMessageText 5935c25fb3acc3127c3d8cd9 0": "A great report, mercenary. Good work.", + "6180385770bf5a029372b9aa description 5935c25fb3acc3127c3d8cd9 0": "Hello, soldier! Are you ready to help the people? Big goals start small. Please survey the marked location and find extraction points, this will help save dozens of lives.", + "6180385770bf5a029372b9aa changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", "6180385770bf5a029372b9aa startedMessageText 5a7c2eca46aef81a7ca2145d 0": "", "6180385770bf5a029372b9aa failMessageText 5a7c2eca46aef81a7ca2145d 0": "", "6180385770bf5a029372b9aa successMessageText 5a7c2eca46aef81a7ca2145d 0": "I’m glad you’re back. I’ve prepared something for you.", @@ -23577,16 +26432,16 @@ "6180385770bf5a029372b9aa successMessageText 5c0647fdd443bc2504c2d371 0": "Understood. Here, that’s for the help.", "6180385770bf5a029372b9aa description 5c0647fdd443bc2504c2d371 0": "Glad you came by. I don’t get many visitors. I myself would be covered by moss already if not for hunting. I’m packing up for one tomorrow, by the way. Can you scout the path? I’ll be going here on the map, wouldn’t want to catch a bullet. You’ve got a way clearer eyesight than me, kid. Let me know of anything you discover. Well, bless you then.", "6180385770bf5a029372b9aa changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6180385770bf5a029372b9aa startedMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9aa failMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9aa successMessageText 54cb57776803fa99248b456e 0": "Thank you for your work. You have helped to save several lives.", - "6180385770bf5a029372b9aa description 54cb57776803fa99248b456e 0": "Good afternoon, young man. Are you able to help us? We’re stationing several seriously injured patients, and we won’t be able to extract them with our forces alone. We have to transfer them from the city, and there they will be taken away and taken to the hospital. Come again? No, you will not have to carry them yourself. You’ll only have to scout the area, the route along which my assistants will evacuate the injured.", - "6180385770bf5a029372b9aa changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9ab startedMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9ab failMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9ab successMessageText 54cb50c76803fa8b248b4571 0": "Thanks, comrade! The country won’t forget this.", "6180385770bf5a029372b9ab description 54cb50c76803fa8b248b4571 0": "Where in the bloody hell is it… It’s always like that, always run out of things just as you need them… Hey, soldier! Can you help me find something?", "6180385770bf5a029372b9ab changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6180385770bf5a029372b9ab startedMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9ab failMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9ab successMessageText 54cb57776803fa99248b456e 0": "Have you found it all? You have my thanks, young man.", + "6180385770bf5a029372b9ab description 54cb57776803fa99248b456e 0": "Yes, young man, something is constantly lacking in the time of war... If there is an excess of bandages - there are not enough antibiotics, if there are antibiotics - there are not enough basic food supplies. Let me write down what we need, and perhaps if you stumble upon any of this, can take this with you for us?", + "6180385770bf5a029372b9ab changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9ab startedMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9ab failMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9ab successMessageText 58330581ace78e27b8b10cee 0": "Got it all? Lemme check. Nice, all here.", @@ -23597,6 +26452,11 @@ "6180385770bf5a029372b9ab successMessageText 5935c25fb3acc3127c3d8cd9 0": "Hold on, I need to check the list. Yes, everything is here. You have my thanks.", "6180385770bf5a029372b9ab description 5935c25fb3acc3127c3d8cd9 0": "Mercenary, I must ask for your help. My clients require these items, but for specific reasons, I cannot officially issue an order for the search.", "6180385770bf5a029372b9ab changeQuestMessageText 5935c25fb3acc3127c3d8cd9 0": "I wouldn’t want to waste time looking for another worker. Are you sure you want to put me into such a complicated situation, mercenary?", + "6180385770bf5a029372b9ab startedMessageText 5a7c2eca46aef81a7ca2145d 0": "", + "6180385770bf5a029372b9ab failMessageText 5a7c2eca46aef81a7ca2145d 0": "", + "6180385770bf5a029372b9ab successMessageText 5a7c2eca46aef81a7ca2145d 0": "Thank you! I knew I could count on you.", + "6180385770bf5a029372b9ab description 5a7c2eca46aef81a7ca2145d 0": "Hey, friend, I need your help again. I need to find some items from this list. I know that you’re a busy man, but if you do want to help me, I’d appreciate it if you did it immediately.", + "6180385770bf5a029372b9ab changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "A pity, certainly. I wanted to ask you specifically to do this job… I really started to like working with you. Don’t rush to refuse though, okay? Maybe things will change.", "6180385770bf5a029372b9ab startedMessageText 5ac3b934156ae10c4430e83c 0": "", "6180385770bf5a029372b9ab failMessageText 5ac3b934156ae10c4430e83c 0": "", "6180385770bf5a029372b9ab successMessageText 5ac3b934156ae10c4430e83c 0": "Alright, show me. Yup, all here. Nice job!", @@ -23607,21 +26467,16 @@ "6180385770bf5a029372b9ab successMessageText 5c0647fdd443bc2504c2d371 0": "Did you find it? Well I’ll be damned! A damn good man you are, soldier.", "6180385770bf5a029372b9ab description 5c0647fdd443bc2504c2d371 0": "Come on in, warrior. The tea is ready. Interested in what I’m writing here, huh? It’s just a list of what I need in the household. Something of this could be useful for business too, to send to the right people. Can you help me find some of it?", "6180385770bf5a029372b9ab changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6180385770bf5a029372b9ab startedMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9ab failMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9ab successMessageText 54cb57776803fa99248b456e 0": "Have you found it all? You have my thanks, young man.", - "6180385770bf5a029372b9ab description 54cb57776803fa99248b456e 0": "Yes, young man, something is constantly lacking in the time of war... If there is an excess of bandages - there are not enough antibiotics, if there are antibiotics - there are not enough basic food supplies. Let me write down what we need, and perhaps if you stumble upon any of this, can take this with you for us?", - "6180385770bf5a029372b9ab changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", - "6180385770bf5a029372b9ab startedMessageText 5a7c2eca46aef81a7ca2145d 0": "", - "6180385770bf5a029372b9ab failMessageText 5a7c2eca46aef81a7ca2145d 0": "", - "6180385770bf5a029372b9ab successMessageText 5a7c2eca46aef81a7ca2145d 0": "Thank you! I knew I could count on you.", - "6180385770bf5a029372b9ab description 5a7c2eca46aef81a7ca2145d 0": "Hey, friend, I need your help again. I need to find some items from this list. I know that you’re a busy man, but if you do want to help me, I’d appreciate it if you did it immediately.", - "6180385770bf5a029372b9ab changeQuestMessageText 5a7c2eca46aef81a7ca2145d 0": "A pity, certainly. I wanted to ask you specifically to do this job… I really started to like working with you. Don’t rush to refuse though, okay? Maybe things will change.", "6180385770bf5a029372b9ad startedMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9ad failMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9ad successMessageText 54cb50c76803fa8b248b4571 0": "How is it, soldier? Great.", "6180385770bf5a029372b9ad description 54cb50c76803fa8b248b4571 0": "Come on in, don’t just stand in the doorway, dammit. Why am I so moody today, you ask? Well, I’ve got a rat problem… People don’t know where they shouldn’t stick their hands in. Maybe you could help me out with this? I’ll get you something in return.", "6180385770bf5a029372b9ad changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6180385770bf5a029372b9ad startedMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9ad failMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9ad successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", + "6180385770bf5a029372b9ad description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", + "6180385770bf5a029372b9ad changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9ad startedMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9ad failMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9ad successMessageText 58330581ace78e27b8b10cee 0": "Get your reward then. Better than a Christmas present, hehe!", @@ -23642,16 +26497,16 @@ "6180385770bf5a029372b9ad successMessageText 5c0647fdd443bc2504c2d371 0": "Oh, well. Looks like there’s no end to this scum. You didn’t get hit, at least?", "6180385770bf5a029372b9ad description 5c0647fdd443bc2504c2d371 0": "Was just thinking of you right now. Every time you leave me, I’m wondering if you’ll return or get killed like others. Hey, I’m not a pessimist. It’s just that there is another new gang, as people say. I’m still hoping that they are wrong. People can’t get into gangs forever, right? It has to stop eventually.", "6180385770bf5a029372b9ad changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6180385770bf5a029372b9ad startedMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9ad failMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9ad successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", - "6180385770bf5a029372b9ad description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", - "6180385770bf5a029372b9ad changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9ae startedMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9ae failMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9ae successMessageText 54cb50c76803fa8b248b4571 0": "How is it, soldier? Great.", "6180385770bf5a029372b9ae description 54cb50c76803fa8b248b4571 0": "Come on in, don’t just stand in the doorway, dammit. Why am I so moody today, you ask? Well, I’ve got a rat problem… People don’t know where they shouldn’t stick their hands in. Maybe you could help me out with this? I’ll get you something in return.", "6180385770bf5a029372b9ae changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6180385770bf5a029372b9ae startedMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9ae failMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9ae successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", + "6180385770bf5a029372b9ae description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", + "6180385770bf5a029372b9ae changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9ae startedMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9ae failMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9ae successMessageText 58330581ace78e27b8b10cee 0": "Get your reward then. Better than a Christmas present, hehe!", @@ -23672,16 +26527,16 @@ "6180385770bf5a029372b9ae successMessageText 5c0647fdd443bc2504c2d371 0": "Oh, well. Looks like there’s no end to this scum. You didn’t get hit, at least?", "6180385770bf5a029372b9ae description 5c0647fdd443bc2504c2d371 0": "Was just thinking of you right now. Every time you leave me, I’m wondering if you’ll return or get killed like others. Hey, I’m not a pessimist. It’s just that there is another new gang, as people say. I’m still hoping that they are wrong. People can’t get into gangs forever, right? It has to stop eventually.", "6180385770bf5a029372b9ae changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6180385770bf5a029372b9ae startedMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9ae failMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9ae successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", - "6180385770bf5a029372b9ae description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", - "6180385770bf5a029372b9ae changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9af startedMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9af failMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9af successMessageText 54cb50c76803fa8b248b4571 0": "How is it, soldier? Great.", "6180385770bf5a029372b9af description 54cb50c76803fa8b248b4571 0": "Come on in, don’t just stand in the doorway, dammit. Why am I so moody today, you ask? Well, I’ve got a rat problem… People don’t know where they shouldn’t stick their hands in. Maybe you could help me out with this? I’ll get you something in return.", "6180385770bf5a029372b9af changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6180385770bf5a029372b9af startedMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9af failMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9af successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", + "6180385770bf5a029372b9af description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", + "6180385770bf5a029372b9af changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9af startedMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9af failMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9af successMessageText 58330581ace78e27b8b10cee 0": "Get your reward then. Better than a Christmas present, hehe!", @@ -23702,16 +26557,16 @@ "6180385770bf5a029372b9af successMessageText 5c0647fdd443bc2504c2d371 0": "Oh, well. Looks like there’s no end to this scum. You didn’t get hit, at least?", "6180385770bf5a029372b9af description 5c0647fdd443bc2504c2d371 0": "Was just thinking of you right now. Every time you leave me, I’m wondering if you’ll return or get killed like others. Hey, I’m not a pessimist. It’s just that there is another new gang, as people say. I’m still hoping that they are wrong. People can’t get into gangs forever, right? It has to stop eventually.", "6180385770bf5a029372b9af changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6180385770bf5a029372b9af startedMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9af failMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9af successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", - "6180385770bf5a029372b9af description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", - "6180385770bf5a029372b9af changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9b0 startedMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9b0 failMessageText 54cb50c76803fa8b248b4571 0": "", "6180385770bf5a029372b9b0 successMessageText 54cb50c76803fa8b248b4571 0": "How is it, soldier? Great.", "6180385770bf5a029372b9b0 description 54cb50c76803fa8b248b4571 0": "Come on in, don’t just stand in the doorway, dammit. Why am I so moody today, you ask? Well, I’ve got a rat problem… People don’t know where they shouldn’t stick their hands in. Maybe you could help me out with this? I’ll get you something in return.", "6180385770bf5a029372b9b0 changeQuestMessageText 54cb50c76803fa8b248b4571 0": "What do you mean you refuse? Soldier, soldier… use your head: who would protect the Motherland if not you? Think this through again.", + "6180385770bf5a029372b9b0 startedMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9b0 failMessageText 54cb57776803fa99248b456e 0": "", + "6180385770bf5a029372b9b0 successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", + "6180385770bf5a029372b9b0 description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", + "6180385770bf5a029372b9b0 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "6180385770bf5a029372b9b0 startedMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9b0 failMessageText 58330581ace78e27b8b10cee 0": "", "6180385770bf5a029372b9b0 successMessageText 58330581ace78e27b8b10cee 0": "Get your reward then. Better than a Christmas present, hehe!", @@ -23732,11 +26587,6 @@ "6180385770bf5a029372b9b0 successMessageText 5c0647fdd443bc2504c2d371 0": "Oh, well. Looks like there’s no end to this scum. You didn’t get hit, at least?", "6180385770bf5a029372b9b0 description 5c0647fdd443bc2504c2d371 0": "Was just thinking of you right now. Every time you leave me, I’m wondering if you’ll return or get killed like others. Hey, I’m not a pessimist. It’s just that there is another new gang, as people say. I’m still hoping that they are wrong. People can’t get into gangs forever, right? It has to stop eventually.", "6180385770bf5a029372b9b0 changeQuestMessageText 5c0647fdd443bc2504c2d371 0": "Ah, you know, while I was explaining the situation, I’ve already noticed in your eyes that you’re doubting whether to take the task or not. How bothersome, I’ll have to look for another man for this job.", - "6180385770bf5a029372b9b0 startedMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9b0 failMessageText 54cb57776803fa99248b456e 0": "", - "6180385770bf5a029372b9b0 successMessageText 54cb57776803fa99248b456e 0": "The bandits were eliminated? You have my thanks.", - "6180385770bf5a029372b9b0 description 54cb57776803fa99248b456e 0": "I need a person that is able to do hard work without unnecessary emotions. A group of people of unknown nationality constantly disrupts the supply of medicines. I’ll be frank: they kill couriers and take medicines for themselves. Mercenary, this arbitrariness must be stopped.", - "6180385770bf5a029372b9b0 changeQuestMessageText 54cb57776803fa99248b456e 0": "Young man, now is not the time for hasty decisions. Think about this carefully, weigh all the options. But do not take too long - the matter is urgent, so I will have to look for a better employee if you refuse.", "62825ef60e88d037dc1eb428 startedMessageText 579dc571d53a0658a154fbec 0": "", "62825ef60e88d037dc1eb428 failMessageText 579dc571d53a0658a154fbec 0": "", "62825ef60e88d037dc1eb428 successMessageText 579dc571d53a0658a154fbec 0": "Well done.", @@ -23774,8 +26624,10 @@ "628f588ebb558574b2260fe5 changeQuestMessageText 579dc571d53a0658a154fbec 0": "There are other tasks available, at the cost of my patience.", "6512ea46f7a078264a4376e4 name": "PMC's Best Friend", "6512ea46f7a078264a4376e4 description": "Survive and extract from Interchange through the Scav Co-Op extraction while playing as a PMC", + "6512ea46f7a078264a4376e4 successMessage": "", "6512eb3ddfb0ae1ee75a0376 name": "Traveler", "6512eb3ddfb0ae1ee75a0376 description": "Survive and extract from every location in Tarkov while playing as a PMC ", + "6512eb3ddfb0ae1ee75a0376 successMessage": "", "6512eb68f6c95fe8862e384d": "Survive and extract from Woods", "6512eb9a12da627da04880b3": "Survive and extract from Streets of Tarkov", "6512efeca198eb75ff9ca1c7": "Survive and extract from Customs", @@ -23788,49 +26640,70 @@ "657b1feef3231fc23e3ccdf7": "Survive and extract from Ground Zero", "6512f16bde333c33d5127cbc name": "Killer of Killers", "6512f16bde333c33d5127cbc description": "Eliminate one of the hooded men with their own knife at night time while playing as a PMC", + "6512f16bde333c33d5127cbc successMessage": "", "6512f1e3be73cc7f07358ed5 name": "Art of Style", "6512f1e3be73cc7f07358ed5 description": "Eliminate Killa for the first time while playing as a PMC", + "6512f1e3be73cc7f07358ed5 successMessage": "", "6513eb6e0dc723592b0f9095 name": "Call Your Brother", "6513eb6e0dc723592b0f9095 description": "Eliminate Tagilla for the first time while playing as a PMC", + "6513eb6e0dc723592b0f9095 successMessage": "", "6513ed89cf2f1c285e606068 name": "Silence of the Sawmill", "6513ed89cf2f1c285e606068 description": "Eliminate Shturman for the first time while playing as a PMC", + "6513ed89cf2f1c285e606068 successMessage": "", "6513ee11a3dd9b6aa7159b4a name": "Deal to Make", "6513ee11a3dd9b6aa7159b4a description": "Eliminate Reshala for the first time while playing as a PMC", + "6513ee11a3dd9b6aa7159b4a successMessage": "", "6513eec00dc723592b0f90cc name": "Grouse Hunting", "6513eec00dc723592b0f90cc description": "Eliminate Glukhar for the first time while playing as a PMC", + "6513eec00dc723592b0f90cc successMessage": "", "6513efa1b49e3253755f47eb name": "Sanatorium Orderly", "6513efa1b49e3253755f47eb description": "Eliminate Sanitar for the first time while playing as a PMC", + "6513efa1b49e3253755f47eb successMessage": "", "6513f0a10dc723592b0f90cf name": "Funny Graveyard Keeper", "6513f0a10dc723592b0f90cf description": "Eliminate Kaban for the first time while playing as a PMC", + "6513f0a10dc723592b0f90cf successMessage": "", "6513f1feec10ff011f17c7ea name": "Now There Are Three of Them!", "6513f1feec10ff011f17c7ea description": "Eliminate Knight, Birdeye, and Big Pipe in a single raid for the first time while playing as a PMC", + "6513f1feec10ff011f17c7ea successMessage": "", "6513f28cb49e3253755f47f3 name": "The Blind Watcher", "6513f28cb49e3253755f47f3 description": "Eliminate Zryachiy for the first time while playing as a PMC", + "6513f28cb49e3253755f47f3 successMessage": "", "65140ab8ec10ff011f17cc10 name": "What Not To Wear", "65140ab8ec10ff011f17cc10 description": "Eliminate Killa 15 times while playing as a PMC", + "65140ab8ec10ff011f17cc10 successMessage": "", "65140b55cf2f1c285e606414 name": "Hammer and Scythe", "65140b55cf2f1c285e606414 description": "Eliminate Tagilla 15 times while playing as a PMC", + "65140b55cf2f1c285e606414 successMessage": "", "65140bbec31fcb0e163577b9 name": "King of the Sawmill", "65140bbec31fcb0e163577b9 description": "Eliminate Shturman 15 times while playing as a PMC", + "65140bbec31fcb0e163577b9 successMessage": "", "65140c00b1c08b0feb216d50 name": "This Is a Tarkov Showdown", "65140c00b1c08b0feb216d50 description": "Eliminate Reshala 15 times while playing as a PMC", + "65140c00b1c08b0feb216d50 successMessage": "", "65141032a3dd9b6aa7159ed3 name": "Another Cold Case", "65141032a3dd9b6aa7159ed3 description": "Eliminate Glukhar 15 times while playing as a PMC", + "65141032a3dd9b6aa7159ed3 successMessage": "", "651411f1cf2f1c285e606423 name": "Who Called the Doctor?", "651411f1cf2f1c285e606423 description": "Eliminate Sanitar 15 times while playing as a PMC", + "651411f1cf2f1c285e606423 successMessage": "", "651412b8c31fcb0e163577c5 name": "Old Dog With Old tricks", "651412b8c31fcb0e163577c5 description": "Eliminate Kaban 15 times while playing as a PMC", + "651412b8c31fcb0e163577c5 successMessage": "", "6514134eec10ff011f17cc26 name": "I Hear the Voice of Darkness", "6514134eec10ff011f17cc26 description": "Eliminate Knight 15 times while playing as a PMC", + "6514134eec10ff011f17cc26 successMessage": "", "651412ef0afef6dad1a21477": "", "65142ceb93d02c082b8e4cc9": "", "65142d0701e02ae1f559d606": "", "651413e9c31fcb0e163577c9 name": "Now That's a Good Shot", "651413e9c31fcb0e163577c9 description": "Eliminate Zryachiy 15 times while playing as a PMC", + "651413e9c31fcb0e163577c9 successMessage": "", "6514143d59647d2cb3213c93 name": "Master of ULTRA", "6514143d59647d2cb3213c93 description": "Eliminate Killa 100 times while playing as a PMC", + "6514143d59647d2cb3213c93 successMessage": "", "651415feb49e3253755f4b68 name": "Long Live the King!", "651415feb49e3253755f4b68 description": "Eliminate every Boss once while playing as a PMC", + "651415feb49e3253755f4b68 successMessage": "", "651414b741f4ad07ba7d55f9": "Locate and eliminate Kaban", "651414eb3ec86f33dd54d978": "Locate and eliminate Reshala", "651415067c262d47d685c6d9": "Locate and eliminate Glukhar", @@ -23844,60 +26717,82 @@ "651415d13c02ff4aa9e9a426": "Locate and eliminate Birdeye", "657b1f2e057c1607e83c2c26": " Locate and eliminate Kollontai", "657b21a3564a9197c2778f5a": "Locate and eliminate Kollontai", + "66c34bbbd5d174a3c9cd1382": "Locate and eliminate Partisan", "6514174fb1c08b0feb216d73 name": "Chris's Heir", "6514174fb1c08b0feb216d73 description": "Eliminate a PMC operative with a headshot from over 500 meters away while playing as a PMC", + "6514174fb1c08b0feb216d73 successMessage": "", "651417d6ec10ff011f17cc31 name": "John's Heir", "651417d6ec10ff011f17cc31 description": "Eliminate 4 PMC operatives with a headshot while using a pistol in a single raid while playing as a PMC", + "651417d6ec10ff011f17cc31 successMessage": "", "6514184ec31fcb0e163577d2 name": "Killer7", "6514184ec31fcb0e163577d2 description": "Eliminate 7 PMC operatives in a single raid while playing as a PMC", + "6514184ec31fcb0e163577d2 successMessage": "", "651419eea3dd9b6aa7159ee5 name": "Blind Fury", "651419eea3dd9b6aa7159ee5 description": "Eliminate any enemy while suffering from the Flash effect while playing as a PMC", + "651419eea3dd9b6aa7159ee5 successMessage": "", "65141a3059647d2cb3213c9e name": "Make a Notch", "65141a3059647d2cb3213c9e description": "Eliminate 30 PMC operators with a melee weapon while playing as a PMC", + "65141a3059647d2cb3213c9e successMessage": "", "65141ab70dc723592b0f9482 name": "Drunken Master", "65141ab70dc723592b0f9482 description": "Eliminate a PMC operative with a headshot while under the alcohol effect while playing as a PMC", + "65141ab70dc723592b0f9482 successMessage": "", "65141b9859647d2cb3213ca2 name": "U-SUCC", "65141b9859647d2cb3213ca2 description": "Eliminate 50 USEC PMC operators", + "65141b9859647d2cb3213ca2 successMessage": "", "65141bdfcf2f1c285e606446 name": "BEAR With Me", "65141bdfcf2f1c285e606446 description": "Eliminate 50 BEAR PMC operators", + "65141bdfcf2f1c285e606446 successMessage": "", "65141c30ec10ff011f17cc3b name": "Welcome to Tarkov", "65141c30ec10ff011f17cc3b description": "Die in Tarkov for the first time", + "65141c30ec10ff011f17cc3b successMessage": "", "65141c80ec10ff011f17cc3e name": "First Time Always Hurts", "65141c80ec10ff011f17cc3e description": "Survive a raid without the Run-through status for the first time", + "65141c80ec10ff011f17cc3e successMessage": "", "65141cd2cf2f1c285e606449 name": "Ready for Anything", "65141cd2cf2f1c285e606449 description": "Survive 10 consecutive raids while playing as a PMC", + "65141cd2cf2f1c285e606449 successMessage": "", "65141dd6303df252af1c72c9 name": "PMC", "65141dd6303df252af1c72c9 description": "Survive 300 raids while playing as a PMC", + "65141dd6303df252af1c72c9 successMessage": "", "65141e37cf2f1c285e606361 name": "That's What She Said", "65141e37cf2f1c285e606361 description": "Search the office in Factory while playing as a PMC", + "65141e37cf2f1c285e606361 successMessage": "", "65141eb5c31fcb0e163577dd name": "Lost", "65141eb5c31fcb0e163577dd description": "Locate the crashed plane on Woods while playing as a PMC", + "65141eb5c31fcb0e163577dd successMessage": "", "65141f80a3dd9b6aa7159ef0 name": "Survivor", "65141f80a3dd9b6aa7159ef0 description": "Survive and extract from any location with each of the possible negative effects either separately or combined while playing as a PMC ", + "65141f80a3dd9b6aa7159ef0 successMessage": "", "65141fb6ed5340c843c5dcb8": "Survive and extract from any location with the Concussion effect", "65141ff769b11104777a6197": "Survive and extract from any location with the Dehydration effect", "651420b3c6c7ce8343cc8976": "Survive and extract from any location with the Bleeding effect", "65142168f401d144e9f3e2ac": "Survive and extract from any location with the Tremor effect", "651421ff151e86f67ca3c3ea": "Survive and extract from any location with the Pain effect", - "65145d0d1d3ff24a185abbb0": "Survive and extract from any location with the Fatigue effect", - "651433702d8de66f60699f98": "Survive and extract from any location with the Fresh wound effect", - "651433371dab0f7e105828ff": "Survive and extract from any location with the Flash effect", - "65143313b1a83e60ef15a45b": "Survive and extract from any location with the Stun effect", "651432b59bf826df60b20d89": "Survive and extract from any location with the Fracture effect", + "65143313b1a83e60ef15a45b": "Survive and extract from any location with the Stun effect", + "651433371dab0f7e105828ff": "Survive and extract from any location with the Flash effect", + "651433702d8de66f60699f98": "Survive and extract from any location with the Fresh wound effect", + "65145d0d1d3ff24a185abbb0": "Survive and extract from any location with the Fatigue effect", "65145e2fd9f595730e564291": "Survive and extract from any location with the Tunnel vision effect", "65145f005e81cb4466a82e04": "Survive and extract from any location with the Toxin effect", "6514321bec10ff011f17ccac name": "Firefly", "6514321bec10ff011f17ccac description": "Meet Lightkeeper for the first time while playing as a PMC", + "6514321bec10ff011f17ccac successMessage": "", "65145cbc303df252af1c73d5 name": "Missing Something?", "65145cbc303df252af1c73d5 description": "Start a raid without any weapon", + "65145cbc303df252af1c73d5 successMessage": "", "6527d2e2c656a951ad1528c3 name": "Smoke the Peace Pipe", "6527d2e2c656a951ad1528c3 description": "Eliminate Big Pipe 15 times while playing as a PMC", + "6527d2e2c656a951ad1528c3 successMessage": "", "6527d3aac656a951ad1528ce name": "The Red Book", "6527d3aac656a951ad1528ce description": "Eliminate Birdeye 15 times while playing as a PMC", + "6527d3aac656a951ad1528ce successMessage": "", "6527ee4a647c29201011defe name": "You Are Not My Brother", "6527ee4a647c29201011defe description": "Eliminate a Scav while playing as a Scav", + "6527ee4a647c29201011defe successMessage": "", "6529097eccf6aa5f8737b3d0 name": "Snowball", "6529097eccf6aa5f8737b3d0 description": "Eliminate every Boss without dying while playing as a PMC", + "6529097eccf6aa5f8737b3d0 successMessage": "", "652909ac342bdd14e0bcb1bb": "Locate and eliminate Kaban", "652909cd3f9e480e9d1a3489": "Locate and eliminate Reshala", "652909ef8cb2a699ccbc2cf0": "Locate and eliminate Glukhar", @@ -23905,29 +26800,76 @@ "65290e22f16e69470b5d6145": "Locate and eliminate Knight", "65290e51fee42b19970ccbfd": "Locate and eliminate Shturman", "65290e8d6193b1a4e12a7967": "Locate and eliminate Sanitar", - "65290f50897943fb9bf8955d": "Locate and eliminate Birdeye", - "65290f3fd7c6005f6d78f453": "Locate and eliminate Big Pipe", - "65290f1579363c7810e7233d": "Locate and eliminate Zryachiy", "65290ed47ef294bc6eb7ee85": "Locate and eliminate Tagilla", + "65290f1579363c7810e7233d": "Locate and eliminate Zryachiy", + "65290f3fd7c6005f6d78f453": "Locate and eliminate Big Pipe", + "65290f50897943fb9bf8955d": "Locate and eliminate Birdeye", "657b1e91958145eb193f9a40": "Locate and eliminate Kollontai", + "66c34ab2c3eee7ac0c41d160": "Locate and eliminate Partisan", "655b49bc91aa9e07687ae47c name": "Justice", "655b49bc91aa9e07687ae47c description": "Eliminate Kollontay for the first time while playing as a PMC", + "655b49bc91aa9e07687ae47c successMessage": "", "655b4a576689c676ce57acb6 name": "True Crime", "655b4a576689c676ce57acb6 description": "Eliminate Kollontay 15 times while playing as a PMC", + "655b4a576689c676ce57acb6 successMessage": "", "65606e084c9e9c2c190bd25f name": "", "65606e084c9e9c2c190bd25f description": "", + "65606e084c9e9c2c190bd25f successMessage": "", "660fe21454670811e304c045 name": "Maslenitsa", - "660fe21454670811e304c045 description": "For the completion of Maslenitsa event quest line", + "660fe21454670811e304c045 description": "Сomplete the Maslenitsa 2024 event task line", + "660fe21454670811e304c045 successMessage": "", "6634c8886e083a141f4aa3f4 name": "Cardinal Richelieu", - "6634c8886e083a141f4aa3f4 description": "Complete The Tarkov Mystery event and find out who actually controls Tarkov", + "6634c8886e083a141f4aa3f4 description": "Find out who actually controls Tarkov and complete The Tarkov Mystery event task line", + "6634c8886e083a141f4aa3f4 successMessage": "", "6634ca69ee506a5c3e61be56 name": "INVOLVED IN PEACE", - "6634ca69ee506a5c3e61be56 description": "Complete The Tarkov Mystery event by picking Peacekeeper's side", + "6634ca69ee506a5c3e61be56 description": "Pick Peacekeeper's side and complete The Tarkov Mystery event task line", + "6634ca69ee506a5c3e61be56 successMessage": "", "6634cae870af846d2868dada name": "Local Strong Man", - "6634cae870af846d2868dada description": "Complete The Tarkov Mystery event by picking Skier's side", - "664f1f8768508d74604bf556 name": "The Kappa path", - "664f1f8768508d74604bf556 description": "Obtain \"Kappa\" secure container", - "664f23e44702fd5db50ee732 name": "Jack of all trades", - "664f23e44702fd5db50ee732 description": "Complete \"Gunsmith\" questline", + "6634cae870af846d2868dada description": "Pick Skier's side and complete The Tarkov Mystery event task line", + "6634cae870af846d2868dada successMessage": "", + "664f1f8768508d74604bf556 name": "The Kappa Path", + "664f1f8768508d74604bf556 description": "Obtain Secure container Kappa", + "664f1f8768508d74604bf556 successMessage": "", + "664f23e44702fd5db50ee732 name": "Jack of All Trades", + "664f23e44702fd5db50ee732 description": "Complete the Gunsmith questline", + "664f23e44702fd5db50ee732 successMessage": "", "66742c003a67b164a300fcbf name": "A Key to Salvation", - "66742c003a67b164a300fcbf description": "Complete the Key to Salvation event and help Therapist save lives" + "66742c003a67b164a300fcbf description": "Help Therapist save lives and complete the Key to Salvation event task line", + "66742c003a67b164a300fcbf successMessage": "", + "668bf47c781d446fdc083711 name": "High Competition", + "668bf47c781d446fdc083711 description": "Choose your side and complete the Arms Race event task line", + "668bf47c781d446fdc083711 successMessage": "", + "66b493bc2d8cd3b5e90a3648 name": "Marathon", + "66b493bc2d8cd3b5e90a3648 description": "Visit all locations in one raid as a PMC", + "66b493bc2d8cd3b5e90a3648 successMessage": "", + "66b49441b14491e93b51599c": "Use the transit from Ground Zero", + "66b497b6ebe746c5514bc15f": "Use the transit from Streets of Tarkov to The Lab", + "66b4993717f669ba37f271a9": "Use the transit from Interchange", + "66b4997047402dedee9d1c55": "Use the transit from Customs", + "66b499a1257913079a6e3645": "Use the transit from Factory", + "66b499c730acccbfc0436665": "Use the transit from Woods", + "66b499d7eb712b1555360355": "Use the transit from Reserve", + "66b499eac980c9c597d23296": "Use the transit from Lighthouse", + "66b49a1662133b59e3e9a92c": "Use the transit from The Lab", + "66b49a3e5665abc69d87b5e6": "Use the transit from Streets of Tarkov", + "66b49a801d6c9c02b92a4e9b": "Survive and extract from Shoreline", + "66c328aca91e7d66fa1b0b7b name": "Vagabond", + "66c328aca91e7d66fa1b0b7b description": "Use the transit from any location", + "66c328aca91e7d66fa1b0b7b successMessage": "", + "66c328ce17df4e6ce92d1120": "Use the transit from any location", + "66c328de9dc78468f4040f35 name": "Time To Clean My Karma", + "66c328de9dc78468f4040f35 description": "Eliminate Partisan for the first time while playing as a PMC", + "66c328de9dc78468f4040f35 successMessage": "", + "66c32996b4c0c017a3319cc3 name": "Samsara Wheel Spins Again", + "66c32996b4c0c017a3319cc3 description": "Eliminate Partisan 15 times while playing as a PMC", + "66c32996b4c0c017a3319cc3 successMessage": "", + "66e2a7e5919bad697104f4b3 name": "Highway to the Danger Zone", + "66e2a7e5919bad697104f4b3 description": "Complete the Mortar Strike 2024 event task line", + "66e2a7e5919bad697104f4b3 successMessage": "", + "670feb95a4e71050310cc14b name": "Complete Remission", + "670feb95a4e71050310cc14b description": "Cure all the infected and complete the Halloween 2024 event task line", + "670feb95a4e71050310cc14b successMessage": "", + "670febed5ee0fc738a0965a4 name": "Fatal Outcome", + "670febed5ee0fc738a0965a4 description": "Destroy the virus along with all the infected and complete the Halloween 2024 event task line", + "670febed5ee0fc738a0965a4 successMessage": "" } diff --git a/external-resources/mapgenie_locations.json b/external-resources/mapgenie_locations.json index 53bf8df5..a9a0eb8a 100644 --- a/external-resources/mapgenie_locations.json +++ b/external-resources/mapgenie_locations.json @@ -121,6 +121,10 @@ { "id": 88025, "description": "Med Tent Gate" + }, + { + "id": 403860, + "description": "Courtyard Gate" } ], "interchange": [ @@ -442,7 +446,7 @@ }, { "id": 24856, - "description": "Factory Gate (Co-Op)" + "description": "Friendship Bridge (Co-Op)" }, { "id": 24857, @@ -491,6 +495,10 @@ { "id": 65038, "description": "Northern UN Roadblock" + }, + { + "id": 410432, + "description": "Power Line Passage" } ], "groundzero": [ diff --git a/external-resources/maps/customs.json b/external-resources/maps/customs.json index 11c88f40..3f967a98 100644 --- a/external-resources/maps/customs.json +++ b/external-resources/maps/customs.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 50, @@ -83,6 +84,27 @@ } ], "BossLocationSpawn": [ + { + "BossChance": 30, + "BossDifficult": "normal", + "BossEscortAmount": "0", + "BossEscortDifficult": "normal", + "BossEscortType": "sectantWarrior", + "BossName": "bossPartisan", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": true, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["regular", "pve"], + "Supports": null, + "Time": 900, + "TriggerId": "PARTISAN_TRIGGER", + "TriggerName": "botEvent" + }, { "BossChance": 4, "BossDifficult": "normal", @@ -93,6 +115,8 @@ "BossPlayer": false, "BossZone": "ZoneScavBase,ZoneDormitory,ZoneFactoryCenter,ZoneCustoms,ZoneBrige", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -103,7 +127,7 @@ "TriggerName": "" }, { - "BossChance": 35, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "2", "BossEscortDifficult": "normal", @@ -112,6 +136,8 @@ "BossPlayer": false, "BossZone": "ZoneScavBase", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": true, @@ -138,7 +164,7 @@ "TriggerName": "" }, { - "BossChance": 35, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "4", "BossEscortDifficult": "normal", @@ -147,6 +173,8 @@ "BossPlayer": false, "BossZone": "ZoneDormitory,ZoneGasStation,ZoneScavBase", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -157,7 +185,7 @@ "TriggerName": "" }, { - "BossChance": 20, + "BossChance": 40, "BossDifficult": "normal", "BossEscortAmount": "4", "BossEscortDifficult": "normal", @@ -166,6 +194,8 @@ "BossPlayer": false, "BossZone": "ZoneScavBase", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -175,6 +205,132 @@ "TriggerId": "", "TriggerName": "" }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, { "BossChance": 5, "BossDifficult": "normal", @@ -199,18 +355,118 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 265, + "DistToActivatePvE": 265, "DistToPersueAxemanCoef": 1, "DistToSleep": 300, + "DistToSleepPvE": 300, "GainSight": 1, "KhorovodChance": 0, "MagnetPower": 44, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1800, + "MinExfiltrationTime": 1200, "Scattering": 1, "VisibleDistance": 1 }, "BotMarksman": 20, - "BotMax": 17, + "BotMax": 19, "BotMaxPlayer": 9, "BotMaxPvE": 30, "BotMaxTimePlayer": 1000, @@ -232,9 +488,89 @@ "EscapeTimeLimit": 40, "EscapeTimeLimitCoop": 25, "EscapeTimeLimitPVE": 40, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 200, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 200, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.9, + "GlobalLootChanceModifier": 0.4, "GlobalLootChanceModifierPvE": 0.9, "IconX": 550, "IconY": 460, @@ -290,6 +626,7 @@ "MinPlayers": 10, "Name": "Customs", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -298,8 +635,8 @@ }, "OcculsionCullingEnabled": false, "OfflineNewSpawn": true, - "OfflineOldSpawn": false, - "OldSpawn": false, + "OfflineOldSpawn": true, + "OldSpawn": true, "OpenZones": "ZoneBrige,ZoneCrossRoad,ZoneDormitory,ZoneGasStation,ZoneFactoryCenter,ZoneFactorySide,ZoneOldAZS,ZoneSnipeBrige,ZoneSnipeTower,ZoneSnipeFactory,ZoneBlockPost,ZoneBlockPostSniper,ZoneBlockPostSniper3,ZoneBlockPost,ZoneTankSquare,ZoneWade,ZoneCustoms", "PlayersRequestCount": -1, "PmcMaxPlayersInGroup": 5, @@ -318,7 +655,7 @@ }, "SpawnPointParams": [ { - "BotZoneName": "ZoneBlockPost", + "BotZoneName": "ZoneWade", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -328,24 +665,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 164.4 } }, - "CorePointId": 19, + "CorePointId": 5, "DelayToCanSpawnSec": 6, - "Id": "001e44f1-406b-4121-be96-aa1e77c3d558", + "Id": "0321a8fe-1219-4574-9557-4d7cb2ae1c0e", "Infiltration": "", "Position": { - "x": 510.865, - "y": 3.43099976, - "z": 46.168 + "x": 5.87000275, + "y": 1.37882686, + "z": -90.5099945 }, - "Rotation": 186.6658, + "Rotation": 229.912613, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneOldAZS", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -354,24 +691,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 6, - "Id": "0168c19d-0e4c-4684-a8ad-4b41a9f02166", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "0327c5d1-cc7f-432f-92dc-f95fb4719f1b", + "Infiltration": "Boiler Tanks", "Position": { - "x": 310.722839, - "y": 1.33199024, - "z": -157.0032 + "x": 571.41, + "y": 1.49, + "z": -53.4799957 }, - "Rotation": 147.656372, - "Sides": ["Savage"] + "Rotation": 180.13, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWade", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -380,23 +717,49 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 5, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "06305c94-bdc3-4355-b2df-4b9060f54ed2", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 584.06, + "y": 9.66, + "z": 146.22 + }, + "Rotation": 230.030014, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 25 + } + }, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "0243940a-ef7e-480e-90a6-12b10523e0dc", + "Id": "06609aab-bf3d-4a8e-9c0f-ba60366663ad", "Infiltration": "", "Position": { - "x": 20.0500031, - "y": 1.138802, - "z": -115.49 + "x": -170.240021, + "y": 1.063748, + "z": -46.4629974 }, - "Rotation": 174.01767, + "Rotation": 273.068, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBrige", + "BotZoneName": "ZoneCustoms", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -406,19 +769,19 @@ "y": 0, "z": 0 }, - "Radius": 117.5 + "Radius": 110 } }, - "CorePointId": 4, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "0293be29-bfd1-4959-85b3-3dfed44cf6e4", + "Id": "06da51ee-f83e-47f3-a947-8d0e6254edce", "Infiltration": "", "Position": { - "x": -9.670734, - "y": -6.85845947, - "z": 127.67 + "x": -329.382019, + "y": 1.01902342, + "z": -211.054 }, - "Rotation": 176.0234, + "Rotation": 99.65997, "Sides": ["Savage"] }, { @@ -437,18 +800,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0327c5d1-cc7f-432f-92dc-f95fb4719f1b", - "Infiltration": "Boiler Tanks", + "Id": "0a780428-48e0-4268-9ef8-0a7f999cc632", + "Infiltration": "Customs", "Position": { - "x": 571.41, - "y": 1.49, - "z": -53.4799957 + "x": -220.212, + "y": 1.0710001, + "z": -141.936 }, - "Rotation": 180.13, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTankSquare", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -458,19 +821,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 77.17 } }, - "CorePointId": 4, + "CorePointId": 25, "DelayToCanSpawnSec": 6, - "Id": "0431d71a-7a61-496e-8fdc-32433ef00f29", + "Id": "0b6da56b-3e12-49e9-adfe-d33d4bd56d34", "Infiltration": "", "Position": { - "x": 119.710007, - "y": 1.10880566, - "z": -34.1 + "x": 420.47, + "y": 1.14899969, + "z": 22.5500011 }, - "Rotation": 309.78418, + "Rotation": 126.588921, "Sides": ["Savage"] }, { @@ -484,24 +847,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 75 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "06305c94-bdc3-4355-b2df-4b9060f54ed2", + "Id": "0bfe7760-902e-4b79-8722-7ce2ad0a970c", "Infiltration": "Boiler Tanks", "Position": { - "x": 584.06, - "y": 9.66, - "z": 146.22 + "x": 288.068, + "y": 1.718, + "z": -201.166 }, - "Rotation": 230.030014, + "Rotation": 17.73762, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -513,21 +876,47 @@ "Radius": 50 } }, - "CorePointId": 16, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0711d5e8-26e2-43fb-a2b5-6998eac2e0e7", - "Infiltration": "", + "Id": "0f054aeb-dae4-4de4-8f19-e96baac1def6", + "Infiltration": "Boiler Tanks", "Position": { - "x": 252.16629, - "y": 1.21224034, - "z": -108.459213 + "x": 531.88, + "y": 9.52, + "z": 195.790009 }, - "Rotation": 135.08139, - "Sides": ["Savage"] + "Rotation": 225.49, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "0fd52df3-8419-4644-917f-efd18d99c85a", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 546.888, + "y": 2.208, + "z": 45.5639954 + }, + "Rotation": 342.4109, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -539,21 +928,21 @@ "Radius": 50 } }, - "CorePointId": 16, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "082ca074-6733-42cc-a855-a36732074c8d", - "Infiltration": "", + "Id": "105e161c-c1ad-4004-8c02-f3c95164a75e", + "Infiltration": "Boiler Tanks", "Position": { - "x": 236.2663, - "y": 1.21224034, - "z": -95.11922 + "x": 574, + "y": 1.46, + "z": -114.85 }, - "Rotation": 111.995163, - "Sides": ["Savage"] + "Rotation": 283.46, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -562,23 +951,23 @@ "y": 0, "z": 0 }, - "Radius": 20 + "Radius": 77 } }, - "CorePointId": 16, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0a598207-bf53-4847-9f87-62fd08170616", - "Infiltration": "", + "Id": "10a75815-d786-43e2-9639-6b94071433f8", + "Infiltration": "Customs", "Position": { - "x": 208.2033, - "y": 1.78224027, - "z": -116.860214 + "x": 101.76799, + "y": 1.18800008, + "z": 11.8939972 }, - "Rotation": 189.840561, - "Sides": ["Savage"] + "Rotation": 167.010742, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", + "BotZoneName": "ZoneCrossRoad", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -588,24 +977,24 @@ "y": 0, "z": 0 }, - "Radius": 93.4 + "Radius": 90 } }, - "CorePointId": 11, + "CorePointId": 7, "DelayToCanSpawnSec": 6, - "Id": "0a71bdc4-7f40-45ba-a99d-7b0ed082fd8f", + "Id": "10b76618-8674-4b79-ad6b-ce258f54bb73", "Infiltration": "", "Position": { - "x": 423.79, - "y": 1.0539999, - "z": 42.34 + "x": 175.290009, + "y": 1.21891308, + "z": -5.380005 }, - "Rotation": 343.038422, + "Rotation": 38.0980873, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -614,21 +1003,47 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0a780428-48e0-4268-9ef8-0a7f999cc632", + "Id": "119b220b-ec7f-41a8-bdb2-eeb831e2c17b", "Infiltration": "Customs", "Position": { - "x": -220.212, - "y": 1.0710001, - "z": -141.936 + "x": 569.208, + "y": -0.322000027, + "z": -8.846008 }, - "Rotation": 0, + "Rotation": 270.218658, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneOldAZS", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 80 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 6, + "Id": "11d4887b-54a6-40bf-87cf-f70d0721da0c", + "Infiltration": "", + "Position": { + "x": 291.5036, + "y": 2.35399628, + "z": -169.449524 + }, + "Rotation": 147.656372, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -640,23 +1055,23 @@ "y": 0, "z": 0 }, - "Radius": 75 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0bfe7760-902e-4b79-8722-7ce2ad0a970c", - "Infiltration": "Boiler Tanks", + "Id": "11e7dc8d-ee50-4800-a400-a2f2761b6e9f", + "Infiltration": "Customs", "Position": { - "x": 288.068, - "y": 1.718, - "z": -201.166 + "x": -195.952, + "y": 1.458, + "z": -234.646 }, - "Rotation": 17.73762, + "Rotation": 17.2243824, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", + "BotZoneName": "ZoneFactorySide", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -666,23 +1081,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 40 } }, - "CorePointId": 16, - "DelayToCanSpawnSec": 4, - "Id": "0cc3c862-6acf-4b00-bac1-962984231138", + "CorePointId": 2, + "DelayToCanSpawnSec": 6, + "Id": "12463505-23d7-4b12-afe7-4e540c04373a", "Infiltration": "", "Position": { - "x": 255.4663, - "y": 1.21224034, - "z": -108.379227 + "x": 513.6549, + "y": 1.21008575, + "z": -55.33365 }, - "Rotation": 135.08139, + "Rotation": 100.786774, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGasStation", + "BotZoneName": "ZoneCustoms", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -692,24 +1107,24 @@ "y": 0, "z": 0 }, - "Radius": 77.17 + "Radius": 110 } }, - "CorePointId": 11, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "0e7d1ee0-4ae3-4845-9c9b-6101409955da", + "Id": "12b8a48c-1b41-4e9f-a2e4-197d9c469d61", "Infiltration": "", "Position": { - "x": 447.43, - "y": 7.59999943, - "z": 111.09 + "x": -157.741013, + "y": 1.60435379, + "z": -190.766 }, - "Rotation": 196.259735, + "Rotation": 273.068, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -721,17 +1136,17 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "0f054aeb-dae4-4de4-8f19-e96baac1def6", - "Infiltration": "Boiler Tanks", + "Id": "130a034a-5c2d-4d81-a04f-728f20421cc2", + "Infiltration": "", "Position": { - "x": 531.88, - "y": 9.52, - "z": 195.790009 + "x": 255.4663, + "y": 1.21224034, + "z": -108.379227 }, - "Rotation": 225.49, - "Sides": ["Pmc"] + "Rotation": 135.08139, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -744,19 +1159,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0fd52df3-8419-4644-917f-efd18d99c85a", + "Id": "158ea18b-12e5-4495-8774-0cb185ce83ba", "Infiltration": "Boiler Tanks", "Position": { - "x": 546.888, - "y": 2.208, - "z": 45.5639954 + "x": 587.85, + "y": 8.89, + "z": 141.949982 }, - "Rotation": 342.4109, + "Rotation": 216.79, "Sides": ["Pmc"] }, { @@ -775,19 +1190,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "105e161c-c1ad-4004-8c02-f3c95164a75e", - "Infiltration": "Boiler Tanks", + "Id": "15a5b4ce-8d57-41b8-8f2b-bcf806a8e803", + "Infiltration": "Customs", "Position": { - "x": 574, - "y": 1.46, - "z": -114.85 + "x": -223.232, + "y": 1.118, + "z": -147.516 }, - "Rotation": 283.46, + "Rotation": 13.3819723, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -796,23 +1211,23 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "10a75815-d786-43e2-9639-6b94071433f8", - "Infiltration": "Customs", + "Id": "16894fca-9b05-4c00-956e-1e352ab68131", + "Infiltration": "", "Position": { - "x": 101.76799, - "y": 1.18800008, - "z": 11.8939972 + "x": 133.786285, + "y": 1.74224031, + "z": -82.02922 }, - "Rotation": 167.010742, - "Sides": ["Pmc"] + "Rotation": 189.840561, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBlockPost", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -822,24 +1237,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 62.3 } }, - "CorePointId": 19, + "CorePointId": 11, "DelayToCanSpawnSec": 6, - "Id": "117bc357-c61a-45ea-9018-6dca47b7e665", + "Id": "16ac5894-aca4-435f-8646-53a2ed3b17df", "Infiltration": "", "Position": { - "x": 487.64, - "y": 1.68252087, - "z": 41.11 + "x": 430.815033, + "y": 1.88306046, + "z": 54.8594666 }, - "Rotation": 186.6658, + "Rotation": 343.038422, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -853,19 +1268,45 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "119b220b-ec7f-41a8-bdb2-eeb831e2c17b", + "Id": "181f7000-df70-4bc7-bff3-a709291c907f", "Infiltration": "Customs", "Position": { - "x": 569.208, - "y": -0.322000027, - "z": -8.846008 + "x": 100.158005, + "y": 1.18800008, + "z": 11.9940033 }, - "Rotation": 270.218658, + "Rotation": 167.010742, "Sides": ["Pmc"] }, { "BotZoneName": "", "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "1a39d596-25e4-4b63-b6da-325aa8409576", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 570.06, + "y": 1.49, + "z": -54.9799957 + }, + "Rotation": 191.11, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -879,18 +1320,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "11e7dc8d-ee50-4800-a400-a2f2761b6e9f", + "Id": "1ae5dc66-b54c-4584-bc24-174f5b3194ec", "Infiltration": "Customs", "Position": { - "x": -195.952, - "y": 1.458, - "z": -234.646 + "x": 569.347961, + "y": -0.322000027, + "z": -10.6060028 }, - "Rotation": 17.2243824, + "Rotation": 270.218658, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactoryCenter", + "BotZoneName": "ZoneOldAZS", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -900,19 +1341,19 @@ "y": 0, "z": 0 }, - "Radius": 114.7 + "Radius": 80 } }, - "CorePointId": 21, + "CorePointId": 13, "DelayToCanSpawnSec": 6, - "Id": "14492c77-9b71-45f7-bbd1-d40e86a04ee1", + "Id": "1b202f92-51b5-4888-acfd-8784a130e14c", "Infiltration": "", "Position": { - "x": 365.1455, - "y": 1.32006228, - "z": -108.90036 + "x": 339.321442, + "y": 1.189998, + "z": -190.771988 }, - "Rotation": 277.4024, + "Rotation": 52.6828651, "Sides": ["Savage"] }, { @@ -931,19 +1372,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "158ea18b-12e5-4495-8774-0cb185ce83ba", - "Infiltration": "Boiler Tanks", + "Id": "1b636e5b-ae6d-4df3-93ea-159f5a2437fd", + "Infiltration": "Customs", "Position": { - "x": 587.85, - "y": 8.89, - "z": 141.949982 + "x": -132.9, + "y": -1.66999984, + "z": 39.8999939 }, - "Rotation": 216.79, + "Rotation": 180.13, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -952,24 +1393,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "15a5b4ce-8d57-41b8-8f2b-bcf806a8e803", + "Id": "1b65286c-52e8-48ef-a369-e89bfd0ab95e", "Infiltration": "Customs", "Position": { - "x": -223.232, - "y": 1.118, - "z": -147.516 + "x": -133.812, + "y": 0.718000054, + "z": 14.2939911 }, - "Rotation": 13.3819723, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrige", - "Categories": ["Bot"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -978,24 +1419,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 25 } }, - "CorePointId": 4, + "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "15efa578-bddc-4e26-b173-18dd95ec8031", + "Id": "1b70ff23-343f-4f57-a21b-b9c22b98a6db", "Infiltration": "", "Position": { - "x": 19.3312683, - "y": -0.88446, - "z": 36.432 + "x": 185.443283, + "y": 2.83624029, + "z": 182.801788 }, - "Rotation": 104.141586, + "Rotation": 168.224945, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1004,23 +1445,49 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 65 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "181f7000-df70-4bc7-bff3-a709291c907f", + "Id": "1b9fddbc-f667-4344-98ef-3d198229bd41", "Infiltration": "Customs", "Position": { - "x": 100.158005, - "y": 1.18800008, - "z": 11.9940033 + "x": -151.782, + "y": 1.258, + "z": -129.81601 }, - "Rotation": 167.010742, + "Rotation": 135.46, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneOldAZS", + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 80 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "1c26a886-b1f5-490e-8fdd-153d991dc393", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 363.248, + "y": 12.698, + "z": 155.594 + }, + "Rotation": 180.91, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneCrossRoad", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1033,16 +1500,16 @@ "Radius": 80 } }, - "CorePointId": 13, + "CorePointId": 7, "DelayToCanSpawnSec": 6, - "Id": "18aa63ac-895c-4178-ac75-5e916a53d0b3", + "Id": "1cb1e3f5-0718-4178-95cf-39f3a5bbddfd", "Infiltration": "", "Position": { - "x": 313.802277, - "y": 1.16418183, - "z": -191.568161 + "x": 213.6, + "y": 1.24984646, + "z": 1.949997 }, - "Rotation": 147.656372, + "Rotation": 327.055481, "Sides": ["Savage"] }, { @@ -1061,19 +1528,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1a39d596-25e4-4b63-b6da-325aa8409576", - "Infiltration": "Boiler Tanks", + "Id": "1d0f26c8-85e5-42d0-b115-7d8f325f97d4", + "Infiltration": "Customs", "Position": { - "x": 570.06, - "y": 1.49, - "z": -54.9799957 + "x": -130.65, + "y": -2.11, + "z": 38.9100037 }, - "Rotation": 191.11, + "Rotation": 180.13, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneWade", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1082,20 +1549,20 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 120 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "1ae5dc66-b54c-4584-bc24-174f5b3194ec", - "Infiltration": "Customs", + "CorePointId": 5, + "DelayToCanSpawnSec": 6, + "Id": "1d5a53ba-2b64-4915-9de8-826f06c7ba97", + "Infiltration": "", "Position": { - "x": 569.347961, - "y": -0.322000027, - "z": -10.6060028 + "x": 6.49000549, + "y": 1.26882577, + "z": -95.06 }, - "Rotation": 270.218658, - "Sides": ["Pmc"] + "Rotation": 168.0339, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1113,19 +1580,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1b636e5b-ae6d-4df3-93ea-159f5a2437fd", + "Id": "1d80614c-e211-42d5-b661-8e2bb1aeae79", "Infiltration": "Customs", "Position": { - "x": -132.9, - "y": -1.66999984, - "z": 39.8999939 + "x": 100.598007, + "y": 1.168, + "z": -110.826004 }, - "Rotation": 180.13, + "Rotation": 0, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1134,24 +1601,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1b65286c-52e8-48ef-a369-e89bfd0ab95e", + "Id": "1fb2eba7-250e-4fd1-ba2a-75fb3d640ed7", "Infiltration": "Customs", "Position": { - "x": -133.812, - "y": 0.718000054, - "z": 14.2939911 + "x": -131.27, + "y": -2.09, + "z": 42.6900024 }, - "Rotation": 85.46295, + "Rotation": 180.13, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1160,20 +1627,20 @@ "y": 0, "z": 0 }, - "Radius": 20 + "Radius": 50 } }, - "CorePointId": 16, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1b997c88-6205-4ec8-b15e-1c2d45aa7700", - "Infiltration": "", + "Id": "20495255-3094-4add-8744-14efc6e05308", + "Infiltration": "Boiler Tanks", "Position": { - "x": 195.336288, - "y": 1.78624034, - "z": -126.129227 + "x": 525.62, + "y": 8.88, + "z": 199 }, - "Rotation": 252.354721, - "Sides": ["Savage"] + "Rotation": 225.49, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -1186,24 +1653,24 @@ "y": 0, "z": 0 }, - "Radius": 65 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1b9fddbc-f667-4344-98ef-3d198229bd41", - "Infiltration": "Customs", + "Id": "2051eb7b-3ae8-49b8-adcb-c13f0ddc7972", + "Infiltration": "Boiler Tanks", "Position": { - "x": -151.782, - "y": 1.258, - "z": -129.81601 + "x": 317.338, + "y": 1.128, + "z": -78.756 }, - "Rotation": 135.46, + "Rotation": 11.5521812, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSnipeFactory", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1212,24 +1679,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 77 } }, - "CorePointId": 9, - "DelayToCanSpawnSec": 1700, - "Id": "1c08d9cd-7ba8-41be-a92f-f233ac7f9da5", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "222800ad-50c8-4c75-b94b-ff1ec3d807d0", + "Infiltration": "Customs", "Position": { - "x": 476.11853, - "y": 14.7500124, - "z": -71.85715 + "x": 569.537964, + "y": -0.322000027, + "z": -12.9960022 }, - "Rotation": 147.656372, - "Sides": ["Savage"] + "Rotation": 270.218658, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1238,20 +1705,20 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "1c26a886-b1f5-490e-8fdd-153d991dc393", - "Infiltration": "Boiler Tanks", + "Id": "232e59b2-edec-429d-99e3-06f70241ce28", + "Infiltration": "", "Position": { - "x": 363.248, - "y": 12.698, - "z": 155.594 + "x": 260.2963, + "y": 1.21224034, + "z": -91.08922 }, - "Rotation": 180.91, - "Sides": ["Pmc"] + "Rotation": 283.470825, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1269,14 +1736,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1d0f26c8-85e5-42d0-b115-7d8f325f97d4", + "Id": "253e504c-4d28-4aa0-926d-14dcbdeebc1c", "Infiltration": "Customs", "Position": { - "x": -130.65, - "y": -2.11, - "z": 38.9100037 + "x": -309.95, + "y": 0.99, + "z": -94.51 }, - "Rotation": 180.13, + "Rotation": 141.8, "Sides": ["Pmc"] }, { @@ -1290,24 +1757,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 65 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1d80614c-e211-42d5-b661-8e2bb1aeae79", + "Id": "27aa4110-1b16-4454-b505-35026255b7f9", "Infiltration": "Customs", "Position": { - "x": 100.598007, - "y": 1.168, - "z": -110.826004 + "x": -147.872, + "y": 1.678, + "z": -135.636 }, - "Rotation": 0, + "Rotation": 21.67, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBlockPost", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1316,24 +1783,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "1fb2eba7-250e-4fd1-ba2a-75fb3d640ed7", - "Infiltration": "Customs", + "CorePointId": 8, + "DelayToCanSpawnSec": 6, + "Id": "2810239e-d13d-4738-9be9-a7289f29ab82", + "Infiltration": "", "Position": { - "x": -131.27, - "y": -2.09, - "z": 42.6900024 + "x": 568.8878, + "y": -1.46942234, + "z": -25.5359821 }, - "Rotation": 180.13, - "Sides": ["Pmc"] + "Rotation": 343.038422, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneTankSquare", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1342,24 +1809,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 120 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "20495255-3094-4add-8744-14efc6e05308", - "Infiltration": "Boiler Tanks", + "CorePointId": 4, + "DelayToCanSpawnSec": 6, + "Id": "28635a4e-a46b-4880-a081-714bd9d14e2d", + "Infiltration": "", "Position": { - "x": 525.62, - "y": 8.88, - "z": 199 + "x": 119.710007, + "y": 1.10880566, + "z": -34.1 }, - "Rotation": 225.49, - "Sides": ["Pmc"] + "Rotation": 309.78418, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1368,47 +1835,21 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2051eb7b-3ae8-49b8-adcb-c13f0ddc7972", - "Infiltration": "Boiler Tanks", + "Id": "287bf35f-5cdc-44dc-97b6-c035d5054bfa", + "Infiltration": "Customs", "Position": { - "x": 317.338, - "y": 1.128, - "z": -78.756 + "x": 100.664017, + "y": 1.18800008, + "z": 16.3029938 }, - "Rotation": 11.5521812, + "Rotation": 167.010742, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneCrossRoad", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 90 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 6, - "Id": "20f9df0c-f775-40a3-84a2-e509be0f399f", - "Infiltration": "", - "Position": { - "x": 191.46, - "y": 1.22457552, - "z": -2.51000214 - }, - "Rotation": 38.0980873, - "Sides": ["Savage"] - }, { "BotZoneName": "ZoneDormitory", "Categories": ["Bot", "Boss"], @@ -1425,7 +1866,7 @@ }, "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "21e744e4-db21-4316-9b33-5c418ca7bc10", + "Id": "2953587e-0cbb-49b1-9189-951adb63a277", "Infiltration": "", "Position": { "x": 171.889282, @@ -1437,7 +1878,7 @@ }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1446,24 +1887,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "222800ad-50c8-4c75-b94b-ff1ec3d807d0", + "Id": "2b5a6af0-0e2e-4fa1-bbf3-a390276b0b13", "Infiltration": "Customs", "Position": { - "x": 569.537964, - "y": -0.322000027, - "z": -12.9960022 + "x": -216.552, + "y": -1.46199989, + "z": -2.10600281 }, - "Rotation": 270.218658, + "Rotation": 138.324036, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1472,24 +1913,24 @@ "y": 0, "z": 0 }, - "Radius": 77.17 + "Radius": 50 } }, - "CorePointId": 25, - "DelayToCanSpawnSec": 6, - "Id": "22bbd9cc-d773-4a85-93ce-b90211534270", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "2c286540-f748-4719-9a6d-6bd0e9a3c143", + "Infiltration": "Customs", "Position": { - "x": 411.6, - "y": 0.96478796, - "z": 0.100000381 + "x": 13.0980072, + "y": 1.19800007, + "z": -125.625992 }, - "Rotation": 209.40004, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCustoms", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1498,20 +1939,20 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 50 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "247c4c9e-7c53-48dd-869b-a4ea7db16dc9", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "2c5cc586-9010-4b6c-8a67-fbfacb76a225", + "Infiltration": "Boiler Tanks", "Position": { - "x": -333.830017, - "y": -0.424789667, - "z": -84.4799957 + "x": 518.3, + "y": 8.35, + "z": 187.459991 }, - "Rotation": 102.860092, - "Sides": ["Savage"] + "Rotation": 225.49, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -1529,18 +1970,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "253e504c-4d28-4aa0-926d-14dcbdeebc1c", - "Infiltration": "Customs", + "Id": "2cb9950d-20ec-484e-919c-5489bb7abd5c", + "Infiltration": "Boiler Tanks", "Position": { - "x": -309.95, - "y": 0.99, - "z": -94.51 + "x": 478, + "y": 2.7, + "z": -83.14 }, - "Rotation": 141.8, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrige", + "BotZoneName": "ZoneFactoryCenter", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1550,24 +1991,24 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 114.7 } }, - "CorePointId": 4, + "CorePointId": 21, "DelayToCanSpawnSec": 6, - "Id": "2557b707-d8e8-40c6-93d5-127033425fa0", + "Id": "2d9d53d3-4263-4911-b76f-7a4fb678898a", "Infiltration": "", "Position": { - "x": 46.75, - "y": -3.94977927, - "z": 126.18 + "x": 365.1455, + "y": 1.32006228, + "z": -108.90036 }, - "Rotation": 182.889908, + "Rotation": 277.4024, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneOldAZS", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1576,24 +2017,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 77 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 6, - "Id": "27051f69-33be-4310-8c69-6bed56e7ccdd", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "2e02fd39-ee4a-4c26-bb44-12324b433a02", + "Infiltration": "Customs", "Position": { - "x": 291.5036, - "y": 2.35399628, - "z": -169.449524 + "x": -133.631989, + "y": 0.718000054, + "z": 8.393997 }, - "Rotation": 147.656372, - "Sides": ["Savage"] + "Rotation": 85.46295, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1602,49 +2043,23 @@ "y": 0, "z": 0 }, - "Radius": 65 + "Radius": 30 } }, - "CorePointId": 0, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "27aa4110-1b16-4454-b505-35026255b7f9", - "Infiltration": "Customs", + "Id": "2f311383-6639-46da-a804-ae43bf804a6a", + "Infiltration": "", "Position": { - "x": -147.872, - "y": 1.678, - "z": -135.636 - }, - "Rotation": 21.67, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneCustoms", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 100 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "27fc8f4c-e3e2-4200-8ed5-22459074647c", - "Infiltration": "", - "Position": { - "x": -311.924, - "y": 0.966500759, - "z": -124.966 + "x": 41.7462921, + "y": 1.23424029, + "z": -143.6092 }, - "Rotation": 93.0682755, + "Rotation": 135.08139, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactorySide", + "BotZoneName": "ZoneWade", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1654,49 +2069,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 130 } }, - "CorePointId": 2, + "CorePointId": 5, "DelayToCanSpawnSec": 6, - "Id": "28736287-2a28-458e-82da-7ab3533d0c9d", + "Id": "31d79ff8-4b21-448a-866d-289775a7f5dd", "Infiltration": "", "Position": { - "x": 603.5282, - "y": 1.14991, - "z": -139.339142 + "x": -17.1999969, + "y": 0.0100492239, + "z": -140.959991 }, - "Rotation": 265.8543, + "Rotation": 333.506073, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 77 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "287bf35f-5cdc-44dc-97b6-c035d5054bfa", - "Infiltration": "Customs", - "Position": { - "x": 100.664017, - "y": 1.18800008, - "z": 16.3029938 - }, - "Rotation": 167.010742, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneFactorySide", + "BotZoneName": "ZoneSnipeTower", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1706,19 +2095,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 130 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 6, - "Id": "29fd0e7e-8056-473f-a34e-33868312a249", + "CorePointId": 10, + "DelayToCanSpawnSec": 1700, + "Id": "33cd6564-129e-444f-91b7-1fc3bfee4f87", "Infiltration": "", "Position": { - "x": 663.252441, - "y": 1.21781647, - "z": -99.46105 + "x": 255.2391, + "y": 53.4429932, + "z": -27.01771 }, - "Rotation": 265.8543, + "Rotation": 147.656372, "Sides": ["Savage"] }, { @@ -1732,19 +2121,19 @@ "y": 0, "z": 0 }, - "Radius": 90 + "Radius": 77.17 } }, - "CorePointId": 11, + "CorePointId": 25, "DelayToCanSpawnSec": 6, - "Id": "2b474bfc-6077-48b1-b2f3-5b03aec9eebe", + "Id": "34e059d8-8d8c-4b35-a747-4d08d3e28561", "Infiltration": "", "Position": { - "x": 454.8, - "y": 2.0766468, - "z": 61.09 + "x": 411.6, + "y": 0.96478796, + "z": 0.100000381 }, - "Rotation": 223.641632, + "Rotation": 209.40004, "Sides": ["Savage"] }, { @@ -1763,19 +2152,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2b5a6af0-0e2e-4fa1-bbf3-a390276b0b13", - "Infiltration": "Customs", + "Id": "3735903c-ebbd-407d-ba27-46129dc360c3", + "Infiltration": "Boiler Tanks", "Position": { - "x": -216.552, - "y": -1.46199989, - "z": -2.10600281 + "x": 539.688, + "y": 2.948, + "z": 48.0039978 }, - "Rotation": 138.324036, + "Rotation": 342.4109, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneDormitory", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1784,20 +2173,20 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 50 } }, - "CorePointId": 1, - "DelayToCanSpawnSec": 6, - "Id": "2be1fb2a-8b38-44b7-b7f8-1893f9b12312", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "38a13157-f0cd-48d5-bada-dff42472b410", + "Infiltration": "Boiler Tanks", "Position": { - "x": 178.5893, - "y": -0.1337597, - "z": 181.282791 + "x": 569.75, + "y": 1.49, + "z": -52.54001 }, - "Rotation": 132.05188, - "Sides": ["Savage"] + "Rotation": 180.26, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -1815,18 +2204,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2c286540-f748-4719-9a6d-6bd0e9a3c143", - "Infiltration": "Customs", + "Id": "38aaf44a-c4a7-49a0-a669-96520c28332d", + "Infiltration": "Boiler Tanks", "Position": { - "x": 13.0980072, - "y": 1.19800007, - "z": -125.625992 + "x": 582.31, + "y": 9.79, + "z": 147.5 }, - "Rotation": 0, + "Rotation": 216.79, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneScavBase", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1836,19 +2225,19 @@ "y": 0, "z": 0 }, - "Radius": 131.24 + "Radius": 50 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "2c546e35-205d-4108-8a80-f0af9d53b156", + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "3a7db815-a833-40e2-a297-5f2d08c6489c", "Infiltration": "", "Position": { - "x": -162.957016, - "y": 3.21176076, - "z": -168.46 + "x": 236.2663, + "y": 1.21224034, + "z": -95.11922 }, - "Rotation": 273.068, + "Rotation": 111.995163, "Sides": ["Savage"] }, { @@ -1867,19 +2256,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2c5cc586-9010-4b6c-8a67-fbfacb76a225", + "Id": "3b128730-ba41-4ac8-9c08-517655a787dd", "Infiltration": "Boiler Tanks", "Position": { - "x": 518.3, - "y": 8.35, - "z": 187.459991 + "x": 570.45, + "y": 1.48, + "z": -111.76 }, - "Rotation": 225.49, + "Rotation": 192.38, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1888,24 +2277,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2cb9950d-20ec-484e-919c-5489bb7abd5c", - "Infiltration": "Boiler Tanks", + "Id": "3b54601a-2e4b-4991-988e-962f1ee45668", + "Infiltration": "Customs", "Position": { - "x": 478, - "y": 2.7, - "z": -83.14 + "x": 96.1380157, + "y": 1.18800008, + "z": 13.3840027 }, - "Rotation": 0, + "Rotation": 167.010742, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1914,24 +2303,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2e02fd39-ee4a-4c26-bb44-12324b433a02", + "Id": "3bb03dcc-70b9-455d-ab44-058121da9469", "Infiltration": "Customs", "Position": { - "x": -133.631989, - "y": 0.718000054, - "z": 8.393997 + "x": -221.702, + "y": -0.741999865, + "z": -3.35600281 }, - "Rotation": 85.46295, + "Rotation": 149.69, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactorySide", - "Categories": ["Bot"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1940,24 +2329,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 30 } }, - "CorePointId": 2, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "2fbc647a-c23b-4bec-9dc7-de6db1e4266f", + "Id": "3e792359-d3d3-4d42-8b3f-83d81721e9fe", "Infiltration": "", "Position": { - "x": 569.0529, - "y": 1.46199012, - "z": -54.5297432 + "x": -183.647, + "y": 1.60172462, + "z": -190.065 }, - "Rotation": 100.786774, + "Rotation": 75.66953, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBlockPost", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1966,24 +2355,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, - "CorePointId": 8, - "DelayToCanSpawnSec": 6, - "Id": "33de60fb-9bc3-48d0-a164-5b91a9182138", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "3ef3c5d0-afaf-44cb-82c5-530c0e6300ab", + "Infiltration": "Boiler Tanks", "Position": { - "x": 568.8878, - "y": -1.46942234, - "z": -25.5359821 + "x": 385.709961, + "y": 1.12, + "z": -116.17 }, - "Rotation": 343.038422, - "Sides": ["Savage"] + "Rotation": 188.39, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneDormitory", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1992,24 +2381,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 131.24 } }, - "CorePointId": 1, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "3405b78f-c24f-45e2-9d48-63433c687c20", + "Id": "3feedcc0-c2be-4462-a242-222e23072c69", "Infiltration": "", "Position": { - "x": 186.527283, - "y": 2.84524035, - "z": 173.873779 + "x": -162.957016, + "y": 3.21176076, + "z": -168.46 }, - "Rotation": 92.26318, + "Rotation": 273.068, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneCustoms", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2018,24 +2407,24 @@ "y": 0, "z": 0 }, - "Radius": 131.24 + "Radius": 65 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "3495bb0c-9832-4c5e-a8bf-790d085cd754", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "413a6ac7-3f9d-4a38-9652-f3c68505dcc0", + "Infiltration": "Customs", "Position": { - "x": -300.564, - "y": 0.032841444, - "z": -44.071 + "x": -154.35199, + "y": 1.038, + "z": -128.096008 }, - "Rotation": 102.860092, - "Sides": ["Savage"] + "Rotation": 7.197772, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWade", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2044,20 +2433,20 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 50 } }, - "CorePointId": 5, - "DelayToCanSpawnSec": 6, - "Id": "36469543-ca01-41f0-8a47-11e9812c5b0a", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "41440b15-7ff8-42fa-893a-5b4b59eaf13b", + "Infiltration": "Customs", "Position": { - "x": -17.1999969, - "y": 0.0100492239, - "z": -140.959991 + "x": -313.92, + "y": 0.940000057, + "z": -88.66 }, - "Rotation": 333.506073, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -2070,19 +2459,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "3735903c-ebbd-407d-ba27-46129dc360c3", - "Infiltration": "Boiler Tanks", + "Id": "426e619c-f5a9-4529-b10b-4796f82d9f6d", + "Infiltration": "Customs", "Position": { - "x": 539.688, - "y": 2.948, - "z": 48.0039978 + "x": -190.972, + "y": 1.518, + "z": -236.686 }, - "Rotation": 342.4109, + "Rotation": 3.01640677, "Sides": ["Pmc"] }, { @@ -2101,14 +2490,40 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "38a13157-f0cd-48d5-bada-dff42472b410", + "Id": "42904c13-d45a-4375-9bd1-67a9da6cdb2e", + "Infiltration": "Customs", + "Position": { + "x": -218.681992, + "y": 1.072, + "z": -148.428009 + }, + "Rotation": 13.3557768, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "42933fa9-9478-4db3-a97f-7d120afa4ca9", "Infiltration": "Boiler Tanks", "Position": { - "x": 569.75, - "y": 1.49, - "z": -52.54001 + "x": 503.2, + "y": 1.18, + "z": -59.83 }, - "Rotation": 180.26, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -2127,19 +2542,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "38aaf44a-c4a7-49a0-a669-96520c28332d", + "Id": "4293a264-a66e-4d7d-8ce7-65cade015117", "Infiltration": "Boiler Tanks", "Position": { - "x": 582.31, - "y": 9.79, - "z": 147.5 + "x": 585.74, + "y": 9.53, + "z": 145.81 }, "Rotation": 216.79, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2148,23 +2563,23 @@ "y": 0, "z": 0 }, - "Radius": 90 + "Radius": 30 } }, - "CorePointId": 11, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "39989383-f53e-47be-80fd-14f92502fc3c", + "Id": "4309052b-e7f7-41d1-89b0-6060c57d06b5", "Infiltration": "", "Position": { - "x": 418.83, - "y": 1.10948467, - "z": 56.67 + "x": 654.803955, + "y": 1.11981535, + "z": -164.4396 }, - "Rotation": 210.9319, + "Rotation": 265.8543, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneOldAZS", + "BotZoneName": "ZoneFactoryCenter", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2174,19 +2589,19 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 6, - "Id": "3a254c66-b92e-4f10-84b2-de66f701952a", + "CorePointId": 21, + "DelayToCanSpawnSec": 3, + "Id": "43e9c231-d666-402f-a8ed-9d946cd3d8ce", "Infiltration": "", "Position": { - "x": 339.321442, - "y": 1.189998, - "z": -190.771988 + "x": 410.909271, + "y": 1.38835239, + "z": -112.0087 }, - "Rotation": 52.6828651, + "Rotation": 308.3462, "Sides": ["Savage"] }, { @@ -2200,24 +2615,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "3b128730-ba41-4ac8-9c08-517655a787dd", + "Id": "468b8eec-29bd-430f-920b-e32d89e2beda", "Infiltration": "Boiler Tanks", "Position": { - "x": 570.45, - "y": 1.48, - "z": -111.76 + "x": 548.068, + "y": 2.838, + "z": 47.554 }, - "Rotation": 192.38, + "Rotation": 342.4109, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2226,23 +2641,23 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 95 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "3b54601a-2e4b-4991-988e-962f1ee45668", + "Id": "471799c4-3aed-4c0e-9489-fabc2e76dd06", "Infiltration": "Customs", "Position": { - "x": 96.1380157, - "y": 1.18800008, - "z": 13.3840027 + "x": -14.371994, + "y": -7.74200058, + "z": 126.363983 }, - "Rotation": 167.010742, + "Rotation": 137.37, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWade", + "BotZoneName": "ZoneFactoryCenter", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2252,49 +2667,23 @@ "y": 0, "z": 0 }, - "Radius": 164.4 + "Radius": 80 } }, - "CorePointId": 5, + "CorePointId": 21, "DelayToCanSpawnSec": 6, - "Id": "3ba21920-cdb3-498d-9aac-f141f08c3492", + "Id": "48d0dd2c-206e-40a6-ba44-08410446439a", "Infiltration": "", "Position": { - "x": 5.78900528, - "y": 1.16781759, - "z": -103.391 + "x": 323.287872, + "y": 1.64894223, + "z": -98.48353 }, - "Rotation": 229.912613, + "Rotation": 179.388351, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 70 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "3bb03dcc-70b9-455d-ab44-058121da9469", - "Infiltration": "Customs", - "Position": { - "x": -221.702, - "y": -0.741999865, - "z": -3.35600281 - }, - "Rotation": 149.69, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneCrossRoad", + "BotZoneName": "ZoneCustoms", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2304,19 +2693,19 @@ "y": 0, "z": 0 }, - "Radius": 90 + "Radius": 110 } }, - "CorePointId": 7, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "3e185028-ab0a-48b7-9967-d55df97467b3", + "Id": "48d1cef3-efce-4d8f-a67b-31ddbbc28f47", "Infiltration": "", "Position": { - "x": 175.290009, - "y": 1.21891308, - "z": -5.380005 + "x": -286.342, + "y": 0.228545427, + "z": -232.641 }, - "Rotation": 38.0980873, + "Rotation": 320.675232, "Sides": ["Savage"] }, { @@ -2335,14 +2724,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "3ef3c5d0-afaf-44cb-82c5-530c0e6300ab", + "Id": "4ba3ef50-0c41-4f25-9419-58152197b15b", "Infiltration": "Boiler Tanks", "Position": { - "x": 385.709961, - "y": 1.12, - "z": -116.17 + "x": 315.797, + "y": 1.128, + "z": -82.132 }, - "Rotation": 188.39, + "Rotation": 187.420029, "Sides": ["Pmc"] }, { @@ -2356,19 +2745,19 @@ "y": 0, "z": 0 }, - "Radius": 65 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "413a6ac7-3f9d-4a38-9652-f3c68505dcc0", - "Infiltration": "Customs", + "Id": "4c18262a-245d-47ee-99c9-f4d36a095d56", + "Infiltration": "Boiler Tanks", "Position": { - "x": -154.35199, - "y": 1.038, - "z": -128.096008 + "x": 645.31, + "y": 1.5, + "z": 46.22 }, - "Rotation": 7.197772, + "Rotation": 293.47, "Sides": ["Pmc"] }, { @@ -2387,18 +2776,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "41440b15-7ff8-42fa-893a-5b4b59eaf13b", - "Infiltration": "Customs", + "Id": "4d2e6d0c-078c-4918-8227-8df098a47a39", + "Infiltration": "Boiler Tanks", "Position": { - "x": -313.92, - "y": 0.940000057, - "z": -88.66 + "x": 478.86, + "y": 2.7, + "z": -79.23001 }, "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneDormitory", + "BotZoneName": "ZoneFactorySide", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2408,19 +2797,19 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 45 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "41c1c31a-fecf-44f6-9f83-ef219c57f886", + "Id": "4d5a42f3-50a8-457a-ad94-7e4c451681e8", "Infiltration": "", "Position": { - "x": 172.605286, - "y": 2.84324026, - "z": 157.337784 + "x": 587.9925, + "y": 1.09995508, + "z": -64.35727 }, - "Rotation": 94.87478, + "Rotation": 4.26114464, "Sides": ["Savage"] }, { @@ -2434,24 +2823,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "426e619c-f5a9-4529-b10b-4796f82d9f6d", - "Infiltration": "Customs", - "Position": { - "x": -190.972, - "y": 1.518, - "z": -236.686 + "Id": "4d676699-1243-452b-b4d7-3353616854fb", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 614.44, + "y": -0.3499999, + "z": -102.62 }, - "Rotation": 3.01640677, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneTankSquare", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2460,24 +2849,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 100 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "42904c13-d45a-4375-9bd1-67a9da6cdb2e", - "Infiltration": "Customs", + "CorePointId": 4, + "DelayToCanSpawnSec": 6, + "Id": "4e108f92-cd14-4d0a-915c-f2ca6d5611f9", + "Infiltration": "", "Position": { - "x": -218.681992, - "y": 1.072, - "z": -148.428009 + "x": 141.97, + "y": 1.14876676, + "z": -14.9800034 }, - "Rotation": 13.3557768, - "Sides": ["Pmc"] + "Rotation": 25.7275429, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2486,24 +2875,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "42933fa9-9478-4db3-a97f-7d120afa4ca9", - "Infiltration": "Boiler Tanks", + "Id": "4e876370-2396-4517-81c1-c535811d18e0", + "Infiltration": "Customs", "Position": { - "x": 503.2, - "y": 1.18, - "z": -59.83 + "x": -133.722, + "y": 0.718000054, + "z": 12.6239929 }, - "Rotation": 0, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2512,50 +2901,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4293a264-a66e-4d7d-8ce7-65cade015117", - "Infiltration": "Boiler Tanks", + "Id": "4f865c11-d533-4fce-9833-fe41a6cb52af", + "Infiltration": "Customs", "Position": { - "x": 585.74, - "y": 9.53, - "z": 145.81 + "x": 101.408005, + "y": 1.21600008, + "z": 17.673996 }, - "Rotation": 216.79, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 2, - "DelayToCanSpawnSec": 3, - "Id": "44ebd934-61f9-4e1d-901c-6376c5568d3e", - "Infiltration": "", - "Position": { - "x": 471.196716, - "y": 2.6568923, - "z": -54.2984543 - }, - "Rotation": 147.656372, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneCustoms", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2564,20 +2927,20 @@ "y": 0, "z": 0 }, - "Radius": 131.24 + "Radius": 77 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "45e153bb-2b3d-4169-8e2b-02142373d437", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "4fb0d413-cf19-4580-8217-b2d6ca431e91", + "Infiltration": "Customs", "Position": { - "x": -161.647, - "y": 3.21376324, - "z": -126.492004 + "x": 101.599991, + "y": 1.18800008, + "z": 19.0269928 }, - "Rotation": 273.068, - "Sides": ["Savage"] + "Rotation": 167.010742, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -2590,19 +2953,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "468b8eec-29bd-430f-920b-e32d89e2beda", + "Id": "4fb8d6d8-c158-42f5-b4d2-5e28feb8c675", "Infiltration": "Boiler Tanks", "Position": { - "x": 548.068, - "y": 2.838, - "z": 47.554 + "x": 503.829956, + "y": 1.19, + "z": -55.25 }, - "Rotation": 342.4109, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -2616,23 +2979,23 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 75 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "471799c4-3aed-4c0e-9489-fabc2e76dd06", - "Infiltration": "Customs", + "Id": "51169827-146f-4993-af37-0de3ccec8d45", + "Infiltration": "Boiler Tanks", "Position": { - "x": -14.371994, - "y": -7.74200058, - "z": 126.363983 + "x": 291.65802, + "y": 1.45800006, + "z": -197.106 }, - "Rotation": 137.37, + "Rotation": 17.73762, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTankSquare", + "BotZoneName": "ZoneBrige", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2642,19 +3005,19 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 130 } }, - "CorePointId": 7, + "CorePointId": 4, "DelayToCanSpawnSec": 6, - "Id": "4ac7ec98-ec6a-4ebd-b2f6-e6a4ed2fc627", + "Id": "51940f3f-de97-4aea-a31f-29ea6ee3861c", "Infiltration": "", "Position": { - "x": 172.51001, - "y": 1.22871351, - "z": -6.28000259 + "x": 27.54927, + "y": -1.12046, + "z": 127.26 }, - "Rotation": 0.00353926537, + "Rotation": 183.768738, "Sides": ["Savage"] }, { @@ -2668,19 +3031,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4ba3ef50-0c41-4f25-9419-58152197b15b", - "Infiltration": "Boiler Tanks", + "Id": "519599b1-5b4d-4c91-8530-13042c3a3a37", + "Infiltration": "Customs", "Position": { - "x": 315.797, - "y": 1.128, - "z": -82.132 + "x": -197.232, + "y": 1.508, + "z": -233.506 }, - "Rotation": 187.420029, + "Rotation": 358.432373, "Sides": ["Pmc"] }, { @@ -2699,14 +3062,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4c18262a-245d-47ee-99c9-f4d36a095d56", + "Id": "52e74209-8ff4-4121-85ef-a54b5b6689be", "Infiltration": "Boiler Tanks", "Position": { - "x": 645.31, - "y": 1.5, - "z": 46.22 + "x": 391.589966, + "y": 1.32, + "z": -117.73 }, - "Rotation": 293.47, + "Rotation": 177.74, "Sides": ["Pmc"] }, { @@ -2725,12 +3088,12 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4d2e6d0c-078c-4918-8227-8df098a47a39", - "Infiltration": "Boiler Tanks", + "Id": "53635fda-547d-4b4c-af82-e9adfd93daf2", + "Infiltration": "Customs", "Position": { - "x": 478.86, - "y": 2.7, - "z": -79.23001 + "x": -217.642, + "y": 1.06800008, + "z": -144.936 }, "Rotation": 0, "Sides": ["Pmc"] @@ -2751,19 +3114,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4d676699-1243-452b-b4d7-3353616854fb", + "Id": "537c1307-b83a-4c57-8c51-21380f5605a1", "Infiltration": "Boiler Tanks", "Position": { - "x": 614.44, - "y": -0.3499999, - "z": -102.62 + "x": 641.47, + "y": 1.27, + "z": 43.53 }, - "Rotation": 0, + "Rotation": 324.43, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2772,24 +3135,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 95 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4e876370-2396-4517-81c1-c535811d18e0", + "Id": "54991d80-f85d-49fd-8ae0-f686d6fdf828", "Infiltration": "Customs", "Position": { - "x": -133.722, - "y": 0.718000054, - "z": 12.6239929 + "x": -1.93199158, + "y": -5.042, + "z": 126.95401 }, - "Rotation": 85.46295, + "Rotation": 147.73, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2798,24 +3161,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 75 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4f865c11-d533-4fce-9833-fe41a6cb52af", - "Infiltration": "Customs", + "Id": "5621e44b-9f44-494b-9695-143a88146d43", + "Infiltration": "Boiler Tanks", "Position": { - "x": 101.408005, - "y": 1.21600008, - "z": 17.673996 + "x": 294.288025, + "y": 1.398, + "z": -195.736008 }, - "Rotation": 85.46295, + "Rotation": 17.73762, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2824,19 +3187,19 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4fb0d413-cf19-4580-8217-b2d6ca431e91", - "Infiltration": "Customs", + "Id": "582b9ea6-4404-4af1-8443-da3db48fcaad", + "Infiltration": "Boiler Tanks", "Position": { - "x": 101.599991, - "y": 1.18800008, - "z": 19.0269928 + "x": 480.55, + "y": 2.7, + "z": -81.46 }, - "Rotation": 167.010742, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -2855,19 +3218,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4fb8d6d8-c158-42f5-b4d2-5e28feb8c675", + "Id": "58a91424-a24c-44e1-9f8a-c5cc6c66489f", "Infiltration": "Boiler Tanks", "Position": { - "x": 503.829956, - "y": 1.19, - "z": -55.25 + "x": 314.128, + "y": 1.20800006, + "z": -90.7260056 }, - "Rotation": 0, + "Rotation": 196.37, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2879,21 +3242,21 @@ "Radius": 50 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "504128ee-ac81-457d-86b3-e79a3d05abe6", - "Infiltration": "", + "Id": "5a551a12-ca0e-41af-9845-270ffce6808a", + "Infiltration": "Boiler Tanks", "Position": { - "x": 133.786285, - "y": 1.74224031, - "z": -82.02922 + "x": 620.14, + "y": -0.3499999, + "z": -96.98 }, - "Rotation": 189.840561, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2902,24 +3265,128 @@ "y": 0, "z": 0 }, - "Radius": 75 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "51169827-146f-4993-af37-0de3ccec8d45", - "Infiltration": "Boiler Tanks", + "Id": "5caf5e1b-0113-41fc-9867-007e37ffe906", + "Infiltration": "Customs", "Position": { - "x": 291.65802, - "y": 1.45800006, - "z": -197.106 + "x": 95.968, + "y": 1.18800008, + "z": 11.6539917 }, - "Rotation": 17.73762, + "Rotation": 167.010742, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneSnipeFactory", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 9, + "DelayToCanSpawnSec": 1700, + "Id": "5d1bbc44-9b97-4a35-9bc3-acfbbe8eae52", + "Infiltration": "", + "Position": { + "x": 476.11853, + "y": 14.7500124, + "z": -71.85715 + }, + "Rotation": 147.656372, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneBrige", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 100 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 6, + "Id": "5de7ed5d-918f-4433-bedf-d7444fc4e82d", + "Infiltration": "", + "Position": { + "x": 19.3312683, + "y": -0.88446, + "z": 36.432 + }, + "Rotation": 104.141586, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneBrige", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 100 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 6, + "Id": "5fe0d0c8-d429-4f54-96f6-33fff540c2ca", + "Infiltration": "", + "Position": { + "x": 29.8222656, + "y": 1.11054, + "z": -29.4749985 + }, + "Rotation": 168.0339, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 131.24 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "60c4be2a-82b8-4cf1-b8c4-fdd4f95ee3cb", + "Infiltration": "", + "Position": { + "x": -273.483, + "y": 0.9775678, + "z": -72.127 + }, + "Rotation": 151.257034, + "Sides": ["Savage"] + }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2933,14 +3400,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "519599b1-5b4d-4c91-8530-13042c3a3a37", + "Id": "61aba24c-79d9-445f-8a1c-f887b36a8417", "Infiltration": "Customs", "Position": { - "x": -197.232, - "y": 1.508, - "z": -233.506 + "x": 569.368, + "y": -0.491999865, + "z": -6.98600769 }, - "Rotation": 358.432373, + "Rotation": 270.218658, "Sides": ["Pmc"] }, { @@ -2954,19 +3421,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "52e74209-8ff4-4121-85ef-a54b5b6689be", + "Id": "61e3a2a4-55af-4b66-bf4f-302f9cdac5b2", "Infiltration": "Boiler Tanks", "Position": { - "x": 391.589966, - "y": 1.32, - "z": -117.73 + "x": 348.438, + "y": 8.858, + "z": 152.824 }, - "Rotation": 177.74, + "Rotation": 171.7, "Sides": ["Pmc"] }, { @@ -2980,21 +3447,99 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "53635fda-547d-4b4c-af82-e9adfd93daf2", + "Id": "62a46181-d31d-4abb-855d-3e24886e171b", "Infiltration": "Customs", "Position": { - "x": -217.642, - "y": 1.06800008, - "z": -144.936 + "x": -323.862, + "y": 1.16, + "z": -225.596008 }, - "Rotation": 0, + "Rotation": 85.08, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Coop", "Group"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 77 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "62f5b14d-cb51-4529-b572-f5a8f5815bb5", + "Infiltration": "Customs", + "Position": { + "x": 104.246017, + "y": 1.21600008, + "z": 18.7420044 + }, + "Rotation": 85.46295, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 110 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "63fef3bf-fd73-4d4f-99d2-50d26f8e8bc6", + "Infiltration": "", + "Position": { + "x": -179.40802, + "y": 1.42873216, + "z": -235.034 + }, + "Rotation": 350.38678, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneBrige", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 117.5 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 6, + "Id": "659377dd-2b6a-4ffa-8a5d-43b104196ad9", + "Infiltration": "", + "Position": { + "x": -9.670734, + "y": -6.85845947, + "z": 127.67 + }, + "Rotation": 176.0234, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3011,18 +3556,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "537c1307-b83a-4c57-8c51-21380f5605a1", + "Id": "66ab21e5-21b1-42aa-bb0a-e7525f793536", "Infiltration": "Boiler Tanks", "Position": { - "x": 641.47, - "y": 1.27, - "z": 43.53 + "x": 569.89, + "y": 1.49, + "z": -50.4499969 }, - "Rotation": 324.43, + "Rotation": 182.67, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBlockPost", + "BotZoneName": "ZoneScavBase", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3035,20 +3580,98 @@ "Radius": 80 } }, - "CorePointId": 15, + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "66ff3527-a97e-4ffe-97c9-35c9ab38ef46", + "Infiltration": "", + "Position": { + "x": 225.976288, + "y": 1.10224032, + "z": -80.73921 + }, + "Rotation": 189.840561, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 77 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "677581fc-5c9f-4e13-913d-e32798dfd61c", + "Infiltration": "Customs", + "Position": { + "x": 569.378, + "y": -0.322000027, + "z": -11.9060059 + }, + "Rotation": 270.218658, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "53ff77a5-4780-410b-b02f-b9d9103dd670", + "Id": "67995511-8d08-4bdc-ba17-d38e81aad1d0", "Infiltration": "", "Position": { - "x": 571.71, - "y": -0.9350004, - "z": 6.60000038 + "x": 603.5282, + "y": 1.14991, + "z": -139.339142 }, - "Rotation": 183.570679, + "Rotation": 265.8543, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneTankSquare", + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "6889bd40-9338-4297-8c15-0f1af8f4f74f", + "Infiltration": "Customs", + "Position": { + "x": 15.9580078, + "y": 1.30800009, + "z": -126.866005 + }, + "Rotation": 0, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneCustoms", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3061,17 +3684,43 @@ "Radius": 100 } }, - "CorePointId": 6, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "5414de25-273d-42fa-9ac9-93f1a1e5d2c6", + "Id": "6a77d0e8-8b88-462a-8138-df49da8d21a6", "Infiltration": "", "Position": { - "x": 101.430008, - "y": 1.22583747, - "z": 22.07 + "x": -311.924, + "y": 0.966500759, + "z": -124.966 + }, + "Rotation": 93.0682755, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "6d8626ec-449b-4d63-a066-38e802756ec9", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 480.24, + "y": 2.7, + "z": -84.47 }, - "Rotation": 204.6489, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -3084,23 +3733,23 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 25 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "54991d80-f85d-49fd-8ae0-f686d6fdf828", - "Infiltration": "Customs", + "Id": "6df008d3-3928-4213-b05b-8285bd15e7c2", + "Infiltration": "Boiler Tanks", "Position": { - "x": -1.93199158, - "y": -5.042, - "z": 126.95401 + "x": 377.708, + "y": 1.418, + "z": -93.356 }, - "Rotation": 147.73, + "Rotation": 94.4417953, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneOldAZS", + "BotZoneName": "ZoneBlockPost", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3113,21 +3762,21 @@ "Radius": 80 } }, - "CorePointId": 13, + "CorePointId": 19, "DelayToCanSpawnSec": 6, - "Id": "55281950-7e25-4013-84d7-dc62e701b52b", + "Id": "6e2300c9-e9ff-48ff-be43-44c13e8b138d", "Infiltration": "", "Position": { - "x": 294.9489, - "y": 2.10008216, - "z": -160.2394 + "x": 487.64, + "y": 1.68252087, + "z": 41.11 }, - "Rotation": 147.656372, + "Rotation": 186.6658, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3136,19 +3785,19 @@ "y": 0, "z": 0 }, - "Radius": 75 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "5621e44b-9f44-494b-9695-143a88146d43", - "Infiltration": "Boiler Tanks", + "Id": "6e3ad315-21c1-4816-84f5-e6d5ad0568af", + "Infiltration": "Customs", "Position": { - "x": 294.288025, - "y": 1.398, - "z": -195.736008 + "x": 569.588, + "y": -0.322000027, + "z": -14.1759949 }, - "Rotation": 17.73762, + "Rotation": 270.218658, "Sides": ["Pmc"] }, { @@ -3167,19 +3816,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "582b9ea6-4404-4af1-8443-da3db48fcaad", + "Id": "6fbb2585-70d7-4f2f-9242-11f88d8dc2f3", "Infiltration": "Boiler Tanks", "Position": { - "x": 480.55, - "y": 2.7, - "z": -81.46 + "x": 647.48, + "y": 1.88, + "z": 48.3699951 }, - "Rotation": 0, + "Rotation": 297.33, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBlockPost", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3188,24 +3837,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "58a91424-a24c-44e1-9f8a-c5cc6c66489f", - "Infiltration": "Boiler Tanks", + "CorePointId": 15, + "DelayToCanSpawnSec": 6, + "Id": "70ddd35e-f67e-473c-97b5-d16f0c8da170", + "Infiltration": "", "Position": { - "x": 314.128, - "y": 1.20800006, - "z": -90.7260056 + "x": 580, + "y": -0.594014168, + "z": 33.12 }, - "Rotation": 196.37, - "Sides": ["Pmc"] + "Rotation": 343.038422, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3214,24 +3863,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "5a551a12-ca0e-41af-9845-270ffce6808a", - "Infiltration": "Boiler Tanks", + "Id": "751ed8cb-d9c5-4c3a-ad31-7ae979f66316", + "Infiltration": "Customs", "Position": { - "x": 620.14, - "y": -0.3499999, - "z": -96.98 + "x": -133.528992, + "y": 0.85800004, + "z": 6.78999329 }, - "Rotation": 0, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTankSquare", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3240,23 +3889,23 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 4, - "DelayToCanSpawnSec": 6, - "Id": "5ba8c30d-3e08-4e6b-8570-91cce2f6d0dc", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "75b634c6-60a6-4846-8d15-c8e79cab0c78", + "Infiltration": "Customs", "Position": { - "x": 141.97, - "y": 1.14876676, - "z": -14.9800034 + "x": -134.19, + "y": -1.37000012, + "z": 38.11 }, - "Rotation": 25.7275429, - "Sides": ["Savage"] + "Rotation": 180.13, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTankSquare", + "BotZoneName": "ZoneFactorySide", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3266,24 +3915,24 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 70 } }, - "CorePointId": 4, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "5be39d24-ec46-4f54-90e8-fcf35e35931a", + "Id": "76b57ba8-351e-4d24-a7b5-9a91d226080a", "Infiltration": "", "Position": { - "x": 87.05, - "y": 1.04846621, - "z": -59.2000046 + "x": 569.0529, + "y": 1.46199012, + "z": -54.5297432 }, - "Rotation": 289.6524, + "Rotation": 100.786774, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3292,24 +3941,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "5caf5e1b-0113-41fc-9867-007e37ffe906", + "Id": "7994d5ba-6c84-44fc-a66e-a16a169fbaed", "Infiltration": "Customs", "Position": { - "x": 95.968, - "y": 1.18800008, - "z": 11.6539917 + "x": -206.282, + "y": -1.28199983, + "z": 2.2440033 }, - "Rotation": 167.010742, + "Rotation": 150.1406, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3318,20 +3967,20 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 110 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "61aba24c-79d9-445f-8a1c-f887b36a8417", - "Infiltration": "Customs", + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "79e06ada-a5df-4109-8f48-3b44bec2e4c5", + "Infiltration": "", "Position": { - "x": 569.368, - "y": -0.491999865, - "z": -6.98600769 + "x": -335.62, + "y": 0.307707071, + "z": -159.7 }, - "Rotation": 270.218658, - "Sides": ["Pmc"] + "Rotation": 276.286957, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -3344,19 +3993,19 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 25 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "61e3a2a4-55af-4b66-bf4f-302f9cdac5b2", + "Id": "7afa635c-296e-42be-8a76-26be3f736827", "Infiltration": "Boiler Tanks", "Position": { - "x": 348.438, - "y": 8.858, - "z": 152.824 + "x": 375.088, + "y": 1.418, + "z": -88.7960052 }, - "Rotation": 171.7, + "Rotation": 15.8534, "Sides": ["Pmc"] }, { @@ -3370,24 +4019,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "62a46181-d31d-4abb-855d-3e24886e171b", - "Infiltration": "Customs", + "Id": "7bf576fa-4a6f-48dc-90a8-8ddd3029816f", + "Infiltration": "Boiler Tanks", "Position": { - "x": -323.862, - "y": 1.16, - "z": -225.596008 + "x": 519.84, + "y": 7.7699995, + "z": 204.15 }, - "Rotation": 85.08, + "Rotation": 225.49, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3396,24 +4045,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "62f5b14d-cb51-4529-b572-f5a8f5815bb5", + "Id": "7c349cb6-2e80-4166-919d-63ae486f618c", "Infiltration": "Customs", "Position": { - "x": 104.246017, - "y": 1.21600008, - "z": 18.7420044 + "x": 98.088, + "y": 1.138, + "z": -107.216 }, - "Rotation": 85.46295, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWade", - "Categories": ["Bot"], + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3422,49 +4071,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 40 } }, - "CorePointId": 5, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "65d3b397-a86b-43a8-95fd-9de96f42e7c2", + "Id": "7ca0eb6c-dae2-49e0-9eba-b4668dfdac90", "Infiltration": "", "Position": { - "x": 6.49000549, - "y": 1.26882577, - "z": -95.06 + "x": 663.252441, + "y": 1.21781647, + "z": -99.46105 }, - "Rotation": 168.0339, + "Rotation": 265.8543, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "66ab21e5-21b1-42aa-bb0a-e7525f793536", - "Infiltration": "Boiler Tanks", - "Position": { - "x": 569.89, - "y": 1.49, - "z": -50.4499969 - }, - "Rotation": 182.67, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneFactorySide", + "BotZoneName": "ZoneBrige", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3474,24 +4097,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 85.4 } }, - "CorePointId": 2, + "CorePointId": 5, "DelayToCanSpawnSec": 6, - "Id": "66b92e80-0a31-4db9-8fe4-4a9c489ec514", + "Id": "7cb21772-a203-4587-a28a-4716a6c59e27", "Infiltration": "", "Position": { - "x": 537.491455, - "y": 1.08002615, - "z": -130.868164 + "x": 19.389267, + "y": 1.14054, + "z": -66.09 }, - "Rotation": 147.656372, + "Rotation": 287.111938, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3500,24 +4123,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 65 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "677581fc-5c9f-4e13-913d-e32798dfd61c", + "Id": "7d47b29d-9758-4925-a614-3e70ed1374f4", "Infiltration": "Customs", "Position": { - "x": 569.378, - "y": -0.322000027, - "z": -11.9060059 + "x": -148.302, + "y": 1.608, + "z": -143.646 }, - "Rotation": 270.218658, + "Rotation": 123.844284, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3526,23 +4149,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "6889bd40-9338-4297-8c15-0f1af8f4f74f", - "Infiltration": "Customs", + "CorePointId": 1, + "DelayToCanSpawnSec": 6, + "Id": "7d4d2abe-e2b8-4973-a478-1783dd79f7c4", + "Infiltration": "", "Position": { - "x": 15.9580078, - "y": 1.30800009, - "z": -126.866005 + "x": 190.702286, + "y": -0.1337597, + "z": 175.85379 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 355.9929, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneCrossRoad", + "BotZoneName": "ZoneOldAZS", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3555,21 +4178,21 @@ "Radius": 80 } }, - "CorePointId": 7, + "CorePointId": 13, "DelayToCanSpawnSec": 6, - "Id": "6b320b9d-2304-47db-a8a8-c7efc0114131", + "Id": "807a3df0-eebb-4f16-ac08-64e3644a40dc", "Infiltration": "", "Position": { - "x": 213.6, - "y": 1.24984646, - "z": 1.949997 + "x": 294.9489, + "y": 2.10008216, + "z": -160.2394 }, - "Rotation": 327.055481, + "Rotation": 147.656372, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3578,20 +4201,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 131.24 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "6d8626ec-449b-4d63-a066-38e802756ec9", - "Infiltration": "Boiler Tanks", + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "8189ba85-9253-4f28-8bf1-781506302bef", + "Infiltration": "", "Position": { - "x": 480.24, - "y": 2.7, - "z": -84.47 + "x": -161.647, + "y": 3.21376324, + "z": -126.492004 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 273.068, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -3604,24 +4227,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6df008d3-3928-4213-b05b-8285bd15e7c2", + "Id": "81fa9972-7d9f-4ad9-9f86-6db8656e211c", "Infiltration": "Boiler Tanks", "Position": { - "x": 377.708, - "y": 1.418, - "z": -93.356 + "x": 544.698, + "y": 2.898, + "z": 48.0639954 }, - "Rotation": 94.4417953, + "Rotation": 342.4109, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneTankSquare", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3630,24 +4253,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 110 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "6e3ad315-21c1-4816-84f5-e6d5ad0568af", - "Infiltration": "Customs", + "CorePointId": 7, + "DelayToCanSpawnSec": 6, + "Id": "8408652f-55cb-400c-95b3-244aa72b112f", + "Infiltration": "", "Position": { - "x": 569.588, - "y": -0.322000027, - "z": -14.1759949 + "x": 172.51001, + "y": 1.22871351, + "z": -6.28000259 }, - "Rotation": 270.218658, - "Sides": ["Pmc"] + "Rotation": 0.00353926537, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3656,23 +4279,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6fbb2585-70d7-4f2f-9242-11f88d8dc2f3", - "Infiltration": "Boiler Tanks", + "Id": "8464e389-d91c-45d4-9e99-5b61d5bcdc69", + "Infiltration": "Customs", "Position": { - "x": 647.48, - "y": 1.88, - "z": 48.3699951 + "x": -133.682, + "y": 0.718000054, + "z": 9.783997 }, - "Rotation": 297.33, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", + "BotZoneName": "ZoneFactorySide", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3682,24 +4305,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 70 } }, - "CorePointId": 16, - "DelayToCanSpawnSec": 4, - "Id": "7123ae4a-c17f-42b8-a19f-37d49eae20d1", + "CorePointId": 2, + "DelayToCanSpawnSec": 6, + "Id": "84d13ed5-5ee0-4154-bded-1fc68d0cc7da", "Infiltration": "", "Position": { - "x": 225.976288, - "y": 1.10224032, - "z": -80.73921 + "x": 536.939453, + "y": 1.38835239, + "z": -114.267776 }, - "Rotation": 189.840561, + "Rotation": 100.786774, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneScavBase", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3708,23 +4331,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, - "CorePointId": 17, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7123eb86-2fe5-4826-8f18-a56498f03ddc", - "Infiltration": "", + "Id": "85efb186-180f-4fdc-9d1b-abf4b1b07696", + "Infiltration": "Boiler Tanks", "Position": { - "x": 195.096283, - "y": 1.49224031, - "z": -170.1392 + "x": 394.927979, + "y": 1.418, + "z": -84.026 }, - "Rotation": 189.840561, - "Sides": ["Savage"] + "Rotation": 163.583008, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3734,24 +4357,24 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 90 } }, - "CorePointId": 3, + "CorePointId": 11, "DelayToCanSpawnSec": 6, - "Id": "71a02066-841b-427f-abf1-0fc34fc19749", + "Id": "864f381c-9fde-4553-87ff-07b68e8c1e60", "Infiltration": "", "Position": { - "x": -286.342, - "y": 0.228545427, - "z": -232.641 + "x": 467.41, + "y": 1.56773758, + "z": 60.0600052 }, - "Rotation": 320.675232, + "Rotation": 232.230225, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactorySide", - "Categories": ["Bot"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3760,47 +4383,21 @@ "y": 0, "z": 0 }, - "Radius": 141.4 + "Radius": 25 } }, - "CorePointId": 2, + "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "74aef5cc-3cda-47d5-86b0-e10433712f38", + "Id": "870ab421-0541-44e6-9965-e1b8816bf103", "Infiltration": "", "Position": { - "x": 657.8154, - "y": 1.12998486, - "z": -134.82048 + "x": 178.5893, + "y": -0.1337597, + "z": 181.282791 }, - "Rotation": 280.85022, + "Rotation": 132.05188, "Sides": ["Savage"] }, - { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 77 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "751ed8cb-d9c5-4c3a-ad31-7ae979f66316", - "Infiltration": "Customs", - "Position": { - "x": -133.528992, - "y": 0.85800004, - "z": 6.78999329 - }, - "Rotation": 85.46295, - "Sides": ["Pmc"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -3817,19 +4414,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "75b634c6-60a6-4846-8d15-c8e79cab0c78", - "Infiltration": "Customs", + "Id": "8878252a-9516-4f33-a54d-56f9705098b6", + "Infiltration": "Boiler Tanks", "Position": { - "x": -134.19, - "y": -1.37000012, - "z": 38.11 + "x": 617.51, + "y": -0.3499999, + "z": -103.12 }, - "Rotation": 180.13, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneCrossRoad", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3838,24 +4435,24 @@ "y": 0, "z": 0 }, - "Radius": 62.3 + "Radius": 45 } }, - "CorePointId": 11, + "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "783ca48b-4a18-438b-a8a7-9d0d6de4eb31", + "Id": "898d0b69-ee35-4d07-9072-991ab93e0678", "Infiltration": "", "Position": { - "x": 430.815033, - "y": 1.88306046, - "z": 54.8594666 + "x": 226.41, + "y": -0.861175954, + "z": 121.28 }, - "Rotation": 343.038422, + "Rotation": 186.911575, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBrige", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3864,20 +4461,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, - "CorePointId": 4, - "DelayToCanSpawnSec": 6, - "Id": "790f0f4b-132f-4795-bb01-b5f8f61e3eb9", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "8998cdf3-aa44-40e9-b34e-df32f1bf4540", + "Infiltration": "Boiler Tanks", "Position": { - "x": -30.9607353, - "y": -12.0579987, - "z": 126.24 + "x": 642.1, + "y": 1.43, + "z": 45.54001 }, - "Rotation": 183.768738, - "Sides": ["Savage"] + "Rotation": 319.46, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -3890,23 +4487,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7994d5ba-6c84-44fc-a66e-a16a169fbaed", - "Infiltration": "Customs", + "Id": "89fe6e6f-7ebc-458e-8297-621824d1d6ac", + "Infiltration": "Boiler Tanks", "Position": { - "x": -206.282, - "y": -1.28199983, - "z": 2.2440033 + "x": 568.08, + "y": 1.48, + "z": -111.66 }, - "Rotation": 150.1406, + "Rotation": 193.88, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneFactoryCenter", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3916,24 +4513,24 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 50 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "7a4edc97-c24b-4a00-bc24-2ea3b0fb7db9", + "CorePointId": 14, + "DelayToCanSpawnSec": 3, + "Id": "8a370e43-eba4-44fa-bad8-6b1ea61286e2", "Infiltration": "", "Position": { - "x": -157.741013, - "y": 1.60435379, - "z": -190.766 + "x": 391.856567, + "y": 1.39002156, + "z": -86.1867752 }, - "Rotation": 273.068, + "Rotation": 189.658691, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneDormitory", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3942,20 +4539,20 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 77 } }, - "CorePointId": 1, - "DelayToCanSpawnSec": 6, - "Id": "7a9af696-f6f8-4561-99f9-98ef5c2f3b6a", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "8b301a0d-e694-4f24-b938-32329a5084f5", + "Infiltration": "Customs", "Position": { - "x": 181.1043, - "y": -0.1127597, - "z": 178.053787 + "x": 105.498, + "y": 1.197, + "z": 17.3639984 }, - "Rotation": 185.167953, - "Sides": ["Savage"] + "Rotation": 85.46295, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -3968,19 +4565,19 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7afa635c-296e-42be-8a76-26be3f736827", + "Id": "8bae21f5-6d20-4368-a820-0a05730f81ad", "Infiltration": "Boiler Tanks", "Position": { - "x": 375.088, - "y": 1.418, - "z": -88.7960052 + "x": 569.03, + "y": 1.48, + "z": -117.38 }, - "Rotation": 15.8534, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -3994,19 +4591,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7bf576fa-4a6f-48dc-90a8-8ddd3029816f", + "Id": "8cb5b38c-2355-4093-8b47-f99c6673a566", "Infiltration": "Boiler Tanks", "Position": { - "x": 519.84, - "y": 7.7699995, - "z": 204.15 + "x": 355.818, + "y": 10.018, + "z": 152.064 }, - "Rotation": 225.49, + "Rotation": 177.79, "Sides": ["Pmc"] }, { @@ -4020,24 +4617,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 65 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7c349cb6-2e80-4166-919d-63ae486f618c", + "Id": "8d6e133a-e996-431b-a120-efa9a96f69e7", "Infiltration": "Customs", "Position": { - "x": 98.088, - "y": 1.138, - "z": -107.216 + "x": -151.962, + "y": 1.288, + "z": -137.946 }, - "Rotation": 0, + "Rotation": 147.46, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrige", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4046,20 +4643,20 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 5, - "DelayToCanSpawnSec": 6, - "Id": "7d3062a3-a1a6-4c5b-b709-5fc9ac9f6ef7", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "8e31a0d6-0d23-4e79-bf7d-089bf232f4ac", + "Infiltration": "Boiler Tanks", "Position": { - "x": 19.3192673, - "y": 1.28754, - "z": -109.24 + "x": 378.977966, + "y": 1.22, + "z": -116.846 }, - "Rotation": 168.0339, - "Sides": ["Savage"] + "Rotation": 196.37, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -4072,23 +4669,23 @@ "y": 0, "z": 0 }, - "Radius": 65 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7d47b29d-9758-4925-a614-3e70ed1374f4", + "Id": "8e59cd3f-750b-4d00-841a-9ebfc41a1ac1", "Infiltration": "Customs", "Position": { - "x": -148.302, - "y": 1.608, - "z": -143.646 + "x": 8.678009, + "y": 1.258, + "z": -127.796005 }, - "Rotation": 123.844284, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactorySide", + "BotZoneName": "ZoneCustoms", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4098,19 +4695,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 110 } }, - "CorePointId": 15, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "7f10f680-35e6-416e-a5d2-a535db289381", + "Id": "91855264-51c0-4474-81ca-9df166e7ad43", "Infiltration": "", "Position": { - "x": 658.0241, - "y": 1.12983537, - "z": -59.1834259 + "x": -236.430008, + "y": 1.4996326, + "z": -235.900009 }, - "Rotation": 58.09279, + "Rotation": 350.38678, "Sides": ["Savage"] }, { @@ -4124,19 +4721,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 25 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "81fa9972-7d9f-4ad9-9f86-6db8656e211c", + "Id": "92eddb79-cfd5-491d-85ed-23769ee28f95", "Infiltration": "Boiler Tanks", "Position": { - "x": 544.698, - "y": 2.898, - "z": 48.0639954 + "x": 368.438, + "y": 1.418, + "z": -90.076004 }, - "Rotation": 342.4109, + "Rotation": 104.504547, "Sides": ["Pmc"] }, { @@ -4150,19 +4747,19 @@ "y": 0, "z": 0 }, - "Radius": 85.4 + "Radius": 110 } }, - "CorePointId": 5, + "CorePointId": 4, "DelayToCanSpawnSec": 6, - "Id": "83fcd970-3686-4e94-90d8-2d53ad8de391", + "Id": "92ee45f4-921c-4782-81a1-3eb1a2e053f5", "Infiltration": "", "Position": { - "x": 19.389267, - "y": 1.14054, - "z": -66.09 + "x": 46.75, + "y": -3.94977927, + "z": 126.18 }, - "Rotation": 287.111938, + "Rotation": 182.889908, "Sides": ["Savage"] }, { @@ -4181,44 +4778,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8464e389-d91c-45d4-9e99-5b61d5bcdc69", + "Id": "93427305-4f03-44d6-8690-7c24dbbb4128", "Infiltration": "Customs", "Position": { - "x": -133.682, + "x": -133.612, "y": 0.718000054, - "z": 9.783997 + "z": 11.1640015 }, "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 25 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "85efb186-180f-4fdc-9d1b-abf4b1b07696", - "Infiltration": "Boiler Tanks", - "Position": { - "x": 394.927979, - "y": 1.418, - "z": -84.026 - }, - "Rotation": 163.583008, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneBlockPostSniper", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4228,50 +4799,24 @@ "y": 0, "z": 0 }, - "Radius": 115 + "Radius": 77.17 } }, - "CorePointId": 15, - "DelayToCanSpawnSec": 1700, - "Id": "8679977b-fa85-4b6d-bf69-9f65f6f9cd05", + "CorePointId": 11, + "DelayToCanSpawnSec": 6, + "Id": "9371d198-a811-4d79-8613-61fbf8518882", "Infiltration": "", "Position": { - "x": 581.8, - "y": 3.06499958, - "z": 0.9200001 - }, - "Rotation": 343.038422, - "Sides": ["Savage"] - }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "8878252a-9516-4f33-a54d-56f9705098b6", - "Infiltration": "Boiler Tanks", - "Position": { - "x": 617.51, - "y": -0.3499999, - "z": -103.12 - }, - "Rotation": 0, - "Sides": ["Pmc"] + "x": 447.43, + "y": 7.59999943, + "z": 111.09 + }, + "Rotation": 196.259735, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4280,20 +4825,20 @@ "y": 0, "z": 0 }, - "Radius": 114.7 + "Radius": 50 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 6, - "Id": "89734df6-d713-4d40-8761-94d69dbc8019", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "95259830-27ef-4056-8bee-cfbba562dedc", + "Infiltration": "Customs", "Position": { - "x": 463.7923, - "y": 1.207964, - "z": -117.402084 + "x": -309.94, + "y": 1, + "z": -96.98 }, - "Rotation": 147.656372, - "Sides": ["Savage"] + "Rotation": 148.43, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -4306,24 +4851,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 95 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8998cdf3-aa44-40e9-b34e-df32f1bf4540", - "Infiltration": "Boiler Tanks", + "Id": "967f3d09-de07-4f11-b68f-2f42ba684f51", + "Infiltration": "Customs", "Position": { - "x": 642.1, - "y": 1.43, - "z": 45.54001 + "x": -14.7019958, + "y": -7.74200058, + "z": 121.603973 }, - "Rotation": 319.46, + "Rotation": 150.83, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4332,24 +4877,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "89fe6e6f-7ebc-458e-8297-621824d1d6ac", - "Infiltration": "Boiler Tanks", + "Id": "97185451-3b24-4e74-baa1-6a706f09c520", + "Infiltration": "Customs", "Position": { - "x": 568.08, - "y": 1.48, - "z": -111.66 + "x": 99.222, + "y": 1.18800008, + "z": 18.9140015 }, - "Rotation": 193.88, + "Rotation": 167.010742, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4363,14 +4908,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8b301a0d-e694-4f24-b938-32329a5084f5", + "Id": "97513a7b-d467-454a-8232-2e77f3e386ef", "Infiltration": "Customs", "Position": { - "x": 105.498, - "y": 1.197, - "z": 17.3639984 + "x": 569.548, + "y": -0.292000055, + "z": -19.1260071 }, - "Rotation": 85.46295, + "Rotation": 270.218658, "Sides": ["Pmc"] }, { @@ -4389,19 +4934,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8bae21f5-6d20-4368-a820-0a05730f81ad", + "Id": "989f1148-f609-4191-8a09-de4d40b117e4", "Infiltration": "Boiler Tanks", "Position": { - "x": 569.03, - "y": 1.48, - "z": -117.38 + "x": 571.17, + "y": 1.49, + "z": -51.70999 }, - "Rotation": 0, + "Rotation": 176.15, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWade", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4410,24 +4955,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 77 } }, - "CorePointId": 5, - "DelayToCanSpawnSec": 6, - "Id": "8bd67c96-1e6d-4d2f-88c3-f6ab41d58af1", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "999c413b-05eb-4c30-a4ef-4e0c95c838ef", + "Infiltration": "Customs", "Position": { - "x": 21.010006, - "y": 1.28880048, - "z": -109.49 + "x": 569.458, + "y": -0.491999865, + "z": -5.43600464 }, - "Rotation": 249.573578, - "Sides": ["Savage"] + "Rotation": 270.218658, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4436,20 +4981,20 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, - "CorePointId": 21, - "DelayToCanSpawnSec": 6, - "Id": "8c6cd06f-8bd6-469a-a8e0-916a96876b9e", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "9a904fab-076c-4fc5-89e3-d6983cba8d89", + "Infiltration": "Customs", "Position": { - "x": 323.287872, - "y": 1.64894223, - "z": -98.48353 + "x": 90.12901, + "y": 1.357, + "z": -102.023 }, - "Rotation": 179.388351, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -4462,24 +5007,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8cb5b38c-2355-4093-8b47-f99c6673a566", + "Id": "9b6a8b4a-f315-4dc2-b294-49094c0c0490", "Infiltration": "Boiler Tanks", "Position": { - "x": 355.818, - "y": 10.018, - "z": 152.064 + "x": 388.419983, + "y": 1.12, + "z": -114.33 }, - "Rotation": 177.79, + "Rotation": 180.09, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4488,20 +5033,20 @@ "y": 0, "z": 0 }, - "Radius": 65 + "Radius": 70 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "8d6e133a-e996-431b-a120-efa9a96f69e7", - "Infiltration": "Customs", + "CorePointId": 15, + "DelayToCanSpawnSec": 6, + "Id": "9ca25ce6-8110-4425-a7a9-43e453b29ecb", + "Infiltration": "", "Position": { - "x": -151.962, - "y": 1.288, - "z": -137.946 + "x": 658.0241, + "y": 1.12983537, + "z": -59.1834259 }, - "Rotation": 147.46, - "Sides": ["Pmc"] + "Rotation": 58.09279, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4514,19 +5059,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8e31a0d6-0d23-4e79-bf7d-089bf232f4ac", + "Id": "9d396201-600c-4920-a915-3e5d0aff2280", "Infiltration": "Boiler Tanks", "Position": { - "x": 378.977966, - "y": 1.22, - "z": -116.846 + "x": 545.018, + "y": 3.238, + "z": 50.95401 }, - "Rotation": 196.37, + "Rotation": 342.4109, "Sides": ["Pmc"] }, { @@ -4540,24 +5085,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8e59cd3f-750b-4d00-841a-9ebfc41a1ac1", - "Infiltration": "Customs", + "Id": "9d4a13b3-bad7-41ee-9d4e-d83149736816", + "Infiltration": "Boiler Tanks", "Position": { - "x": 8.678009, - "y": 1.258, - "z": -127.796005 + "x": 388.888, + "y": 1.418, + "z": -97.196 }, - "Rotation": 0, + "Rotation": 272.3188, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4566,23 +5111,23 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 77 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 6, - "Id": "8e7ac880-5649-442e-ad45-f639116d26ba", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "9dd4bcc0-062e-45a4-9346-2b488ed4ad72", + "Infiltration": "Customs", "Position": { - "x": 356.541382, - "y": 1.15009761, - "z": -24.1884918 + "x": 104.638016, + "y": 1.197, + "z": 14.3540039 }, - "Rotation": 105.675018, - "Sides": ["Savage"] + "Rotation": 85.46295, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", + "BotZoneName": "ZoneFactorySide", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4592,24 +5137,24 @@ "y": 0, "z": 0 }, - "Radius": 77.17 + "Radius": 141.4 } }, - "CorePointId": 25, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "9249f0f9-ef25-4fd3-986a-0dc219148a19", + "Id": "9e487143-1230-4f12-87cb-e50f9a0f50d9", "Infiltration": "", "Position": { - "x": 420.47, - "y": 1.14899969, - "z": 22.5500011 + "x": 657.8154, + "y": 1.12998486, + "z": -134.82048 }, - "Rotation": 126.588921, + "Rotation": 280.85022, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4618,24 +5163,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "92eddb79-cfd5-491d-85ed-23769ee28f95", - "Infiltration": "Boiler Tanks", + "Id": "9f6cbe96-7d68-45bf-8f4b-4ccac2550961", + "Infiltration": "Customs", "Position": { - "x": 368.438, - "y": 1.418, - "z": -90.076004 + "x": 569.568, + "y": -0.292000055, + "z": -16.1860046 }, - "Rotation": 104.504547, + "Rotation": 270.218658, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4644,19 +5189,19 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "93427305-4f03-44d6-8690-7c24dbbb4128", - "Infiltration": "Customs", + "Id": "a092494e-01bf-496f-b789-8e9790639784", + "Infiltration": "Boiler Tanks", "Position": { - "x": -133.612, - "y": 0.718000054, - "z": 11.1640015 + "x": 502.349976, + "y": 1.18, + "z": -64.42999 }, - "Rotation": 85.46295, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -4670,24 +5215,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "95259830-27ef-4056-8bee-cfbba562dedc", + "Id": "a1e820f6-34ae-474c-818f-aa67c35266aa", "Infiltration": "Customs", "Position": { - "x": -309.94, - "y": 1, - "z": -96.98 + "x": -194.301987, + "y": 1.558, + "z": -232.946 }, - "Rotation": 148.43, + "Rotation": 346.9238, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCustoms", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4696,20 +5241,20 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 50 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "966d9bc9-dfd7-47e8-8704-f70b703f7ed5", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "a44d5d64-8570-48b7-b696-52db3db8ac13", + "Infiltration": "Boiler Tanks", "Position": { - "x": -329.382019, - "y": 1.01902342, - "z": -211.054 + "x": 648.75, + "y": 1.81, + "z": 50.1600037 }, - "Rotation": 99.65997, - "Sides": ["Savage"] + "Rotation": 319.88, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -4722,24 +5267,24 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "967f3d09-de07-4f11-b68f-2f42ba684f51", + "Id": "a64e8bd1-42f5-4c0d-b132-ddc01cd46d33", "Infiltration": "Customs", "Position": { - "x": -14.7019958, - "y": -7.74200058, - "z": 121.603973 + "x": -189.071991, + "y": 1.538, + "z": -235.216 }, - "Rotation": 150.83, + "Rotation": 350.7271, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneGasStation", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4748,24 +5293,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 93.4 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "97185451-3b24-4e74-baa1-6a706f09c520", - "Infiltration": "Customs", + "CorePointId": 11, + "DelayToCanSpawnSec": 6, + "Id": "a8063503-8f74-4305-9ae9-548fa5ff7fe6", + "Infiltration": "", "Position": { - "x": 99.222, - "y": 1.18800008, - "z": 18.9140015 + "x": 423.79, + "y": 1.0539999, + "z": 42.34 }, - "Rotation": 167.010742, - "Sides": ["Pmc"] + "Rotation": 343.038422, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4774,19 +5319,19 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "97513a7b-d467-454a-8232-2e77f3e386ef", + "Id": "a8dafd79-4811-4598-9061-7062654a1200", "Infiltration": "Customs", "Position": { - "x": 569.548, - "y": -0.292000055, - "z": -19.1260071 + "x": 96.618, + "y": 1.268, + "z": -106.206 }, - "Rotation": 270.218658, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -4805,19 +5350,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "989f1148-f609-4191-8a09-de4d40b117e4", + "Id": "a97b15dc-9f2b-4de6-ae02-ec4417bef821", "Infiltration": "Boiler Tanks", "Position": { - "x": 571.17, - "y": 1.49, - "z": -51.70999 + "x": 394.919983, + "y": 2.18, + "z": -120.68 }, - "Rotation": 176.15, + "Rotation": 179.19, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneOldAZS", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4826,24 +5371,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 80 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "999c413b-05eb-4c30-a4ef-4e0c95c838ef", - "Infiltration": "Customs", + "CorePointId": 13, + "DelayToCanSpawnSec": 6, + "Id": "ae5d8ae0-3fb4-4853-9f71-c868cb2c2060", + "Infiltration": "", "Position": { - "x": 569.458, - "y": -0.491999865, - "z": -5.43600464 + "x": 310.722839, + "y": 1.33199024, + "z": -157.0032 }, - "Rotation": 270.218658, - "Sides": ["Pmc"] + "Rotation": 147.656372, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneTankSquare", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4852,24 +5397,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 110 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "9a904fab-076c-4fc5-89e3-d6983cba8d89", - "Infiltration": "Customs", + "CorePointId": 4, + "DelayToCanSpawnSec": 6, + "Id": "aeac7f0b-3c23-46e9-a7af-fd9aae4fc8b4", + "Infiltration": "", "Position": { - "x": 90.12901, - "y": 1.357, - "z": -102.023 + "x": 87.05, + "y": 1.04846621, + "z": -59.2000046 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 289.6524, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4878,24 +5423,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9b6a8b4a-f315-4dc2-b294-49094c0c0490", - "Infiltration": "Boiler Tanks", + "Id": "b0126d65-ba76-45ad-b25e-32f4f3509904", + "Infiltration": "Customs", "Position": { - "x": 388.419983, - "y": 1.12, - "z": -114.33 + "x": 102.168015, + "y": 1.228, + "z": 19.8840027 }, - "Rotation": 180.09, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4904,19 +5449,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9d396201-600c-4920-a915-3e5d0aff2280", - "Infiltration": "Boiler Tanks", + "Id": "b049c6f8-afb9-42f9-9591-2f265fef2097", + "Infiltration": "Customs", "Position": { - "x": 545.018, - "y": 3.238, - "z": 50.95401 + "x": 99.65102, + "y": 1.18800008, + "z": 14.6369934 }, - "Rotation": 342.4109, + "Rotation": 167.010742, "Sides": ["Pmc"] }, { @@ -4930,23 +5475,23 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9d4a13b3-bad7-41ee-9d4e-d83149736816", - "Infiltration": "Boiler Tanks", + "Id": "b1a57f2f-89ab-49ae-81ab-3d4e5f6e9f1c", + "Infiltration": "Customs", "Position": { - "x": 388.888, - "y": 1.418, - "z": -97.196 + "x": -217.362, + "y": 1.19, + "z": -136.956009 }, - "Rotation": 272.3188, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSnipeBrige", + "BotZoneName": "ZoneBlockPostSniper", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4956,23 +5501,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 115 } }, - "CorePointId": 12, + "CorePointId": 15, "DelayToCanSpawnSec": 1700, - "Id": "9da42bb6-fa0c-4f6a-ab93-15a2955c648d", + "Id": "b33fb6f9-36aa-48f0-9bad-60f3ce2cd16a", "Infiltration": "", "Position": { - "x": 107.138275, - "y": 16.2157822, - "z": -47.88827 + "x": 581.8, + "y": 3.06499958, + "z": 0.9200001 }, - "Rotation": 147.656372, + "Rotation": 343.038422, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactorySide", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4982,24 +5527,24 @@ "y": 0, "z": 0 }, - "Radius": 114.7 + "Radius": 90 } }, - "CorePointId": 2, + "CorePointId": 11, "DelayToCanSpawnSec": 6, - "Id": "9da61bca-625a-4e66-9791-2cfd8249593b", + "Id": "b4e899f8-8da5-4f9c-878b-37320aff71c9", "Infiltration": "", "Position": { - "x": 629.6786, - "y": 1.42986572, - "z": -135.632492 + "x": 454.8, + "y": 2.0766468, + "z": 61.09 }, - "Rotation": 184.215363, + "Rotation": 223.641632, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5008,24 +5553,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9dd4bcc0-062e-45a4-9346-2b488ed4ad72", + "Id": "b523d044-6957-4cd1-b039-b653cd4acbe4", "Infiltration": "Customs", "Position": { - "x": 104.638016, - "y": 1.197, - "z": 14.3540039 + "x": -320.612, + "y": 0.940000057, + "z": -223.796 }, - "Rotation": 85.46295, + "Rotation": 59.1799965, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5034,19 +5579,45 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "b54ce786-74b8-41b1-889f-0fe62c36d8e0", + "Infiltration": "Boiler Tanks", + "Position": { + "x": 481.06, + "y": 2.7, + "z": -79.22 + }, + "Rotation": 0, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9f6cbe96-7d68-45bf-8f4b-4ccac2550961", + "Id": "b5552110-2313-4285-9a06-769077e3c16b", "Infiltration": "Customs", "Position": { - "x": 569.568, - "y": -0.292000055, - "z": -16.1860046 + "x": -132.87, + "y": -1.81000018, + "z": 43.9799957 }, - "Rotation": 270.218658, + "Rotation": 180.13, "Sides": ["Pmc"] }, { @@ -5060,24 +5631,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 95 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a092494e-01bf-496f-b789-8e9790639784", - "Infiltration": "Boiler Tanks", + "Id": "b623ab89-4538-4afa-b6a6-49e9aad4324a", + "Infiltration": "Customs", "Position": { - "x": 502.349976, - "y": 1.18, - "z": -64.42999 + "x": -21.2619934, + "y": -8.542, + "z": 115.303986 }, - "Rotation": 0, + "Rotation": 101.48, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5086,24 +5657,24 @@ "y": 0, "z": 0 }, - "Radius": 90 + "Radius": 50 } }, - "CorePointId": 11, - "DelayToCanSpawnSec": 6, - "Id": "a1530917-9969-4b25-a0c6-913481f7deb7", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "b736a3e7-270e-4797-92d0-6c3a7927f008", + "Infiltration": "Customs", "Position": { - "x": 467.41, - "y": 1.56773758, - "z": 60.0600052 + "x": 18.778, + "y": 1.358, + "z": -127.086 }, - "Rotation": 232.230225, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5117,18 +5688,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a1e820f6-34ae-474c-818f-aa67c35266aa", + "Id": "b96df3dc-23f2-4e1d-8a9a-9fbe05a94f47", "Infiltration": "Customs", "Position": { - "x": -194.301987, - "y": 1.558, - "z": -232.946 + "x": 102.318008, + "y": 1.21600008, + "z": 16.2639923 }, - "Rotation": 346.9238, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", + "BotZoneName": "ZoneWade", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5138,19 +5709,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 100 } }, "CorePointId": 5, - "DelayToCanSpawnSec": 4, - "Id": "a303e429-e91c-4a91-883d-a73de8966231", + "DelayToCanSpawnSec": 6, + "Id": "b9d55350-ef6c-40a4-86a0-2a29f02c7b3a", "Infiltration": "", "Position": { - "x": 260.2963, - "y": 1.21224034, - "z": -91.08922 + "x": 21.010006, + "y": 1.28880048, + "z": -109.49 }, - "Rotation": 283.470825, + "Rotation": 249.573578, "Sides": ["Savage"] }, { @@ -5169,19 +5740,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a44d5d64-8570-48b7-b696-52db3db8ac13", + "Id": "bb1128eb-b548-48b8-a785-c18ef08d7c37", "Infiltration": "Boiler Tanks", "Position": { - "x": 648.75, - "y": 1.81, - "z": 50.1600037 + "x": 571.59, + "y": 11.37, + "z": 145.269989 }, - "Rotation": 319.88, + "Rotation": 216.79, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5190,24 +5761,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 114.7 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "a64e8bd1-42f5-4c0d-b132-ddc01cd46d33", - "Infiltration": "Customs", + "CorePointId": 2, + "DelayToCanSpawnSec": 6, + "Id": "bcdd9759-698e-4924-9f19-0c41dfd5b25c", + "Infiltration": "", "Position": { - "x": -189.071991, - "y": 1.538, - "z": -235.216 + "x": 629.6786, + "y": 1.42986572, + "z": -135.632492 }, - "Rotation": 350.7271, - "Sides": ["Pmc"] + "Rotation": 184.215363, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5216,23 +5787,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "a8dafd79-4811-4598-9061-7062654a1200", - "Infiltration": "Customs", + "CorePointId": 1, + "DelayToCanSpawnSec": 6, + "Id": "bdd442fd-c45c-486c-8de5-61c6a6f7dd60", + "Infiltration": "", "Position": { - "x": 96.618, - "y": 1.268, - "z": -106.206 + "x": 181.1043, + "y": -0.1127597, + "z": 178.053787 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 185.167953, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneBrige", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5242,19 +5813,19 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 131.24 } }, - "CorePointId": 3, + "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "a951473e-1fc9-4e63-820f-5985ac4c2b9a", + "Id": "c0192b74-ef4d-41de-8bd9-81712ad31ba0", "Infiltration": "", "Position": { - "x": -335.62, - "y": 0.307707071, - "z": -159.7 + "x": 34.1792679, + "y": 1.08854008, + "z": -49.5179977 }, - "Rotation": 276.286957, + "Rotation": 347.1565, "Sides": ["Savage"] }, { @@ -5273,19 +5844,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a97b15dc-9f2b-4de6-ae02-ec4417bef821", + "Id": "c11f719c-3491-4a60-901e-cf20832b432e", "Infiltration": "Boiler Tanks", "Position": { - "x": 394.919983, - "y": 2.18, - "z": -120.68 + "x": 617.72, + "y": -0.3499999, + "z": -96.86 }, - "Rotation": 179.19, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactorySide", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5294,24 +5865,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 6, - "Id": "aa8a8760-b3f1-4017-9496-2fec25e42a08", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "c21695bd-f460-4e72-8138-54d7aa92b965", + "Infiltration": "Boiler Tanks", "Position": { - "x": 536.939453, - "y": 1.38835239, - "z": -114.267776 + "x": 522.43, + "y": 10.14, + "z": 179.68 }, - "Rotation": 100.786774, - "Sides": ["Savage"] + "Rotation": 225.49, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrige", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5320,24 +5891,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 80 } }, - "CorePointId": 4, - "DelayToCanSpawnSec": 6, - "Id": "ac2cf869-74ad-4f68-8914-76a0a6b9267f", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "c26390c5-80e1-428e-a11f-5d34d33fcc69", + "Infiltration": "Customs", "Position": { - "x": 29.8222656, - "y": 1.11054, - "z": -29.4749985 + "x": -323.872, + "y": 1.13, + "z": -222.056 }, - "Rotation": 168.0339, - "Sides": ["Savage"] + "Rotation": 19.29, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5346,19 +5917,19 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 75 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b0126d65-ba76-45ad-b25e-32f4f3509904", - "Infiltration": "Customs", + "Id": "c351748e-915b-4be3-ae56-2bb13470f278", + "Infiltration": "Boiler Tanks", "Position": { - "x": 102.168015, - "y": 1.228, - "z": 19.8840027 + "x": 296.557983, + "y": 1.868, + "z": -200.606 }, - "Rotation": 85.46295, + "Rotation": 17.73762, "Sides": ["Pmc"] }, { @@ -5377,19 +5948,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b049c6f8-afb9-42f9-9591-2f265fef2097", + "Id": "c36b37b1-e654-45b8-a921-4864d1a325a4", "Infiltration": "Customs", "Position": { - "x": 99.65102, + "x": 98.10802, "y": 1.18800008, - "z": 14.6369934 + "z": 11.9839935 }, "Rotation": 167.010742, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneWade", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5398,20 +5969,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 164.4 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "b1a57f2f-89ab-49ae-81ab-3d4e5f6e9f1c", - "Infiltration": "Customs", + "CorePointId": 5, + "DelayToCanSpawnSec": 6, + "Id": "c6e01f12-08c7-4b2a-ba95-7b27e2018b7c", + "Infiltration": "", "Position": { - "x": -217.362, - "y": 1.19, - "z": -136.956009 + "x": 5.78900528, + "y": 1.16781759, + "z": -103.391 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 229.912613, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5424,24 +5995,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b523d044-6957-4cd1-b039-b653cd4acbe4", - "Infiltration": "Customs", + "Id": "c70da15f-6bc8-4dda-b666-e4163754bcd5", + "Infiltration": "Boiler Tanks", "Position": { - "x": -320.612, - "y": 0.940000057, - "z": -223.796 + "x": 576.38, + "y": 1.48, + "z": -115.35 }, - "Rotation": 59.1799965, + "Rotation": 270.35, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCrossRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5450,24 +6021,24 @@ "y": 0, "z": 0 }, - "Radius": 90 + "Radius": 25 } }, - "CorePointId": 7, + "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "b5266e62-e41e-4b88-8d79-0c34b1f52db2", + "Id": "c789117c-9d94-456b-be1d-25dd5043a359", "Infiltration": "", "Position": { - "x": 188.06, - "y": 1.289891, - "z": -1.38000488 + "x": 172.605286, + "y": 2.84324026, + "z": 157.337784 }, - "Rotation": 17.3450165, + "Rotation": 94.87478, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneFactoryCenter", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5476,20 +6047,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "b54ce786-74b8-41b1-889f-0fe62c36d8e0", - "Infiltration": "Boiler Tanks", + "CorePointId": 2, + "DelayToCanSpawnSec": 6, + "Id": "c7ba0d24-249b-459f-8364-51ae66454bff", + "Infiltration": "", "Position": { - "x": 481.06, - "y": 2.7, - "z": -79.22 + "x": 356.541382, + "y": 1.15009761, + "z": -24.1884918 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 105.675018, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5502,24 +6073,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b5552110-2313-4285-9a06-769077e3c16b", + "Id": "c838176a-28e6-4871-89a2-827ec044b3f4", "Infiltration": "Customs", "Position": { - "x": -132.87, - "y": -1.81000018, - "z": 43.9799957 + "x": -321.022, + "y": 0.950000048, + "z": -220.866013 }, - "Rotation": 180.13, + "Rotation": 34.52, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5528,19 +6099,19 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b623ab89-4538-4afa-b6a6-49e9aad4324a", + "Id": "c8b04f3f-1f80-49a7-8530-3180b3ff71e9", "Infiltration": "Customs", "Position": { - "x": -21.2619934, - "y": -8.542, - "z": 115.303986 + "x": 103.26799, + "y": 1.197, + "z": 15.322998 }, - "Rotation": 101.48, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { @@ -5559,19 +6130,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b736a3e7-270e-4797-92d0-6c3a7927f008", - "Infiltration": "Customs", + "Id": "c98a753b-d534-4fa4-9430-478b7d8bf27d", + "Infiltration": "Boiler Tanks", "Position": { - "x": 18.778, - "y": 1.358, - "z": -127.086 + "x": 502.7, + "y": 1.18, + "z": -62.1199951 }, "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneBlockPost", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5580,20 +6151,20 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 80 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "b96df3dc-23f2-4e1d-8a9a-9fbe05a94f47", - "Infiltration": "Customs", + "CorePointId": 15, + "DelayToCanSpawnSec": 6, + "Id": "cb0dd763-21a3-4c29-95ea-f3ef51e412fd", + "Infiltration": "", "Position": { - "x": 102.318008, - "y": 1.21600008, - "z": 16.2639923 + "x": 571.71, + "y": -0.9350004, + "z": 6.60000038 }, - "Rotation": 85.46295, - "Sides": ["Pmc"] + "Rotation": 183.570679, + "Sides": ["Savage"] }, { "BotZoneName": "ZoneTankSquare", @@ -5611,7 +6182,7 @@ }, "CorePointId": 4, "DelayToCanSpawnSec": 6, - "Id": "b984d943-0a4b-4d24-9a55-76ab0357128d", + "Id": "cc2436ce-797c-4bd5-995d-255b7a0b7c37", "Infiltration": "", "Position": { "x": 73.591, @@ -5632,24 +6203,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "bb1128eb-b548-48b8-a785-c18ef08d7c37", - "Infiltration": "Boiler Tanks", + "Id": "cd52aa33-141e-4f89-9120-2dd899fd23f2", + "Infiltration": "Customs", "Position": { - "x": 571.59, - "y": 11.37, - "z": 145.269989 + "x": -209.142, + "y": -1.43199992, + "z": 0.694000244 }, - "Rotation": 216.79, + "Rotation": 144.14, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5658,23 +6229,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c11f719c-3491-4a60-901e-cf20832b432e", - "Infiltration": "Boiler Tanks", + "Id": "cdabcf05-fa38-4640-89a6-294133b99a5c", + "Infiltration": "Customs", "Position": { - "x": 617.72, - "y": -0.3499999, - "z": -96.86 + "x": -131.743988, + "y": 0.718000054, + "z": 7.36000061 }, - "Rotation": 0, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneWade", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5684,19 +6255,19 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 100 } }, - "CorePointId": 3, + "CorePointId": 5, "DelayToCanSpawnSec": 6, - "Id": "c16dfabf-db42-4f4f-befe-9b92b0c19932", + "Id": "ce31b755-dc15-4c1f-80b8-f35a2d4804b4", "Infiltration": "", "Position": { - "x": -179.40802, - "y": 1.42873216, - "z": -235.034 + "x": 20.0500031, + "y": 1.138802, + "z": -115.49 }, - "Rotation": 350.38678, + "Rotation": 174.01767, "Sides": ["Savage"] }, { @@ -5715,19 +6286,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c21695bd-f460-4e72-8138-54d7aa92b965", + "Id": "ce469ace-55c1-4381-b3a1-6458f1bea611", "Infiltration": "Boiler Tanks", "Position": { - "x": 522.43, - "y": 10.14, - "z": 179.68 + "x": 503.409973, + "y": 1.18, + "z": -57.5599976 }, - "Rotation": 225.49, + "Rotation": 0, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5736,23 +6307,23 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c26390c5-80e1-428e-a11f-5d34d33fcc69", + "Id": "cec675dc-0443-44f1-90bb-61b0fc25b2fc", "Infiltration": "Customs", "Position": { - "x": -323.872, - "y": 1.13, - "z": -222.056 + "x": -131.972, + "y": 0.718000054, + "z": 12.5540009 }, - "Rotation": 19.29, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTankSquare", + "BotZoneName": "ZoneBrige", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5762,19 +6333,19 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 100 } }, - "CorePointId": 6, + "CorePointId": 5, "DelayToCanSpawnSec": 6, - "Id": "c33efaa2-f678-43fc-bf48-b6af6d403669", + "Id": "cf783f2b-042c-42fe-8417-4f7d75139aeb", "Infiltration": "", "Position": { - "x": 57.6700058, - "y": 1.18891406, - "z": -37.5 + "x": 19.3192673, + "y": 1.28754, + "z": -109.24 }, - "Rotation": 11.0327263, + "Rotation": 168.0339, "Sides": ["Savage"] }, { @@ -5788,24 +6359,24 @@ "y": 0, "z": 0 }, - "Radius": 75 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c351748e-915b-4be3-ae56-2bb13470f278", + "Id": "cfb2039d-a575-4246-9903-bd20336478de", "Infiltration": "Boiler Tanks", "Position": { - "x": 296.557983, - "y": 1.868, - "z": -200.606 + "x": 315.768, + "y": 1.128, + "z": -79.116 }, - "Rotation": 17.73762, + "Rotation": 11.5521812, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneFactoryCenter", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5814,24 +6385,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "c36b37b1-e654-45b8-a921-4864d1a325a4", - "Infiltration": "Customs", + "CorePointId": 2, + "DelayToCanSpawnSec": 3, + "Id": "d035661b-dbba-4f54-a66e-d4ac53e2f2c1", + "Infiltration": "", "Position": { - "x": 98.10802, - "y": 1.18800008, - "z": 11.9839935 + "x": 471.196716, + "y": 2.6568923, + "z": -54.2984543 }, - "Rotation": 167.010742, - "Sides": ["Pmc"] + "Rotation": 147.656372, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneDormitory", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5840,24 +6411,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 95 } }, - "CorePointId": 1, - "DelayToCanSpawnSec": 6, - "Id": "c37fc9fb-a3cc-4097-9687-a22d32cb51e1", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "d12962b9-c23f-47c4-96fa-afe2b1ef30be", + "Infiltration": "Customs", "Position": { - "x": 174.652283, - "y": -0.12775971, - "z": 152.706787 + "x": -19.7720032, + "y": -8.492001, + "z": 113.283966 }, - "Rotation": 81.11248, - "Sides": ["Savage"] + "Rotation": 131.598984, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWade", - "Categories": ["Bot"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5866,24 +6437,24 @@ "y": 0, "z": 0 }, - "Radius": 164.4 + "Radius": 25 } }, - "CorePointId": 5, + "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "c5eb01ed-5fef-4535-ab9b-9a7394dafb8e", + "Id": "d18b6493-9fc7-462c-952d-df410e4924b2", "Infiltration": "", "Position": { - "x": 5.87000275, - "y": 1.37882686, - "z": -90.5099945 + "x": 122.026291, + "y": 0.2622403, + "z": 129.290787 }, - "Rotation": 229.912613, + "Rotation": 46.6169, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5892,20 +6463,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 131.24 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "c70da15f-6bc8-4dda-b666-e4163754bcd5", - "Infiltration": "Boiler Tanks", + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "d23681ef-3f6c-466d-924b-d2a76db60f4f", + "Infiltration": "", "Position": { - "x": 576.38, - "y": 1.48, - "z": -115.35 + "x": -247.488, + "y": -0.234708309, + "z": -14.3019981 }, - "Rotation": 270.35, - "Sides": ["Pmc"] + "Rotation": 156.825577, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5918,23 +6489,23 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 75 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c838176a-28e6-4871-89a2-827ec044b3f4", - "Infiltration": "Customs", + "Id": "d591be31-c6f9-444d-9b7e-15faf5825066", + "Infiltration": "Boiler Tanks", "Position": { - "x": -321.022, - "y": 0.950000048, - "z": -220.866013 + "x": 288.998, + "y": 1.388, + "z": -196.146 }, - "Rotation": 34.52, + "Rotation": 17.73762, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBlockPost", + "BotZoneName": "ZoneCustoms", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5944,24 +6515,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 131.24 } }, - "CorePointId": 15, + "CorePointId": 3, "DelayToCanSpawnSec": 6, - "Id": "c83af793-2422-41e5-a9fb-4808f4e0e41f", + "Id": "d655a83e-c30f-493c-b3cf-6a9872426bd6", "Infiltration": "", "Position": { - "x": 580, - "y": -0.594014168, - "z": 33.12 + "x": -300.564, + "y": 0.032841444, + "z": -44.071 }, - "Rotation": 343.038422, + "Rotation": 102.860092, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5970,20 +6541,20 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 45 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "c8b04f3f-1f80-49a7-8530-3180b3ff71e9", - "Infiltration": "Customs", + "CorePointId": 2, + "DelayToCanSpawnSec": 6, + "Id": "d75cbe99-8316-4e7a-a913-f3048198062c", + "Infiltration": "", "Position": { - "x": 103.26799, - "y": 1.197, - "z": 15.322998 + "x": 537.491455, + "y": 1.08002615, + "z": -130.868164 }, - "Rotation": 85.46295, - "Sides": ["Pmc"] + "Rotation": 147.656372, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -6001,18 +6572,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c98a753b-d534-4fa4-9430-478b7d8bf27d", + "Id": "d7bae537-f5a0-416d-9849-d939cc3575f4", "Infiltration": "Boiler Tanks", "Position": { - "x": 502.7, - "y": 1.18, - "z": -62.1199951 + "x": 615.61, + "y": -0.3499999, + "z": -96.83 }, "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSnipeTower", + "BotZoneName": "ZoneFactoryCenter", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6022,24 +6593,24 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 50 } }, - "CorePointId": 10, - "DelayToCanSpawnSec": 1700, - "Id": "ccf7a261-a540-4d17-a3c3-445521a8dd22", + "CorePointId": 2, + "DelayToCanSpawnSec": 5, + "Id": "d86d794e-6f15-4a9e-ac69-8bf0172d3893", "Infiltration": "", "Position": { - "x": 255.2391, - "y": 53.4429932, - "z": -27.01771 + "x": 454.29303, + "y": 2.67591476, + "z": -81.5390244 }, - "Rotation": 147.656372, + "Rotation": 89.51053, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6048,24 +6619,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "cd52aa33-141e-4f89-9120-2dd899fd23f2", + "Id": "daaa4a02-1f51-460b-bdf8-29b3bd2c838b", "Infiltration": "Customs", "Position": { - "x": -209.142, - "y": -1.43199992, - "z": 0.694000244 + "x": 96.56099, + "y": 1.238, + "z": 17.1719971 }, - "Rotation": 144.14, + "Rotation": 167.010742, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6074,24 +6645,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "cdabcf05-fa38-4640-89a6-294133b99a5c", - "Infiltration": "Customs", + "Id": "dbab2e51-b5f5-4bd8-9324-9f3fd4cc977f", + "Infiltration": "Boiler Tanks", "Position": { - "x": -131.743988, - "y": 0.718000054, - "z": 7.36000061 + "x": 365.458, + "y": 11.478, + "z": 149.264 }, - "Rotation": 85.46295, + "Rotation": 220.28, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6100,24 +6671,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, - "CorePointId": 0, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "ce469ace-55c1-4381-b3a1-6458f1bea611", - "Infiltration": "Boiler Tanks", + "Id": "dbcf3640-5c76-453e-8022-6c8aaa21c77b", + "Infiltration": "", "Position": { - "x": 503.409973, - "y": 1.18, - "z": -57.5599976 + "x": 227.906281, + "y": 1.29224026, + "z": -86.3992157 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 189.840561, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneOldAZS", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6126,24 +6697,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 80 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "cec675dc-0443-44f1-90bb-61b0fc25b2fc", - "Infiltration": "Customs", + "CorePointId": 13, + "DelayToCanSpawnSec": 6, + "Id": "dce9812c-a766-40c8-8718-161a483337c4", + "Infiltration": "", "Position": { - "x": -131.972, - "y": 0.718000054, - "z": 12.5540009 + "x": 313.802277, + "y": 1.16418183, + "z": -191.568161 }, - "Rotation": 85.46295, - "Sides": ["Pmc"] + "Rotation": 147.656372, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneCrossRoad", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6152,24 +6723,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 90 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "cfb2039d-a575-4246-9903-bd20336478de", - "Infiltration": "Boiler Tanks", + "CorePointId": 7, + "DelayToCanSpawnSec": 6, + "Id": "dd2cab78-453d-4341-8180-bd2d93e37b06", + "Infiltration": "", "Position": { - "x": 315.768, - "y": 1.128, - "z": -79.116 + "x": 188.06, + "y": 1.289891, + "z": -1.38000488 }, - "Rotation": 11.5521812, - "Sides": ["Pmc"] + "Rotation": 17.3450165, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneCustoms", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6178,24 +6749,24 @@ "y": 0, "z": 0 }, - "Radius": 131.24 + "Radius": 50 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 6, - "Id": "d0a62fe5-f5fa-40cc-b832-9b59ae4c0317", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "dd81d0d1-c0de-48c2-afed-49522f652d00", + "Infiltration": "Customs", "Position": { - "x": -247.488, - "y": -0.234708309, - "z": -14.3019981 + "x": -306.09, + "y": 1.01, + "z": -89.42 }, - "Rotation": 156.825577, - "Sides": ["Savage"] + "Rotation": 44.5400047, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6204,23 +6775,23 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 77 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d12962b9-c23f-47c4-96fa-afe2b1ef30be", + "Id": "ddca1267-6caa-4986-bd13-0ed29a81e6d2", "Infiltration": "Customs", "Position": { - "x": -19.7720032, - "y": -8.492001, - "z": 113.283966 + "x": 104.470016, + "y": 1.197, + "z": 16.5079956 }, - "Rotation": 131.598984, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase", + "BotZoneName": "ZoneBlockPost", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6230,23 +6801,49 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 + } + }, + "CorePointId": 8, + "DelayToCanSpawnSec": 6, + "Id": "de83684c-cb7a-446c-81c1-dd40ef737d12", + "Infiltration": "", + "Position": { + "x": 529.57, + "y": 2.519843, + "z": 43.679 + }, + "Rotation": 188.080261, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 77 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d1bc73de-4089-433b-9427-99085917973f", - "Infiltration": "", + "Id": "df949703-1471-4367-a395-3afa78fcf886", + "Infiltration": "Customs", "Position": { - "x": 109.876289, - "y": 1.24224031, - "z": -109.7592 + "x": -134.012, + "y": 0.718000054, + "z": 15.9940033 }, - "Rotation": 135.08139, - "Sides": ["Savage"] + "Rotation": 85.46295, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrige", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6256,24 +6853,24 @@ "y": 0, "z": 0 }, - "Radius": 131.24 + "Radius": 90 } }, - "CorePointId": 1, + "CorePointId": 11, "DelayToCanSpawnSec": 6, - "Id": "d4ae72bc-93d0-4a3c-b322-eccf42a579c4", + "Id": "e028a78a-7785-4f59-bbe4-bb7de71fb182", "Infiltration": "", "Position": { - "x": 34.1792679, - "y": 1.08854008, - "z": -49.5179977 + "x": 418.83, + "y": 1.10948467, + "z": 56.67 }, - "Rotation": 347.1565, + "Rotation": 210.9319, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSnipeBrige", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6282,24 +6879,24 @@ "y": 0, "z": 0 }, - "Radius": 75 + "Radius": 120 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "d591be31-c6f9-444d-9b7e-15faf5825066", - "Infiltration": "Boiler Tanks", + "CorePointId": 12, + "DelayToCanSpawnSec": 1700, + "Id": "e388e0c4-74a8-44c1-b03a-10b1296def6a", + "Infiltration": "", "Position": { - "x": 288.998, - "y": 1.388, - "z": -196.146 + "x": 107.138275, + "y": 16.2157822, + "z": -47.88827 }, - "Rotation": 17.73762, - "Sides": ["Pmc"] + "Rotation": 147.656372, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6308,24 +6905,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 20 } }, - "CorePointId": 0, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "d7bae537-f5a0-416d-9849-d939cc3575f4", - "Infiltration": "Boiler Tanks", + "Id": "e44d3970-258b-4d91-a96e-2fd10c4a7b38", + "Infiltration": "", "Position": { - "x": 615.61, - "y": -0.3499999, - "z": -96.83 + "x": 195.336288, + "y": 1.78624034, + "z": -126.129227 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 252.354721, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6334,24 +6931,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 37 } }, - "CorePointId": 21, - "DelayToCanSpawnSec": 3, - "Id": "d94ce36a-9c3d-4d2a-b786-3fdf23c31733", + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "e5999caf-d8b9-40f9-9e3f-0963106a7b86", "Infiltration": "", "Position": { - "x": 410.909271, - "y": 1.38835239, - "z": -112.0087 + "x": -160.840012, + "y": 3.12176442, + "z": -101.729996 }, - "Rotation": 308.3462, + "Rotation": 273.068, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6365,19 +6962,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "daaa4a02-1f51-460b-bdf8-29b3bd2c838b", + "Id": "e5da63fb-4d33-4ebb-a621-dd414deecab5", "Infiltration": "Customs", "Position": { - "x": 96.56099, - "y": 1.238, - "z": 17.1719971 + "x": 569.548, + "y": -0.292000055, + "z": -17.6360016 }, - "Rotation": 167.010742, + "Rotation": 270.218658, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneCustoms", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6386,23 +6983,23 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 120 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "dbab2e51-b5f5-4bd8-9324-9f3fd4cc977f", - "Infiltration": "Boiler Tanks", + "CorePointId": 3, + "DelayToCanSpawnSec": 6, + "Id": "e5fcfb36-0475-48a8-8243-afbfc051bbfc", + "Infiltration": "", "Position": { - "x": 365.458, - "y": 11.478, - "z": 149.264 + "x": -333.830017, + "y": -0.424789667, + "z": -84.4799957 }, - "Rotation": 220.28, - "Sides": ["Pmc"] + "Rotation": 102.860092, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneDormitory", + "BotZoneName": "ZoneCrossRoad", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6412,24 +7009,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 30 } }, "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "dc52e5af-2c9d-4b09-8e2e-de871bd18829", + "Id": "e630b29d-fd39-48f3-bbfd-3c1b1befd9ca", "Infiltration": "", "Position": { - "x": 185.443283, - "y": 2.83624029, - "z": 182.801788 + "x": 219.26, + "y": -0.5611635, + "z": 196.37 }, - "Rotation": 168.224945, + "Rotation": 186.911575, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneFactorySide", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6438,24 +7035,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 114.7 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "dd81d0d1-c0de-48c2-afed-49522f652d00", - "Infiltration": "Customs", + "CorePointId": 2, + "DelayToCanSpawnSec": 6, + "Id": "e66da548-6555-4abe-a132-1629e68b6f25", + "Infiltration": "", "Position": { - "x": -306.09, - "y": 1.01, - "z": -89.42 + "x": 604.9504, + "y": 1.21291232, + "z": -119.5414 }, - "Rotation": 44.5400047, - "Sides": ["Pmc"] + "Rotation": 4.26114464, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6464,23 +7061,23 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ddca1267-6caa-4986-bd13-0ed29a81e6d2", + "Id": "e765e08d-9ea3-46f0-ad0b-774d78da5478", "Infiltration": "Customs", "Position": { - "x": 104.470016, - "y": 1.197, - "z": 16.5079956 + "x": 91.29799, + "y": 1.218, + "z": -104.936005 }, - "Rotation": 85.46295, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBlockPost", + "BotZoneName": "ZoneBrige", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6490,47 +7087,21 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 70 } }, - "CorePointId": 8, + "CorePointId": 4, "DelayToCanSpawnSec": 6, - "Id": "ddf17e52-f093-4a66-880d-c23546e8c6f0", + "Id": "e7cfc09e-bb1f-4993-a887-9b203097c210", "Infiltration": "", "Position": { - "x": 529.57, - "y": 2.519843, - "z": 43.679 + "x": -30.9607353, + "y": -12.0579987, + "z": 126.24 }, - "Rotation": 188.080261, + "Rotation": 183.768738, "Sides": ["Savage"] }, - { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 77 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "df949703-1471-4367-a395-3afa78fcf886", - "Infiltration": "Customs", - "Position": { - "x": -134.012, - "y": 0.718000054, - "z": 15.9940033 - }, - "Rotation": 85.46295, - "Sides": ["Pmc"] - }, { "BotZoneName": "ZoneScavBase", "Categories": ["Bot"], @@ -6542,24 +7113,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 50 } }, "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "e04805f7-14c0-490b-82d0-8ab2d4cee314", + "Id": "e8398178-82d4-4042-bcf8-342bca0e65b8", "Infiltration": "", "Position": { - "x": 227.906281, - "y": 1.29224026, - "z": -86.3992157 + "x": 252.16629, + "y": 1.21224034, + "z": -108.459213 }, - "Rotation": 189.840561, + "Rotation": 135.08139, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactorySide", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6568,24 +7139,24 @@ "y": 0, "z": 0 }, - "Radius": 114.7 + "Radius": 50 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 6, - "Id": "e1430515-568a-42f8-a264-5fec7dbaa576", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "e8dcecc5-1fda-4553-bffb-7efbd681c11d", + "Infiltration": "Customs", "Position": { - "x": 604.9504, - "y": 1.21291232, - "z": -119.5414 + "x": 20.428009, + "y": 1.218, + "z": -124.846 }, - "Rotation": 4.26114464, - "Sides": ["Savage"] + "Rotation": 0, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6594,19 +7165,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 30 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 5, - "Id": "e269db37-96ee-48a1-9ed8-0938be9f9cf4", + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "ec55a5b0-6317-4f27-8add-62b150a0d424", "Infiltration": "", "Position": { - "x": 454.29303, - "y": 2.67591476, - "z": -81.5390244 + "x": 125.176292, + "y": 1.32224035, + "z": -146.1392 }, - "Rotation": 89.51053, + "Rotation": 253.594025, "Sides": ["Savage"] }, { @@ -6625,14 +7196,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e5da63fb-4d33-4ebb-a621-dd414deecab5", + "Id": "f0113a3b-12cd-4801-ad39-c5ebc9578d38", "Infiltration": "Customs", "Position": { - "x": 569.548, - "y": -0.292000055, - "z": -17.6360016 + "x": -131.786987, + "y": 0.718000054, + "z": 9.414993 }, - "Rotation": 270.218658, + "Rotation": 85.46295, "Sides": ["Pmc"] }, { @@ -6646,24 +7217,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e765e08d-9ea3-46f0-ad0b-774d78da5478", + "Id": "f02af868-e415-4779-bbf6-a1eabeee7ae3", "Infiltration": "Customs", "Position": { - "x": 91.29799, - "y": 1.218, - "z": -104.936005 + "x": -214.582, + "y": -1.23199987, + "z": -0.3959961 }, - "Rotation": 0, + "Rotation": 128.039261, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6672,24 +7243,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "e8dcecc5-1fda-4553-bffb-7efbd681c11d", - "Infiltration": "Customs", + "CorePointId": 1, + "DelayToCanSpawnSec": 6, + "Id": "f1a9dfc3-1bad-43cd-b6e5-f2348468789d", + "Infiltration": "", "Position": { - "x": 20.428009, - "y": 1.218, - "z": -124.846 + "x": 186.527283, + "y": 2.84524035, + "z": 173.873779 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 92.26318, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6698,24 +7269,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 80 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f0113a3b-12cd-4801-ad39-c5ebc9578d38", - "Infiltration": "Customs", + "Id": "f2755660-ab11-4982-a774-26119ce5241e", + "Infiltration": "Boiler Tanks", "Position": { - "x": -131.786987, - "y": 0.718000054, - "z": 9.414993 + "x": 359.958, + "y": 11.478, + "z": 154.314 }, - "Rotation": 85.46295, + "Rotation": 171.58, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneTankSquare", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6724,23 +7295,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 110 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "f02af868-e415-4779-bbf6-a1eabeee7ae3", - "Infiltration": "Customs", + "CorePointId": 6, + "DelayToCanSpawnSec": 6, + "Id": "f31226a6-20e7-42f7-b7b7-cffda28fb4eb", + "Infiltration": "", "Position": { - "x": -214.582, - "y": -1.23199987, - "z": -0.3959961 + "x": 57.6700058, + "y": 1.18891406, + "z": -37.5 }, - "Rotation": 128.039261, - "Sides": ["Pmc"] + "Rotation": 11.0327263, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneBlockPost", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6750,24 +7321,24 @@ "y": 0, "z": 0 }, - "Radius": 131.24 + "Radius": 80 } }, - "CorePointId": 3, + "CorePointId": 19, "DelayToCanSpawnSec": 6, - "Id": "f08cc0db-6948-498f-b26a-51ebf2f30af8", + "Id": "f39537d4-1aef-4af6-9e06-be1d17a637ec", "Infiltration": "", "Position": { - "x": -273.483, - "y": 0.9775678, - "z": -72.127 + "x": 510.865, + "y": 3.43099976, + "z": 46.168 }, - "Rotation": 151.257034, + "Rotation": 186.6658, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneFactoryCenter", - "Categories": ["Bot"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6776,24 +7347,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 20 } }, - "CorePointId": 14, - "DelayToCanSpawnSec": 3, - "Id": "f1607318-b27d-44c8-bc0d-2a7376b8d231", + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "f543ed8a-858e-44c1-92b0-043f7002c8ce", "Infiltration": "", "Position": { - "x": 391.856567, - "y": 1.39002156, - "z": -86.1867752 + "x": 208.2033, + "y": 1.78224027, + "z": -116.860214 }, - "Rotation": 189.658691, + "Rotation": 189.840561, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6802,24 +7373,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 30 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "f2755660-ab11-4982-a774-26119ce5241e", - "Infiltration": "Boiler Tanks", + "Id": "f55825ba-d987-4238-ae5a-dfcfdd40af07", + "Infiltration": "", "Position": { - "x": 359.958, - "y": 11.478, - "z": 154.314 + "x": 77.77829, + "y": 1.43224025, + "z": -108.103226 }, - "Rotation": 171.58, - "Sides": ["Pmc"] + "Rotation": 135.08139, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneCrossRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneDormitory", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6828,19 +7399,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 25 } }, "CorePointId": 1, "DelayToCanSpawnSec": 6, - "Id": "f44a3dce-3acb-4e54-af80-49c3c53ebca4", + "Id": "f5741813-5583-42dc-acd1-5c45b948a7d2", "Infiltration": "", "Position": { - "x": 227.562, - "y": -0.695065, - "z": 124.912994 + "x": 174.652283, + "y": -0.12775971, + "z": 152.706787 }, - "Rotation": 186.911575, + "Rotation": 81.11248, "Sides": ["Savage"] }, { @@ -6869,6 +7440,32 @@ "Rotation": 167.010742, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneScavBase", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "f67b7e7f-4060-4fac-9a98-33a308349022", + "Infiltration": "", + "Position": { + "x": 195.096283, + "y": 1.49224031, + "z": -170.1392 + }, + "Rotation": 189.840561, + "Sides": ["Savage"] + }, { "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], @@ -6885,7 +7482,7 @@ }, "CorePointId": 11, "DelayToCanSpawnSec": 6, - "Id": "f66533f0-ec28-4c8a-8b38-a058c2ed6563", + "Id": "f722d19c-37f1-436a-a82e-14ef8b6a87cd", "Infiltration": "", "Position": { "x": 422.29, @@ -6896,7 +7493,7 @@ "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBrige", + "BotZoneName": "ZoneTankSquare", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6906,19 +7503,19 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 100 } }, - "CorePointId": 4, + "CorePointId": 6, "DelayToCanSpawnSec": 6, - "Id": "f6d3a5c7-5880-42b4-b98d-7d5c8ec3c438", + "Id": "f827894f-23cd-4720-ab4f-c5dc137895bb", "Infiltration": "", "Position": { - "x": 27.54927, - "y": -1.12046, - "z": 127.26 + "x": 101.430008, + "y": 1.22583747, + "z": 22.07 }, - "Rotation": 183.768738, + "Rotation": 204.6489, "Sides": ["Savage"] }, { @@ -6974,33 +7571,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneDormitory", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 25 - } - }, - "CorePointId": 1, - "DelayToCanSpawnSec": 6, - "Id": "fb16a717-c61a-488d-985e-0ec16dd288ec", - "Infiltration": "", - "Position": { - "x": 190.702286, - "y": -0.1337597, - "z": 175.85379 - }, - "Rotation": 355.9929, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneCustoms", + "BotZoneName": "ZoneFactoryCenter", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -7010,19 +7581,19 @@ "y": 0, "z": 0 }, - "Radius": 110 + "Radius": 114.7 } }, - "CorePointId": 3, + "CorePointId": 2, "DelayToCanSpawnSec": 6, - "Id": "fc913846-cd48-4398-82c4-b2be3b60eb7c", + "Id": "fd03b7ac-e83c-43b7-9046-09a4c6a901e1", "Infiltration": "", "Position": { - "x": -236.430008, - "y": 1.4996326, - "z": -235.900009 + "x": 463.7923, + "y": 1.207964, + "z": -117.402084 }, - "Rotation": 350.38678, + "Rotation": 147.656372, "Sides": ["Savage"] }, { @@ -7076,6 +7647,32 @@ }, "Rotation": 167.010742, "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneCrossRoad", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 90 + } + }, + "CorePointId": 7, + "DelayToCanSpawnSec": 6, + "Id": "fe9878ea-5664-4981-86a9-e8de8ecf73bb", + "Infiltration": "", + "Position": { + "x": 191.46, + "y": 1.22457552, + "z": -2.51000214 + }, + "Rotation": 38.0980873, + "Sides": ["Savage"] } ], "UnixDateTime": 1636382469, @@ -7280,328 +7877,50 @@ "matching_min_seconds": 60, "maxItemCountInLocation": [ { - "TemplateId": "54009119af1c881c07000029", - "Value": 0 + "TemplateId": "634959225289190e5e773b3b", + "Value": 6 } ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "CUS_TRANSIT_9_COND", + "description": "CUS_TRANSIT_9_DESC", + "id": 9, + "location": "RezervBase", + "name": "CUS_TRANSIT_9", + "target": "5704e5fad2720bc05b8b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "CUS_TRANSIT_10_COND", + "description": "CUS_TRANSIT_10_DESC", + "id": 10, + "location": "factory4_day", + "name": "CUS_TRANSIT_10", + "target": "55f2d3fd4bdc2d5f408b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "CUS_TRANSIT_11_COND", + "description": "CUS_TRANSIT_11_DESC", + "id": 11, + "location": "Interchange", + "name": "CUS_TRANSIT_11", + "target": "5714dbc024597771384a510d", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [ - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneBrige", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 0, - "slots_min": 0, - "time_max": 1, - "time_min": 0 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneCrossRoad", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 1, - "slots_max": 0, - "slots_min": 0, - "time_max": 30, - "time_min": 20 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneDormitory", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 2, - "slots_max": 4, - "slots_min": 2, - "time_max": 60, - "time_min": 30 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneGasStation", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 3, - "slots_max": 2, - "slots_min": 0, - "time_max": 31, - "time_min": 30 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneFactoryCenter", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 4, - "slots_max": 1, - "slots_min": 0, - "time_max": 380, - "time_min": 350 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneFactorySide", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 5, - "slots_max": 1, - "slots_min": 0, - "time_max": 410, - "time_min": 400 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneOldAZS", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 6, - "slots_max": 1, - "slots_min": 0, - "time_max": 600, - "time_min": 420 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSnipeBrige", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 7, - "slots_max": 1, - "slots_min": 0, - "time_max": 30, - "time_min": 10 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSnipeTower", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 8, - "slots_max": 1, - "slots_min": 0, - "time_max": 50, - "time_min": 40 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSnipeFactory", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 9, - "slots_max": 1, - "slots_min": 0, - "time_max": 30, - "time_min": 10 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneBlockPost", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 10, - "slots_max": 1, - "slots_min": 0, - "time_max": 350, - "time_min": 301 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneBlockPostSniper", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 11, - "slots_max": 1, - "slots_min": 0, - "time_max": 3, - "time_min": 2 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneBlockPostSniper3", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 13, - "slots_max": 1, - "slots_min": 0, - "time_max": 4, - "time_min": 2 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneCrossRoad", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 14, - "slots_max": 2, - "slots_min": 0, - "time_max": 550, - "time_min": 500 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneBlockPost", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 15, - "slots_max": 0, - "slots_min": 0, - "time_max": 740, - "time_min": 700 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneTankSquare", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 16, - "slots_max": 1, - "slots_min": 0, - "time_max": 55, - "time_min": 0 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneWade", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 17, - "slots_max": 2, - "slots_min": 0, - "time_max": 55, - "time_min": 0 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 0, - "slots_min": 0, - "time_max": -1, - "time_min": -1 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 5, - "slots_min": 2, - "time_max": 750, - "time_min": 500 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 5, - "slots_min": 1, - "time_max": 1000, - "time_min": 750 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 4, - "slots_min": 2, - "time_max": 400, - "time_min": 200 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 5, - "slots_min": 1, - "time_max": 2000, - "time_min": 1200 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 2, - "slots_min": 0, - "time_max": 1000, - "time_min": 600 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 3, - "slots_min": 2, - "time_max": 120, - "time_min": 70 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 5, - "slots_min": 2, - "time_max": 20, - "time_min": 0 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 4, - "slots_min": 2, - "time_max": 180, - "time_min": 140 - } - ] + "waves": [] } diff --git a/external-resources/maps/factory.json b/external-resources/maps/factory.json index 14964bbc..8ee18f19 100644 --- a/external-resources/maps/factory.json +++ b/external-resources/maps/factory.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "Area": 0.9, "AveragePlayTime": 15, "AveragePlayerLevel": 1, @@ -70,7 +71,7 @@ ], "BossLocationSpawn": [ { - "BossChance": 35, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "0", "BossEscortDifficult": "normal", @@ -82,7 +83,77 @@ "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], "Supports": null, - "Time": -1 + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" } ], "BotAssault": 0, @@ -91,18 +162,118 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 140, + "DistToActivatePvE": 140, "DistToPersueAxemanCoef": 0.9, "DistToSleep": 150, + "DistToSleepPvE": 150, "GainSight": 1, "KhorovodChance": 0, "MagnetPower": 15, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 900, + "MinExfiltrationTime": 600, "Scattering": 1, "VisibleDistance": 1 }, "BotMarksman": 0, - "BotMax": 20, + "BotMax": 0, "BotMaxPlayer": 0, "BotMaxPvE": 20, "BotMaxTimePlayer": 0, @@ -124,9 +295,89 @@ "EscapeTimeLimit": 20, "EscapeTimeLimitCoop": 15, "EscapeTimeLimitPVE": 20, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 13, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 40, + "TargetPointSearchRadiusLimit": 80, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 50, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.3, + "GlobalLootChanceModifier": 0.27, "GlobalLootChanceModifierPvE": 0.3, "IconX": 470, "IconY": 510, @@ -137,33 +388,46 @@ "Loot": [], "MatchMakerMinPlayersByWaitTime": [ { - "minPlayers": 4, + "minPlayers": 7, "time": 60 }, { - "minPlayers": 3, + "minPlayers": 6, + "time": 70 + }, + { + "minPlayers": 5, "time": 120 }, { - "minPlayers": 2, + "minPlayers": 4, + "time": 180 + }, + { + "minPlayers": 3, "time": 250 }, { - "minPlayers": 1, + "minPlayers": 2, "time": 330 + }, + { + "minPlayers": 1, + "time": 420 } ], "MaxBotPerZone": 4, "MaxCoopGroup": 6, "MaxDistToFreePoint": 900, - "MaxPlayers": 6, + "MaxPlayers": 8, "MinDistToExitPoint": 30, "MinDistToFreePoint": 10, "MinMaxBots": [], "MinPlayerLvlAccessKeys": 0, - "MinPlayers": 5, + "MinPlayers": 7, "Name": "Factory", "NewSpawn": false, + "NewSpawnForPlayers": false, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -210,11 +474,11 @@ "Id": "0246436c-7d69-4036-999d-ebcb956970b5", "Infiltration": "Factory", "Position": { - "x": -29.763, - "y": 0.21, - "z": 7.584 + "x": -45.3968, + "y": 0.2904, + "z": 5.5814 }, - "Rotation": 54.99, + "Rotation": 64.50763, "Sides": ["All"] }, { @@ -283,7 +547,7 @@ "Radius": 35 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, "Id": "03a779de-ef2d-43e3-a4f3-fdcfed474f05", "Infiltration": "", @@ -314,11 +578,37 @@ "Id": "05e75eb3-eb43-46c6-94d3-59e1e9ba4435", "Infiltration": "Factory", "Position": { - "x": -21.614, - "y": -2.62, - "z": 37.611 + "x": 11.22, + "y": 0.04, + "z": -42.1099968 + }, + "Rotation": 150.141159, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "0a8181f7-c8f0-4db1-8eb2-932dfb3545f3", + "Infiltration": "Factory", + "Position": { + "x": 42.433, + "y": -2.639, + "z": -8.306 }, - "Rotation": 160.78, + "Rotation": 262.378082, "Sides": ["All"] }, { @@ -340,11 +630,11 @@ "Id": "0a92f51c-52b4-4e76-b839-f7ce82f2b36b", "Infiltration": "Factory", "Position": { - "x": 59.594, - "y": 0.103, - "z": 22.151 + "x": 56.864, + "y": 0.261, + "z": 52.568 }, - "Rotation": 53.49001, + "Rotation": 159.0315, "Sides": ["All"] }, { @@ -418,11 +708,11 @@ "Id": "120a0777-e825-4de7-a855-c3eaa8eba46b", "Infiltration": "Factory", "Position": { - "x": -28.958, - "y": 0.21, - "z": 6.595 + "x": -43.8128, + "y": 0.2904, + "z": 6.7404 }, - "Rotation": 54.99, + "Rotation": 90.74365, "Sides": ["All"] }, { @@ -444,11 +734,11 @@ "Id": "13883982-2ab8-4dd5-a9b4-45e2c6d8e1cc", "Infiltration": "Factory", "Position": { - "x": -20.215, - "y": -2.62, - "z": 38.789 + "x": 12.595, + "y": 0.04, + "z": -42.522 }, - "Rotation": 160.78, + "Rotation": 239.798431, "Sides": ["All"] }, { @@ -496,11 +786,37 @@ "Id": "1a5819f2-ff42-4632-af5e-fe5ea8f886fc", "Infiltration": "Factory", "Position": { - "x": 61, - "y": 0.117, - "z": 20.95 + "x": 58.1779976, + "y": 0.261, + "z": 51.283 + }, + "Rotation": 174.141357, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "1c8f1067-d5df-401c-b05a-3c2c6b36ab9a", + "Infiltration": "Factory", + "Position": { + "x": 15.7, + "y": 4.571, + "z": 38.976 }, - "Rotation": 53.49001, + "Rotation": 0, "Sides": ["All"] }, { @@ -548,11 +864,11 @@ "Id": "1facfcfc-9ee5-4638-83b3-117fce7b3303", "Infiltration": "Factory", "Position": { - "x": -30.978, - "y": 0.21, - "z": 6.713 + "x": -46.6908, + "y": 0.2904, + "z": 8.3904 }, - "Rotation": 54.99, + "Rotation": 103.706047, "Sides": ["All"] }, { @@ -574,11 +890,11 @@ "Id": "22a7740a-5a91-4bca-af36-668342522b42", "Infiltration": "Factory", "Position": { - "x": 70.465, - "y": 0.211, - "z": -61.785 + "x": 70.75821, + "y": 0.311, + "z": -72.8016052 }, - "Rotation": 56.43, + "Rotation": 356.430054, "Sides": ["All"] }, { @@ -607,6 +923,32 @@ "Rotation": 101.387489, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "2497205e-6fc4-49cd-a1e3-f46c780e214f", + "Infiltration": "Factory", + "Position": { + "x": 31.624, + "y": 0.119, + "z": 18.284 + }, + "Rotation": 281.606659, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -704,11 +1046,11 @@ "Id": "2a1f1b80-72be-444d-9d8d-5f645a3fc019", "Infiltration": "Factory", "Position": { - "x": 46.163, - "y": 0.16, - "z": -37.009 + "x": 32.272, + "y": 0.064, + "z": -34.013 }, - "Rotation": 0, + "Rotation": 100.290321, "Sides": ["All"] }, { @@ -730,11 +1072,11 @@ "Id": "2a5aad92-b5f9-40c0-a380-460247300227", "Infiltration": "Factory", "Position": { - "x": 60.445, - "y": 0.073, - "z": 19.302 + "x": 57.944, + "y": 0.261, + "z": 49.646 }, - "Rotation": 53.49001, + "Rotation": 174.141357, "Sides": ["All"] }, { @@ -782,11 +1124,11 @@ "Id": "2e1843a1-fd2a-4ccd-8b38-747c1a70f228", "Infiltration": "Factory", "Position": { - "x": -8.413, - "y": 0.005, - "z": -33.898 + "x": -16.91, + "y": 0.294, + "z": -39.428 }, - "Rotation": 340.262238, + "Rotation": 270, "Sides": ["All"] }, { @@ -808,11 +1150,11 @@ "Id": "2eed18b6-9fbb-40de-979f-985f203f251e", "Infiltration": "Factory", "Position": { - "x": -28.19, - "y": 0.21, - "z": 5.58 + "x": -42.4368, + "y": 0.2904, + "z": 7.44339943 }, - "Rotation": 54.99, + "Rotation": 83.8970261, "Sides": ["All"] }, { @@ -834,11 +1176,11 @@ "Id": "30edcdf0-73e0-4ab5-a9e7-4d24a9a83aa9", "Infiltration": "Factory", "Position": { - "x": 28.464, - "y": 0.244, - "z": 16.991 + "x": 27.775, + "y": 0.119, + "z": 20.567 }, - "Rotation": 77.36217, + "Rotation": 121.344116, "Sides": ["All"] }, { @@ -860,11 +1202,11 @@ "Id": "336d3c25-9f38-475f-8eb9-db6393f06b6c", "Infiltration": "Factory", "Position": { - "x": 67.872, - "y": 0.245, - "z": -60.357 + "x": 71.73021, + "y": 0.311, + "z": -71.4116 }, - "Rotation": 56.43, + "Rotation": 356.430054, "Sides": ["All"] }, { @@ -912,11 +1254,37 @@ "Id": "38a8fe02-f871-4b79-91e5-69c2c68d1bbc", "Infiltration": "Factory", "Position": { - "x": -4.123, - "y": 0.005, - "z": -34.711 + "x": -16.984, + "y": 0.26700002, + "z": -41.3249969 + }, + "Rotation": 270, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "3906ac26-47d3-4602-8783-049633778a29", + "Infiltration": "Factory", + "Position": { + "x": 14.636, + "y": 4.571, + "z": 39.737 }, - "Rotation": 359.768463, + "Rotation": 0, "Sides": ["All"] }, { @@ -938,11 +1306,11 @@ "Id": "3bcd754a-b299-4d63-9d7f-e4d05c2f13e3", "Infiltration": "Factory", "Position": { - "x": -23.044, - "y": 1.07, - "z": 65.688 + "x": -22.174, + "y": 2.729, + "z": 23.772 }, - "Rotation": 263.74, + "Rotation": 89.99999, "Sides": ["All"] }, { @@ -1023,6 +1391,32 @@ "Rotation": 269.225647, "Sides": ["Pmc"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "42c3f263-52c6-428c-b97f-6acd100ec669", + "Infiltration": "Factory", + "Position": { + "x": -3.28900051, + "y": -3.858, + "z": -17.514 + }, + "Rotation": 0, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -1068,11 +1462,11 @@ "Id": "4755c538-4ee5-4125-8cd3-885787da7ad5", "Infiltration": "Factory", "Position": { - "x": 19.87, - "y": -2.61, - "z": -1.3 + "x": 12.6300011, + "y": 1.797, + "z": 60.15 }, - "Rotation": 0, + "Rotation": 88.5811157, "Sides": ["All"] }, { @@ -1120,11 +1514,11 @@ "Id": "4a4e5ee5-a314-4a78-939d-cf3c05818435", "Infiltration": "Factory", "Position": { - "x": -4.765, - "y": 0.005, - "z": -33.066 + "x": -16.7849979, + "y": 0.312, + "z": -37.434 }, - "Rotation": 53.49001, + "Rotation": 246.299744, "Sides": ["All"] }, { @@ -1146,11 +1540,11 @@ "Id": "4bc2255b-75b0-44a3-91ed-c1b35499cbc5", "Infiltration": "Factory", "Position": { - "x": -17.21, - "y": -2.62, - "z": 38.282 + "x": 7.90300035, + "y": 0.04, + "z": -44.6099968 }, - "Rotation": 160.78, + "Rotation": 195.357437, "Sides": ["All"] }, { @@ -1172,11 +1566,11 @@ "Id": "503cf951-8e80-4ca0-aa2d-993f71a6a4a6", "Infiltration": "Factory", "Position": { - "x": -51.426, - "y": 1.353, - "z": 54.339 + "x": -44.191, + "y": 1.188, + "z": 48.4250031 }, - "Rotation": 118.999352, + "Rotation": 90, "Sides": ["All"] }, { @@ -1198,11 +1592,11 @@ "Id": "50560c89-4136-4cfb-b155-485519110c93", "Infiltration": "Factory", "Position": { - "x": -3.503, - "y": 0.005, - "z": -32.728 + "x": -17.6909981, + "y": 0.291, + "z": -43.159996 }, - "Rotation": 53.49001, + "Rotation": 286.887238, "Sides": ["All"] }, { @@ -1224,11 +1618,11 @@ "Id": "57254982-c470-440d-911a-e8854f42398a", "Infiltration": "Factory", "Position": { - "x": -52.617, - "y": 1.353, - "z": 55.629 + "x": -42.617, + "y": 1.279, + "z": 48.353 }, - "Rotation": 118.999352, + "Rotation": 90, "Sides": ["All"] }, { @@ -1328,11 +1722,11 @@ "Id": "5be1a535-4865-433c-b645-33c7ff65bd94", "Infiltration": "Factory", "Position": { - "x": -31.67, - "y": 0.21, - "z": 8.2 + "x": -46.2658, + "y": 0.2904, + "z": 7.04739952 }, - "Rotation": 54.99, + "Rotation": 82.15895, "Sides": ["All"] }, { @@ -1380,11 +1774,37 @@ "Id": "60b47eab-b2a6-4ba2-b30c-fea14a7169bf", "Infiltration": "Factory", "Position": { - "x": 68.514, - "y": 0.194, - "z": -4.796 + "x": -5.918, + "y": -3.858, + "z": -14.1830006 + }, + "Rotation": 53.7435837, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "63f705ca-a0db-4f4f-8e50-20d5a97af053", + "Infiltration": "Factory", + "Position": { + "x": -0.09300041, + "y": -3.858, + "z": -12.227 }, - "Rotation": 5.86497259, + "Rotation": 252.025253, "Sides": ["All"] }, { @@ -1401,7 +1821,7 @@ "Radius": 35 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, "Id": "6670b804-5f1a-45f1-a462-585cb8619d09", "Infiltration": "", @@ -1417,18 +1837,14 @@ "BotZoneName": "", "Categories": ["Player"], "ColliderParams": { - "_parent": "SpawnBoxParams", + "_parent": "SpawnSphereParams", "_props": { "Center": { "x": 0, "y": 0, "z": 0 }, - "Size": { - "x": 40, - "y": 4, - "z": 40 - } + "Radius": 20 } }, "CorePointId": 0, @@ -1436,11 +1852,11 @@ "Id": "67fb48f8-0359-458b-876c-2e4963cbd14e", "Infiltration": "Factory", "Position": { - "x": -5.93, - "y": -3.889, - "z": -22.49 + "x": 21.4049988, + "y": -2.668999, + "z": -14.6159992 }, - "Rotation": 1.93020487, + "Rotation": 255.000031, "Sides": ["All"] }, { @@ -1462,11 +1878,11 @@ "Id": "683f2734-6398-4b77-9bab-b87f3be35938", "Infiltration": "Factory", "Position": { - "x": 69.644, - "y": 0.211, - "z": -60.426 + "x": 69.98521, + "y": 0.311, + "z": -71.3536 }, - "Rotation": 56.43, + "Rotation": 356.430054, "Sides": ["All"] }, { @@ -1537,14 +1953,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6d7bf2bb-6211-4495-8509-58ceadea72e0", + "Id": "6ce1f898-79ff-498e-8b52-fda05d7ee05d", "Infiltration": "Factory", "Position": { - "x": -18.579, - "y": -2.62, - "z": 38.04 + "x": 59.516, + "y": -2.63900042, + "z": 6.828 }, - "Rotation": 160.78, + "Rotation": 46.93951, "Sides": ["All"] }, { @@ -1563,44 +1979,40 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6d97a439-de10-42c5-99ef-6cf92e243aca", + "Id": "6d7bf2bb-6211-4495-8509-58ceadea72e0", "Infiltration": "Factory", "Position": { - "x": 17.043, - "y": -2.61, - "z": -2.117 + "x": 9.994, + "y": 0.04, + "z": -42.204 }, - "Rotation": 183.2318, + "Rotation": 271.3531, "Sides": ["All"] }, { "BotZoneName": "", "Categories": ["Player"], "ColliderParams": { - "_parent": "SpawnBoxParams", + "_parent": "SpawnSphereParams", "_props": { "Center": { "x": 0, "y": 0, "z": 0 }, - "Size": { - "x": 40, - "y": 4, - "z": 50 - } + "Radius": 20 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6ecc9492-5fbb-43d8-a0c0-8509fa39eb1d", + "Id": "6d97a439-de10-42c5-99ef-6cf92e243aca", "Infiltration": "Factory", "Position": { - "x": -2.238, - "y": -3.905, - "z": -15.408 + "x": 10.2300014, + "y": 1.14, + "z": 58.7600021 }, - "Rotation": 1.93020487, + "Rotation": 88.5811157, "Sides": ["All"] }, { @@ -1619,19 +2031,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "74059b40-4072-495f-a02c-2ffce404d728", + "Id": "6ecc9492-5fbb-43d8-a0c0-8509fa39eb1d", "Infiltration": "Factory", "Position": { - "x": 32.213, - "y": 2.333, - "z": 18.67 + "x": 20.198, + "y": -2.668999, + "z": -16.3809986 }, - "Rotation": 249.746887, + "Rotation": 347.009827, "Sides": ["All"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1645,15 +2057,15 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "792180b4-c67c-45f6-a5d4-f3973c7e2c9b", + "Id": "71c2ba1e-e226-47be-814f-d52ddd931603", "Infiltration": "Factory", "Position": { - "x": 45.914814, - "y": 0.11818099, - "z": -26.4251 + "x": -2.81400013, + "y": -2.598, + "z": 18.476 }, - "Rotation": 3.0047307, - "Sides": ["Pmc"] + "Rotation": 226.745529, + "Sides": ["All"] }, { "BotZoneName": "", @@ -1671,12 +2083,12 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7ea1b4b8-a496-4bc0-bf61-e5ba4f3aa1fa", + "Id": "74059b40-4072-495f-a02c-2ffce404d728", "Infiltration": "Factory", "Position": { - "x": 43.604, - "y": 0.16, - "z": -36.675 + "x": 2.363, + "y": -2.639, + "z": 49.415 }, "Rotation": 0, "Sides": ["All"] @@ -1697,19 +2109,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "80532206-b2e1-4578-b559-99eae931a957", + "Id": "789a1686-f35d-4dc4-b469-0687a4fad804", "Infiltration": "Factory", "Position": { - "x": 46.118, - "y": 0.16, - "z": -39.159 + "x": 41.089, + "y": -2.639, + "z": -9.549 }, - "Rotation": 0, + "Rotation": 343.771973, "Sides": ["All"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1723,19 +2135,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8128ea83-0d4f-4e64-b109-5acc9e477b33", + "Id": "792180b4-c67c-45f6-a5d4-f3973c7e2c9b", "Infiltration": "Factory", "Position": { - "x": 69.838, - "y": 0.194, - "z": -6.105 + "x": 45.914814, + "y": 0.11818099, + "z": -26.4251 }, - "Rotation": 5.86497259, - "Sides": ["All"] + "Rotation": 3.0047307, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1749,15 +2161,15 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "824c7aed-9a71-4158-91e4-a153c42bbddc", + "Id": "7ea1b4b8-a496-4bc0-bf61-e5ba4f3aa1fa", "Infiltration": "Factory", "Position": { - "x": 47.3188133, - "y": 0.11818099, - "z": -25.6161 + "x": 32.2320023, + "y": 0.064, + "z": -31.639 }, - "Rotation": 3.0047307, - "Sides": ["Pmc"] + "Rotation": 303.679382, + "Sides": ["All"] }, { "BotZoneName": "", @@ -1775,14 +2187,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8429bed9-52e2-4731-a425-4912db8529a9", + "Id": "80532206-b2e1-4578-b559-99eae931a957", "Infiltration": "Factory", "Position": { - "x": 57.902, - "y": 0.06, - "z": 21.998 + "x": 32.668, + "y": 0.064, + "z": -35.46 }, - "Rotation": 53.49001, + "Rotation": 41.47584, "Sides": ["All"] }, { @@ -1801,19 +2213,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "867576c4-1152-48ad-80bf-a802d7318379", + "Id": "8128ea83-0d4f-4e64-b109-5acc9e477b33", "Infiltration": "Factory", "Position": { - "x": -49.516, - "y": 1.353, - "z": 55.556 + "x": -4.302, + "y": -2.598, + "z": 14.318 }, - "Rotation": 118.999352, + "Rotation": 0, "Sides": ["All"] }, { "BotZoneName": "", - "Categories": ["Bot"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1822,18 +2234,122 @@ "y": 0, "z": 0 }, - "Radius": 41.97 + "Radius": 20 } }, - "CorePointId": 3, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "86ff84ac-edf7-4efd-9643-4bacc59073e7", - "Infiltration": "", + "Id": "824c7aed-9a71-4158-91e4-a153c42bbddc", + "Infiltration": "Factory", "Position": { - "x": -6.77, - "y": 0.17, - "z": 10.01 - }, + "x": 47.3188133, + "y": 0.11818099, + "z": -25.6161 + }, + "Rotation": 3.0047307, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "8429bed9-52e2-4731-a425-4912db8529a9", + "Infiltration": "Factory", + "Position": { + "x": 58.4149971, + "y": 0.261, + "z": 52.6900024 + }, + "Rotation": 178.765686, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "85d68e69-87f9-4702-aa92-1d652dc47cf8", + "Infiltration": "Factory", + "Position": { + "x": 3.99100018, + "y": -2.639, + "z": 50.653 + }, + "Rotation": 201.047623, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "867576c4-1152-48ad-80bf-a802d7318379", + "Infiltration": "Factory", + "Position": { + "x": -44.013, + "y": 1.41200006, + "z": 50.136 + }, + "Rotation": 5.15359545, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 41.97 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "86ff84ac-edf7-4efd-9643-4bacc59073e7", + "Infiltration": "", + "Position": { + "x": -6.77, + "y": 0.17, + "z": 10.01 + }, "Rotation": 327.8234, "Sides": ["Savage"] }, @@ -1856,11 +2372,11 @@ "Id": "8df78011-1568-4e66-99b8-5c4ed736b99a", "Infiltration": "Factory", "Position": { - "x": -6.95, - "y": 0.005, - "z": -32.83 + "x": -19.1069984, + "y": 0.26000002, + "z": -43.166 }, - "Rotation": 315.70224, + "Rotation": 89.99994, "Sides": ["All"] }, { @@ -1877,7 +2393,7 @@ "Radius": 41.97 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, "Id": "90da8fb3-422a-46cd-b540-648cde8ee9f3", "Infiltration": "", @@ -1889,6 +2405,32 @@ "Rotation": 0, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "91c08464-492f-443d-8632-54e01d6bdd20", + "Infiltration": "Factory", + "Position": { + "x": -1.06100035, + "y": -2.638, + "z": -7.05 + }, + "Rotation": 197.617111, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1908,11 +2450,11 @@ "Id": "91ec8f79-6cc4-422d-966f-4cd6a02d5a87", "Infiltration": "Factory", "Position": { - "x": -21.217, - "y": -2.62, - "z": 40.645 + "x": 8.5, + "y": 0.04, + "z": -43.579998 }, - "Rotation": 160.78, + "Rotation": 8.130259, "Sides": ["All"] }, { @@ -1934,11 +2476,11 @@ "Id": "92822146-7c98-4570-8bde-8d0d042ae3cf", "Infiltration": "Factory", "Position": { - "x": 43.591, - "y": 0.16, - "z": -38.865 + "x": 35.354, + "y": 0.064, + "z": -34.507 }, - "Rotation": 0, + "Rotation": 283.0167, "Sides": ["All"] }, { @@ -1971,18 +2513,40 @@ "BotZoneName": "", "Categories": ["Player"], "ColliderParams": { - "_parent": "SpawnBoxParams", + "_parent": "SpawnSphereParams", "_props": { "Center": { "x": 0, "y": 0, "z": 0 }, - "Size": { - "x": 40, - "y": 4, - "z": 40 - } + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "97998a75-baa4-4b03-ac1f-f86dfbf48d79", + "Infiltration": "Factory", + "Position": { + "x": -6.689, + "y": -2.598, + "z": 17.303 + }, + "Rotation": 100.67749, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 } }, "CorePointId": 0, @@ -1990,11 +2554,11 @@ "Id": "990aa5a0-d549-4479-8af2-a196ddb3bb35", "Infiltration": "Factory", "Position": { - "x": -8.58, - "y": -3.905, - "z": -18.89 + "x": 18.637, + "y": -2.668999, + "z": -15.6589994 }, - "Rotation": 84.01993, + "Rotation": 58.42367, "Sides": ["All"] }, { @@ -2049,6 +2613,32 @@ "Rotation": 96.73777, "Sides": ["Pmc"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "9a858e10-3752-4543-9550-ddf6bc9b1891", + "Infiltration": "Factory", + "Position": { + "x": 39.642, + "y": -2.639, + "z": -9.06 + }, + "Rotation": 79.07639, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2068,11 +2658,11 @@ "Id": "9dd99893-91c5-4e64-b808-bbe46852022a", "Infiltration": "Factory", "Position": { - "x": 58.6, - "y": 0.101, - "z": 19.7 + "x": 60.093, + "y": 0.261, + "z": 52.592 }, - "Rotation": 53.49001, + "Rotation": 197.7287, "Sides": ["All"] }, { @@ -2120,11 +2710,37 @@ "Id": "9f14e22f-3971-4440-8f48-c597cc7d9166", "Infiltration": "Factory", "Position": { - "x": 30.238, - "y": 0.256, - "z": 15.246 + "x": 30.26, + "y": 0.119, + "z": 21.699 }, - "Rotation": 77.36217, + "Rotation": 153.3458, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "a3a76c4b-983f-4920-9c87-c2705283f5ac", + "Infiltration": "Factory", + "Position": { + "x": -0.737, + "y": -2.639, + "z": 50.57 + }, + "Rotation": 164.999939, "Sides": ["All"] }, { @@ -2148,7 +2764,7 @@ "Position": { "x": 36.043, "y": 1.09, - "z": 38.349 + "z": 38.348 }, "Rotation": 182.971283, "Sides": ["Savage"] @@ -2198,11 +2814,11 @@ "Id": "a5c47219-1ebc-4254-90cb-934d6f9d4790", "Infiltration": "Factory", "Position": { - "x": -20.958, - "y": 1.07, - "z": 65.523 + "x": -22.174, + "y": 2.729, + "z": 30.386 }, - "Rotation": 93.9956055, + "Rotation": 89.99999, "Sides": ["All"] }, { @@ -2231,6 +2847,58 @@ "Rotation": 3.0047307, "Sides": ["Pmc"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "a8635306-f041-47fe-bf9b-1f1d528d5d5b", + "Infiltration": "Factory", + "Position": { + "x": 14.969, + "y": 4.571, + "z": 35.1550026 + }, + "Rotation": 0, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "aacb1cf6-c980-47f0-8ed0-c72f1a236ec1", + "Infiltration": "Factory", + "Position": { + "x": 14.855999, + "y": 4.571, + "z": 37.77 + }, + "Rotation": 0, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -2276,11 +2944,11 @@ "Id": "ad0cbd99-02ee-4ff1-b799-6b50b8a3fa0f", "Infiltration": "Factory", "Position": { - "x": 68.564, - "y": 0.245, - "z": -61.448 + "x": 72.0582047, + "y": 0.311, + "z": -73.8616 }, - "Rotation": 56.43, + "Rotation": 356.430054, "Sides": ["All"] }, { @@ -2302,11 +2970,11 @@ "Id": "adee9078-b5a3-4f9e-b384-e984cbea15fc", "Infiltration": "Factory", "Position": { - "x": -52.297, - "y": 1.353, - "z": 57.053 + "x": -44.2819977, + "y": 1.343, + "z": 46.326004 }, - "Rotation": 118.999352, + "Rotation": 171.581924, "Sides": ["All"] }, { @@ -2328,11 +2996,11 @@ "Id": "ae4693d5-a309-4cbc-85db-ce8a59cf7ff4", "Infiltration": "Factory", "Position": { - "x": 44.96, - "y": 0.16, - "z": -37.574 + "x": 34.375, + "y": 0.064, + "z": -33.252 }, - "Rotation": 0, + "Rotation": 180.603928, "Sides": ["All"] }, { @@ -2361,6 +3029,32 @@ "Rotation": 269.225647, "Sides": ["Pmc"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "af816038-d1bd-4fb1-8355-e5adcdd4556e", + "Infiltration": "Factory", + "Position": { + "x": 41.166, + "y": -2.639, + "z": -7.624 + }, + "Rotation": 223.2953, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2380,11 +3074,11 @@ "Id": "afacfed6-7a03-418b-9fca-420590d639c0", "Infiltration": "Factory", "Position": { - "x": 69.275, - "y": 0.245, - "z": -62.56 + "x": 69.198204, + "y": 0.311, + "z": -73.4416046 }, - "Rotation": 56.43, + "Rotation": 18.1724968, "Sides": ["All"] }, { @@ -2406,11 +3100,11 @@ "Id": "b776e3ed-a02d-4141-8eba-35d4746547ca", "Infiltration": "Factory", "Position": { - "x": -51.114, - "y": 1.353, - "z": 55.87 + "x": -42.916, + "y": 1.094, + "z": 39.102 }, - "Rotation": 118.999352, + "Rotation": 90, "Sides": ["All"] }, { @@ -2484,11 +3178,11 @@ "Id": "bcae7a9f-8b2f-4a4c-9cb0-589d4a227c70", "Infiltration": "Factory", "Position": { - "x": 22.331, - "y": -2.61, - "z": 0.232 + "x": 12.5600014, + "y": 1.21, + "z": 52.73 }, - "Rotation": 0, + "Rotation": 123.00354, "Sides": ["All"] }, { @@ -2536,11 +3230,11 @@ "Id": "be7bf7f0-6892-4d55-b1af-85492250ea55", "Infiltration": "Factory", "Position": { - "x": 69.994, - "y": 0.194, - "z": -8.13 + "x": -0.171000481, + "y": -3.858, + "z": -14.33 }, - "Rotation": 5.86497259, + "Rotation": 298.784668, "Sides": ["All"] }, { @@ -2588,11 +3282,11 @@ "Id": "c249a42b-3b54-4680-ac4d-2c923ca4f530", "Infiltration": "Factory", "Position": { - "x": 30.674, - "y": 0.264, - "z": 20.54 + "x": 28.743, + "y": 0.119, + "z": 17.499 }, - "Rotation": 77.36217, + "Rotation": 30.7684727, "Sides": ["All"] }, { @@ -2614,11 +3308,11 @@ "Id": "c2d01ce0-e0e4-41af-8311-44dc5cf38a93", "Infiltration": "Factory", "Position": { - "x": 68.624, - "y": 0.194, - "z": -8.916 + "x": -6.47099972, + "y": -2.598, + "z": 15.79 }, - "Rotation": 184.931458, + "Rotation": 64.0924149, "Sides": ["All"] }, { @@ -2647,6 +3341,32 @@ "Rotation": 3.0047307, "Sides": ["Pmc"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "c61cee41-a0f3-470d-9b83-01f2189705fc", + "Infiltration": "Factory", + "Position": { + "x": 38.839, + "y": -2.639, + "z": -7.702 + }, + "Rotation": 89.99995, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2666,11 +3386,11 @@ "Id": "c671337f-e58f-4de6-a387-307d877954a3", "Infiltration": "Factory", "Position": { - "x": 18.411, - "y": -2.61, - "z": -1.321 + "x": 14.018, + "y": 1.18999994, + "z": 58.119 }, - "Rotation": 0, + "Rotation": 123.00354, "Sides": ["All"] }, { @@ -2687,7 +3407,7 @@ "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, "Id": "c949937b-c669-41ab-a5d6-1f93e58d4af8", "Infiltration": "", @@ -2699,6 +3419,32 @@ "Rotation": 82.28416, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "cbe988f1-2264-414f-b070-79434b27a4ca", + "Infiltration": "Factory", + "Position": { + "x": 58.204, + "y": -2.63900042, + "z": 6.1590004 + }, + "Rotation": 1.51046038, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Bot"], @@ -2729,18 +3475,14 @@ "BotZoneName": "", "Categories": ["Player"], "ColliderParams": { - "_parent": "SpawnBoxParams", + "_parent": "SpawnSphereParams", "_props": { "Center": { "x": 0, "y": 0, "z": 0 }, - "Size": { - "x": 40, - "y": 4, - "z": 40 - } + "Radius": 20 } }, "CorePointId": 0, @@ -2748,11 +3490,11 @@ "Id": "d2b48374-53d1-45a7-a3d2-5e1fc58a8499", "Infiltration": "Factory", "Position": { - "x": -3.612, - "y": -3.889, - "z": -25.528 + "x": 20.348999, + "y": -2.668999, + "z": -13.374 }, - "Rotation": 70.69419, + "Rotation": 199.173172, "Sides": ["All"] }, { @@ -2837,18 +3579,14 @@ "BotZoneName": "", "Categories": ["Player"], "ColliderParams": { - "_parent": "SpawnBoxParams", + "_parent": "SpawnSphereParams", "_props": { "Center": { "x": 0, "y": 0, "z": 0 }, - "Size": { - "x": 40, - "y": 4, - "z": 40 - } + "Radius": 20 } }, "CorePointId": 0, @@ -2856,11 +3594,11 @@ "Id": "d6564897-4b3e-4b7e-9b56-34cb3b9a235d", "Infiltration": "Factory", "Position": { - "x": -5.769, - "y": -3.905, - "z": -20.331 + "x": 18.6309986, + "y": -2.668999, + "z": -13.999999 }, - "Rotation": 84.01993, + "Rotation": 119.999939, "Sides": ["All"] }, { @@ -3012,11 +3750,63 @@ "Id": "e0f65b5b-c67b-4e15-a102-f92bbdf95f65", "Infiltration": "Factory", "Position": { - "x": 68.472, - "y": 0.194, - "z": -7.34 + "x": 15.502, + "y": 4.571, + "z": 36.609 }, - "Rotation": 184.931458, + "Rotation": 0, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "e1be22a2-9bba-40b5-a546-3bf6268b60cf", + "Infiltration": "Factory", + "Position": { + "x": 57.079, + "y": -2.63900042, + "z": 7.11500025 + }, + "Rotation": 288.1994, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "e1dbe2e4-626f-4205-b71e-5f640eb764ac", + "Infiltration": "Factory", + "Position": { + "x": 3.709, + "y": -2.639, + "z": 48.036 + }, + "Rotation": 344.457062, "Sides": ["All"] }, { @@ -3064,11 +3854,11 @@ "Id": "e5cd7bad-0f60-4cc2-bdd9-8a8943232b01", "Infiltration": "Factory", "Position": { - "x": -25.718, - "y": 1.07, - "z": 65.627 + "x": -22.174, + "y": 2.729, + "z": 29.192 }, - "Rotation": 263.74, + "Rotation": 89.99999, "Sides": ["All"] }, { @@ -3090,11 +3880,63 @@ "Id": "e60d8dce-ee35-4b30-9c3a-afddf4c5445e", "Infiltration": "Factory", "Position": { - "x": 21.389, - "y": -2.61, - "z": -1.214 + "x": 13.76, + "y": 1.1, + "z": 54.64 }, - "Rotation": 0, + "Rotation": 123.00354, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "ea010f6f-4860-4339-b576-09439f8f4c3a", + "Infiltration": "Factory", + "Position": { + "x": -5.58, + "y": -2.598, + "z": 14.757 + }, + "Rotation": 33.10973, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "eb5c4efc-759f-4ff9-8a73-8cd3eb0eca03", + "Infiltration": "Factory", + "Position": { + "x": 55.517, + "y": -2.63900042, + "z": 6.433 + }, + "Rotation": 300.7341, "Sides": ["All"] }, { @@ -3116,11 +3958,11 @@ "Id": "efb39132-1eff-4655-8fb0-d795f8f98eb3", "Infiltration": "Factory", "Position": { - "x": 29.409, - "y": 0.256, - "z": 20.577 + "x": 31.781, + "y": 0.119, + "z": 19.447 }, - "Rotation": 77.36217, + "Rotation": 271.344177, "Sides": ["All"] }, { @@ -3142,11 +3984,37 @@ "Id": "f0864450-ffa8-4d7e-aa93-59ea6b218641", "Infiltration": "Factory", "Position": { - "x": -19.789, - "y": 1.07, - "z": 66.592 + "x": -22.174, + "y": 2.729, + "z": 25.5719986 }, - "Rotation": 93.9956055, + "Rotation": 89.99999, + "Sides": ["All"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "f23f74fc-1c16-41b9-aeeb-0ca222222cbc", + "Infiltration": "Factory", + "Position": { + "x": -0.128999949, + "y": -2.639, + "z": 48.722 + }, + "Rotation": 50.8312836, "Sides": ["All"] }, { @@ -3194,11 +4062,11 @@ "Id": "f3c6d9ee-ca4e-44ca-abdf-0622a8249f1d", "Infiltration": "Factory", "Position": { - "x": -24.534, - "y": 1.07, - "z": 66.641 + "x": -22.174, + "y": 2.729, + "z": 31.529 }, - "Rotation": 263.74, + "Rotation": 89.99999, "Sides": ["All"] }, { @@ -3215,13 +4083,13 @@ "Radius": 41.97 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, "Id": "f6276290-95d6-4d35-9b1a-53e1db1c08ec", "Infiltration": "", "Position": { "x": 15, - "y": 0.148353577, + "y": 0.1483535, "z": 3.79 }, "Rotation": 232.964813, @@ -3279,6 +4147,32 @@ "Rotation": 3.0047307, "Sides": ["Pmc"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "feea31cd-8a3f-43a5-839f-fd2276a2cce8", + "Infiltration": "Factory", + "Position": { + "x": 61.5259972, + "y": -2.63900042, + "z": 6.418 + }, + "Rotation": 24.9815483, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -3332,7 +4226,7 @@ "Sides": ["Savage"] } ], - "UnixDateTime": 1707142653, + "UnixDateTime": 1621511450, "_Id": "55f2d3fd4bdc2d5f408b4567", "doors": [], "exit_access_time": 60, @@ -3342,7 +4236,6 @@ { "Chance": 100, "ChancePVE": 100, - "Count": 0, "CountPVE": 0, "EntryPoints": "Factory", "EventAvailable": false, @@ -3360,7 +4253,6 @@ { "Chance": 100, "ChancePVE": 100, - "Count": 0, "CountPVE": 0, "EntryPoints": "Factory", "EventAvailable": false, @@ -3378,7 +4270,6 @@ { "Chance": 100, "ChancePVE": 100, - "Count": 0, "CountPVE": 0, "EntryPoints": "Factory", "EventAvailable": false, @@ -3396,7 +4287,6 @@ { "Chance": 100, "ChancePVE": 100, - "Count": 0, "CountPVE": 0, "EntryPoints": "Factory", "EventAvailable": false, @@ -3410,19 +4300,77 @@ "Name": "Gate m", "PlayersCount": 0, "PlayersCountPVE": 0 + }, + { + "Chance": 100, + "ChancePVE": 100, + "CountPVE": 0, + "EntryPoints": "Factory", + "EventAvailable": false, + "ExfiltrationTime": 10, + "ExfiltrationTimePVE": 10, + "Id": "", + "MaxTime": 0, + "MaxTimePVE": 0, + "MinTime": 0, + "MinTimePVE": 0, + "Name": "Gate_o", + "PlayersCount": 0, + "PlayersCountPVE": 0 } ], "filter_ex": [], - "limits": [], + "limits": [ + { + "items": ["634959225289190e5e773b3b"], + "max": 4, + "min": 3 + } + ], "matching_min_seconds": 45, "maxItemCountInLocation": [ { - "TemplateId": "54009119af1c881c07000029", - "Value": 0 + "TemplateId": "634959225289190e5e773b3b", + "Value": 5 } ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "FAC_TRANSIT_12_COND", + "description": "FAC_TRANSIT_12_DESC", + "id": 12, + "location": "Woods", + "name": "FAC_TRANSIT_12", + "target": "5704e3c2d2720bac5b8b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "FAC_TRANSIT_13_COND", + "description": "FAC_TRANSIT_13_DESC", + "id": 13, + "location": "bigmap", + "name": "FAC_TRANSIT_13", + "target": "56f40101d2720b2a4d8b45d6", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "FAC_TRANSIT_14_COND", + "description": "FAC_TRANSIT_14_DESC", + "id": 14, + "location": "laboratory", + "name": "FAC_TRANSIT_14", + "target": "5b0fc42d86f7744a585f9105", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 180, @@ -3431,6 +4379,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": false, @@ -3443,18 +4392,20 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": false, "number": 1, "slots_max": 4, - "slots_min": 1, + "slots_min": 2, "time_max": -1, "time_min": -1 }, { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": true, @@ -3467,6 +4418,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": true, @@ -3479,6 +4431,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": true, @@ -3491,6 +4444,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": true, @@ -3503,6 +4457,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": false, @@ -3515,6 +4470,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "BotZone", "WildSpawnType": "assault", "isPlayers": false, diff --git a/external-resources/maps/groundzero.json b/external-resources/maps/groundzero.json index 328ce48c..e31fa2cb 100644 --- a/external-resources/maps/groundzero.json +++ b/external-resources/maps/groundzero.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 100, @@ -18,23 +19,194 @@ "AveragePlayTime": 35, "AveragePlayerLevel": 20, "Banners": [], - "BossLocationSpawn": [], + "BossLocationSpawn": [ + { + "BossChance": 50, + "BossDifficult": "easy", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "easy", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "easy", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "easy", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "easy", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "easy", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "easy", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "easy", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + } + ], "BotAssault": 100, "BotEasy": 100, "BotHard": 0, "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 35, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 50, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 50, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 35, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], + "DistToActivate": 260, + "DistToActivatePvE": 260, + "DistToSleep": 300, + "DistToSleepPvE": 300, "GainSight": 1, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1500, + "MinExfiltrationTime": 1200, "Scattering": 1, "VisibleDistance": 1 }, "BotMarksman": 0, - "BotMax": 20, - "BotMaxPlayer": 0, + "BotMax": 12, + "BotMaxPlayer": 10, "BotMaxPvE": 20, - "BotMaxTimePlayer": 0, + "BotMaxTimePlayer": 1000, "BotNormal": 0, "BotSpawnCountStep": 3, "BotSpawnPeriodCheck": 14, @@ -43,7 +215,7 @@ "BotSpawnTimeOnMax": 380, "BotSpawnTimeOnMin": 290, "BotStart": 120, - "BotStartPlayer": 0, + "BotStartPlayer": 126, "BotStop": 1800, "Description": "The downtown Tarkov with banks, malls, hotels and all the other things a striving modern city could have needed.", "DisabledForScav": false, @@ -53,15 +225,93 @@ "EscapeTimeLimit": 35, "EscapeTimeLimitCoop": 30, "EscapeTimeLimitPVE": 35, - "ExitZones": { - "$oid": "5c82534488a45046451a2386" + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 20 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 80 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 5 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 35 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 60 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 150, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 100, + "ZombieMultiplier": 5 + } }, + "ExitZones": "5c82534488a45046451a2386", + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.72, + "GlobalLootChanceModifier": 0.34, "GlobalLootChanceModifierPvE": 0.72, "IconX": 760, - "IconY": 740, + "IconY": 735, "Id": "Sandbox", "Insurance": true, "IsSecret": false, @@ -108,6 +358,7 @@ "MinPlayers": 9, "Name": "Sandbox", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -116,8 +367,8 @@ }, "OcculsionCullingEnabled": false, "OfflineNewSpawn": true, - "OfflineOldSpawn": false, - "OldSpawn": false, + "OfflineOldSpawn": true, + "OldSpawn": true, "OpenZones": "", "PlayersRequestCount": -1, "PmcMaxPlayersInGroup": 5, @@ -4936,7 +5187,7 @@ "Sides": ["Savage"] } ], - "UnixDateTime": 1707141759, + "UnixDateTime": 1621511450, "_Id": "653e6760052c01c1c805532f", "doors": [], "exit_access_time": 35, @@ -5060,178 +5311,33 @@ "matching_min_seconds": 60, "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "SAN_TRANSIT_1_COND", + "description": "SAN_TRANSIT_1_DESC", + "id": 1, + "location": "TarkovStreets", + "name": "SAN_TRANSIT_1", + "target": "5714dc692459777137212e12", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": false, + "conditions": "SAN_TRANSIT_2_COND", + "description": "SAN_TRANSIT_2_DESC", + "id": 2, + "location": "laboratory", + "name": "SAN_TRANSIT_2", + "target": "5b0fc42d86f7744a585f9105", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [ - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneSW00", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 4, - "slots_min": 3, - "time_max": 10, - "time_min": 1 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 1, - "slots_max": 4, - "slots_min": 2, - "time_max": 10, - "time_min": 1 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 2, - "slots_max": 4, - "slots_min": 2, - "time_max": 30, - "time_min": 10 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 3, - "slots_max": 4, - "slots_min": 2, - "time_max": 40, - "time_min": 15 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandSnipeCenter", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 4, - "slots_max": 1, - "slots_min": 1, - "time_max": 100, - "time_min": 1 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 5, - "slots_max": 5, - "slots_min": 2, - "time_max": 60, - "time_min": 20 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandSnipeCenter", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 6, - "slots_max": 1, - "slots_min": 1, - "time_max": 120, - "time_min": 1 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 7, - "slots_max": 3, - "slots_min": 2, - "time_max": 90, - "time_min": 40 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandSnipeCenter", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 8, - "slots_max": 1, - "slots_min": 1, - "time_max": 120, - "time_min": 1 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandSnipeCenter", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 9, - "slots_max": 1, - "slots_min": 1, - "time_max": 120, - "time_min": 1 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 10, - "slots_max": 4, - "slots_min": 1, - "time_max": 90, - "time_min": 30 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 11, - "slots_max": 4, - "slots_min": 1, - "time_max": 100, - "time_min": 50 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 12, - "slots_max": 3, - "slots_min": 2, - "time_max": 110, - "time_min": 70 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSandbox", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 13, - "slots_max": 4, - "slots_min": 2, - "time_max": 120, - "time_min": 90 - } - ] + "waves": [] } diff --git a/external-resources/maps/interchange.json b/external-resources/maps/interchange.json index 829af0c8..e5b927cc 100644 --- a/external-resources/maps/interchange.json +++ b/external-resources/maps/interchange.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 100, @@ -42,7 +43,7 @@ ], "BossLocationSpawn": [ { - "BossChance": 35, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "0", "BossEscortDifficult": "normal", @@ -59,6 +60,120 @@ "Time": -1, "TriggerId": "", "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" } ], "BotAssault": 100, @@ -67,17 +182,119 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], + "DistToActivate": 260, + "DistToActivatePvE": 260, "DistToPersueAxemanCoef": 1, + "DistToSleep": 300, + "DistToSleepPvE": 300, "GainSight": 1, "KhorovodChance": 0, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1800, + "MinExfiltrationTime": 1200, "Scattering": 1, "VisibleDistance": 1 }, "BotMarksman": 0, - "BotMax": 19, + "BotMax": 22, "BotMaxPlayer": 10, - "BotMaxPvE": 32, + "BotMaxPvE": 30, "BotMaxTimePlayer": 1000, "BotNormal": 50, "BotSpawnCountStep": 4, @@ -87,7 +304,7 @@ "BotSpawnTimeOnMax": 350, "BotSpawnTimeOnMin": 340, "BotStart": 20, - "BotStartPlayer": 0, + "BotStartPlayer": 200, "BotStop": 2400, "Description": "The South-Eastern highway interchange is a critical point in the transportation system of the city. Essentially, it is a strategical node connecting the port and harbour infrastructure with the industrial outskirts of Tarkov. ", "DisabledForScav": false, @@ -97,9 +314,89 @@ "EscapeTimeLimit": 40, "EscapeTimeLimitCoop": 30, "EscapeTimeLimitPVE": 40, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 200, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 125, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.74, + "GlobalLootChanceModifier": 0.35, "GlobalLootChanceModifierPvE": 0.74, "IconX": 660, "IconY": 360, @@ -149,6 +446,7 @@ "MinPlayers": 10, "Name": "Interchange", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -157,8 +455,8 @@ }, "OcculsionCullingEnabled": true, "OfflineNewSpawn": true, - "OfflineOldSpawn": false, - "OldSpawn": false, + "OfflineOldSpawn": true, + "OldSpawn": true, "OpenZones": "ZoneCenter,ZoneCenterBot,ZoneOLI,ZoneIDEA,ZoneRoad,ZoneIDEAPark,ZoneGoshan,ZonePowerStation,ZoneTrucks,ZoneOLIPark", "PlayersRequestCount": -1, "PmcMaxPlayersInGroup": 5, @@ -6248,313 +6546,41 @@ "filter_ex": [], "limits": [], "matching_min_seconds": 60, - "maxItemCountInLocation": [], + "maxItemCountInLocation": [ + { + "TemplateId": "634959225289190e5e773b3b", + "Value": 7 + } + ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "INT_TRANSIT_6_COND", + "description": "INT_TRANSIT_6_DESC", + "id": 6, + "location": "bigmap", + "name": "INT_TRANSIT_6", + "target": "56f40101d2720b2a4d8b45d6", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "INT_TRANSIT_7_COND", + "description": "INT_TRANSIT_7_DESC", + "id": 7, + "location": "TarkovStreets", + "name": "INT_TRANSIT_7", + "target": "5714dc692459777137212e12", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [ - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneCenter", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 1, - "slots_min": 0, - "time_max": 11, - "time_min": 1 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneCenterBot", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 1, - "slots_max": 1, - "slots_min": 0, - "time_max": 30, - "time_min": 10 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneOLI", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 2, - "slots_max": 3, - "slots_min": 1, - "time_max": 120, - "time_min": 30 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneIDEA", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 3, - "slots_max": 1, - "slots_min": 0, - "time_max": 150, - "time_min": 120 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneRoad", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 4, - "slots_max": 1, - "slots_min": 0, - "time_max": 180, - "time_min": 150 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneIDEAPark", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 5, - "slots_max": 2, - "slots_min": 1, - "time_max": 250, - "time_min": 180 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneGoshan", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 6, - "slots_max": 1, - "slots_min": 0, - "time_max": 300, - "time_min": 250 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZonePowerStation", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 7, - "slots_max": 1, - "slots_min": 0, - "time_max": 400, - "time_min": 300 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneTrucks", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 8, - "slots_max": 3, - "slots_min": 1, - "time_max": 500, - "time_min": 300 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneCenterBot", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 9, - "slots_max": 1, - "slots_min": 0, - "time_max": 700, - "time_min": 500 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneRoad", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 10, - "slots_max": 1, - "slots_min": 0, - "time_max": 700, - "time_min": 600 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneCenter", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 11, - "slots_max": 2, - "slots_min": 1, - "time_max": 750, - "time_min": 700 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "ZoneIDEAPark", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 12, - "slots_max": 1, - "slots_min": 0, - "time_max": 800, - "time_min": 750 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneIDEA", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 13, - "slots_max": 1, - "slots_min": 0, - "time_max": 900, - "time_min": 800 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneGoshan", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 14, - "slots_max": 3, - "slots_min": 1, - "time_max": 1200, - "time_min": 900 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneOLI", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 15, - "slots_max": 1, - "slots_min": 0, - "time_max": 600, - "time_min": 200 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 16, - "slots_max": 1, - "slots_min": 0, - "time_max": 1800, - "time_min": 800 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 17, - "slots_max": 2, - "slots_min": 1, - "time_max": 1100, - "time_min": 1000 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 18, - "slots_max": 1, - "slots_min": 0, - "time_max": 1200, - "time_min": 1000 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 19, - "slots_max": 1, - "slots_min": 0, - "time_max": 1300, - "time_min": 1200 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 20, - "slots_max": 3, - "slots_min": 1, - "time_max": 1500, - "time_min": 1300 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 21, - "slots_max": 1, - "slots_min": 0, - "time_max": 1700, - "time_min": 1500 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 22, - "slots_max": 1, - "slots_min": 0, - "time_max": 1800, - "time_min": 1700 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 23, - "slots_max": 2, - "slots_min": 1, - "time_max": 3000, - "time_min": 1800 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 24, - "slots_max": 2, - "slots_min": 0, - "time_max": 3100, - "time_min": 3000 - } - ] + "waves": [] } diff --git a/external-resources/maps/laboratory.json b/external-resources/maps/laboratory.json index 70205dbf..3853c7db 100644 --- a/external-resources/maps/laboratory.json +++ b/external-resources/maps/laboratory.json @@ -1,5 +1,6 @@ { "AccessKeys": ["5c94bbff86f7747ee735c08f"], + "AccessKeysPvE": ["5c94bbff86f7747ee735c08f"], "Area": 0, "AveragePlayTime": 30, "AveragePlayerLevel": 45, @@ -44,8 +45,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor1", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 900, "TriggerId": "", "TriggerName": "" @@ -60,8 +63,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor2", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 300, "TriggerId": "", "TriggerName": "" @@ -76,8 +81,10 @@ "BossPlayer": false, "BossZone": "BotZoneBasement", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 450, "TriggerId": "autoId_00008_EXFIL", "TriggerName": "interactObject" @@ -92,8 +99,10 @@ "BossPlayer": false, "BossZone": "BotZoneBasement", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 800, "TriggerId": "autoId_00010_EXFIL", "TriggerName": "interactObject" @@ -108,8 +117,10 @@ "BossPlayer": false, "BossZone": "BotZoneBasement", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00007_EXFIL", "TriggerName": "interactObject" @@ -124,8 +135,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor2", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00007_EXFIL", "TriggerName": "interactObject" @@ -140,8 +153,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor1", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 600, "TriggerId": "autoId_00632_EXFIL", "TriggerName": "interactObject" @@ -156,8 +171,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor2", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 600, "TriggerId": "autoId_00632_EXFIL", "TriggerName": "interactObject" @@ -172,8 +189,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor1", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00012_EXFIL", "TriggerName": "interactObject" @@ -188,8 +207,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor2", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00012_EXFIL", "TriggerName": "interactObject" @@ -204,8 +225,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor1", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 1200, "TriggerId": "autoId_00014_EXFIL", "TriggerName": "interactObject" @@ -220,8 +243,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor2", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": 1200, "TriggerId": "autoId_00014_EXFIL", "TriggerName": "interactObject" @@ -236,8 +261,10 @@ "BossPlayer": false, "BossZone": "BotZoneFloor1", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00009_EXFIL", "TriggerName": "interactObject" @@ -252,14 +279,16 @@ "BossPlayer": false, "BossZone": "BotZoneFloor2", "Delay": 0, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00009_EXFIL", "TriggerName": "interactObject" }, { - "BossChance": 40, + "BossChance": 35, "BossDifficult": "normal", "BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3", "BossEscortDifficult": "normal", @@ -268,8 +297,10 @@ "BossPlayer": false, "BossZone": "BotZoneGate2", "Delay": 8, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00014_EXFIL", "TriggerName": "interactObject" @@ -284,11 +315,85 @@ "BossPlayer": false, "BossZone": "BotZoneGate1", "Delay": 8, + "IgnoreMaxBots": false, "RandomTimeSpawn": false, "SpawnMode": ["regular", "pve"], + "Supports": null, "Time": -1, "TriggerId": "autoId_00632_EXFIL", "TriggerName": "interactObject" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "BotZoneFloor1", + "Delay": 0, + "IgnoreMaxBots": false, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "BotZoneFloor2", + "Delay": 0, + "IgnoreMaxBots": false, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "BotZoneFloor1", + "Delay": 0, + "IgnoreMaxBots": false, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "BotZoneFloor2", + "Delay": 0, + "IgnoreMaxBots": false, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" } ], "BotAssault": 100, @@ -297,18 +402,118 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 100, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 100, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 100, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 100, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 140, + "DistToActivatePvE": 140, "DistToPersueAxemanCoef": 1, "DistToSleep": 160, + "DistToSleepPvE": 160, "GainSight": 1, "KhorovodChance": 0, "MagnetPower": 10, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1800, + "MinExfiltrationTime": 1200, "Scattering": 1, "VisibleDistance": 1 }, "BotMarksman": 0, - "BotMax": 14, + "BotMax": 15, "BotMaxPlayer": 14, "BotMaxPvE": 25, "BotMaxTimePlayer": 1000, @@ -329,10 +534,90 @@ "Enabled": true, "EscapeTimeLimit": 35, "EscapeTimeLimitCoop": 30, - "EscapeTimeLimitPVE": 27, + "EscapeTimeLimitPVE": 35, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 22 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 90 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 60 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 23 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 75 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 13, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 40, + "TargetPointSearchRadiusLimit": 80, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 50, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.77, + "GlobalLootChanceModifier": 0.33, "GlobalLootChanceModifierPvE": 0.77, "IconX": 700, "IconY": 800, @@ -382,6 +667,7 @@ "MinPlayers": 8, "Name": "Laboratory", "NewSpawn": false, + "NewSpawnForPlayers": false, "NonWaveGroupScenario": { "Chance": 50, "Enabled": false, @@ -461,32 +747,6 @@ "Rotation": 88.9786758, "Sides": ["All"] }, - { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 27 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "0171ec0f-4050-4303-8504-b742922cf80b", - "Infiltration": "", - "Position": { - "x": -255.632, - "y": 4.146, - "z": -376.374 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -643,58 +903,6 @@ "Rotation": 270.60022, "Sides": ["Pmc"] }, - { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 35 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "04f71bcb-922f-48bc-992b-3a64a20d589c", - "Infiltration": "", - "Position": { - "x": -178.15, - "y": 0.114, - "z": -415.292 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 35 - } - }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "07863ac5-27c5-4001-85a2-13356eda6133", - "Infiltration": "", - "Position": { - "x": -116.4, - "y": 0.004, - "z": -256.52 - }, - "Rotation": 263.038635, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -748,8 +956,8 @@ "Sides": ["All"] }, { - "BotZoneName": "BotZoneGate1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -758,24 +966,24 @@ "y": 0, "z": 0 }, - "Radius": 7 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0b5e336a-2cb6-4619-b9a5-07ff0afad1ee", - "Infiltration": "", + "Id": "0d7728c8-59c8-493a-8849-fa22a1346fcd", + "Infiltration": "Common", "Position": { - "x": -183.645, - "y": 2.711, - "z": -227.118988 + "x": -254.79, + "y": -4.03, + "z": -298.46 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 185.57, + "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -784,20 +992,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "0d7728c8-59c8-493a-8849-fa22a1346fcd", - "Infiltration": "Common", + "Id": "0e00d2de-8c18-4b98-a5b2-9d5d6db335e6", + "Infiltration": "", "Position": { - "x": -254.79, - "y": -4.03, - "z": -298.46 + "x": -279.23, + "y": 0.078, + "z": -349.22998 }, - "Rotation": 185.57, - "Sides": ["All"] + "Rotation": 126.849854, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -878,8 +1086,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -888,24 +1096,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "13ea441c-75e5-48a2-9d87-396590d9bc98", - "Infiltration": "Common", + "Id": "12caf244-967e-4bc8-9900-e66d2f1bb4b0", + "Infiltration": "", "Position": { - "x": -276.29, - "y": -3.99, - "z": -362.3 + "x": -179.44, + "y": 0.114, + "z": -407.409973 }, - "Rotation": 92.55, - "Sides": ["All"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -914,20 +1122,20 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 50 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "15c0ac46-c1e4-498b-9466-1c071554be06", - "Infiltration": "", + "Id": "13ea441c-75e5-48a2-9d87-396590d9bc98", + "Infiltration": "Common", "Position": { - "x": -116.011, - "y": 0.036, - "z": -336.378 + "x": -276.29, + "y": -3.99, + "z": -362.3 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 92.55, + "Sides": ["All"] }, { "BotZoneName": "", @@ -1008,8 +1216,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1018,21 +1226,47 @@ "y": 0, "z": 0 }, - "Radius": 27 + "Radius": 35 } }, - "CorePointId": 5, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "19e75b93-4470-4d65-b5f8-e3a09fb4a71d", + "Id": "1a9ca4f6-edea-4a52-9b99-162ad016e81d", "Infiltration": "", "Position": { - "x": -127.768, - "y": 4.2, - "z": -382.271973 + "x": -260.287, + "y": 0.04, + "z": -390.578 }, "Rotation": 0, "Sides": ["Savage"] }, + { + "BotZoneName": "BotZoneGate1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 7 + } + }, + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "1ad2a57c-64ff-4c87-961b-8a1226cdaf36", + "Infiltration": "", + "Position": { + "x": -157.568, + "y": 2.711, + "z": -222.756989 + }, + "Rotation": 201.596924, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -1164,8 +1398,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneGate2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1174,21 +1408,47 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 7 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "242085cb-6ffa-4aa5-8268-dc8b138c7b74", - "Infiltration": "Common", + "Id": "24169507-5cd9-42d3-9944-4345f96fe01e", + "Infiltration": "", "Position": { - "x": -118.503, - "y": -4.025, - "z": -399.522 + "x": -244.976, + "y": 2.664, + "z": -448.615 }, - "Rotation": 88.9786758, - "Sides": ["All"] - }, + "Rotation": 181.596954, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "242085cb-6ffa-4aa5-8268-dc8b138c7b74", + "Infiltration": "Common", + "Position": { + "x": -118.503, + "y": -4.025, + "z": -399.522 + }, + "Rotation": 88.9786758, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1215,6 +1475,32 @@ "Rotation": 270.47, "Sides": ["All"] }, + { + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 27 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "2535f603-e3ed-4e23-8765-4c1c9ddc8c08", + "Infiltration": "", + "Position": { + "x": -208.019, + "y": 4.207, + "z": -297.85498 + }, + "Rotation": 113.883675, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -1293,6 +1579,84 @@ "Rotation": 181.81, "Sides": ["All"] }, + { + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 27 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "2b1ad2d6-7e44-4282-b557-ac0c72cca19a", + "Infiltration": "", + "Position": { + "x": -255.632, + "y": 4.146, + "z": -376.374 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 27 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "2c447dc9-2865-4803-bb14-2302b3890a9c", + "Infiltration": "", + "Position": { + "x": -253.55899, + "y": 4.146, + "z": -376.292 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 35 + } + }, + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "2dfb3a5d-9977-4697-812b-288e9ba36357", + "Infiltration": "", + "Position": { + "x": -226.68, + "y": 0.082, + "z": -279.617 + }, + "Rotation": 164.3535, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1345,9 +1709,35 @@ "Rotation": 89.61, "Sides": ["All"] }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "35beb4da-36a6-48e3-bbd1-810126872d3c", + "Infiltration": "Common", + "Position": { + "x": -172.66, + "y": 0.08, + "z": -264.14 + }, + "Rotation": 175.539871, + "Sides": ["Pmc"] + }, { "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1359,21 +1749,21 @@ "Radius": 35 } }, - "CorePointId": 7, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "330b076f-bd90-494d-8c3d-bed9e5959378", + "Id": "35f11413-d269-4cf0-b9dc-2ea7f0bbdbf3", "Infiltration": "", "Position": { - "x": -202.231, - "y": 0.0499999523, - "z": -393.883972 + "x": -279.68, + "y": 0.078, + "z": -352.99 }, - "Rotation": 0, + "Rotation": 126.849854, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "BotZoneBasement", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1382,20 +1772,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, - "CorePointId": 0, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "35beb4da-36a6-48e3-bbd1-810126872d3c", - "Infiltration": "Common", + "Id": "35fd4e75-132a-4ff0-b208-49d150bb5bc1", + "Infiltration": "", "Position": { - "x": -172.66, - "y": 0.08, - "z": -264.14 + "x": -128.38, + "y": -4.041, + "z": -417.949982 }, - "Rotation": 175.539871, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1423,9 +1813,35 @@ "Rotation": 3.2020905, "Sides": ["Pmc"] }, + { + "BotZoneName": "BotZoneGate2", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 7 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "3ac16ebd-106a-4357-8410-da375bbe07bd", + "Infiltration": "", + "Position": { + "x": -218.066, + "y": 2.664, + "z": -448.59198 + }, + "Rotation": 181.596954, + "Sides": ["Savage"] + }, { "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1437,14 +1853,14 @@ "Radius": 35 } }, - "CorePointId": 3, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "3a7f4c28-ea1f-466d-8920-3f2871d69cf3", + "Id": "3b4c3c07-59e9-4ff1-9a22-bbd0665d09c3", "Infiltration": "", "Position": { - "x": -260.287, - "y": 0.04, - "z": -390.578 + "x": -202.231, + "y": 0.0499999523, + "z": -393.883972 }, "Rotation": 0, "Sides": ["Savage"] @@ -1476,8 +1892,8 @@ "Sides": ["All"] }, { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1486,24 +1902,24 @@ "y": 0, "z": 0 }, - "Radius": 27 + "Radius": 50 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "3dbca587-2589-4370-9594-407655be3186", - "Infiltration": "", + "Id": "40b7da99-8f93-4ca6-bb33-c94b8a7c92a7", + "Infiltration": "Common", "Position": { - "x": -134.355011, - "y": 4.181, - "z": -341.102 + "x": -264.74, + "y": -3.99, + "z": -390.32 }, - "Rotation": 273.155945, - "Sides": ["Savage"] + "Rotation": 15.050004, + "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1512,20 +1928,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "40b7da99-8f93-4ca6-bb33-c94b8a7c92a7", - "Infiltration": "Common", + "Id": "461de8d5-6efe-4d47-8833-4298d14d5dc0", + "Infiltration": "", "Position": { - "x": -264.74, - "y": -3.99, - "z": -390.32 + "x": -279.611, + "y": 0.078, + "z": -365.445984 }, - "Rotation": 15.050004, - "Sides": ["All"] + "Rotation": 197.191254, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1606,8 +2022,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1616,24 +2032,24 @@ "y": 0, "z": 0 }, - "Radius": 27 + "Radius": 35 } }, - "CorePointId": 4, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "4cd0a70e-8349-4707-b3f6-4b0d18cf989b", + "Id": "4f5d267c-f86b-4cde-ba2c-1558f6be7279", "Infiltration": "", "Position": { - "x": -207.064, - "y": 4.207, - "z": -295.159 + "x": -205.29, + "y": 0.0499999523, + "z": -390.55 }, - "Rotation": 113.883675, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1642,19 +2058,19 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 27 } }, - "CorePointId": 3, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "4e9cd17c-ae56-4408-a308-4b9722e6e344", + "Id": "4f8abb15-998a-47ff-9352-84e5be19f44b", "Infiltration": "", "Position": { - "x": -257.955017, - "y": 0.0090277195, - "z": -385.453 + "x": -134.355011, + "y": 4.181, + "z": -341.102 }, - "Rotation": 184.764816, + "Rotation": 273.155945, "Sides": ["Savage"] }, { @@ -1684,86 +2100,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 35 - } - }, - "CorePointId": 5, - "DelayToCanSpawnSec": 4, - "Id": "50bda7e6-480e-412c-a91c-8dda1faffa45", - "Infiltration": "", - "Position": { - "x": -116.089, - "y": 0.036, - "z": -339.412 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 35 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "51d82d49-97b2-4fba-b1f8-219b20005c17", - "Infiltration": "", - "Position": { - "x": -205.29, - "y": 0.0499999523, - "z": -390.55 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "BotZoneGate2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 7 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "52005238-4fb5-4775-9052-c1f52bfd1c94", - "Infiltration": "", - "Position": { - "x": -244.101, - "y": 2.664, - "z": -452.923981 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1772,19 +2110,19 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 27 } }, - "CorePointId": 8, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "584031bc-1dbb-4fec-a95f-7297e0b6a540", + "Id": "53f65149-ac7d-453a-8536-364911b6a114", "Infiltration": "", "Position": { - "x": -213.124, - "y": 0.05, - "z": -378.754974 + "x": -199.41, + "y": 4.127, + "z": -296.5 }, - "Rotation": 0, + "Rotation": 85.5867, "Sides": ["Savage"] }, { @@ -1943,6 +2281,32 @@ "Rotation": 72.84, "Sides": ["All"] }, + { + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 35 + } + }, + "CorePointId": 8, + "DelayToCanSpawnSec": 4, + "Id": "606fbd9c-1111-4536-99cb-79b9c2479593", + "Infiltration": "", + "Position": { + "x": -213.124, + "y": 0.05, + "z": -378.754974 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2058,46 +2422,20 @@ "y": 0, "z": 0 }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "666b38f8-c232-4b2e-994e-ead3b121990c", - "Infiltration": "Common", - "Position": { - "x": -219.433, - "y": -3.997, - "z": -383.072 - }, - "Rotation": 270.60022, - "Sides": ["All"] - }, - { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 27 + "Radius": 50 } }, - "CorePointId": 8, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "66d2a253-d1a0-490c-93d3-b1e3dd589c3d", - "Infiltration": "", + "Id": "666b38f8-c232-4b2e-994e-ead3b121990c", + "Infiltration": "Common", "Position": { - "x": -248.84, - "y": 4.231, - "z": -362.24 + "x": -219.433, + "y": -3.997, + "z": -383.072 }, - "Rotation": 175.868637, - "Sides": ["Savage"] + "Rotation": 270.60022, + "Sides": ["All"] }, { "BotZoneName": "", @@ -2204,8 +2542,8 @@ "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2214,24 +2552,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "6e2cf61e-85a6-4cfa-b232-ae4cd892e4e0", - "Infiltration": "Common", + "Id": "6b60909d-5251-4149-ae99-2e5fd8204f23", + "Infiltration": "", "Position": { - "x": -115.67, - "y": 0.01, - "z": -256.94 + "x": -116.4, + "y": 0.004, + "z": -256.52 }, - "Rotation": 188.05, - "Sides": ["All"] + "Rotation": 263.038635, + "Sides": ["Savage"] }, { - "BotZoneName": "BotZoneGate2", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2240,20 +2578,20 @@ "y": 0, "z": 0 }, - "Radius": 7 + "Radius": 50 } }, - "CorePointId": 3, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6e35cbe7-b819-40df-9262-656d3ac42a31", - "Infiltration": "", + "Id": "6e2cf61e-85a6-4cfa-b232-ae4cd892e4e0", + "Infiltration": "Common", "Position": { - "x": -215.217, - "y": 2.664, - "z": -448.71 + "x": -115.67, + "y": 0.01, + "z": -256.94 }, - "Rotation": 181.596954, - "Sides": ["Savage"] + "Rotation": 188.05, + "Sides": ["All"] }, { "BotZoneName": "", @@ -2308,8 +2646,8 @@ "Sides": ["All"] }, { - "BotZoneName": "BotZoneBasement", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2318,24 +2656,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 35 } }, - "CorePointId": 5, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "75a36d48-cf3e-48f6-98cd-ca520bf8ff2d", + "Id": "71528dc9-436b-4b2f-9cd0-86e843178faa", "Infiltration": "", "Position": { - "x": -128.38, - "y": -4.041, - "z": -417.949982 + "x": -257.955017, + "y": 0.0090277195, + "z": -385.453 }, - "Rotation": 0, + "Rotation": 184.764816, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2344,24 +2682,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "75febbcd-6f56-495e-a74a-e93f0f8b7827", - "Infiltration": "Common", + "Id": "74619df7-5a9c-40a0-8558-f7eec50cf388", + "Infiltration": "", "Position": { - "x": -269.34, - "y": -2.06, - "z": -387.7 + "x": -178.15, + "y": 0.114, + "z": -415.292 }, - "Rotation": 90.05, - "Sides": ["All"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneGate2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2370,21 +2708,47 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 7 } }, - "CorePointId": 4, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "7716a644-0c23-4f0b-9613-b9fc4767ba35", + "Id": "747f2875-8f64-4629-94f3-71321cf8d00e", "Infiltration": "", "Position": { - "x": -231.636, - "y": 0.082, - "z": -286.69397 + "x": -245.28, + "y": 2.664, + "z": -452.873 }, - "Rotation": 164.3535, + "Rotation": 0, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "75febbcd-6f56-495e-a74a-e93f0f8b7827", + "Infiltration": "Common", + "Position": { + "x": -269.34, + "y": -2.06, + "z": -387.7 + }, + "Rotation": 90.05, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -2437,6 +2801,32 @@ "Rotation": 348.83, "Sides": ["All"] }, + { + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 35 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "7af1c11a-5946-4356-add6-409b9c7d54be", + "Infiltration": "", + "Position": { + "x": -279.611, + "y": 0.078, + "z": -365.445984 + }, + "Rotation": 197.191254, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2490,8 +2880,8 @@ "Sides": ["All"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneGate1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2500,24 +2890,24 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 7 } }, - "CorePointId": 3, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "7eb7a024-be39-49ab-8a3c-82aecf4c1f95", + "Id": "7d2e52a2-4f79-4be7-8082-a59bba591c28", "Infiltration": "", "Position": { - "x": -279.611, - "y": 0.078, - "z": -365.445984 + "x": -183.645, + "y": 2.711, + "z": -227.118988 }, - "Rotation": 197.191254, + "Rotation": 0, "Sides": ["Savage"] }, { "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2529,21 +2919,21 @@ "Radius": 35 } }, - "CorePointId": 3, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "7ffdd6c9-29dc-43d3-8348-349bbf64c128", + "Id": "7e5708fe-ef38-4a0c-8525-356be4e04dc7", "Infiltration": "", "Position": { - "x": -279.611, - "y": 0.078, - "z": -365.445984 + "x": -184.597, + "y": 0.114, + "z": -416.456 }, - "Rotation": 197.191254, + "Rotation": 0, "Sides": ["Savage"] }, { "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2555,14 +2945,14 @@ "Radius": 35 } }, - "CorePointId": 7, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "81e2c355-e3dd-4a70-a076-0fea62aec9f1", + "Id": "7f166814-529e-46fd-8526-e7e1eea2af17", "Infiltration": "", "Position": { - "x": -184.597, - "y": 0.114, - "z": -416.456 + "x": -275.248, + "y": 0.078, + "z": -381.095978 }, "Rotation": 0, "Sides": ["Savage"] @@ -2594,8 +2984,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneBasement", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2604,24 +2994,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 50 } }, - "CorePointId": 3, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "8442480f-2fd2-4867-a558-7f95aa75211b", - "Infiltration": "", + "Id": "84fa5d1e-635b-439a-8f61-26eb2e37f36f", + "Infiltration": "Common", "Position": { - "x": -244.796, - "y": -4.001, - "z": -414.788 + "x": -237.693, + "y": 0.09, + "z": -418.472 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 3.2020905, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "BotZoneGate1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2630,20 +3020,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 7 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "84fa5d1e-635b-439a-8f61-26eb2e37f36f", - "Infiltration": "Common", + "Id": "85bdcb26-519e-464d-bc60-90c0d496cd25", + "Infiltration": "", "Position": { - "x": -237.693, - "y": 0.09, - "z": -418.472 + "x": -157.212, + "y": 2.711, + "z": -227.040985 }, - "Rotation": 3.2020905, - "Sides": ["Pmc"] + "Rotation": 324.67, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -2697,35 +3087,9 @@ "Rotation": 270.60022, "Sides": ["Pmc"] }, - { - "BotZoneName": "BotZoneGate2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 7 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "8ae99f32-2b96-4a1a-9ff6-62bbf3f452bb", - "Infiltration": "", - "Position": { - "x": -245.28, - "y": 2.664, - "z": -452.873 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2737,16 +3101,16 @@ "Radius": 27 } }, - "CorePointId": 3, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "8f0dd3c2-9339-484e-b4ed-785a7929a545", + "Id": "8ce350f3-7654-45b1-8e6e-5818c2686426", "Infiltration": "", "Position": { - "x": -253.55899, - "y": 4.146, - "z": -376.292 + "x": -207.064, + "y": 4.207, + "z": -295.159 }, - "Rotation": 0, + "Rotation": 113.883675, "Sides": ["Savage"] }, { @@ -3088,8 +3452,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneGate1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3098,24 +3462,24 @@ "y": 0, "z": 0 }, - "Radius": 7 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9dbe0dc5-6380-41d3-9798-75b98f89c8a8", - "Infiltration": "", + "Id": "a0fdcb82-40f8-4996-83e5-39389c6b846a", + "Infiltration": "Common", "Position": { - "x": -157.568, - "y": 2.711, - "z": -222.756989 + "x": -125.39, + "y": 4.13, + "z": -338.41 }, - "Rotation": 201.596924, - "Sides": ["Savage"] + "Rotation": 75.25, + "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneGate2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3124,20 +3488,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 7 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "a0fdcb82-40f8-4996-83e5-39389c6b846a", - "Infiltration": "Common", + "Id": "a273a838-1560-4423-8194-d95185114493", + "Infiltration": "", "Position": { - "x": -125.39, - "y": 4.13, - "z": -338.41 + "x": -215.217, + "y": 2.664, + "z": -448.71 }, - "Rotation": 75.25, - "Sides": ["All"] + "Rotation": 181.596954, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -3165,6 +3529,32 @@ "Rotation": 270.60022, "Sides": ["Pmc"] }, + { + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 35 + } + }, + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "a3789b1a-5689-4609-a15e-35ecb8910e6d", + "Infiltration": "", + "Position": { + "x": -116.089, + "y": 0.036, + "z": -339.412 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3192,8 +3582,8 @@ "Sides": ["All"] }, { - "BotZoneName": "BotZoneGate1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3202,24 +3592,24 @@ "y": 0, "z": 0 }, - "Radius": 7 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a66912bd-3583-4285-bb40-bf5a0bb2d7ad", - "Infiltration": "", + "Id": "a98ef4db-61cc-4588-a8e8-52e59ce8bace", + "Infiltration": "Common", "Position": { - "x": -184.359, - "y": 2.711, - "z": -222.758987 + "x": -205.847, + "y": 4.16135359, + "z": -289.085 }, - "Rotation": 151.039291, - "Sides": ["Savage"] + "Rotation": 89.0511551, + "Sides": ["All"] }, { - "BotZoneName": "BotZoneGate1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3228,24 +3618,24 @@ "y": 0, "z": 0 }, - "Radius": 7 + "Radius": 27 } }, - "CorePointId": 2, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "a7c8500d-3a45-4ab4-8bde-4891ebdb33be", + "Id": "a9cdf626-2906-405c-a39b-669cb741c98c", "Infiltration": "", "Position": { - "x": -157.212, - "y": 2.711, - "z": -227.040985 + "x": -248.84, + "y": 4.231, + "z": -362.24 }, - "Rotation": 324.67, + "Rotation": 175.868637, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3254,20 +3644,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 27 } }, - "CorePointId": 0, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "a98ef4db-61cc-4588-a8e8-52e59ce8bace", - "Infiltration": "Common", + "Id": "aa22008a-0429-4f85-9024-b6118b73a5d6", + "Infiltration": "", "Position": { - "x": -205.847, - "y": 4.16135359, - "z": -289.085 + "x": -134.647, + "y": 4.181, + "z": -346.005981 }, - "Rotation": 89.0511551, - "Sides": ["All"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -3295,32 +3685,6 @@ "Rotation": 53.9400024, "Sides": ["All"] }, - { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 35 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "ad4dd281-ed1d-4bbb-a15e-1b719c90fe8f", - "Infiltration": "", - "Position": { - "x": -179.44, - "y": 0.114, - "z": -407.409973 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -3374,8 +3738,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3384,24 +3748,24 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b25de2ee-d9fb-4c35-a73b-fe516b436d10", - "Infiltration": "", + "Id": "b71e139d-c363-4b9a-b87e-1a6bef552641", + "Infiltration": "Common", "Position": { - "x": -224.879, - "y": 0.082, - "z": -279.867 + "x": -170.49, + "y": 0.06, + "z": -419.39 }, - "Rotation": 164.3535, - "Sides": ["Savage"] + "Rotation": 349.64, + "Sides": ["All"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneGate1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3410,47 +3774,21 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 7 } }, - "CorePointId": 3, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "b53cfa11-2ce4-4a85-a3c2-674068472d58", + "Id": "b757f551-4421-436b-af49-91844c1b848f", "Infiltration": "", "Position": { - "x": -275.248, - "y": 0.078, - "z": -381.095978 + "x": -184.359, + "y": 2.711, + "z": -222.758987 }, - "Rotation": 0, + "Rotation": 151.039291, "Sides": ["Savage"] }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "b71e139d-c363-4b9a-b87e-1a6bef552641", - "Infiltration": "Common", - "Position": { - "x": -170.49, - "y": 0.06, - "z": -419.39 - }, - "Rotation": 349.64, - "Sides": ["All"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -3477,32 +3815,6 @@ "Rotation": 89.0511551, "Sides": ["All"] }, - { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 35 - } - }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "bb29ab56-4425-40e2-b133-8abc10c4fe39", - "Infiltration": "", - "Position": { - "x": -226.68, - "y": 0.082, - "z": -279.617 - }, - "Rotation": 164.3535, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -3552,38 +3864,12 @@ "y": 0.06, "z": -335.35 }, - "Rotation": 141.39, - "Sides": ["All"] - }, - { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 27 - } - }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "c18b92b0-7915-4e30-995e-e163bc06d9fb", - "Infiltration": "", - "Position": { - "x": -199.41, - "y": 4.127, - "z": -296.5 - }, - "Rotation": 85.5867, - "Sides": ["Savage"] + "Rotation": 141.39, + "Sides": ["All"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "BotZoneBasement", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3592,19 +3878,19 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 25 } }, - "CorePointId": 8, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "c260494b-0ace-42f0-9b3c-945cbb77d608", + "Id": "c1270e3a-65da-430f-9522-8bc2fecbfc63", "Infiltration": "", "Position": { - "x": -279.23, - "y": 0.078, - "z": -349.22998 + "x": -141.92, + "y": -4.041, + "z": -416.659973 }, - "Rotation": 126.849854, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -3685,32 +3971,6 @@ "Rotation": 270.60022, "Sides": ["Pmc"] }, - { - "BotZoneName": "BotZoneGate2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 7 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "c6928e60-e4ce-40db-94c3-8c84915366e2", - "Infiltration": "", - "Position": { - "x": -218.066, - "y": 2.664, - "z": -448.59198 - }, - "Rotation": 181.596954, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -3791,33 +4051,7 @@ }, { "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 27 - } - }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "cb64847e-76a6-42a9-ab3d-9e5629e4bf5b", - "Infiltration": "", - "Position": { - "x": -208.019, - "y": 4.207, - "z": -297.85498 - }, - "Rotation": 113.883675, - "Sides": ["Savage"] - }, - { - "BotZoneName": "BotZoneFloor2", - "Categories": ["Bot"], + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3829,14 +4063,14 @@ "Radius": 27 } }, - "CorePointId": 5, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "cde4c94f-1f0a-43bc-a0d7-b07758171d61", + "Id": "cb6fb7f0-2ecc-4cb0-a3f6-5814d8ecc410", "Infiltration": "", "Position": { - "x": -134.647, - "y": 4.181, - "z": -346.005981 + "x": -127.768, + "y": 4.2, + "z": -382.271973 }, "Rotation": 0, "Sides": ["Savage"] @@ -3893,6 +4127,58 @@ "Rotation": 176.03, "Sides": ["All"] }, + { + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 35 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "cff559a6-e9cf-447c-a432-2e872fa14e1d", + "Infiltration": "", + "Position": { + "x": -206.267, + "y": 1.51, + "z": -290.977 + }, + "Rotation": 184.024811, + "Sides": ["Savage"] + }, + { + "BotZoneName": "BotZoneBasement", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 25 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "d03b1791-4b04-40bc-b099-46c565862277", + "Infiltration": "", + "Position": { + "x": -244.796, + "y": -4.001, + "z": -414.788 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -4050,8 +4336,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneBasement", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4060,24 +4346,24 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 50 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d67c127c-7f89-4ad6-a4c4-90f56a6bf666", - "Infiltration": "", + "Id": "d7eb2d80-10a1-48e1-b214-d7cac5eff13a", + "Infiltration": "Common", "Position": { - "x": -141.92, - "y": -4.041, - "z": -416.659973 + "x": -207.754, + "y": 4.16135359, + "z": -295.225 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 89.0511551, + "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4086,20 +4372,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "d7eb2d80-10a1-48e1-b214-d7cac5eff13a", - "Infiltration": "Common", + "Id": "d997c558-0b61-4fab-bdc3-9b7543fee051", + "Infiltration": "", "Position": { - "x": -207.754, - "y": 4.16135359, - "z": -295.225 + "x": -224.879, + "y": 0.082, + "z": -279.867 }, - "Rotation": 89.0511551, - "Sides": ["All"] + "Rotation": 164.3535, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4258,8 +4544,8 @@ "Sides": ["All"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4268,24 +4554,24 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 50 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e9147ec4-61b7-43e9-8e9b-515e127167d2", - "Infiltration": "", + "Id": "eb45ebae-4f05-49d4-b5d7-8851ba7f042b", + "Infiltration": "Common", "Position": { - "x": -206.267, - "y": 1.51, - "z": -290.977 + "x": -233.962, + "y": 0.09, + "z": -418.431 }, - "Rotation": 184.024811, - "Sides": ["Savage"] + "Rotation": 3.2020905, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4294,20 +4580,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "eb45ebae-4f05-49d4-b5d7-8851ba7f042b", - "Infiltration": "Common", + "Id": "ec7553c5-ee02-4c0f-9c68-4879ae217556", + "Infiltration": "", "Position": { - "x": -233.962, - "y": 0.09, - "z": -418.431 + "x": -116.011, + "y": 0.036, + "z": -336.378 }, - "Rotation": 3.2020905, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4336,8 +4622,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneFloor1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4346,24 +4632,24 @@ "y": 0, "z": 0 }, - "Radius": 35 + "Radius": 50 } }, - "CorePointId": 8, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f1cf8f15-cc59-48ef-8d98-840d12972120", - "Infiltration": "", + "Id": "f3b5e0b0-0996-4191-81f3-a709b324d5b9", + "Infiltration": "Common", "Position": { - "x": -279.68, - "y": 0.078, - "z": -352.99 + "x": -108.59, + "y": 4.2, + "z": -413.89 }, - "Rotation": 126.849854, - "Sides": ["Savage"] + "Rotation": 204.36, + "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "BotZoneGate2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4372,20 +4658,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 7 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "f3b5e0b0-0996-4191-81f3-a709b324d5b9", - "Infiltration": "Common", + "Id": "f41dc624-2d0a-4f46-9f46-57956e3892a2", + "Infiltration": "", "Position": { - "x": -108.59, - "y": 4.2, - "z": -413.89 + "x": -244.101, + "y": 2.664, + "z": -452.923981 }, - "Rotation": 204.36, - "Sides": ["All"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4440,8 +4726,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "BotZoneGate2", - "Categories": ["Bot"], + "BotZoneName": "BotZoneFloor1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4450,23 +4736,23 @@ "y": 0, "z": 0 }, - "Radius": 7 + "Radius": 35 } }, - "CorePointId": 3, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "fe0e7112-8129-4749-8aed-e357368172af", + "Id": "fa6ab194-d384-4730-979f-cc84e7fac828", "Infiltration": "", "Position": { - "x": -244.976, - "y": 2.664, - "z": -448.615 + "x": -231.636, + "y": 0.082, + "z": -286.69397 }, - "Rotation": 181.596954, + "Rotation": 164.3535, "Sides": ["Savage"] } ], - "UnixDateTime": 1707142616, + "UnixDateTime": 1636383862, "_Id": "5b0fc42d86f7744a585f9105", "doors": [], "exit_access_time": 60, @@ -4633,12 +4919,29 @@ "matching_min_seconds": 60, "maxItemCountInLocation": [ { - "TemplateId": "54009119af1c881c07000029", - "Value": 0 + "TemplateId": "634959225289190e5e773b3b", + "Value": 7 + }, + { + "TemplateId": "5c0530ee86f774697952d952", + "Value": 2 } ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 111, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "LAB_TRANSIT_8_COND", + "description": "LAB_TRANSIT_8_DESC", + "id": 8, + "location": "TarkovStreets", + "name": "LAB_TRANSIT_8", + "target": "5714dc692459777137212e12", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, diff --git a/external-resources/maps/lighthouse.json b/external-resources/maps/lighthouse.json index b35e0906..76332cd2 100644 --- a/external-resources/maps/lighthouse.json +++ b/external-resources/maps/lighthouse.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 50, @@ -51,6 +52,8 @@ "BossPlayer": false, "BossZone": "Zone_Island", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -61,7 +64,28 @@ "TriggerName": "" }, { - "BossChance": 37, + "BossChance": 30, + "BossDifficult": "normal", + "BossEscortAmount": "0", + "BossEscortDifficult": "normal", + "BossEscortType": "exUsec", + "BossName": "bossPartisan", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": true, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["regular", "pve"], + "Supports": null, + "Time": 900, + "TriggerId": "PARTISAN_TRIGGER", + "TriggerName": "botEvent" + }, + { + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "2", "BossEscortDifficult": "normal", @@ -70,6 +94,8 @@ "BossPlayer": false, "BossZone": "Zone_TreatmentContainers,Zone_Chalet", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": true, @@ -105,6 +131,8 @@ "BossPlayer": false, "BossZone": "Zone_Blockpost", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -124,6 +152,8 @@ "BossPlayer": false, "BossZone": "Zone_RoofContainers", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -143,6 +173,8 @@ "BossPlayer": false, "BossZone": "Zone_TreatmentRocks", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -162,6 +194,8 @@ "BossPlayer": false, "BossZone": "Zone_TreatmentBeach", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -181,6 +215,8 @@ "BossPlayer": false, "BossZone": "Zone_Island", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -200,6 +236,8 @@ "BossPlayer": false, "BossZone": "Zone_RoofRocks", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -219,6 +257,8 @@ "BossPlayer": false, "BossZone": "Zone_RoofBeach", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -238,6 +278,8 @@ "BossPlayer": false, "BossZone": "Zone_Hellicopter", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -247,6 +289,132 @@ "TriggerId": "", "TriggerName": "" }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, { "BossChance": 5, "BossDifficult": "normal", @@ -257,6 +425,8 @@ "BossPlayer": false, "BossZone": "Zone_OldHouse", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -273,17 +443,117 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 0.6, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 330, + "DistToActivatePvE": 330, "DistToPersueAxemanCoef": 0.7, "DistToSleep": 350, + "DistToSleepPvE": 350, "GainSight": 1.3, "KhorovodChance": 0, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1800, + "MinExfiltrationTime": 1200, "Scattering": 0.6, "VisibleDistance": 1.3 }, "BotMarksman": 0, - "BotMax": 17, + "BotMax": 22, "BotMaxPlayer": 7, "BotMaxPvE": 29, "BotMaxTimePlayer": 1000, @@ -295,7 +565,7 @@ "BotSpawnTimeOnMax": 320, "BotSpawnTimeOnMin": 260, "BotStart": 20, - "BotStartPlayer": 0, + "BotStartPlayer": 550, "BotStop": 1900, "Description": "The lighthouse at Cape Dalniy used to be an important strategic point of the city. At the outbreak of the conflict, USEC used it as a landing zone, thus attracting the attention of BEAR troops that aimed to reduce the hostile PMC presence to zero. ", "DisabledForScav": false, @@ -305,9 +575,89 @@ "EscapeTimeLimit": 40, "EscapeTimeLimitCoop": 30, "EscapeTimeLimitPVE": 40, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 200, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 200, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.26, + "GlobalLootChanceModifier": 0.12, "GlobalLootChanceModifierPvE": 0.26, "IconX": 120, "IconY": 450, @@ -357,6 +707,7 @@ "MinPlayers": 10, "Name": "Lighthouse", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -365,8 +716,8 @@ }, "OcculsionCullingEnabled": false, "OfflineNewSpawn": true, - "OfflineOldSpawn": false, - "OldSpawn": false, + "OfflineOldSpawn": true, + "OldSpawn": true, "OpenZones": "Zone_Containers,Zone_Rocks,Zone_Chalet,Zone_Village,Zone_Bridge,Zone_OldHouse,Zone_LongRoad,Zone_DestroyedHouse,Zone_SniperPeak,Zone_Island", "PlayersRequestCount": -1, "PmcMaxPlayersInGroup": 5, @@ -385,8 +736,8 @@ }, "SpawnPointParams": [ { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Bridge", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -398,20 +749,20 @@ "Radius": 120 } }, - "CorePointId": 6, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "002581fa-b12b-4db2-bd5c-55950f679f46", + "Id": "000b6c76-206e-4c26-932b-bda107773b32", "Infiltration": "", "Position": { - "x": 40.03, - "y": 9.52565, - "z": 71.81999 + "x": -38.27002, + "y": 5.640217, + "z": -299.52 }, "Rotation": 256.630219, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_LongRoad", + "BotZoneName": "Zone_Containers", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -421,50 +772,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 6, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "0091f071-4cca-43c9-8076-7cb8c1ec55aa", - "Infiltration": "", - "Position": { - "x": 48.19998, - "y": 1.645649, - "z": -116.300018 - }, - "Rotation": 256.630219, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_TreatmentContainers", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 15, - "DelayToCanSpawnSec": 3600, - "Id": "00c322b5-b54f-4bf0-9574-7eaa580e3ea8", + "Id": "0156db2d-5136-4bff-a562-9fb4fb952999", "Infiltration": "", "Position": { - "x": -109.02002, - "y": 4.92964935, - "z": -729.52 + "x": -131.030029, + "y": 10.5248337, + "z": -807.85 }, - "Rotation": 256.404022, + "Rotation": 71.051445, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_SniperPeak", - "Categories": ["Bot"], + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -476,42 +801,16 @@ "Radius": 60 } }, - "CorePointId": 17, - "DelayToCanSpawnSec": 2000, - "Id": "015606c3-4476-410d-83c5-7dcd8cc4e2b6", - "Infiltration": "", - "Position": { - "x": -58.01001, - "y": 39.5256538, - "z": 459.39 - }, - "Rotation": 256.404022, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_Island", - "Categories": ["Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 18, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "02e373cc-3526-4b6b-ad54-deb582627725", + "Id": "02d3353c-9df3-4ac1-8140-f0d700a95de3", "Infiltration": "", "Position": { - "x": 356.39, - "y": 15.51865, - "z": 553.695 + "x": -130.450012, + "y": 11.2891312, + "z": -205.959991 }, - "Rotation": 158.316177, + "Rotation": 244.211288, "Sides": ["Savage"] }, { @@ -541,7 +840,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_RoofContainers", + "BotZoneName": "Zone_TreatmentContainers", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -554,20 +853,20 @@ "Radius": 30 } }, - "CorePointId": 11, + "CorePointId": 15, "DelayToCanSpawnSec": 3600, - "Id": "076b8ba4-c73e-492a-b397-feff39eb37a6", + "Id": "06b05fe3-3a1e-4634-9157-52e02edfb3cc", "Infiltration": "", "Position": { - "x": -124.830017, - "y": 14.0356522, - "z": -738.319946 + "x": -94.92001, + "y": 4.93265152, + "z": -750.14 }, "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_Rocks", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -580,20 +879,20 @@ "Radius": 120 } }, - "CorePointId": 19, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "0a7449f0-358e-4c1e-bdbc-ef7841422440", + "Id": "071f0fa9-b3dc-44c2-b0ec-1ce2b3c354af", "Infiltration": "", "Position": { - "x": 54.22998, - "y": 11.75729, - "z": 200.579987 + "x": -152.920013, + "y": 37.55528, + "z": 138.09 }, - "Rotation": 256.404022, + "Rotation": 128.073547, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Chalet", + "BotZoneName": "Zone_Village", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -603,24 +902,24 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 60 } }, - "CorePointId": 7, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "0bee161d-e32f-4d12-b63b-26094858ffa2", + "Id": "089bb581-e642-43e5-88e9-22ca3accd2ee", "Infiltration": "", "Position": { - "x": -116.140015, - "y": 17.79565, - "z": -32.0899963 + "x": -197.74, + "y": 5.882332, + "z": -261.949982 }, - "Rotation": 208.517929, + "Rotation": 348.435364, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentRocks", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -632,20 +931,20 @@ "Radius": 60 } }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "0e90cf48-179b-40c1-b0b6-8928297ac29f", + "CorePointId": 13, + "DelayToCanSpawnSec": 3600, + "Id": "0a105306-31c1-4408-b1df-86dd3890693c", "Infiltration": "", "Position": { - "x": -84.46002, - "y": 5.86565, - "z": -271.620026 + "x": -199.700012, + "y": 4.910652, + "z": -665.11 }, - "Rotation": 348.435364, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Containers", + "BotZoneName": "Zone_Rocks", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -655,24 +954,24 @@ "y": 0, "z": 0 }, - "Radius": 160 + "Radius": 120 } }, - "CorePointId": 24, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "1078e538-5be7-432d-bfa7-11188d84622d", + "Id": "0c2117e8-6737-4400-9b2f-9215654d779a", "Infiltration": "", "Position": { - "x": -51.1490173, - "y": 10.70362, - "z": -794.814941 + "x": -128.16, + "y": 39.89565, + "z": 95.26999 }, - "Rotation": 129.653656, + "Rotation": 23.3241863, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "Zone_Bridge", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -681,24 +980,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 120 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "10b98bcc-fa01-4045-9de1-31a89b9d2c24", - "Infiltration": "North", + "Id": "0c4dfb6a-2745-4c43-b3da-3a049334b318", + "Infiltration": "", "Position": { - "x": 26.39, - "y": 6.01, - "z": -81.62 + "x": -59.11502, + "y": 5.86565, + "z": -290.691 }, - "Rotation": 266.5001, - "Sides": ["Pmc"] + "Rotation": 256.630219, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -707,20 +1006,20 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 70 } }, - "CorePointId": 3, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "115080c3-9cf6-4adc-b9e8-755e3e17bfc6", - "Infiltration": "", + "Id": "10b98bcc-fa01-4045-9de1-31a89b9d2c24", + "Infiltration": "North", "Position": { - "x": -213.080017, - "y": 12.7456512, - "z": -187.81 + "x": 26.39, + "y": 6.01, + "z": -81.62 }, - "Rotation": 177.55925, - "Sides": ["Savage"] + "Rotation": 266.5001, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -748,32 +1047,6 @@ "Rotation": 358.2052, "Sides": ["Pmc"] }, - { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "11cd4250-9e90-4a82-9f54-7913734ed0ea", - "Infiltration": "", - "Position": { - "x": -237.310013, - "y": 14.7656517, - "z": -170.290009 - }, - "Rotation": 194.970718, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -827,8 +1100,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Containers", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Island", + "Categories": ["Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -837,71 +1110,19 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 11, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "1686e5c5-05e3-4247-bb87-a9a8f9329202", - "Infiltration": "", - "Position": { - "x": -140.080017, - "y": 10.5248337, - "z": -870.77 - }, - "Rotation": 53.9718971, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_SniperPeak", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 17, - "DelayToCanSpawnSec": 2000, - "Id": "185d66e6-80df-40a6-a4e4-b0e148a273a8", - "Infiltration": "", - "Position": { - "x": -71.78, - "y": 39.2056541, - "z": 451.11 - }, - "Rotation": 256.404022, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_TreatmentBeach", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 30 - } - }, - "CorePointId": 1, - "DelayToCanSpawnSec": 3600, - "Id": "18fef17b-8926-4502-9565-d582c36c5d24", + "Id": "189bf4a7-9b7c-4038-b6c8-6f319a0e124f", "Infiltration": "", "Position": { - "x": 55.44998, - "y": 4.94265, - "z": -633.199951 + "x": 371.841, + "y": 15.1656494, + "z": 571.147 }, - "Rotation": 81.6740341, + "Rotation": 115.016975, "Sides": ["Savage"] }, { @@ -983,8 +1204,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_RoofBeach", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -993,23 +1214,23 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 30 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "1bbc9a7b-1a0b-419c-9e39-7780b4c9e18c", + "CorePointId": 8, + "DelayToCanSpawnSec": 3600, + "Id": "1cd9b175-2223-449f-a63b-064a5a860057", "Infiltration": "", "Position": { - "x": -149.85, - "y": 11.95565, - "z": -200.76001 + "x": 29.3799744, + "y": 14.0556488, + "z": -621.069946 }, - "Rotation": 244.211288, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_TreatmentBeach", + "BotZoneName": "Zone_TreatmentContainers", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1019,19 +1240,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 30 } }, - "CorePointId": 1, + "CorePointId": 15, "DelayToCanSpawnSec": 3600, - "Id": "1e9cce28-b106-4af6-a5db-88c995b79ad4", + "Id": "1d327156-2c17-446f-9f62-8400f1178247", "Infiltration": "", "Position": { - "x": 37.48999, + "x": -106.490021, "y": 4.94265, - "z": -641.36 + "z": -754.910034 }, - "Rotation": 81.6740341, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -1061,34 +1282,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Containers", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 100 - } - }, - "CorePointId": 11, - "DelayToCanSpawnSec": 4, - "Id": "1fc2f33f-5c1e-49ac-998e-c04c696e7ce7", - "Infiltration": "", - "Position": { - "x": -139.07, - "y": 10.5248337, - "z": -856.98 - }, - "Rotation": 53.9718971, - "Sides": ["Savage"] - }, - { - "BotZoneName": "", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1097,19 +1292,19 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 30 } }, - "CorePointId": 5, - "DelayToCanSpawnSec": 4, - "Id": "2179d6f4-48a2-4946-805b-bfcf24034b23", + "CorePointId": 1, + "DelayToCanSpawnSec": 3600, + "Id": "21990f73-d577-4f31-a2e7-7a6b905011e2", "Infiltration": "", "Position": { - "x": -249, - "y": 0.8441658, - "z": -382.21 + "x": 54.1099854, + "y": 4.95064926, + "z": -606.329956 }, - "Rotation": 236.87, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { @@ -1139,8 +1334,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_TreatmentRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1149,23 +1344,23 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 120 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 3600, - "Id": "2285b8a6-9199-4d55-8f4f-32cdc8ffc05e", + "CorePointId": 19, + "DelayToCanSpawnSec": 4, + "Id": "23c3b739-987a-42d4-a639-0a55f93bd563", "Infiltration": "", "Position": { - "x": -172.51001, - "y": 5.02565, - "z": -655.47 + "x": 57.3399963, + "y": 12.8756523, + "z": 193.669983 }, "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_LongRoad", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1178,16 +1373,16 @@ "Radius": 120 } }, - "CorePointId": 19, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "266d1705-229c-4eb2-a93d-8c235f001084", + "Id": "263cbb1f-5046-49be-8845-652a12561acd", "Infiltration": "", "Position": { - "x": 57.3399963, - "y": 12.8756523, - "z": 193.669983 - }, - "Rotation": 256.404022, + "x": 44.8999939, + "y": 2.95565033, + "z": -211.6 + }, + "Rotation": 256.630219, "Sides": ["Savage"] }, { @@ -1242,6 +1437,32 @@ "Rotation": 119.557549, "Sides": ["All"] }, + { + "BotZoneName": "Zone_Island", + "Categories": ["Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 40 + } + }, + "CorePointId": 18, + "DelayToCanSpawnSec": 4, + "Id": "27e85a39-0768-4a6f-9d46-c7ec39a5cba1", + "Infiltration": "", + "Position": { + "x": 332.006958, + "y": 2.03665161, + "z": 518.079 + }, + "Rotation": 190.619385, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1295,8 +1516,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1308,20 +1529,46 @@ "Radius": 60 } }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "2ada76f6-d423-4092-bff3-475ac189685b", + "CorePointId": 1, + "DelayToCanSpawnSec": 3600, + "Id": "286920a4-6f50-4335-a9a2-e9dae4ffc337", "Infiltration": "", "Position": { - "x": -87.52002, - "y": 6.034649, - "z": -269.98 + "x": 30.5999756, + "y": 4.90765, + "z": -631.13 }, - "Rotation": 348.435364, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Rocks", + "BotZoneName": "Zone_Blockpost", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 140 + } + }, + "CorePointId": 14, + "DelayToCanSpawnSec": 3600, + "Id": "291165b2-16c2-4c7a-8baf-1a7e9f6f83bb", + "Infiltration": "", + "Position": { + "x": 15.2599792, + "y": 4.728651, + "z": -447.690033 + }, + "Rotation": 26.8442173, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_Village", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1331,24 +1578,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 2, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "2bdca984-0c29-42bd-b1e2-a63abab199e7", + "Id": "2a961493-b814-4e69-be25-f9fe23837fe5", "Infiltration": "", "Position": { - "x": -128.16, - "y": 39.89565, - "z": 95.26999 + "x": -120.820007, + "y": 11.11565, + "z": -228.91 }, - "Rotation": 23.3241863, + "Rotation": 244.211288, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Bridge", - "Categories": ["Bot"], + "BotZoneName": "Zone_Containers", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1357,24 +1604,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 4, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "2ccdc080-edb6-4924-b4ac-521851aa98c5", + "Id": "2b5868a8-5bbd-47c9-9409-7235d46ad58a", "Infiltration": "", "Position": { - "x": -59.11502, - "y": 5.86565, - "z": -290.691 + "x": -102.210022, + "y": 10.6186514, + "z": -844.2999 }, - "Rotation": 256.630219, + "Rotation": 4.104724, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_RoofContainers", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1383,19 +1630,19 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 120 } }, - "CorePointId": 15, - "DelayToCanSpawnSec": 3600, - "Id": "2d0afcc7-3b8d-4c99-a8d0-a7f49c6d6529", + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "2d1563cd-b15e-4ee0-a528-e1822285b0c5", "Infiltration": "", "Position": { - "x": -66.2750244, - "y": 14.0756493, - "z": -734.574 + "x": 39.1399841, + "y": 11.02565, + "z": -11.1400146 }, - "Rotation": 34.3430061, + "Rotation": 256.630219, "Sides": ["Savage"] }, { @@ -1424,6 +1671,58 @@ "Rotation": 179.094986, "Sides": ["Pmc"] }, + { + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "2ea50142-be25-479c-9a0c-b5b959114c16", + "Infiltration": "", + "Position": { + "x": -178.26001, + "y": 12.25, + "z": -193.290009 + }, + "Rotation": 194.970718, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 1, + "DelayToCanSpawnSec": 3600, + "Id": "2ef81c28-b7d9-4333-ad88-4187bf83be56", + "Infiltration": "", + "Position": { + "x": 37.48999, + "y": 4.94265, + "z": -641.36 + }, + "Rotation": 81.6740341, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -1450,6 +1749,32 @@ "Rotation": 266.5001, "Sides": ["Pmc"] }, + { + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "2ff52f01-f8ad-42c2-977b-e3b136c80057", + "Infiltration": "", + "Position": { + "x": -8.480011, + "y": 0.763252258, + "z": 81.53 + }, + "Rotation": 113.936485, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1477,8 +1802,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Blockpost", - "Categories": ["Boss"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1487,19 +1812,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 120 } }, - "CorePointId": 14, - "DelayToCanSpawnSec": 3600, - "Id": "30f66af2-911c-4ec5-98bc-e7114cf55b59", + "CorePointId": 21, + "DelayToCanSpawnSec": 4, + "Id": "3134f27a-31ed-41ee-866d-0f1e35f0ff7d", "Infiltration": "", "Position": { - "x": -8.040009, - "y": 7.268448, - "z": -452.21 + "x": 46.75, + "y": 7.32564926, + "z": 324.84 }, - "Rotation": 26.8442173, + "Rotation": 116.208389, "Sides": ["Savage"] }, { @@ -1528,32 +1853,6 @@ "Rotation": 212.519348, "Sides": ["All"] }, - { - "BotZoneName": "Zone_Blockpost", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 140 - } - }, - "CorePointId": 14, - "DelayToCanSpawnSec": 3600, - "Id": "33d1635f-9909-42c6-8e8f-c6b2a6443b86", - "Infiltration": "", - "Position": { - "x": 15.2599792, - "y": 4.728651, - "z": -447.690033 - }, - "Rotation": 26.8442173, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -1607,7 +1906,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Rocks", + "BotZoneName": "Zone_Village", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1617,24 +1916,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 22, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "35a5987f-e00a-4b67-ada2-54f4476c7319", + "Id": "36f8e82f-3b95-4386-ace5-53d1b32d9beb", "Infiltration": "", "Position": { - "x": -113.19, - "y": 30.6256828, - "z": 154.11 + "x": -122.320007, + "y": 6.45565033, + "z": -270.449982 }, - "Rotation": 195.903351, + "Rotation": 348.435364, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_RoofRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_Bridge", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1643,24 +1942,24 @@ "y": 0, "z": 0 }, - "Radius": 240 + "Radius": 120 } }, - "CorePointId": 12, - "DelayToCanSpawnSec": 3600, - "Id": "3649e5c4-370c-449e-adb7-edb543e4c0cf", + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "374e67dc-29cb-4968-93ab-ce1a45843e4b", "Infiltration": "", "Position": { - "x": -186.51001, - "y": 14.0341454, - "z": -643.839966 + "x": 12.5099792, + "y": 6.105652, + "z": -238.940033 }, - "Rotation": 256.404022, + "Rotation": 297.348724, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Bridge", - "Categories": ["Bot"], + "BotZoneName": "Zone_Village", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1669,24 +1968,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 30 } }, "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "3a68b926-0820-4474-9e58-790844b554cc", + "Id": "37f1ab84-276c-494f-9b03-690b75720f7f", "Infiltration": "", "Position": { - "x": -38.27002, - "y": 5.640217, - "z": -299.52 + "x": -108.170013, + "y": 6.57564926, + "z": -271.120026 }, - "Rotation": 256.630219, + "Rotation": 348.435364, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1695,24 +1994,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "3a76b2a9-1dbb-4f5f-87e3-277d1980bcb8", - "Infiltration": "Tunnel", + "Id": "38532084-60d9-4b4e-8e0a-bde16882f98b", + "Infiltration": "", "Position": { - "x": 103.953522, - "y": 0.480896, - "z": 426.513062 + "x": -133.150024, + "y": 11.353878, + "z": -203.670013 }, - "Rotation": 260.715424, - "Sides": ["All"] + "Rotation": 244.211288, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_TreatmentBeach", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_Rocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1721,21 +2020,47 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 120 } }, - "CorePointId": 1, - "DelayToCanSpawnSec": 3600, - "Id": "3cbfddff-c764-46dd-a9dd-d8a406f39f1f", + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "38c4ebc9-fbe8-4e71-bc7b-1f234b942387", "Infiltration": "", "Position": { - "x": 30.5999756, - "y": 4.90765, - "z": -631.13 + "x": -113.915009, + "y": 36.7456474, + "z": 102.474991 }, - "Rotation": 81.6740341, + "Rotation": 275.2177, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "3a76b2a9-1dbb-4f5f-87e3-277d1980bcb8", + "Infiltration": "Tunnel", + "Position": { + "x": 103.953522, + "y": 0.480896, + "z": 426.513062 + }, + "Rotation": 260.715424, + "Sides": ["All"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1763,7 +2088,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Rocks", + "BotZoneName": "", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1773,23 +2098,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 2, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "3f39a5f9-4923-423e-abf6-d88fb7443987", + "Id": "41310551-d363-4643-9bad-390a5ccb3562", "Infiltration": "", "Position": { - "x": -128.050018, - "y": 39.9256477, - "z": 74.29999 + "x": -299.567017, + "y": 0.110027313, + "z": -323.816 }, - "Rotation": 23.3241863, + "Rotation": 85.4818039, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_RoofRocks", + "BotZoneName": "Zone_RoofBeach", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1799,19 +2124,45 @@ "y": 0, "z": 0 }, - "Radius": 40 + "Radius": 30 } }, - "CorePointId": 13, + "CorePointId": 8, "DelayToCanSpawnSec": 3600, - "Id": "42016d8d-696e-4ee1-a33c-1bb486876a07", + "Id": "41cf4fd7-e698-4aed-8966-180df81dbb59", "Infiltration": "", "Position": { - "x": -190.35, - "y": 13.9855, - "z": -660.22 + "x": 30.5599976, + "y": 13.95565, + "z": -591.73 }, - "Rotation": 256.404022, + "Rotation": 81.6740341, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_RoofBeach", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 30 + } + }, + "CorePointId": 8, + "DelayToCanSpawnSec": 3600, + "Id": "435828ad-da49-4163-b005-169181c66e4f", + "Infiltration": "", + "Position": { + "x": 29.8399963, + "y": 13.95565, + "z": -623.39 + }, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { @@ -1841,8 +2192,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentRocks", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1851,24 +2202,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 60 } }, - "CorePointId": 5, - "DelayToCanSpawnSec": 4, - "Id": "44d4b41d-0baf-4d66-b3a7-22fa72052095", + "CorePointId": 13, + "DelayToCanSpawnSec": 3600, + "Id": "4485b593-d7db-4329-82e2-655af293dc13", "Infiltration": "", "Position": { - "x": -301.271, - "y": 0.09542465, - "z": -319.793976 + "x": -172.51001, + "y": 5.02565, + "z": -655.47 }, - "Rotation": 85.4818039, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_RoofBeach", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1877,23 +2228,23 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 120 } }, - "CorePointId": 8, - "DelayToCanSpawnSec": 3600, - "Id": "4549b4e0-b358-44f4-a23b-93da31616bb0", + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "44d7c65a-e893-4cd0-8e3c-724211b28c31", "Infiltration": "", "Position": { - "x": 29.8399963, - "y": 13.95565, - "z": -623.39 + "x": -12.6200256, + "y": 2.82564926, + "z": 108.479996 }, - "Rotation": 81.6740341, + "Rotation": 113.936485, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", + "BotZoneName": "Zone_Containers", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1903,19 +2254,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 100 } }, - "CorePointId": 3, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "45e48063-0d1c-466c-9c32-a4356bbb8bf6", + "Id": "460b507b-ed63-4a4a-8502-eecd321a1d3d", "Infiltration": "", "Position": { - "x": -202.62001, - "y": 12.3556519, - "z": -194.37 + "x": -140.080017, + "y": 10.5248337, + "z": -870.77 }, - "Rotation": 194.970718, + "Rotation": 53.9718971, "Sides": ["Savage"] }, { @@ -1945,8 +2296,8 @@ "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "Zone_Village", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1955,24 +2306,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 40 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "46d9652b-5416-42be-bd85-92a6064a3444", - "Infiltration": "Tunnel", + "Id": "46be8874-7a0e-431e-934d-918e75423c94", + "Infiltration": "", "Position": { - "x": -168.237411, - "y": 30.4148979, - "z": -65.0293 + "x": -124.001007, + "y": 11.7786522, + "z": -218.06 }, - "Rotation": 148.08, - "Sides": ["All"] + "Rotation": 149.101685, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Hellicopter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1981,20 +2332,20 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 70 } }, - "CorePointId": 9, - "DelayToCanSpawnSec": 3600, - "Id": "495374f8-b0dc-417e-ae96-ff1cdc3650ac", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "46d9652b-5416-42be-bd85-92a6064a3444", + "Infiltration": "Tunnel", "Position": { - "x": -101.01001, - "y": 0.0156517029, - "z": -537.61 + "x": -168.237411, + "y": 30.4148979, + "z": -65.0293 }, - "Rotation": 256.404022, - "Sides": ["Savage"] + "Rotation": 148.08, + "Sides": ["All"] }, { "BotZoneName": "", @@ -2023,8 +2374,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_TreatmentRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_Containers", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2033,19 +2384,19 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 100 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 3600, - "Id": "4d14b40a-3452-4871-9f17-e897ea33fe0c", + "CorePointId": 11, + "DelayToCanSpawnSec": 4, + "Id": "4c2205a2-be1a-4abd-addf-7ea9c77a0c0a", "Infiltration": "", "Position": { - "x": -199.430008, - "y": 4.92964935, - "z": -680.459961 + "x": -139.07, + "y": 10.5248337, + "z": -856.98 }, - "Rotation": 256.404022, + "Rotation": 53.9718971, "Sides": ["Savage"] }, { @@ -2075,8 +2426,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_TreatmentRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2085,33 +2436,7 @@ "y": 0, "z": 0 }, - "Radius": 60 - } - }, - "CorePointId": 13, - "DelayToCanSpawnSec": 3600, - "Id": "4e73d9dd-88a6-4402-95b8-48e68f50e38e", - "Infiltration": "", - "Position": { - "x": -199.700012, - "y": 4.910652, - "z": -665.11 - }, - "Rotation": 256.404022, - "Sides": ["Savage"] - }, - { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 77 + "Radius": 77 } }, "CorePointId": 0, @@ -2127,8 +2452,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_DestroyedHouse", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentRocks", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2137,19 +2462,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 30 } }, - "CorePointId": 21, - "DelayToCanSpawnSec": 4, - "Id": "4fe4b399-0f8d-4589-9e12-54144538d136", + "CorePointId": 12, + "DelayToCanSpawnSec": 3600, + "Id": "4f8bd9ad-447d-4da5-b2d5-fda9cc05d026", "Infiltration": "", "Position": { - "x": 46.75, - "y": 7.32564926, - "z": 324.84 + "x": -180.49, + "y": 5.02565, + "z": -633.040039 }, - "Rotation": 116.208389, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -2179,34 +2504,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Blockpost", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 140 - } - }, - "CorePointId": 14, - "DelayToCanSpawnSec": 3600, - "Id": "509ea05a-99b8-4f04-8100-e401ece7bb94", - "Infiltration": "", - "Position": { - "x": 12.9400024, - "y": 4.7986509999999996, - "z": -447.53 - }, - "Rotation": 26.8442173, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_Hellicopter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2215,23 +2514,23 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 120 } }, - "CorePointId": 9, - "DelayToCanSpawnSec": 3600, - "Id": "514c7cfa-601e-418b-83e2-e609740c05e6", + "CorePointId": 21, + "DelayToCanSpawnSec": 4, + "Id": "51349452-d639-43bc-9eef-b9bb80bd6af1", "Infiltration": "", "Position": { - "x": -83.70001, - "y": -0.106666565, - "z": -541.36 + "x": 68.32999, + "y": 5.76124954, + "z": 373.38 }, - "Rotation": 256.404022, + "Rotation": 116.208389, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", + "BotZoneName": "", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2241,19 +2540,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 100 } }, - "CorePointId": 3, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "51d89cbf-aea1-4cda-b6a2-093a6d667dae", + "Id": "5140a6ba-a2cf-466e-b7fb-0c122647eab4", "Infiltration": "", "Position": { - "x": -185.040009, - "y": 5.405651, - "z": -261.759979 + "x": -301.271, + "y": 0.09542465, + "z": -319.793976 }, - "Rotation": 348.435364, + "Rotation": 85.4818039, "Sides": ["Savage"] }, { @@ -2309,8 +2608,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Hellicopter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2319,19 +2618,45 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 120 } }, - "CorePointId": 9, - "DelayToCanSpawnSec": 3600, - "Id": "5877e848-3422-4da9-a9c6-e9015f4b4152", + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "57217803-b7b9-4cc7-83d2-bfe316750c2e", "Infiltration": "", "Position": { - "x": -62.53, - "y": 3.95565033, - "z": -586.410034 + "x": 40.6599731, + "y": 9.495651, + "z": 14.6900024 }, - "Rotation": 256.404022, + "Rotation": 256.630219, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_Bridge", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "58a77a58-141b-4239-87dc-c11016aae8c2", + "Infiltration": "", + "Position": { + "x": 9.919983, + "y": 6.11565, + "z": -243.28 + }, + "Rotation": 297.348724, "Sides": ["Savage"] }, { @@ -2361,7 +2686,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_RoofBeach", + "BotZoneName": "Zone_TreatmentContainers", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2374,21 +2699,21 @@ "Radius": 30 } }, - "CorePointId": 8, + "CorePointId": 11, "DelayToCanSpawnSec": 3600, - "Id": "5ba33aaf-2f0d-41e6-b046-6bbb86b8e97f", + "Id": "5c1c074b-9696-435a-81ad-e924202b98f2", "Infiltration": "", "Position": { - "x": 30.5599976, - "y": 13.95565, - "z": -591.73 + "x": -130.090027, + "y": 7.734501, + "z": -747.189941 }, - "Rotation": 81.6740341, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Rocks", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Hellicopter", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2397,24 +2722,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "5d19f3c2-95fd-461d-a6e7-77c308c65e1f", + "CorePointId": 9, + "DelayToCanSpawnSec": 3600, + "Id": "5c38a67f-0095-42d3-9ba6-d5726f071972", "Infiltration": "", "Position": { - "x": -148.040009, - "y": 39.9856529, - "z": 94.89 + "x": -101.01001, + "y": 0.0156517029, + "z": -537.61 }, - "Rotation": 23.3241863, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Island", - "Categories": ["Boss"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2423,24 +2748,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 120 } }, - "CorePointId": 18, + "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "5d92c260-8598-4f93-b4da-85469cdcc9ce", + "Id": "5c814f61-bbe3-48ab-8063-b2a70eb3542c", "Infiltration": "", "Position": { - "x": 365.69, - "y": 15.5336494, - "z": 545.678 + "x": 25.0499878, + "y": 6.88413239, + "z": 374.950348 }, - "Rotation": 19.1368885, + "Rotation": 116.208389, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentRocks", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2449,24 +2774,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 30 } }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "5e053090-f061-46da-b086-afa83a685ca3", + "CorePointId": 13, + "DelayToCanSpawnSec": 3600, + "Id": "5e2936bd-1966-4e6a-b731-bce646ca2136", "Infiltration": "", "Position": { - "x": 49.4099731, - "y": 1.63565063, - "z": -147.12 + "x": -198.790009, + "y": 5.189949, + "z": -697.670044 }, - "Rotation": 256.630219, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Village", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2475,23 +2800,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 40 } }, - "CorePointId": 6, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "5e2634c2-c71c-4c41-b85d-877f65e9a1cf", + "Id": "5ebc7b0c-ffa1-47a6-bf9a-23ce4dae6fcc", "Infiltration": "", "Position": { - "x": 40.6599731, - "y": 9.495651, - "z": 14.6900024 + "x": -26.1110229, + "y": 3.299652, + "z": -213.541016 }, - "Rotation": 256.630219, + "Rotation": 348.435364, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Rocks", + "BotZoneName": "Zone_Containers", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2501,24 +2826,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 2, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "5e65154a-be4c-4d82-b6c7-65c2ab0123e9", + "Id": "61840dd5-4d19-4f8c-b386-feed2db3efce", "Infiltration": "", "Position": { - "x": -152.920013, - "y": 37.55528, - "z": 138.09 + "x": -100.570007, + "y": 10.6186514, + "z": -844.319946 }, - "Rotation": 128.073547, + "Rotation": 4.104724, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Containers", - "Categories": ["Player", "Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2527,24 +2852,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 77 } }, - "CorePointId": 11, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "5f785f8e-a59d-40f5-b809-23e099d95322", - "Infiltration": "", + "Id": "61aba24c-79d9-445f-8a1c-f887b36a8417", + "Infiltration": "North", "Position": { - "x": -131.030029, - "y": 10.5248337, - "z": -807.85 + "x": -7.6000576, + "y": 10.72, + "z": -800.92 }, - "Rotation": 71.051445, - "Sides": ["Savage"] + "Rotation": 358.2052, + "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_TreatmentContainers", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2553,59 +2878,7 @@ "y": 0, "z": 0 }, - "Radius": 30 - } - }, - "CorePointId": 11, - "DelayToCanSpawnSec": 3600, - "Id": "60e4b3d9-4fe1-4ed1-9b0f-0a1dd7113e18", - "Infiltration": "", - "Position": { - "x": -130.090027, - "y": 7.734501, - "z": -747.189941 - }, - "Rotation": 256.404022, - "Sides": ["Savage"] - }, - { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 77 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "61aba24c-79d9-445f-8a1c-f887b36a8417", - "Infiltration": "North", - "Position": { - "x": -7.6000576, - "y": 10.72, - "z": -800.92 - }, - "Rotation": 358.2052, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 70 + "Radius": 70 } }, "CorePointId": 0, @@ -2621,8 +2894,8 @@ "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Island", + "Categories": ["Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2631,45 +2904,19 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 5, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "631ea928-02f4-4530-a701-1c33fd5cc240", - "Infiltration": "", - "Position": { - "x": -248.670044, - "y": 0.7086563, - "z": -379.630035 - }, - "Rotation": 13.6, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_TreatmentRocks", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 30 - } - }, - "CorePointId": 12, - "DelayToCanSpawnSec": 3600, - "Id": "634e45e0-5531-49fb-ba4a-cac293b3000b", + "Id": "64322540-a704-4d6c-9ba5-1d4ded2bf28a", "Infiltration": "", "Position": { - "x": -180.530014, - "y": 5.02565, - "z": -647.310059 + "x": 329.55, + "y": 1.75564957, + "z": 505.63 }, - "Rotation": 256.404022, + "Rotation": 115.016975, "Sides": ["Savage"] }, { @@ -2725,8 +2972,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentContainers", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2735,19 +2982,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 30 } }, - "CorePointId": 6, - "DelayToCanSpawnSec": 4, - "Id": "660c568b-186f-457d-ad55-5d70d1f48e55", + "CorePointId": 15, + "DelayToCanSpawnSec": 3600, + "Id": "6643cdd3-37af-45fb-93f4-2c2f9b2ec580", "Infiltration": "", "Position": { - "x": -8.480011, - "y": 0.763252258, - "z": 81.53 + "x": -66.66, + "y": 4.92964935, + "z": -753.74 }, - "Rotation": 113.936485, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -2776,6 +3023,32 @@ "Rotation": 266.5001, "Sides": ["Pmc"] }, + { + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "66d74b51-9203-42e6-bef5-9e452ba871dc", + "Infiltration": "", + "Position": { + "x": 35.19998, + "y": 7.20565033, + "z": 95.5 + }, + "Rotation": 256.630219, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -2828,58 +3101,6 @@ "Rotation": 134.737534, "Sides": ["All"] }, - { - "BotZoneName": "Zone_Rocks", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 120 - } - }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "68988ed2-79f2-41d4", - "Infiltration": "", - "Position": { - "x": -145.71, - "y": 37.33565, - "z": 144.76 - }, - "Rotation": 236.87, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 120 - } - }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "68dc4f72-944c-4112-b5be-d4fa2b67f88b", - "Infiltration": "", - "Position": { - "x": 44.8999939, - "y": 2.95565033, - "z": -211.6 - }, - "Rotation": 256.630219, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -2933,33 +3154,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Island", - "Categories": ["Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 18, - "DelayToCanSpawnSec": 4, - "Id": "6abb6205-62c8-43c9-b7e1-b3faab3821e3", - "Infiltration": "", - "Position": { - "x": 329.55, - "y": 1.75564957, - "z": 505.63 - }, - "Rotation": 115.016975, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_LongRoad", + "BotZoneName": "Zone_Chalet", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2969,23 +3164,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 130 } }, - "CorePointId": 6, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "6b24a87d-27cc-457e-868d-857affb6c58d", + "Id": "6b305477-7b1e-4ca1-9139-a4e3848e003c", "Infiltration": "", "Position": { - "x": 38.4199829, - "y": 9.165649, - "z": 1.27999878 + "x": -93.54001, + "y": 17.63565, + "z": -13.2000122 }, - "Rotation": 256.630219, + "Rotation": 208.517929, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Rocks", + "BotZoneName": "", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2995,19 +3190,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 2, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "6dce8130-db22-49d4-9415-361805bdc271", + "Id": "6b7c5283-2d13-46c8-ac57-73f99472cb39", "Infiltration": "", "Position": { - "x": -127.975006, - "y": 39.88065, - "z": 87.26099 + "x": -321.75, + "y": 1.06699753, + "z": -331.889984 }, - "Rotation": 23.3241863, + "Rotation": 60.8000031, "Sides": ["Savage"] }, { @@ -3037,7 +3232,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_TreatmentContainers", + "BotZoneName": "Zone_Hellicopter", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3047,17 +3242,17 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 100 } }, - "CorePointId": 15, + "CorePointId": 9, "DelayToCanSpawnSec": 3600, - "Id": "6ed3e863-6eb3-4341-a0d8-334f2484169f", + "Id": "71331f39-d65f-4b08-924e-366209cb46b6", "Infiltration": "", "Position": { - "x": -106.490021, - "y": 4.94265, - "z": -754.910034 + "x": -83.70001, + "y": -0.106666565, + "z": -541.36 }, "Rotation": 256.404022, "Sides": ["Savage"] @@ -3115,7 +3310,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_LongRoad", + "BotZoneName": "Zone_Rocks", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3128,16 +3323,16 @@ "Radius": 120 } }, - "CorePointId": 6, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "73d83024-b0b0-484e-9dd4-5c5a38db3202", + "Id": "723e2598-d770-4243-9d68-4b932a9f91de", "Infiltration": "", "Position": { - "x": 39.1399841, - "y": 11.02565, - "z": -11.1400146 + "x": -144.540009, + "y": 37.33565, + "z": 149.299988 }, - "Rotation": 256.630219, + "Rotation": 128.073547, "Sides": ["Savage"] }, { @@ -3167,7 +3362,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Chalet", + "BotZoneName": "Zone_DestroyedHouse", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3177,24 +3372,24 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 120 } }, - "CorePointId": 7, + "CorePointId": 21, "DelayToCanSpawnSec": 4, - "Id": "74d74961-84a9-4274-b62b-77537f9721b9", + "Id": "74bed501-a620-4f27-bac1-b7e3a556dc22", "Infiltration": "", "Position": { - "x": -128.51001, - "y": 20.06565, - "z": -106.149994 + "x": 86.00998, + "y": 0.5456505, + "z": 363.7 }, - "Rotation": 81.6740341, + "Rotation": 116.208389, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3203,24 +3398,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 120 } }, - "CorePointId": 0, + "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "751ed8cb-d9c5-4c3a-ad31-7ae979f66316", - "Infiltration": "North", + "Id": "74d88c3b-3b82-4949-9ab1-98c30141e588", + "Infiltration": "", "Position": { - "x": 7.01300144, - "y": 6.3, - "z": -26.49399 + "x": 47.00998, + "y": 7.28757858, + "z": 328.47 }, - "Rotation": 179.094986, - "Sides": ["Pmc"] + "Rotation": 116.208389, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_TreatmentRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3229,23 +3424,23 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 77 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 3600, - "Id": "76ccb05b-3e51-45ab-994c-8409139dd913", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "751ed8cb-d9c5-4c3a-ad31-7ae979f66316", + "Infiltration": "North", "Position": { - "x": -198.790009, - "y": 5.189949, - "z": -697.670044 + "x": 7.01300144, + "y": 6.3, + "z": -26.49399 }, - "Rotation": 256.404022, - "Sides": ["Savage"] + "Rotation": 179.094986, + "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Containers", + "BotZoneName": "Zone_Rocks", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3255,23 +3450,23 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 120 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "76d93e79-9740-4c26-9c83-b4b3a0c478fe", + "Id": "75955117-2bf2-4677-90d3-ebb4535ef1b4", "Infiltration": "", "Position": { - "x": 35.9400024, - "y": 12.0053339, - "z": -833.12 + "x": -105.090027, + "y": 33.39565, + "z": 89.31 }, - "Rotation": 4.104724, + "Rotation": 275.2177, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", + "BotZoneName": "Zone_LongRoad", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3281,19 +3476,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 120 } }, - "CorePointId": 3, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "7add102b-7b4e-4022-8054-e1d7280e287e", + "Id": "76d4a9a5-bcda-46af-b16c-e87fb867492b", "Infiltration": "", "Position": { - "x": -222.950012, - "y": 12.668705, - "z": -186.459991 + "x": 53.5499878, + "y": 11.145649, + "z": 47.9299927 }, - "Rotation": 194.970718, + "Rotation": 256.630219, "Sides": ["Savage"] }, { @@ -3376,7 +3571,7 @@ }, { "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3385,23 +3580,23 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 35 } }, - "CorePointId": 26, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "7d680389-9562-4d6a-961e-78f206e84d22", + "Id": "7cc47cc4-c9b3-4f8a-a5fd-9be54d43f752", "Infiltration": "", "Position": { - "x": -93.54001, - "y": 17.63565, - "z": -13.2000122 + "x": -124.53, + "y": 18.21967, + "z": -135.450012 }, - "Rotation": 208.517929, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_LongRoad", + "BotZoneName": "Zone_Containers", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3411,45 +3606,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 160 } }, - "CorePointId": 6, + "CorePointId": 24, "DelayToCanSpawnSec": 4, - "Id": "7d876011-d9cb-4874-ad8a-61fd488b6c87", - "Infiltration": "", - "Position": { - "x": -12.6200256, - "y": 2.82564926, - "z": 108.479996 - }, - "Rotation": 113.936485, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_TreatmentRocks", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 30 - } - }, - "CorePointId": 12, - "DelayToCanSpawnSec": 3600, - "Id": "7e7fa95f-ad64-498b-b405-571e5307f9a5", + "Id": "800af768-9fbd-407a-9544-f76e13b5a523", "Infiltration": "", "Position": { - "x": -180.49, - "y": 5.02565, - "z": -633.040039 + "x": -51.1490173, + "y": 10.70362, + "z": -794.814941 }, - "Rotation": 256.404022, + "Rotation": 129.653656, "Sides": ["Savage"] }, { @@ -3479,7 +3648,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Village", + "BotZoneName": "Zone_Chalet", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3489,24 +3658,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 130 } }, - "CorePointId": 3, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "8215c14c-a052-4ab7-b8bf-69da9038ea86", + "Id": "81bd9e3f-0ff6-49af-8769-00cb781786c5", "Infiltration": "", "Position": { - "x": -120.820007, - "y": 11.11565, - "z": -228.91 + "x": -109.380005, + "y": 17.66565, + "z": -24.2799988 }, - "Rotation": 244.211288, + "Rotation": 208.517929, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Island", + "Categories": ["Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3515,19 +3684,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 50 } }, - "CorePointId": 3, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "8462c88e-0e9c-466c-8454-6d2ddc2a679d", + "Id": "84047c7f-e461-460e-8378-6f85a74b835f", "Infiltration": "", "Position": { - "x": -161.500015, - "y": 9.84565, - "z": -261.699982 + "x": 356.39, + "y": 15.51865, + "z": 553.695 }, - "Rotation": 348.435364, + "Rotation": 158.316177, "Sides": ["Savage"] }, { @@ -3661,8 +3830,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_RoofRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3671,23 +3840,23 @@ "y": 0, "z": 0 }, - "Radius": 240 + "Radius": 120 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 3600, - "Id": "8bbbc6ef-0d30-462f-9b0f-89bd3b6f93c8", + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "8a5e9fbb-8014-4711-abc2-bc9010c30721", "Infiltration": "", "Position": { - "x": -185.700012, - "y": 13.9855, - "z": -693.6416 + "x": 49.4099731, + "y": 1.63565063, + "z": -147.12 }, - "Rotation": 256.404022, + "Rotation": 256.630219, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_Rocks", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3700,21 +3869,21 @@ "Radius": 120 } }, - "CorePointId": 20, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "8bc011ed-0ada-4bde-9db4-7f589f0a2bf9", + "Id": "8b8f52d5-820c-4c25-aec0-94671c8c7b55", "Infiltration": "", "Position": { - "x": 25.0499878, - "y": 6.88413239, - "z": 374.950348 + "x": -145.71, + "y": 37.33565, + "z": 144.76 }, - "Rotation": 116.208389, + "Rotation": 236.87, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Hellicopter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3723,21 +3892,47 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 120 } }, - "CorePointId": 9, - "DelayToCanSpawnSec": 3600, - "Id": "8cbafafd-9e9c-4da0-8d1b-9623aa2d8917", + "CorePointId": 19, + "DelayToCanSpawnSec": 4, + "Id": "8c8942d2-33d7-4926-b61e-b844b10fb18b", "Infiltration": "", "Position": { - "x": -56.8900146, - "y": 1.88565063, - "z": -586.440063 + "x": 54.1099854, + "y": 11.9674034, + "z": 197.849991 }, "Rotation": 256.404022, "Sides": ["Savage"] }, + { + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "8fae9265-05f2-4210-bdcb-11834b1424a7", + "Infiltration": "", + "Position": { + "x": 38.4199829, + "y": 9.165649, + "z": 1.27999878 + }, + "Rotation": 256.630219, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3765,8 +3960,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Island", - "Categories": ["Boss"], + "BotZoneName": "Zone_Containers", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3775,24 +3970,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 100 } }, - "CorePointId": 18, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "909c90fc-fba2-400e-8545-60edc039886e", + "Id": "909fdb57-c4d6-4740-8907-d8ee324ab9bc", "Infiltration": "", "Position": { - "x": 371.841, - "y": 15.1656494, - "z": 571.147 - }, - "Rotation": 115.016975, + "x": 31.8799744, + "y": 10.768651, + "z": -827.27 + }, + "Rotation": 279.3638, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "Zone_Hellicopter", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3801,24 +3996,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 60 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "93427305-4f03-44d6-8690-7c24dbbb4128", - "Infiltration": "North", + "CorePointId": 9, + "DelayToCanSpawnSec": 3600, + "Id": "91f49ddc-7c01-4569-9b51-6d7ac019120b", + "Infiltration": "", "Position": { - "x": 6.92999363, - "y": 6.16, - "z": -22.1199818 + "x": -90.26001, + "y": 1.71564865, + "z": -577.11 }, - "Rotation": 179.094986, - "Sides": ["Pmc"] + "Rotation": 256.404022, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "Zone_Chalet", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3827,24 +4022,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 25, "DelayToCanSpawnSec": 4, - "Id": "934c3322-9145-4406-a23f-c2e90b99b969", - "Infiltration": "North", + "Id": "92c20fd6-5480-4298-a104-dbb7b09f0e6b", + "Infiltration": "", "Position": { - "x": -12.26741, - "y": 0.9448967, - "z": -133.069336 + "x": -84.91, + "y": 16.95565, + "z": 20.1499939 }, - "Rotation": 151.1096, - "Sides": ["All"] + "Rotation": 208.517929, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_RoofRocks", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3853,24 +4048,24 @@ "y": 0, "z": 0 }, - "Radius": 40 + "Radius": 77 } }, - "CorePointId": 13, - "DelayToCanSpawnSec": 3600, - "Id": "940ff6d2-58dc-4343-aae0-baa05201061b", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "93427305-4f03-44d6-8690-7c24dbbb4128", + "Infiltration": "North", "Position": { - "x": -181.590012, - "y": 14.0029526, - "z": -659.829956 + "x": 6.92999363, + "y": 6.16, + "z": -22.1199818 }, - "Rotation": 256.404022, - "Sides": ["Savage"] + "Rotation": 179.094986, + "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3879,24 +4074,24 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 70 } }, - "CorePointId": 26, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "949f23a6-6836-4528-ad02-267ec42227d5", - "Infiltration": "", + "Id": "934c3322-9145-4406-a23f-c2e90b99b969", + "Infiltration": "North", "Position": { - "x": -73.20001, - "y": 11.4756508, - "z": 4.47998047 + "x": -12.26741, + "y": 0.9448967, + "z": -133.069336 }, - "Rotation": 208.517929, - "Sides": ["Savage"] + "Rotation": 151.1096, + "Sides": ["All"] }, { "BotZoneName": "", - "Categories": ["Player", "Bot"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3905,24 +4100,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 77 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "94a28475-61e7-4f86-9618-2fe22fb5d6d3", - "Infiltration": "", + "Id": "97513a7b-d467-454a-8232-2e77f3e386ef", + "Infiltration": "North", "Position": { - "x": -321.75, - "y": 1.06699753, - "z": -331.889984 + "x": -3.76, + "y": 10.920001, + "z": -802.2 }, - "Rotation": 60.8000031, - "Sides": ["Savage"] + "Rotation": 358.2052, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "Zone_Bridge", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3931,20 +4126,20 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 120 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "97513a7b-d467-454a-8232-2e77f3e386ef", - "Infiltration": "North", + "Id": "976a4d47-bbed-4966-855b-5433c8407921", + "Infiltration": "", "Position": { - "x": -3.76, - "y": 10.920001, - "z": -802.2 + "x": 6.5, + "y": 3.62565231, + "z": -311.800018 }, - "Rotation": 358.2052, - "Sides": ["Pmc"] + "Rotation": 297.348724, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4025,8 +4220,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Rocks", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4035,19 +4230,19 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 35 } }, - "CorePointId": 7, + "CorePointId": 22, "DelayToCanSpawnSec": 4, - "Id": "99260787-9de9-4d2f-a9b9-31f0fcbf53e8", + "Id": "98c771f5-a2ab-4979-a514-654576598195", "Infiltration": "", "Position": { - "x": -124.53, - "y": 18.21967, - "z": -135.450012 + "x": -113.200012, + "y": 30.6256828, + "z": 153.7 }, - "Rotation": 81.6740341, + "Rotation": 195.903351, "Sides": ["Savage"] }, { @@ -4077,33 +4272,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Containers", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 100 - } - }, - "CorePointId": 1, - "DelayToCanSpawnSec": 4, - "Id": "99c851c9-7377-4ce3-ba9d-0e0c8ba1e2be", - "Infiltration": "", - "Position": { - "x": -102.210022, - "y": 10.6186514, - "z": -844.2999 - }, - "Rotation": 4.104724, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_Chalet", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4113,23 +4282,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 130 } }, - "CorePointId": 20, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "9a28153d-431f-4a28-bb09-4a93d02b0928", + "Id": "9aae4ab4-74ff-4384-b691-03b1ed0b5fb7", "Infiltration": "", "Position": { - "x": 47.00998, - "y": 7.28757858, - "z": 328.47 + "x": -128.51001, + "y": 20.06565, + "z": -106.149994 }, - "Rotation": 116.208389, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_Village", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4139,24 +4308,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 21, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "9a2f575a-ecfe-48c7-bd25-d3aa9c1b3a2d", + "Id": "9ab140af-b8b3-4656-b7cf-b9bcd6393779", "Infiltration": "", "Position": { - "x": 66.3899841, - "y": 6.049885, - "z": 374.950348 + "x": -149.85, + "y": 11.95565, + "z": -200.76001 }, - "Rotation": 116.208389, + "Rotation": 244.211288, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Blockpost", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4165,19 +4334,19 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 60 } }, - "CorePointId": 26, - "DelayToCanSpawnSec": 4, - "Id": "9ab07c01-7d6e-4bd5-b2e8-fd93e44d8137", + "CorePointId": 14, + "DelayToCanSpawnSec": 3600, + "Id": "9bc9c196-b64b-465b-ae16-c91ebd5080ef", "Infiltration": "", "Position": { - "x": -81, - "y": 16.4738655, - "z": 19.2799988 + "x": 31.8899841, + "y": 4.7986509999999996, + "z": -451.1 }, - "Rotation": 208.517929, + "Rotation": 26.8442173, "Sides": ["Savage"] }, { @@ -4232,32 +4401,6 @@ "Rotation": 141.822754, "Sides": ["All"] }, - { - "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 130 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "9e623a8b-1645-4b5f-8379-5c0a1cbb39e1", - "Infiltration": "", - "Position": { - "x": -109.380005, - "y": 17.66565, - "z": -24.2799988 - }, - "Rotation": 208.517929, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -4285,8 +4428,8 @@ "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "Zone_Island", + "Categories": ["Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4295,24 +4438,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "9f6cbe96-7d68-45bf-8f4b-4ccac2550961", - "Infiltration": "North", + "Id": "9eedd190-88a3-42f2-84ae-9483691d9986", + "Infiltration": "", "Position": { - "x": -10.31, - "y": 10.63, - "z": -802.38 - }, - "Rotation": 358.2052, - "Sides": ["Pmc"] + "x": 365.69, + "y": 15.5336494, + "z": 545.678 + }, + "Rotation": 19.1368885, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4321,20 +4464,20 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 77 } }, - "CorePointId": 3, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9f8dbb1e-cb76-49aa-ba99-1448705341f7", - "Infiltration": "", + "Id": "9f6cbe96-7d68-45bf-8f4b-4ccac2550961", + "Infiltration": "North", "Position": { - "x": -178.26001, - "y": 12.25, - "z": -193.290009 + "x": -10.31, + "y": 10.63, + "z": -802.38 }, - "Rotation": 194.970718, - "Sides": ["Savage"] + "Rotation": 358.2052, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -4373,17 +4516,17 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 40 } }, - "CorePointId": 9, + "CorePointId": 11, "DelayToCanSpawnSec": 3600, - "Id": "a033450e-822c-4153-b613-a8d61858e332", + "Id": "a068f918-1c5f-4311-b088-2c294f1bdaa1", "Infiltration": "", "Position": { - "x": -84.34003, - "y": -0.104351044, - "z": -565.560059 + "x": -130.75, + "y": 4.945652, + "z": -738.22 }, "Rotation": 256.404022, "Sides": ["Savage"] @@ -4414,6 +4557,58 @@ "Rotation": 294.262756, "Sides": ["All"] }, + { + "BotZoneName": "Zone_SniperPeak", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 2000, + "Id": "a22f75f6-0e9a-4e19-be56-a9099861c045", + "Infiltration": "", + "Position": { + "x": -71.78, + "y": 39.2056541, + "z": 451.11 + }, + "Rotation": 256.404022, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "a250b7d8-8b4e-4658-8a6c-103081685256", + "Infiltration": "", + "Position": { + "x": -161.500015, + "y": 9.84565, + "z": -261.699982 + }, + "Rotation": 348.435364, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -4441,7 +4636,33 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_TreatmentBeach", + "BotZoneName": "Zone_Chalet", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 130 + } + }, + "CorePointId": 26, + "DelayToCanSpawnSec": 4, + "Id": "a552c808-942d-4db8-b09b-abfdd3ef45fe", + "Infiltration": "", + "Position": { + "x": -81, + "y": 16.4738655, + "z": 19.2799988 + }, + "Rotation": 208.517929, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_RoofContainers", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4454,16 +4675,16 @@ "Radius": 30 } }, - "CorePointId": 1, + "CorePointId": 11, "DelayToCanSpawnSec": 3600, - "Id": "a3cee408-9055-44c3-b21e-bae5eb4097c8", + "Id": "a59edfb4-1545-4908-9391-42ed1653821a", "Infiltration": "", "Position": { - "x": 54.1099854, - "y": 4.95064926, - "z": -606.329956 + "x": -124.830017, + "y": 14.0356522, + "z": -738.319946 }, - "Rotation": 81.6740341, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -4482,7 +4703,7 @@ }, "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "a9793c49-762e-4cb8-8a5f-67dcda49f860", + "Id": "a69d60a1-8252-4404-9e58-87b1dfbcd2ac", "Infiltration": "", "Position": { "x": 41.1099854, @@ -4492,6 +4713,32 @@ "Rotation": 116.208389, "Sides": ["Savage"] }, + { + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 6, + "DelayToCanSpawnSec": 4, + "Id": "a91f971b-d962-4be7-83eb-a4319e0fa8ad", + "Infiltration": "", + "Position": { + "x": 48.19998, + "y": 1.645649, + "z": -116.300018 + }, + "Rotation": 256.630219, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -4519,8 +4766,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Bridge", - "Categories": ["Bot"], + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4532,16 +4779,16 @@ "Radius": 120 } }, - "CorePointId": 4, + "CorePointId": 19, "DelayToCanSpawnSec": 4, - "Id": "acf54a2b-c564-4c05-afaf-b7093c3255c0", + "Id": "ab68fd30-5aa4-4091-9987-a3772136bc00", "Infiltration": "", "Position": { - "x": 12.5099792, - "y": 6.105652, - "z": -238.940033 + "x": 29.4199829, + "y": 4.57564926, + "z": 133.43 }, - "Rotation": 297.348724, + "Rotation": 256.630219, "Sides": ["Savage"] }, { @@ -4571,34 +4818,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 120 - } - }, - "CorePointId": 6, - "DelayToCanSpawnSec": 4, - "Id": "ae838831-8e08-45d7-8960-1a4032c0078c", - "Infiltration": "", - "Position": { - "x": -5.5, - "y": 1.90975571, - "z": 37.3999939 - }, - "Rotation": 113.936485, - "Sides": ["Savage"] - }, - { - "BotZoneName": "Zone_LongRoad", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Bridge", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4610,21 +4831,21 @@ "Radius": 120 } }, - "CorePointId": 6, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "af93ff54-264c-4697-a0dc-36b6900eb864", + "Id": "b077ec12-e061-4971-a60f-986d5ed226fe", "Infiltration": "", "Position": { - "x": 53.5499878, - "y": 11.145649, - "z": 47.9299927 + "x": -49.6600037, + "y": 5.86565, + "z": -290.65 }, "Rotation": 256.630219, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Island", + "Categories": ["Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4633,23 +4854,23 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 50 } }, - "CorePointId": 25, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "b0bb6d46-3b34-4db9-a4b6-e28a0b0cc664", + "Id": "b10fefc8-e1a2-478a-b2ca-04ac0d0f7cac", "Infiltration": "", "Position": { - "x": -84.91, - "y": 16.95565, - "z": 20.1499939 + "x": 392.156, + "y": 15.2086487, + "z": 567.006 }, - "Rotation": 208.517929, + "Rotation": 115.016975, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Containers", + "BotZoneName": "", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4662,16 +4883,16 @@ "Radius": 100 } }, - "CorePointId": 1, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "b1b1dbcd-c86c-47b9-8577-04a51263f1b3", + "Id": "b193ef40-123d-48c6-a1ad-f1fb09a20ef5", "Infiltration": "", "Position": { - "x": 31.8799744, - "y": 10.768651, - "z": -827.27 + "x": -321.065338, + "y": 1.67699814, + "z": -334.890045 }, - "Rotation": 279.3638, + "Rotation": 52.1100044, "Sides": ["Savage"] }, { @@ -4727,8 +4948,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Blockpost", - "Categories": ["Bot"], + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4737,24 +4958,24 @@ "y": 0, "z": 0 }, - "Radius": 240 + "Radius": 60 } }, - "CorePointId": 14, - "DelayToCanSpawnSec": 3600, - "Id": "b3c56d60-89c9-4066-ba26-ab6cf3f980a2", + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "b712c860-4678-45b7-a39c-ad16f1e73c4d", "Infiltration": "", "Position": { - "x": -1.39001465, - "y": 1.78865123, - "z": -470.79 + "x": -87.52002, + "y": 6.034649, + "z": -269.98 }, - "Rotation": 26.8442173, + "Rotation": 348.435364, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Bridge", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4763,24 +4984,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 4, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "b49d04db-99f0-49e5-99a2-9b8be710da3b", + "Id": "b7a7460a-c8b6-472d-bf3b-d4a41d1f5387", "Infiltration": "", "Position": { - "x": -49.6600037, - "y": 5.86565, - "z": -290.65 - }, - "Rotation": 256.630219, + "x": -246.780029, + "y": 1.246952, + "z": -381.949982 + }, + "Rotation": 4.91000032, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player", "Bot"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4789,20 +5010,20 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 70 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b4cdb703-82be-415a-9974-bc22653ac07e", - "Infiltration": "", + "Id": "b7bea9fa-5af8-47e2-b3d1-d2be915cbf31", + "Infiltration": "North", "Position": { - "x": -321.065338, - "y": 1.67699814, - "z": -334.890045 + "x": -443.404419, + "y": 28.4408989, + "z": -371.109375 }, - "Rotation": 52.1100044, - "Sides": ["Savage"] + "Rotation": 294.262756, + "Sides": ["All"] }, { "BotZoneName": "Zone_Rocks", @@ -4820,19 +5041,19 @@ }, "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "b695a9dd-cb34-4058-84a2-94f12d7245e6", + "Id": "ba0ad9af-e742-4380-aa57-5000f75b44e5", "Infiltration": "", "Position": { - "x": -105.090027, - "y": 33.39565, - "z": 89.31 + "x": -128.050018, + "y": 39.9256477, + "z": 74.29999 }, - "Rotation": 275.2177, + "Rotation": 23.3241863, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4841,24 +5062,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "b7bea9fa-5af8-47e2-b3d1-d2be915cbf31", - "Infiltration": "North", + "Id": "bc7d2613-a056-4d4c-8e43-b703b211d3d3", + "Infiltration": "", "Position": { - "x": -443.404419, - "y": 28.4408989, - "z": -371.109375 + "x": -84.46002, + "y": 5.86565, + "z": -271.620026 }, - "Rotation": 294.262756, - "Sides": ["All"] + "Rotation": 348.435364, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Hellicopter", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4867,24 +5088,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 60 } }, - "CorePointId": 5, - "DelayToCanSpawnSec": 4, - "Id": "b9853b5e-6fa4-43c9-9593-b0a2b05eade1", + "CorePointId": 9, + "DelayToCanSpawnSec": 3600, + "Id": "be8fb70e-ab66-40ef-a82e-2a49c2d9ed43", "Infiltration": "", "Position": { - "x": -246.109985, - "y": 1.216999, - "z": -379.630035 + "x": -62.53, + "y": 3.95565033, + "z": -586.410034 }, - "Rotation": 4.91000032, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_TreatmentBeach", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4893,24 +5114,24 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 70 } }, - "CorePointId": 10, - "DelayToCanSpawnSec": 3600, - "Id": "bb11993f-6793-4aee-a9d0-1e39d36e3894", - "Infiltration": "", + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "bf33b549-99fd-4974-956a-0be2cc5174e0", + "Infiltration": "North", "Position": { - "x": 51.8299866, - "y": 5.187237, - "z": -589.9 + "x": -382.737427, + "y": 24.7548981, + "z": -512.699341 }, - "Rotation": 81.6740341, - "Sides": ["Savage"] + "Rotation": 141.822754, + "Sides": ["All"] }, { - "BotZoneName": "Zone_Blockpost", - "Categories": ["Bot"], + "BotZoneName": "Zone_RoofRocks", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4919,24 +5140,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 40 } }, - "CorePointId": 14, + "CorePointId": 13, "DelayToCanSpawnSec": 3600, - "Id": "bcab93a1-4305-4a13-9989-c538db00a4e2", + "Id": "bf975195-82da-46b7-9f69-9257a3f2dce0", "Infiltration": "", "Position": { - "x": 31.8899841, - "y": 4.7986509999999996, - "z": -451.1 + "x": -190.35, + "y": 13.9855, + "z": -660.22 }, - "Rotation": 26.8442173, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Chalet", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4945,24 +5166,24 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 30 } }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "be0f5248-010f-4e40-93b6-a7e3a6246929", + "CorePointId": 1, + "DelayToCanSpawnSec": 3600, + "Id": "c05428b6-9ec3-4890-8c36-d62810187ca7", "Infiltration": "", "Position": { - "x": -123.577026, - "y": 18.21967, - "z": -132.695 + "x": 111.659973, + "y": 5.02565, + "z": -671.98 }, "Rotation": 81.6740341, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4971,20 +5192,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 120 } }, - "CorePointId": 0, + "CorePointId": 19, "DelayToCanSpawnSec": 4, - "Id": "bf33b549-99fd-4974-956a-0be2cc5174e0", - "Infiltration": "North", + "Id": "c0c2f790-c283-4e6a-aecb-c6e5f06aa9e5", + "Infiltration": "", "Position": { - "x": -382.737427, - "y": 24.7548981, - "z": -512.699341 + "x": 54.22998, + "y": 11.75729, + "z": 200.579987 }, - "Rotation": 141.822754, - "Sides": ["All"] + "Rotation": 256.404022, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5013,8 +5234,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_DestroyedHouse", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Chalet", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5023,24 +5244,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 35 } }, - "CorePointId": 20, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "c3a94f22-5cc4-4867-a1be-221b508bca08", + "Id": "c269b7f5-17fa-4c7e-b5a6-bbacb5ce0003", "Infiltration": "", "Position": { - "x": 31.75998, - "y": 7.055649, - "z": 371.66 + "x": -123.577026, + "y": 18.21967, + "z": -132.695 }, - "Rotation": 116.208389, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Island", - "Categories": ["Boss"], + "BotZoneName": "Zone_Blockpost", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5049,24 +5270,24 @@ "y": 0, "z": 0 }, - "Radius": 40 + "Radius": 140 } }, - "CorePointId": 18, - "DelayToCanSpawnSec": 4, - "Id": "c3d1583f-a2bb-4898-a416-f07b38009eda", + "CorePointId": 14, + "DelayToCanSpawnSec": 3600, + "Id": "c3bcd168-85f1-48c8-a46c-58727bfeb632", "Infiltration": "", "Position": { - "x": 332.006958, - "y": 2.03665161, - "z": 518.079 + "x": 12.9400024, + "y": 4.7986509999999996, + "z": -447.53 }, - "Rotation": 190.619385, + "Rotation": 26.8442173, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Rocks", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5075,19 +5296,45 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 35 } }, - "CorePointId": 3, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "c43603f1-97c7-4d3e-b97f-9ab2badaf2ee", + "Id": "c4219a3c-1490-4883-9977-51ca0cb89280", "Infiltration": "", "Position": { - "x": -130.450012, - "y": 11.2891312, - "z": -205.959991 + "x": -69.18002, + "y": 26.78165, + "z": 112.903 }, - "Rotation": 244.211288, + "Rotation": 195.903351, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_RoofRocks", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 240 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 3600, + "Id": "c4a79941-9132-4067-9678-b5bbe1104713", + "Infiltration": "", + "Position": { + "x": -185.700012, + "y": 13.9855, + "z": -693.6416 + }, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -5117,8 +5364,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Rocks", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentContainers", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5127,19 +5374,19 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "c9240dcf-85b2-48b4-94f3-02bce0fad90c", + "CorePointId": 15, + "DelayToCanSpawnSec": 3600, + "Id": "c820f8ff-0b02-4078-a5ea-27604950b4f8", "Infiltration": "", "Position": { - "x": -117.630005, - "y": 37.0256538, - "z": 113.7 + "x": -109.02002, + "y": 4.92964935, + "z": -729.52 }, - "Rotation": 275.2177, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -5169,8 +5416,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Bridge", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5179,25 +5426,25 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 70 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ca4582c8-adc1-4ef0-9044-7d3c2993241b", - "Infiltration": "", + "Id": "cb454f82-501c-4633-a1ab-2ae86c2559d8", + "Infiltration": "North", "Position": { - "x": 6.5, - "y": 3.62565231, - "z": -311.800018 + "x": -217.447433, + "y": 12.584898, + "z": -181.449341 }, - "Rotation": 297.348724, - "Sides": ["Savage"] + "Rotation": 4.4928484, + "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], + "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { "Center": { @@ -5205,24 +5452,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "cb454f82-501c-4633-a1ab-2ae86c2559d8", - "Infiltration": "North", + "Id": "cbee66a4-e0f0-476c-9a44-c042ab290cd5", + "Infiltration": "", "Position": { - "x": -217.447433, - "y": 12.584898, - "z": -181.449341 + "x": -237.310013, + "y": 14.7656517, + "z": -170.290009 }, - "Rotation": 4.4928484, - "Sides": ["All"] + "Rotation": 194.970718, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Bridge", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5231,23 +5478,23 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 77 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "cb6eb036-c7d3-4eea-84af-516792738995", - "Infiltration": "", + "Id": "cdabcf05-fa38-4640-89a6-294133b99a5c", + "Infiltration": "North", "Position": { - "x": 9.919983, - "y": 6.11565, - "z": -243.28 + "x": 8.798004, + "y": 6.16, + "z": -25.9239826 }, - "Rotation": 297.348724, - "Sides": ["Savage"] + "Rotation": 179.094986, + "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_Rocks", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5260,44 +5507,18 @@ "Radius": 120 } }, - "CorePointId": 19, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "cd270f80-5ec5-4d6c-9615-b60ce6a55f52", + "Id": "ce07d1ba-6bc7-4f65-898c-e2309ec3bbf9", "Infiltration": "", "Position": { - "x": 54.1099854, - "y": 11.9674034, - "z": 197.849991 + "x": -117.630005, + "y": 37.0256538, + "z": 113.7 }, - "Rotation": 256.404022, + "Rotation": 275.2177, "Sides": ["Savage"] }, - { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 77 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "cdabcf05-fa38-4640-89a6-294133b99a5c", - "Infiltration": "North", - "Position": { - "x": 8.798004, - "y": 6.16, - "z": -25.9239826 - }, - "Rotation": 179.094986, - "Sides": ["Pmc"] - }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -5351,8 +5572,8 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_Rocks", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_Blockpost", + "Categories": ["Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5361,24 +5582,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "cf98b1f0-0e1e-4fe6-a896-37e0a927576e", + "CorePointId": 14, + "DelayToCanSpawnSec": 3600, + "Id": "d0b5c25c-7439-45b9-a830-21a194831752", "Infiltration": "", "Position": { - "x": -144.540009, - "y": 37.33565, - "z": 149.299988 + "x": -8.040009, + "y": 7.268448, + "z": -452.21 }, - "Rotation": 128.073547, + "Rotation": 26.8442173, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_RoofBeach", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5387,24 +5608,24 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 120 } }, - "CorePointId": 8, - "DelayToCanSpawnSec": 3600, - "Id": "d0885831-706a-4703-97fa-ef11f0a7af61", + "CorePointId": 21, + "DelayToCanSpawnSec": 4, + "Id": "d12dfa52-8fa4-4e79-9d84-1edbc2b5edfb", "Infiltration": "", "Position": { - "x": 29.3799744, - "y": 14.0556488, - "z": -621.069946 + "x": 66.3899841, + "y": 6.049885, + "z": 374.950348 }, - "Rotation": 81.6740341, + "Rotation": 116.208389, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentRocks", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5413,24 +5634,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 30 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "d128dd3c-23a3-4d41-92a6-858333de53bc", + "CorePointId": 13, + "DelayToCanSpawnSec": 3600, + "Id": "d26c7492-92de-4513-907a-baeb78f34630", "Infiltration": "", "Position": { - "x": -133.150024, - "y": 11.353878, - "z": -203.670013 + "x": -199.430008, + "y": 4.92964935, + "z": -680.459961 }, - "Rotation": 244.211288, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Island", - "Categories": ["Boss"], + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5439,19 +5660,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 30 } }, - "CorePointId": 18, - "DelayToCanSpawnSec": 4, - "Id": "d2604e10-837f-40fd-899b-4d0b71de013d", + "CorePointId": 10, + "DelayToCanSpawnSec": 3600, + "Id": "d3097675-4b9b-43d2-a6c7-0dfe4cac7df6", "Infiltration": "", "Position": { - "x": 392.156, - "y": 15.2086487, - "z": 567.006 + "x": 105.329987, + "y": 7.43565, + "z": -529.73 }, - "Rotation": 115.016975, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { @@ -5481,8 +5702,8 @@ "Sides": ["All"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "Zone_Chalet", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5491,23 +5712,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 130 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "d72a6e26-6f13-4e56-b902-a50465fd844b", - "Infiltration": "North", + "Id": "d547f03e-36ca-4e98-a441-91ab2e6c7499", + "Infiltration": "", "Position": { - "x": 31.7, - "y": 6.66, - "z": -86.84 + "x": -116.140015, + "y": 17.79565, + "z": -32.0899963 }, - "Rotation": 266.5001, - "Sides": ["Pmc"] + "Rotation": 208.517929, + "Sides": ["Savage"] }, { - "BotZoneName": "", + "BotZoneName": "Zone_Containers", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5517,24 +5738,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 200 } }, - "CorePointId": 5, + "CorePointId": 24, "DelayToCanSpawnSec": 4, - "Id": "d8363139-1b5d-4fd6-8a18-1dcba352c6dd", + "Id": "d600851d-0b6a-4aff-855c-1e077c49a5ee", "Infiltration": "", "Position": { - "x": -299.567017, - "y": 0.110027313, - "z": -323.816 + "x": -16.74002, + "y": 10.5248337, + "z": -782.680054 }, - "Rotation": 85.4818039, + "Rotation": 129.653656, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Village", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5543,24 +5764,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 30 } }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "d8fb0212-ef94-4f8b-93e2-76b6a0e99fa2", + "CorePointId": 1, + "DelayToCanSpawnSec": 3600, + "Id": "d6ce18d5-98f4-43ae-920c-bd7fbc504f9c", "Infiltration": "", "Position": { - "x": -122.320007, - "y": 6.38565063, - "z": -270.449982 + "x": 55.44998, + "y": 4.94265, + "z": -633.199951 }, - "Rotation": 348.435364, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5574,19 +5795,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d994edf1-9146-4863-a39d-d223a1ecf5ea", - "Infiltration": "Tunnel", + "Id": "d72a6e26-6f13-4e56-b902-a50465fd844b", + "Infiltration": "North", "Position": { - "x": -167.4974, - "y": 30.4148979, - "z": -66.609314 + "x": 31.7, + "y": 6.66, + "z": -86.84 }, - "Rotation": 148.08, - "Sides": ["All"] + "Rotation": 266.5001, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player", "Bot"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5595,20 +5816,20 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 70 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d9bdfa7e-cf4f-4a2f-9667-a6d112a37729", - "Infiltration": "", + "Id": "d994edf1-9146-4863-a39d-d223a1ecf5ea", + "Infiltration": "Tunnel", "Position": { - "x": -322.080017, - "y": 1.177166, - "z": -329.620026 + "x": -167.4974, + "y": 30.4148979, + "z": -66.609314 }, - "Rotation": 52.1100044, - "Sides": ["Savage"] + "Rotation": 148.08, + "Sides": ["All"] }, { "BotZoneName": "", @@ -5664,7 +5885,7 @@ }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5673,20 +5894,20 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 100 } }, - "CorePointId": 0, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "df949703-1471-4367-a395-3afa78fcf886", - "Infiltration": "North", + "Id": "db8d86bc-0016-4535-88a6-e5c201961dc5", + "Infiltration": "", "Position": { - "x": 6.52999973, - "y": 6.16, - "z": -17.28998 + "x": -248.670044, + "y": 0.7086563, + "z": -379.630035 }, - "Rotation": 179.094986, - "Sides": ["Pmc"] + "Rotation": 13.6, + "Sides": ["Savage"] }, { "BotZoneName": "Zone_Rocks", @@ -5704,18 +5925,18 @@ }, "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "e0040c0c-4663-4997-b3b1-13bde2f2d4a2", + "Id": "dba7bf78-421b-4e32-bad4-1716e5550472", "Infiltration": "", "Position": { - "x": -113.915009, - "y": 36.7456474, - "z": 102.474991 + "x": -127.975006, + "y": 39.88065, + "z": 87.26099 }, - "Rotation": 275.2177, + "Rotation": 23.3241863, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_LongRoad", + "BotZoneName": "", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5725,19 +5946,123 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 100 } }, - "CorePointId": 4, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "e05fc1d0-27f7-48c6-9962-2a5117f328a5", + "Id": "dbea7bef-9e12-46f7-bbdf-62a80851cc14", "Infiltration": "", "Position": { - "x": 47.5999756, - "y": 0.4856491, - "z": -173.4 + "x": -322.080017, + "y": 1.177166, + "z": -329.620026 }, - "Rotation": 256.630219, + "Rotation": 52.1100044, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 100 + } + }, + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "dd9aa54a-5841-43af-af9c-e2fd2c7bbf0a", + "Infiltration": "", + "Position": { + "x": -249, + "y": 0.8441658, + "z": -382.21 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_TreatmentBeach", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 30 + } + }, + "CorePointId": 10, + "DelayToCanSpawnSec": 3600, + "Id": "de169321-3165-4434-84b4-c6d39a069191", + "Infiltration": "", + "Position": { + "x": 51.8299866, + "y": 5.187237, + "z": -589.9 + }, + "Rotation": 81.6740341, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 77 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "df949703-1471-4367-a395-3afa78fcf886", + "Infiltration": "North", + "Position": { + "x": 6.52999973, + "y": 6.16, + "z": -17.28998 + }, + "Rotation": 179.094986, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "Zone_SniperPeak", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 2000, + "Id": "dffa485d-70ef-4bdb-869b-c42d27ec8987", + "Infiltration": "", + "Position": { + "x": -58.01001, + "y": 39.5256538, + "z": 459.39 + }, + "Rotation": 256.404022, "Sides": ["Savage"] }, { @@ -5777,21 +6102,99 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 150 } }, "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "e39299f0-f38e-4956-a3a3-f12b4f9f97fa", + "Id": "e18c5b63-5aa7-419b-9f2d-340fe7546097", "Infiltration": "", "Position": { - "x": -100.570007, - "y": 10.6186514, - "z": -844.319946 + "x": -3.55001831, + "y": 12.0293722, + "z": -870.1699 }, "Rotation": 4.104724, "Sides": ["Savage"] }, + { + "BotZoneName": "Zone_RoofRocks", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 40 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 3600, + "Id": "e23d24cf-1b50-4ddb-b622-7d4aa930ab7d", + "Infiltration": "", + "Position": { + "x": -181.590012, + "y": 14.0029526, + "z": -659.829956 + }, + "Rotation": 256.404022, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_TreatmentRocks", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 30 + } + }, + "CorePointId": 12, + "DelayToCanSpawnSec": 3600, + "Id": "e2889fae-f2fb-44ce-a6df-be10d4908137", + "Infiltration": "", + "Position": { + "x": -180.530014, + "y": 5.02565, + "z": -647.310059 + }, + "Rotation": 256.404022, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "e3309a9d-1562-4836-9705-61f6df7daf2b", + "Infiltration": "", + "Position": { + "x": -213.080017, + "y": 12.7456512, + "z": -187.81 + }, + "Rotation": 177.55925, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -5819,8 +6222,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Containers", - "Categories": ["Player", "Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5829,23 +6232,75 @@ "y": 0, "z": 0 }, - "Radius": 150 + "Radius": 70 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e625ce3e-b83f-4cf5-bb75-485078977fb5", + "Id": "e8aad4bd-3990-45f0-9106-197afd5251a0", + "Infiltration": "Tunnel", + "Position": { + "x": -162.8074, + "y": 31.3148975, + "z": 254.180664 + }, + "Rotation": 104.295624, + "Sides": ["All"] + }, + { + "BotZoneName": "Zone_Hellicopter", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 9, + "DelayToCanSpawnSec": 3600, + "Id": "e9af3bc9-ebf6-4252-8551-ec64bd75c390", "Infiltration": "", "Position": { - "x": -3.55001831, - "y": 12.0293722, - "z": -870.1699 + "x": -84.34003, + "y": -0.104351044, + "z": -565.560059 }, - "Rotation": 4.104724, + "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_LongRoad", + "BotZoneName": "", + "Categories": ["Coop", "Group"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "ea3ee12f-63bf-40b0-86b2-d73e575e6b38", + "Infiltration": "North", + "Position": { + "x": 22.91, + "y": 6.01, + "z": -81.8 + }, + "Rotation": 266.5001, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "Zone_Village", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5855,21 +6310,47 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 60 } }, - "CorePointId": 19, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "e69e4bbb-e3c9-482c-a5d9-66a00b46d7ad", + "Id": "ec0f240b-d414-4041-b28c-6dd72f3a8c13", "Infiltration": "", "Position": { - "x": 29.4199829, - "y": 4.57564926, - "z": 133.43 + "x": -222.950012, + "y": 12.668705, + "z": -186.459991 }, - "Rotation": 256.630219, + "Rotation": 194.970718, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "ed90c8a5-b740-4aa2-868a-f91e710d4e17", + "Infiltration": "Tunnel", + "Position": { + "x": -171.187408, + "y": 30.3048973, + "z": -66.78931 + }, + "Rotation": 148.08, + "Sides": ["All"] + }, { "BotZoneName": "Zone_LongRoad", "Categories": ["Player", "Bot"], @@ -5886,19 +6367,19 @@ }, "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "e78f5fbc-3bef-4ac2-b57f-7600e50cb71e", + "Id": "ee12a020-cec0-496b-8755-42ddaf928be0", "Infiltration": "", "Position": { - "x": 35.19998, - "y": 7.20565033, - "z": 95.5 + "x": 40.03, + "y": 9.52565, + "z": 71.81999 }, "Rotation": 256.630219, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "Zone_DestroyedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5907,23 +6388,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 120 } }, - "CorePointId": 0, + "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "e8aad4bd-3990-45f0-9106-197afd5251a0", - "Infiltration": "Tunnel", + "Id": "ee4478fd-aa92-42b2-aa63-0bcd41d3215b", + "Infiltration": "", "Position": { - "x": -162.8074, - "y": 31.3148975, - "z": 254.180664 + "x": 31.75998, + "y": 7.055649, + "z": 371.66 }, - "Rotation": 104.295624, - "Sides": ["All"] + "Rotation": 116.208389, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_TreatmentContainers", + "BotZoneName": "Zone_Hellicopter", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5933,24 +6414,24 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 60 } }, - "CorePointId": 15, + "CorePointId": 9, "DelayToCanSpawnSec": 3600, - "Id": "e9f58e0c-0947-4061-95d1-d6fe3294dcb4", + "Id": "ef14df08-71d8-48c8-a8e5-db0c3af8f0ab", "Infiltration": "", "Position": { - "x": -94.92001, - "y": 4.93265152, - "z": -750.14 + "x": -56.8900146, + "y": 1.88565063, + "z": -586.440063 }, "Rotation": 256.404022, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5959,23 +6440,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 120 } }, - "CorePointId": 0, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "ea3ee12f-63bf-40b0-86b2-d73e575e6b38", - "Infiltration": "North", + "Id": "ef216442-d3df-4ccf-b797-94a695827a57", + "Infiltration": "", "Position": { - "x": 22.91, - "y": 6.01, - "z": -81.8 + "x": -5.5, + "y": 1.90975571, + "z": 37.3999939 }, - "Rotation": 266.5001, - "Sides": ["Pmc"] + "Rotation": 113.936485, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Containers", + "BotZoneName": "Zone_Village", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5985,24 +6466,24 @@ "y": 0, "z": 0 }, - "Radius": 200 + "Radius": 60 } }, - "CorePointId": 24, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "eba75083-dbd6-486b-826b-f0bda020ebe0", + "Id": "ef79c37b-639e-498c-a2d2-b20036748f2f", "Infiltration": "", "Position": { - "x": -16.74002, - "y": 10.5248337, - "z": -782.680054 + "x": -202.62001, + "y": 12.3556519, + "z": -194.37 }, - "Rotation": 129.653656, + "Rotation": 194.970718, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player", "Bot"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6011,23 +6492,23 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 77 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ebc94a58-3e0f-4276-b06a-c27ec6481cbf", - "Infiltration": "", + "Id": "f0113a3b-12cd-4801-ad39-c5ebc9578d38", + "Infiltration": "North", "Position": { - "x": -246.780029, - "y": 1.246952, - "z": -381.949982 + "x": 8.755005, + "y": 6.16, + "z": -23.86899 }, - "Rotation": 4.91000032, - "Sides": ["Savage"] + "Rotation": 179.094986, + "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_Village", + "BotZoneName": "Zone_Containers", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6037,24 +6518,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 100 } }, - "CorePointId": 3, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "ed25a5aa-217b-48c8-9e1c-f8f17a49f2c8", + "Id": "f06fb745-0fbb-4ed6-bc3f-0fb36d5e87b2", "Infiltration": "", "Position": { - "x": -197.74, - "y": 5.882332, - "z": -261.949982 + "x": 35.9400024, + "y": 12.0053339, + "z": -833.12 }, - "Rotation": 348.435364, + "Rotation": 4.104724, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6063,24 +6544,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 100 } }, - "CorePointId": 0, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "ed90c8a5-b740-4aa2-868a-f91e710d4e17", - "Infiltration": "Tunnel", + "Id": "f0e2fe27-9ac5-4127-9a4e-30bf7eddac5c", + "Infiltration": "", "Position": { - "x": -171.187408, - "y": 30.3048973, - "z": -66.78931 + "x": -246.109985, + "y": 1.216999, + "z": -379.630035 }, - "Rotation": 148.08, - "Sides": ["All"] + "Rotation": 4.91000032, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_DestroyedHouse", - "Categories": ["Player", "Bot"], + "BotZoneName": "Zone_RoofContainers", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6089,24 +6570,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 30 } }, - "CorePointId": 21, - "DelayToCanSpawnSec": 4, - "Id": "edf7d0ec-dd55-40b0-b459-d7461cdc11ce", + "CorePointId": 15, + "DelayToCanSpawnSec": 3600, + "Id": "f0f76982-288f-4cfa-8c5a-397f7b9422b7", "Infiltration": "", "Position": { - "x": 86.00998, - "y": 0.5456505, - "z": 363.7 + "x": -66.2750244, + "y": 14.0756493, + "z": -734.574 }, - "Rotation": 116.208389, + "Rotation": 34.3430061, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "Zone_Blockpost", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6115,24 +6596,24 @@ "y": 0, "z": 0 }, - "Radius": 77 + "Radius": 240 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "f0113a3b-12cd-4801-ad39-c5ebc9578d38", - "Infiltration": "North", + "CorePointId": 14, + "DelayToCanSpawnSec": 3600, + "Id": "f143f0ca-33af-4541-aa88-1e4d18059ec4", + "Infiltration": "", "Position": { - "x": 8.755005, - "y": 6.16, - "z": -23.86899 + "x": -1.39001465, + "y": 1.78865123, + "z": -470.79 }, - "Rotation": 179.094986, - "Sides": ["Pmc"] + "Rotation": 26.8442173, + "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Hellicopter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "Zone_Blockpost", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6141,19 +6622,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 140 } }, - "CorePointId": 9, + "CorePointId": 14, "DelayToCanSpawnSec": 3600, - "Id": "f120ba21-6633-4266-9c55-9c205075bc55", + "Id": "f2b31e14-8d7f-4348-8464-5ab9fe7f462e", "Infiltration": "", "Position": { - "x": -90.26001, - "y": 1.71564865, - "z": -577.11 + "x": -13.3700256, + "y": 4.528651, + "z": -449.639984 }, - "Rotation": 256.404022, + "Rotation": 26.8442173, "Sides": ["Savage"] }, { @@ -6183,7 +6664,7 @@ "Sides": ["All"] }, { - "BotZoneName": "Zone_DestroyedHouse", + "BotZoneName": "Zone_Chalet", "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6193,24 +6674,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 130 } }, - "CorePointId": 21, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "f6de0668-1ce1-4045-8ffb-8a12b93f678c", + "Id": "f69e3535-6c4d-4607-85e5-7eb5cfa0a111", "Infiltration": "", "Position": { - "x": 68.32999, - "y": 5.76124954, - "z": 373.38 + "x": -73.20001, + "y": 11.4756508, + "z": 4.47998047 }, - "Rotation": 116.208389, + "Rotation": 208.517929, "Sides": ["Savage"] }, { - "BotZoneName": "Zone_Blockpost", - "Categories": ["Bot"], + "BotZoneName": "Zone_Chalet", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6219,19 +6700,19 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 35 } }, - "CorePointId": 14, - "DelayToCanSpawnSec": 3600, - "Id": "f78d5456-02ca-4234-90f6-42d38bb4ae54", + "CorePointId": 7, + "DelayToCanSpawnSec": 4, + "Id": "f6cebfe5-4844-49c7-b424-187b4403bf88", "Infiltration": "", "Position": { - "x": -13.3700256, - "y": 4.528651, - "z": -449.639984 + "x": -62.0599976, + "y": 19.86565, + "z": -134.26001 }, - "Rotation": 26.8442173, + "Rotation": 81.6740341, "Sides": ["Savage"] }, { @@ -6286,6 +6767,32 @@ "Rotation": 108.442146, "Sides": ["All"] }, + { + "BotZoneName": "Zone_Village", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "f8a1c7aa-a550-479b-8e81-cf1e7af59445", + "Infiltration": "", + "Position": { + "x": -185.040009, + "y": 5.405651, + "z": -261.759979 + }, + "Rotation": 348.435364, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -6365,7 +6872,59 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "Zone_TreatmentContainers", + "BotZoneName": "Zone_LongRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "fd71e948-35d6-49c1-b647-5248d6234bb1", + "Infiltration": "", + "Position": { + "x": 47.5999756, + "y": 0.4856491, + "z": -173.4 + }, + "Rotation": 256.630219, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_Rocks", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "fe428f41-73e2-468f-8cb8-ac6c27050690", + "Infiltration": "", + "Position": { + "x": -148.040009, + "y": 39.9856529, + "z": 94.89 + }, + "Rotation": 23.3241863, + "Sides": ["Savage"] + }, + { + "BotZoneName": "Zone_RoofRocks", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6375,17 +6934,17 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 240 } }, - "CorePointId": 15, + "CorePointId": 12, "DelayToCanSpawnSec": 3600, - "Id": "fff1ea06-d91f-44ec-8e75-edcaa95ee5c6", + "Id": "ff80b050-df12-4859-9f5f-37ba90a68599", "Infiltration": "", "Position": { - "x": -66.66, - "y": 4.92964935, - "z": -753.74 + "x": -186.51001, + "y": 14.0341454, + "z": -643.839966 }, "Rotation": 256.404022, "Sides": ["Savage"] @@ -6401,7 +6960,7 @@ { "Chance": 100, "ChancePVE": 100, - "Count": 300, + "Count": 400, "CountPVE": 300, "EntryPoints": "Tunnel,North", "EventAvailable": false, @@ -6409,9 +6968,9 @@ "ExfiltrationTimePVE": 5, "ExfiltrationType": "SharedTimer", "Id": "0", - "MaxTime": 1420, + "MaxTime": 1500, "MaxTimePVE": 1420, - "MinTime": 1300, + "MinTime": 1200, "MinTimePVE": 1300, "Name": "EXFIL_Train", "PassageRequirement": "Train", @@ -6559,166 +7118,44 @@ "maxItemCountInLocation": [], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "LIG_TRANSIT_21_COND", + "description": "LIG_TRANSIT_21_DESC", + "id": 21, + "location": "Shoreline", + "name": "LIG_TRANSIT_21", + "target": "5704e554d2720bac5b8b456e", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "LIG_TRANSIT_22_COND", + "description": "LIG_TRANSIT_22_DESC", + "id": 22, + "location": "RezervBase", + "name": "LIG_TRANSIT_22", + "target": "5704e5fad2720bc05b8b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "LIG_TRANSIT_23_COND", + "description": "LIG_TRANSIT_23_DESC", + "id": 23, + "location": "Woods", + "name": "LIG_TRANSIT_23", + "target": "5704e3c2d2720bac5b8b4567", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [ - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_Village", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 4, - "slots_min": 2, - "time_max": 30, - "time_min": 10 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "Zone_DestroyedHouse", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 1, - "slots_max": 4, - "slots_min": 2, - "time_max": 120, - "time_min": 60 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_SniperPeak", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 2, - "slots_max": 1, - "slots_min": 1, - "time_max": 250, - "time_min": 90 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "Zone_Containers", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 3, - "slots_max": 4, - "slots_min": 0, - "time_max": 320, - "time_min": 100 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_Rocks", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 4, - "slots_max": 2, - "slots_min": 0, - "time_max": 450, - "time_min": 225 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_Chalet", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 5, - "slots_max": 2, - "slots_min": 1, - "time_max": 890, - "time_min": 420 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "Zone_Bridge", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 6, - "slots_max": 3, - "slots_min": 2, - "time_max": 450, - "time_min": 300 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_OldHouse", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 7, - "slots_max": 3, - "slots_min": 0, - "time_max": 800, - "time_min": 200 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_LongRoad", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 8, - "slots_max": 3, - "slots_min": 1, - "time_max": 800, - "time_min": 580 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "Zone_DestroyedHouse", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 9, - "slots_max": 3, - "slots_min": 0, - "time_max": 1000, - "time_min": 630 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_Village", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 10, - "slots_max": 4, - "slots_min": 2, - "time_max": 1200, - "time_min": 900 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "Zone_Containers", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 11, - "slots_max": 4, - "slots_min": 2, - "time_max": 1110, - "time_min": 650 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "Zone_OldHouse", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 12, - "slots_max": 3, - "slots_min": 1, - "time_max": 1400, - "time_min": 1200 - } - ] + "waves": [] } diff --git a/external-resources/maps/reserve.json b/external-resources/maps/reserve.json index 68d5fefa..47208b83 100644 --- a/external-resources/maps/reserve.json +++ b/external-resources/maps/reserve.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 50, @@ -42,7 +43,7 @@ ], "BossLocationSpawn": [ { - "BossChance": 35, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "2", "BossEscortDifficult": "normal", @@ -54,7 +55,7 @@ "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": [ { "BossEscortAmount": "2", @@ -89,14 +90,14 @@ "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": null, "Time": 1470, "TriggerId": "", "TriggerName": "" }, { - "BossChance": 40, + "BossChance": 25, "BossDifficult": "normal", "BossEscortAmount": "2,2,2,2,3", "BossEscortDifficult": "normal", @@ -108,14 +109,14 @@ "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": null, "Time": -1, "TriggerId": "autoId_00632_EXFIL", "TriggerName": "interactObject" }, { - "BossChance": 40, + "BossChance": 25, "BossDifficult": "normal", "BossEscortAmount": "2,2,2,2,3", "BossEscortDifficult": "normal", @@ -127,14 +128,14 @@ "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": null, "Time": -1, "TriggerId": "autoId_00000_D2_LEVER", "TriggerName": "interactObject" }, { - "BossChance": 40, + "BossChance": 25, "BossDifficult": "normal", "BossEscortAmount": "2,2,2,2,3", "BossEscortDifficult": "normal", @@ -146,11 +147,125 @@ "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": null, "Time": 3, "TriggerId": "raider_simple_patroling", "TriggerName": "interactObject" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" } ], "BotAssault": 100, @@ -159,12 +274,112 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 0.6, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 330, + "DistToActivatePvE": 330, "DistToPersueAxemanCoef": 1.1, "DistToSleep": 350, + "DistToSleepPvE": 350, "GainSight": 1.3, "KhorovodChance": 0, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1800, + "MinExfiltrationTime": 1200, "Scattering": 0.6, "VisibleDistance": 1.3 }, @@ -181,7 +396,7 @@ "BotSpawnTimeOnMax": 320, "BotSpawnTimeOnMin": 260, "BotStart": 20, - "BotStartPlayer": 0, + "BotStartPlayer": 100, "BotStop": 1500, "Description": "The secret Federal State Reserve Agency base that, according to urban legends, contains enough supplies to last for years: food, medications and other resources, enough to survive an all-out nuclear war.", "DisabledForScav": false, @@ -191,9 +406,89 @@ "EscapeTimeLimit": 40, "EscapeTimeLimitCoop": 30, "EscapeTimeLimitPVE": 40, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 150, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 125, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.4, + "GlobalLootChanceModifier": 0.17, "GlobalLootChanceModifierPvE": 0.4, "IconX": 360, "IconY": 410, @@ -243,6 +538,7 @@ "MinPlayers": 9, "Name": "ReserveBase", "NewSpawn": false, + "NewSpawnForPlayers": false, "NonWaveGroupScenario": { "Chance": 50, "Enabled": false, @@ -5201,7 +5497,7 @@ { "Chance": 100, "ChancePVE": 100, - "Count": 400, + "Count": 420, "CountPVE": 400, "EntryPoints": "Common", "EventAvailable": false, @@ -5332,11 +5628,57 @@ } ], "filter_ex": [], - "limits": [], + "limits": [ + { + "items": ["634959225289190e5e773b3b"], + "max": 8, + "min": 7 + } + ], "matching_min_seconds": 60, - "maxItemCountInLocation": [], + "maxItemCountInLocation": [ + { + "TemplateId": "634959225289190e5e773b3b", + "Value": 7 + } + ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "REZ_TRANSIT_18_COND", + "description": "REZ_TRANSIT_18_DESC", + "id": 18, + "location": "bigmap", + "name": "REZ_TRANSIT_18", + "target": "56f40101d2720b2a4d8b45d6", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "REZ_TRANSIT_19_COND", + "description": "REZ_TRANSIT_19_DESC", + "id": 19, + "location": "Woods", + "name": "REZ_TRANSIT_19", + "target": "5704e3c2d2720bac5b8b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "REZ_TRANSIT_20_COND", + "description": "REZ_TRANSIT_20_DESC", + "id": 20, + "location": "Lighthouse", + "name": "REZ_TRANSIT_20", + "target": "5704e4dad2720bb55b8b4567", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, @@ -5345,18 +5687,20 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, "number": 1, - "slots_max": 1, - "slots_min": 0, + "slots_max": 4, + "slots_min": 1, "time_max": -1, "time_min": -1 }, { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5369,6 +5713,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5381,6 +5726,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5393,6 +5739,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": true, @@ -5405,6 +5752,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": true, @@ -5417,6 +5765,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5429,6 +5778,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": true, @@ -5441,6 +5791,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": true, @@ -5453,6 +5804,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": true, @@ -5465,6 +5817,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": true, @@ -5477,6 +5830,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5489,6 +5843,7 @@ { "BotPreset": "normal", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5501,6 +5856,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, @@ -5513,6 +5869,7 @@ { "BotPreset": "hard", "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], "SpawnPoints": "", "WildSpawnType": "assault", "isPlayers": false, diff --git a/external-resources/maps/shoreline.json b/external-resources/maps/shoreline.json index 504cfa71..0d8bbc24 100644 --- a/external-resources/maps/shoreline.json +++ b/external-resources/maps/shoreline.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 50, @@ -61,19 +62,42 @@ "TriggerName": "" }, { - "BossChance": 37, + "BossChance": 30, "BossDifficult": "normal", - "BossEscortAmount": "2", + "BossEscortAmount": "0", + "BossEscortDifficult": "normal", + "BossEscortType": "sectantWarrior", + "BossName": "bossPartisan", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": true, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve", "regular"], + "Supports": null, + "Time": -1, + "TriggerId": "PARTISAN_TRIGGER", + "TriggerName": "botEvent" + }, + { + "BossChance": 30, + "BossDifficult": "normal", + "BossEscortAmount": "0", "BossEscortDifficult": "normal", "BossEscortType": "exUsec", "BossName": "bossKnight", "BossPlayer": false, - "BossZone": "ZoneSanatorium1,ZoneSanatorium2", + "BossZone": "ZoneMeteoStation", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": true, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": [ { "BossEscortAmount": "1", @@ -96,57 +120,231 @@ "TriggerName": "" }, { - "BossChance": 37, + "BossChance": 30, "BossDifficult": "normal", - "BossEscortAmount": "2,3", + "BossEscortAmount": "3", "BossEscortDifficult": "normal", "BossEscortType": "followerSanitar", "BossName": "bossSanitar", "BossPlayer": false, "BossZone": "ZoneGreenHouses,ZoneSanatorium1,ZoneGreenHouses,ZoneSanatorium2,ZonePort", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": null, "Time": -1, "TriggerId": "", "TriggerName": "" }, { - "BossChance": 20, + "BossChance": 15, "BossDifficult": "normal", - "BossEscortAmount": "3", + "BossEscortAmount": "3,4", "BossEscortDifficult": "normal", "BossEscortType": "sectantWarrior", "BossName": "sectantPriest", "BossPlayer": false, "BossZone": "ZoneSanatorium1,ZoneSanatorium2,ZoneForestSpawn,ZoneForestSpawn,ZoneForestSpawn", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve", "regular"], "Supports": null, "Time": -1, "TriggerId": "", "TriggerName": "" }, { - "BossChance": 20, + "BossChance": 50, "BossDifficult": "normal", - "BossEscortAmount": "3", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", "BossEscortDifficult": "normal", - "BossEscortType": "sectantWarrior", - "BossName": "sectantPriest", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", "BossPlayer": false, - "BossZone": "ZoneForestSpawn", + "BossZone": "", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, - "SpawnMode": ["regular", "pve"], + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 30, + "BossDifficult": "normal", + "BossEscortAmount": "0,1,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "ZoneSmuglers", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], "Supports": null, "Time": -1, "TriggerId": "", @@ -159,21 +357,121 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 260, + "DistToActivatePvE": 260, "DistToPersueAxemanCoef": 1.1, "DistToSleep": 300, + "DistToSleepPvE": 300, "GainSight": 1.1, "KhorovodChance": 0, "MagnetPower": 40, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 2000, + "MinExfiltrationTime": 1500, "Scattering": 0.8, "VisibleDistance": 1.2 }, "BotMarksman": 20, - "BotMax": 32, - "BotMaxPlayer": 0, - "BotMaxPvE": 32, - "BotMaxTimePlayer": 0, + "BotMax": 17, + "BotMaxPlayer": 9, + "BotMaxPvE": 31, + "BotMaxTimePlayer": 1000, "BotNormal": 50, "BotSpawnCountStep": 4, "BotSpawnPeriodCheck": 15, @@ -182,7 +480,7 @@ "BotSpawnTimeOnMax": 320, "BotSpawnTimeOnMin": 260, "BotStart": 20, - "BotStartPlayer": 0, + "BotStartPlayer": 220, "BotStop": 2700, "Description": "The coastline that leads to the port.", "DisabledForScav": false, @@ -192,9 +490,89 @@ "EscapeTimeLimit": 45, "EscapeTimeLimitCoop": 35, "EscapeTimeLimitPVE": 45, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 200, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 200, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.55, + "GlobalLootChanceModifier": 0.25, "GlobalLootChanceModifierPvE": 0.55, "IconX": 220, "IconY": 300, @@ -244,6 +622,7 @@ "MinPlayers": 10, "Name": "Shoreline", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -252,8 +631,8 @@ }, "OcculsionCullingEnabled": true, "OfflineNewSpawn": true, - "OfflineOldSpawn": false, - "OldSpawn": false, + "OfflineOldSpawn": true, + "OldSpawn": true, "OpenZones": "ZoneSanatorium1,ZoneSanatorium2,ZoneIsland,ZoneGasStation,ZoneMeteoStation,ZonePowerStation,ZoneBusStation,ZoneRailWays,ZonePort,ZoneBunkeSniper,ZonePowerStationSniper,ZoneForestTruck,ZoneForestSpawn,ZoneSmuglers", "PlayersRequestCount": -1, "PmcMaxPlayersInGroup": 5, @@ -297,58 +676,6 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneSanatorium2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 70 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "022690b2-2baf-4e69-a93d-55ea0141b79b", - "Infiltration": "", - "Position": { - "x": -343.3, - "y": -5.16733074, - "z": -113.69 - }, - "Rotation": 19.4150581, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneIsland", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 117 - } - }, - "CorePointId": 17, - "DelayToCanSpawnSec": 4, - "Id": "0479a467-5b2d-44b7-aba5-d44ada5723e1", - "Infiltration": "", - "Position": { - "x": 228.1, - "y": -64.56713, - "z": 425.740021 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -376,7 +703,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSmuglers", + "BotZoneName": "ZoneSanatorium2", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -386,24 +713,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, - "CorePointId": 26, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "05fbc02c-7eb9-4010-9864-cce78ff51ed7", + "Id": "0706f78c-9b04-45b9-bcfe-405ea09a68e6", "Infiltration": "", "Position": { - "x": -615.14, - "y": -29.7413483, - "z": -177.85 + "x": -295.389984, + "y": -5.134326, + "z": -127.259995 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneStartVillage", - "Categories": ["Bot"], + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -412,19 +739,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 35 } }, - "CorePointId": 6, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "083124e9-0e5c-4116-8f1f-98b6b157bfb7", + "Id": "07a58e70-dbfe-4226-8b2e-237c3e3675f5", "Infiltration": "", "Position": { - "x": 458.95, - "y": -54.54093, - "z": 159.47 + "x": 183.65, + "y": -46.69635, + "z": 44.0399933 }, - "Rotation": 89.74151, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -506,8 +833,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSmuglers", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -516,24 +843,24 @@ "y": 0, "z": 0 }, - "Radius": 30 + "Radius": 50 } }, - "CorePointId": 26, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "096f6165-0280-4991-9180-694703f99f24", - "Infiltration": "", + "Id": "0a656c0b-40b8-4dfb-9821-eaf053da5bd8", + "Infiltration": "Village", "Position": { - "x": -659.261, - "y": -26.8373489, - "z": -162.341 + "x": 420.5501, + "y": -54.49, + "z": 153.660019 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 230.53, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium2", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -542,88 +869,10 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, - "CorePointId": 8, - "DelayToCanSpawnSec": 4, - "Id": "09cf04db-53c8-4330-b07a-a688d2a2d14b", - "Infiltration": "", - "Position": { - "x": -318.789978, - "y": -5.134326, - "z": -173.12999 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZonePassClose", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 175 - } - }, - "CorePointId": 18, - "DelayToCanSpawnSec": 4, - "Id": "0a5f3d13-da27-4b98-920e-879cf60aeb08", - "Infiltration": "", - "Position": { - "x": -891.31, - "y": -46.061348, - "z": 2.02999878 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "0a656c0b-40b8-4dfb-9821-eaf053da5bd8", - "Infiltration": "Village", - "Position": { - "x": 420.5501, - "y": -54.49, - "z": 153.660019 - }, - "Rotation": 230.53, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, + "CorePointId": 0, "DelayToCanSpawnSec": 4, "Id": "0baf5b66-31b0-4c2f-8f2e-4f4320a25243", "Infiltration": "Village", @@ -713,6 +962,32 @@ "Rotation": 316.25, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneTunnel", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 220 + } + }, + "CorePointId": 19, + "DelayToCanSpawnSec": 4, + "Id": "0f1035bf-0342-4430-8b92-e463f896fc94", + "Infiltration": "", + "Position": { + "x": 328.860016, + "y": -64.65135, + "z": 326.53 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -733,15 +1008,15 @@ "Infiltration": "Village", "Position": { "x": -58.0944748, - "y": -17.9803963, + "y": -17.9813957, "z": -189.791611 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSmuglers", - "Categories": ["Bot"], + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -753,16 +1028,16 @@ "Radius": 50 } }, - "CorePointId": 26, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "0fa03b15-1a78-4bb4-951b-fecb4a0db2e2", + "Id": "0fa17404-2e01-429c-846b-783becee6163", "Infiltration": "", "Position": { - "x": -622.62, - "y": -29.7413483, - "z": -172.66 + "x": -156.265991, + "y": -3.644, + "z": -82.5099945 }, - "Rotation": 0, + "Rotation": 19.4150581, "Sides": ["Savage"] }, { @@ -921,6 +1196,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneMeteoStation", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 170 + } + }, + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "147b236f-de32-4086-8f95-00ca3ab4714b", + "Infiltration": "", + "Position": { + "x": -443.9, + "y": -25.962225, + "z": 259.87 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -948,8 +1249,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneForestSpawn", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneForestTruck", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -958,23 +1259,23 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 165 } }, - "CorePointId": 9, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "1885424a-9202-4567-aab5-091bc247a2f0", + "Id": "17c35797-5dff-4662-b4d1-ccfea505387a", "Infiltration": "", "Position": { - "x": 162.59, - "y": -34.96685, - "z": -296.289978 + "x": 27.3945618, + "y": -20.5940456, + "z": -211.800018 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSanatorium2", + "BotZoneName": "ZonePassClose", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -984,24 +1285,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 175 } }, - "CorePointId": 7, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "189ab454-4413-4d10-9dc7-041138ea86ff", + "Id": "19e44d79-d199-444b-97e7-89e4b6a48ca2", "Infiltration": "", "Position": { - "x": -350.31, - "y": -5.134326, - "z": -175.090012 + "x": -891.31, + "y": -46.061348, + "z": 2.02999878 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRailWays", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1010,23 +1311,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "1aff115b-65d6-4b27-bbe1-4f147541caad", - "Infiltration": "Village", + "Id": "1a879937-4315-42ca-92f4-4b56d45e3c69", + "Infiltration": "", "Position": { - "x": 269.370178, - "y": -56.42, - "z": 188.090012 + "x": -697.6, + "y": -59.5997047, + "z": 497.7 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSanatorium2", + "BotZoneName": "ZonePowerStationSniper", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1036,17 +1337,17 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 25 } }, - "CorePointId": 8, - "DelayToCanSpawnSec": 4, - "Id": "1b54123b-bbfe-454e-a01d-104927723544", + "CorePointId": 10, + "DelayToCanSpawnSec": 1700, + "Id": "1af5e649-023c-44a3-b55b-29bf555cd816", "Infiltration": "", "Position": { - "x": -295.389984, - "y": -5.134326, - "z": -127.259995 + "x": -220.86, + "y": -29.7583351, + "z": 189.53 }, "Rotation": 0, "Sides": ["Savage"] @@ -1067,12 +1368,12 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1c009c5c-0593-443b-8ae3-3ecf3bcf89ed", + "Id": "1aff115b-65d6-4b27-bbe1-4f147541caad", "Infiltration": "Village", "Position": { - "x": 434.240051, - "y": -54.28, - "z": 70.2500153 + "x": 269.370178, + "y": -56.42, + "z": 188.090012 }, "Rotation": 271.08, "Sides": ["Pmc"] @@ -1093,19 +1394,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1d8bfebb-e39d-4bf4-9f24-9275e754b857", + "Id": "1c009c5c-0593-443b-8ae3-3ecf3bcf89ed", "Infiltration": "Village", "Position": { - "x": 433.95, - "y": -54.33, - "z": 67.82002 + "x": 434.240051, + "y": -54.28, + "z": 70.2500153 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePort", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneBunker", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1114,24 +1415,24 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 98.1 } }, - "CorePointId": 13, + "CorePointId": 15, "DelayToCanSpawnSec": 4, - "Id": "1ec850c9-cee0-420f-8514-1570f53ddd88", + "Id": "1c0dbe2f-d873-4ae8-9505-43a0f777aef9", "Infiltration": "", "Position": { - "x": -296.3232, - "y": -62.0376167, - "z": 490.1558 + "x": -134.798325, + "y": -10.67804, + "z": -351.499146 }, - "Rotation": 197.8742, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGreenHouses", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1140,25 +1441,77 @@ "y": 0, "z": 0 }, - "Radius": 5 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1fe7dfd1-9e33-436c-aee2-4ff9379dc0e3", - "Infiltration": "", + "Id": "1d8bfebb-e39d-4bf4-9f24-9275e754b857", + "Infiltration": "Village", "Position": { - "x": 128.37, - "y": -48.44106, - "z": 76.78 + "x": 433.95, + "y": -54.33, + "z": 67.82002 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], - "ColliderParams": { + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 112 + } + }, + "CorePointId": 1, + "DelayToCanSpawnSec": 4, + "Id": "1e6d24f0-05d1-400b-bfff-a901d0c1dfab", + "Infiltration": "", + "Position": { + "x": 160.559982, + "y": -48.30135, + "z": 62.09999 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneBunkeSniper", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 25 + } + }, + "CorePointId": 12, + "DelayToCanSpawnSec": 1700, + "Id": "1e9215b0-eca7-43e9-a098-750d3a1d0718", + "Infiltration": "", + "Position": { + "x": -151.93, + "y": -4.86000061, + "z": -268.55 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { "Center": { @@ -1208,7 +1561,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium1", + "BotZoneName": "ZoneStartVillage", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1218,24 +1571,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 8, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "237912ed-a166-42c9-bdb0-2126261f747f", + "Id": "2510bd08-e90c-4d01-9d63-2fd9115851bc", "Infiltration": "", "Position": { - "x": -197.609985, - "y": -5.05, - "z": -169.939987 + "x": 459.89, + "y": -54.4532776, + "z": 92.4900055 }, - "Rotation": 0, + "Rotation": 277.9801, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneForestSpawn", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1244,24 +1597,24 @@ "y": 0, "z": 0 }, - "Radius": 165 + "Radius": 50 } }, - "CorePointId": 9, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2392d197-eb8c-4ee8-adee-c4903b94f81c", - "Infiltration": "", + "Id": "28048da3-ecaa-45a6-8c3c-ff5c2956fe7c", + "Infiltration": "Village", "Position": { - "x": 181.433884, - "y": -37.2266273, - "z": -268.557648 + "x": 342.230042, + "y": -56.29, + "z": 116.64003 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1275,19 +1628,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "28048da3-ecaa-45a6-8c3c-ff5c2956fe7c", + "Id": "2912d83e-b7a3-404e-8cc2-5a801c64e524", "Infiltration": "Village", "Position": { - "x": 342.230042, - "y": -56.29, - "z": 116.64003 + "x": -55.58847, + "y": -18.5793972, + "z": -187.481613 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1301,18 +1654,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2912d83e-b7a3-404e-8cc2-5a801c64e524", - "Infiltration": "Village", + "Id": "2c11e954-f7e5-4a67-845c-54328c8b9c27", + "Infiltration": "Riverside", "Position": { - "x": -55.58847, - "y": -18.5793972, - "z": -187.481613 + "x": -916.209961, + "y": -58.34, + "z": 252.64003 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGasStation", + "BotZoneName": "ZoneGreenHouses", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1322,24 +1675,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 112 } }, - "CorePointId": 20, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "29cdcee1-39c7-415c-ae31-840903f9a144", + "Id": "2cff2324-432f-4e6e-bf5a-d15bff5354d1", "Infiltration": "", "Position": { - "x": -166.7232, - "y": -55.6530457, - "z": 368.7158 + "x": 110.25, + "y": -48.48343, + "z": 138.139984 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRailWays", - "Categories": ["Bot"], + "BotZoneName": "ZoneMeteoStation", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1348,24 +1701,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 30 } }, - "CorePointId": 4, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "29efa145-f725-47f7-984c-8ff037e38146", + "Id": "2dbe2a68-dcba-4334-8e7f-04c5b77e2288", "Infiltration": "", "Position": { - "x": -697.6, - "y": -59.5997047, - "z": 497.7 + "x": -490.86, + "y": -24.1813488, + "z": 203.33 }, "Rotation": 0, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1374,23 +1727,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 100 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2c11e954-f7e5-4a67-845c-54328c8b9c27", + "Id": "2dd04c2a-7e3e-426f-b6eb-9cf99ae0f01e", "Infiltration": "Riverside", "Position": { - "x": -916.209961, - "y": -58.34, - "z": 252.64003 + "x": -469.34845, + "y": -27.859396, + "z": -96.37161 }, - "Rotation": 271.08, + "Rotation": 83.38443, "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePort", + "BotZoneName": "ZonePowerStation", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1400,24 +1753,24 @@ "y": 0, "z": 0 }, - "Radius": 95 + "Radius": 30 } }, - "CorePointId": 13, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "2ce3720b-5e38-42c4-bafd-8c0518982838", + "Id": "2e857187-f38e-4479-a6b8-19edbe9f1c50", "Infiltration": "", "Position": { - "x": -309.5032, - "y": -62.0376167, - "z": 505.5958 + "x": -254.633, + "y": -45.5623474, + "z": 218.166992 }, - "Rotation": 197.8742, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZonePowerStation", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1426,23 +1779,23 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 15 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "2dd04c2a-7e3e-426f-b6eb-9cf99ae0f01e", - "Infiltration": "Riverside", + "Id": "30d699d9-b86d-4d75-b894-ad7f7d2396ed", + "Infiltration": "", "Position": { - "x": -469.34845, - "y": -27.859396, - "z": -96.37161 + "x": -225.588989, + "y": -40.7633476, + "z": 167.765 }, - "Rotation": 83.38443, - "Sides": ["Pmc"] + "Rotation": 84.57507, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSanatorium1", + "BotZoneName": "ZoneBusStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1452,23 +1805,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 7, + "CorePointId": 14, "DelayToCanSpawnSec": 4, - "Id": "2feb5d85-c55d-4d69-8dfa-644627b2b86b", + "Id": "320348b2-0ef0-4df1-9643-4fb2be5c21c0", "Infiltration": "", "Position": { - "x": -131.652, - "y": -5.080117, - "z": -103.83 + "x": -72.17, + "y": -21.967, + "z": 10.4600067 }, - "Rotation": 301.760071, + "Rotation": 233.659576, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSanatorium1", + "BotZoneName": "ZoneStartVillage", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1478,24 +1831,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 8, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "326e30ff-d547-4175-9c87-724f0ffa10f3", + "Id": "33cc2001-9b63-41bd-8f70-4c5406990171", "Infiltration": "", "Position": { - "x": -195.01, - "y": -5.16733074, - "z": -113.72 + "x": 459.31, + "y": -54.17835, + "z": 55.7920074 }, - "Rotation": 19.4150581, + "Rotation": 266.625641, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneForestGasStation", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1507,14 +1860,14 @@ "Radius": 158.9 } }, - "CorePointId": 20, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "33c0b5ea-01b1-4a25-bedf-c2f6808b19c0", + "Id": "349818b4-45de-4996-8c10-364391288c5c", "Infiltration": "", "Position": { - "x": -192.393188, - "y": -55.693428, - "z": 367.8458 + "x": -87.8699951, + "y": -42.39235, + "z": 272.28 }, "Rotation": 0, "Sides": ["Savage"] @@ -1545,6 +1898,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneIsland", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 117 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "3667563e-7a11-4b78-8343-2d1c16a34616", + "Infiltration": "", + "Position": { + "x": 203.769989, + "y": -64.57, + "z": 441.370026 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1624,8 +2003,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneForestTruck", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1634,24 +2013,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 165 } }, - "CorePointId": 0, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "3a50464e-38ed-483d-8945-8c43ab5850e6", - "Infiltration": "Riverside", + "Id": "3854290b-d134-402f-bf5a-0255dd0639bd", + "Infiltration": "", "Position": { - "x": -597.399963, - "y": -45.4100037, - "z": 155.610031 + "x": 13.6999817, + "y": -26.2264748, + "z": -163.839981 }, - "Rotation": 88.89, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRailWays", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1660,20 +2039,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "3eddbe61-12b7-4bc2-aa73-2087c2eb9f2b", - "Infiltration": "Village", + "Id": "398cd48f-d699-4073-9878-2d699fbe76aa", + "Infiltration": "", "Position": { - "x": 448.879944, - "y": -54.46, - "z": 188.720016 + "x": -581, + "y": -59.3917923, + "z": 499.800018 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1691,19 +2070,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "3fd55f19-ef15-4017-b468-cff2d9fe9b35", + "Id": "3a50464e-38ed-483d-8945-8c43ab5850e6", "Infiltration": "Riverside", "Position": { - "x": -932.111938, - "y": -54.481, - "z": 162.864029 + "x": -597.399963, + "y": -45.4100037, + "z": 155.610031 }, - "Rotation": 33.26, + "Rotation": 88.89, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1712,24 +2091,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 30 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "4161383c-4c28-487c-a858-7733e662bec4", - "Infiltration": "Village", + "Id": "3ca7c6e3-3fb2-4a6d-ac4b-1eb77a32b9ac", + "Infiltration": "", "Position": { - "x": 341.460022, - "y": -56.29, - "z": 122.720016 + "x": -326.03, + "y": -4.52999973, + "z": -105.619995 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 19.4150581, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "ZonePort", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1738,24 +2117,24 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 95 } }, - "CorePointId": 20, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "41736f9e-482a-4629-931f-78eec3f9c3fb", + "Id": "3d50c926-5b75-4541-af13-f8c0e730e72d", "Infiltration": "", "Position": { - "x": -188.5232, - "y": -65.00135, - "z": 447.6358 + "x": -296.3232, + "y": -62.0376167, + "z": 490.1558 }, - "Rotation": 0, + "Rotation": 197.8742, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneTunnel", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1764,20 +2143,20 @@ "y": 0, "z": 0 }, - "Radius": 220 + "Radius": 50 } }, - "CorePointId": 19, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "42e41992-cad0-4904-9453-f72feb8a34b3", - "Infiltration": "", + "Id": "3eddbe61-12b7-4bc2-aa73-2087c2eb9f2b", + "Infiltration": "Village", "Position": { - "x": 328.860016, - "y": -64.65135, - "z": 326.53 + "x": 448.879944, + "y": -54.46, + "z": 188.720016 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -1795,19 +2174,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4349ecfb-ccd5-4a68-be17-d7fc1fe7cbb8", - "Infiltration": "Village", + "Id": "3fd55f19-ef15-4017-b468-cff2d9fe9b35", + "Infiltration": "Riverside", "Position": { - "x": 335.399963, - "y": -41.8500023, - "z": -273.149963 + "x": -932.111938, + "y": -54.481, + "z": 162.864029 }, - "Rotation": 349.17, + "Rotation": 33.26, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneIsland", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1816,20 +2195,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 117 } }, - "CorePointId": 0, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "438f6b11-098b-4b8a-96ed-954766b846e3", - "Infiltration": "Village", + "Id": "408efa74-7257-4ffe-87f2-da4e05bacc23", + "Infiltration": "", "Position": { - "x": 282.750061, - "y": -56.24, - "z": 172.330032 + "x": 206.450012, + "y": -64.8, + "z": 443.370026 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1847,18 +2226,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4514864e-beb2-4e98-aa1e-c39d9da1db0c", - "Infiltration": "Riverside", + "Id": "4161383c-4c28-487c-a858-7733e662bec4", + "Infiltration": "Village", "Position": { - "x": -596.4799, - "y": -45.4100037, - "z": 157.780045 + "x": 341.460022, + "y": -56.29, + "z": 122.720016 }, - "Rotation": 108.770004, + "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRailWays", + "BotZoneName": "ZoneMeteoStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1868,23 +2247,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 170 } }, - "CorePointId": 4, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "4524d903-747c-478c-8756-127afd0f06ee", + "Id": "41baa266-6cd1-4990-ad73-443f9102cddf", "Infiltration": "", "Position": { - "x": -581, - "y": -59.3917923, - "z": 499.800018 + "x": -520.37, + "y": -25.6599045, + "z": 284.63 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneForestTruck", + "BotZoneName": "ZonePort", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1894,17 +2273,17 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 131.2 } }, - "CorePointId": 11, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "4561ce9a-aa86-405d-a474-48be917d2d50", + "Id": "4221f0c0-6158-4e35-9a72-cb10c741706f", "Infiltration": "", "Position": { - "x": 72.59999, - "y": -31.1844521, - "z": -156.3 + "x": -292.6332, + "y": -62.0376167, + "z": 493.6858 }, "Rotation": 0, "Sides": ["Savage"] @@ -1925,14 +2304,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "474b3d06-7368-4b8d-9a4d-2c9c223b71b2", + "Id": "4349ecfb-ccd5-4a68-be17-d7fc1fe7cbb8", "Infiltration": "Village", "Position": { - "x": 442.0301, - "y": -54.3, - "z": 103.970016 + "x": 335.399963, + "y": -41.8500023, + "z": -273.149963 }, - "Rotation": 271.08, + "Rotation": 349.17, "Sides": ["Pmc"] }, { @@ -1951,19 +2330,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "47b2c388-edcf-4366-ad4b-f323db229951", + "Id": "438f6b11-098b-4b8a-96ed-954766b846e3", "Infiltration": "Village", "Position": { - "x": 235.570114, - "y": -56.13, - "z": 129.720016 + "x": 282.750061, + "y": -56.24, + "z": 172.330032 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1975,20 +2354,20 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "47f2d197-7e3e-49b6-803b-66fea4a4f34e", - "Infiltration": "Riverside", + "Id": "43bffd59-d912-4815-8999-33b995da8646", + "Infiltration": "", "Position": { - "x": -776.879944, - "y": -40.06, - "z": 2.35002136 + "x": -632.42, + "y": -26.8423481, + "z": -240.12 }, - "Rotation": 17.1399956, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneForestTruck", + "BotZoneName": "ZoneMeteoStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1998,17 +2377,17 @@ "y": 0, "z": 0 }, - "Radius": 165 + "Radius": 170 } }, - "CorePointId": 11, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "4b087685-b3d2-4059-9386-3088e541a462", + "Id": "4463561f-1ba3-4a5c-afdc-3981a4fd9642", "Infiltration": "", "Position": { - "x": 13.6999817, - "y": -26.2264748, - "z": -163.839981 + "x": -443.47998, + "y": -25.283453, + "z": 248.040009 }, "Rotation": 0, "Sides": ["Savage"] @@ -2029,19 +2408,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4b2a193c-2749-4497-93ba-75a8f6a3e218", + "Id": "4514864e-beb2-4e98-aa1e-c39d9da1db0c", "Infiltration": "Riverside", "Position": { - "x": -816.4799, - "y": -41.13, - "z": 2.33000183 + "x": -596.4799, + "y": -45.4100037, + "z": 157.780045 }, - "Rotation": 3.259948, + "Rotation": 108.770004, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBunker", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2050,23 +2429,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 98.1 } }, - "CorePointId": 0, + "CorePointId": 15, "DelayToCanSpawnSec": 4, - "Id": "4d45d646-18b4-4602-b06d-128c933eb919", - "Infiltration": "Riverside", + "Id": "46825a63-3cc2-4652-a14d-f0ef49bd72b3", + "Infiltration": "", "Position": { - "x": -693.9699, - "y": -59.57, - "z": 497.599976 + "x": -156.61, + "y": -13.4983215, + "z": -343.31 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 44.298996, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneStartVillage", + "BotZoneName": "ZonePowerStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2076,25 +2455,51 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 90 } }, - "CorePointId": 6, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "4e06ab3f-4a84-4ea3-a78d-e679b08b8e2a", + "Id": "46f4c17a-b7f5-4240-b591-78f776dcfd6d", "Infiltration": "", "Position": { - "x": 462.4, - "y": -54.4639664, - "z": 119.560013 + "x": -217.540009, + "y": -41.0012, + "z": 166.4 }, - "Rotation": 195.821518, + "Rotation": 276.228271, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { + "BotZoneName": "ZoneTunnel", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 212 + } + }, + "CorePointId": 19, + "DelayToCanSpawnSec": 4, + "Id": "4726b2e5-f64a-46b4-835a-f766f19ba25c", + "Infiltration": "", + "Position": { + "x": 357.550018, + "y": -59.62579, + "z": 328.87 + }, + "Rotation": 222.77774, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { "Center": { @@ -2107,19 +2512,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4e3a2705-96a2-467a-af09-a6f9b4a67f3e", + "Id": "474b3d06-7368-4b8d-9a4d-2c9c223b71b2", "Infiltration": "Village", "Position": { - "x": 441.909973, + "x": 442.0301, "y": -54.3, - "z": 106.030014 + "z": 103.970016 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSmuglers", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2131,14 +2536,40 @@ "Radius": 50 } }, - "CorePointId": 26, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "47b2c388-edcf-4366-ad4b-f323db229951", + "Infiltration": "Village", + "Position": { + "x": 235.570114, + "y": -56.13, + "z": 129.720016 + }, + "Rotation": 271.08, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZonePort", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "4e8af6e0-b057-442c-93d3-eabb63252650", + "Id": "47ea469e-314d-4d28-b095-32517d782669", "Infiltration": "", "Position": { - "x": -644.133, - "y": -26.85735, - "z": -230.226013 + "x": -358.3532, + "y": -62.0151253, + "z": 555.8658 }, "Rotation": 0, "Sides": ["Savage"] @@ -2159,19 +2590,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4f340491-d43e-4fd5-8447-65c925eacce6", + "Id": "47f2d197-7e3e-49b6-803b-66fea4a4f34e", "Infiltration": "Riverside", "Position": { - "x": -808.54, - "y": -59.17, - "z": 457.39 + "x": -776.879944, + "y": -40.06, + "z": 2.35002136 }, - "Rotation": 199.92, + "Rotation": 17.1399956, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGreenHouses", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2180,23 +2611,23 @@ "y": 0, "z": 0 }, - "Radius": 5 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "4fdabc47-befa-4711-93b7-a0395b624fb3", - "Infiltration": "", + "Id": "4b2a193c-2749-4497-93ba-75a8f6a3e218", + "Infiltration": "Riverside", "Position": { - "x": 122.47, - "y": -48.44106, - "z": 92.81999 + "x": -816.4799, + "y": -41.13, + "z": 2.33000183 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 3.259948, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium2", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2206,21 +2637,99 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 8, + "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "4fe78674-ecb1-4636-9a7e-2d7f94809cfb", + "Id": "4cf56dad-70f1-457c-824a-1628a508933a", "Infiltration": "", "Position": { - "x": -299.15, - "y": -5.134326, - "z": -151.41 + "x": -218.900024, + "y": -55.6409073, + "z": 379.015839 }, "Rotation": 0, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "4d45d646-18b4-4602-b06d-128c933eb919", + "Infiltration": "Riverside", + "Position": { + "x": -693.9699, + "y": -59.57, + "z": 497.599976 + }, + "Rotation": 271.08, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "4e3a2705-96a2-467a-af09-a6f9b4a67f3e", + "Infiltration": "Village", + "Position": { + "x": 441.909973, + "y": -54.3, + "z": 106.030014 + }, + "Rotation": 271.08, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "4f340491-d43e-4fd5-8447-65c925eacce6", + "Infiltration": "Riverside", + "Position": { + "x": -808.54, + "y": -59.17, + "z": 457.39 + }, + "Rotation": 199.92, + "Sides": ["Pmc"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2248,7 +2757,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneForestSpawn", + "BotZoneName": "ZonePort", "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2258,17 +2767,43 @@ "y": 0, "z": 0 }, - "Radius": 165 + "Radius": 95 } }, - "CorePointId": 9, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "5227e44f-575e-4592-9bd3-e5e01e3e4026", + "Id": "512349e6-7fbe-4f54-9234-59bcdb913d84", "Infiltration": "", "Position": { - "x": 143.34, - "y": -33.54049, - "z": -288.24 + "x": -309.5032, + "y": -62.0376167, + "z": 505.5958 + }, + "Rotation": 197.8742, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 98.1 + } + }, + "CorePointId": 15, + "DelayToCanSpawnSec": 4, + "Id": "524d3dd3-fc54-4252-a2d6-3796462f47ab", + "Infiltration": "", + "Position": { + "x": -116.02, + "y": -10, + "z": -360.64 }, "Rotation": 0, "Sides": ["Savage"] @@ -2352,7 +2887,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneIsland", + "BotZoneName": "ZoneSanatorium2", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2362,17 +2897,43 @@ "y": 0, "z": 0 }, - "Radius": 117 + "Radius": 70 } }, - "CorePointId": 17, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "547e6f58-82c9-421c-9e46-22eeb01e35fd", + "Id": "5479a2e2-883c-4371-86a2-01098fb73d45", "Infiltration": "", "Position": { - "x": 212.299988, - "y": -64.98019, - "z": 443.23 + "x": -318.789978, + "y": -5.134326, + "z": -173.12999 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 8, + "DelayToCanSpawnSec": 4, + "Id": "554075de-18c4-468b-9145-4bc8421fa158", + "Infiltration": "", + "Position": { + "x": -197.609985, + "y": -5.05, + "z": -169.939987 }, "Rotation": 0, "Sides": ["Savage"] @@ -2430,7 +2991,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneStartVillage", + "BotZoneName": "ZoneGreenHouses", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2440,24 +3001,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 112 } }, - "CorePointId": 6, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "56d550e7-f871-481a-863c-6045ba1e9ebc", + "Id": "57664e55-8b30-470e-9835-b0a782b742ea", "Infiltration": "", "Position": { - "x": 459.89, - "y": -54.4532776, - "z": 92.4900055 + "x": 123.419983, + "y": -48.44106, + "z": 55.3199921 }, - "Rotation": 277.9801, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRailWays", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2466,24 +3027,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 50 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "5763be21-e44a-4f43-bfa9-c54fa1f54337", - "Infiltration": "", + "Id": "58474a2e-3915-4fd5-b6e1-5fc4a581c2f2", + "Infiltration": "Village", "Position": { - "x": -663.53, - "y": -59.5880241, - "z": 496.900024 + "x": 453.490051, + "y": -54.46, + "z": 188.680008 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBunker", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2492,24 +3053,24 @@ "y": 0, "z": 0 }, - "Radius": 120 + "Radius": 50 } }, - "CorePointId": 15, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "58186668-ecbf-44b9-9cf0-b40f6d81bde9", - "Infiltration": "", + "Id": "58a5c474-0e2f-4f65-98d0-50106e504300", + "Infiltration": "Riverside", "Position": { - "x": -143.76, - "y": -11.7710037, - "z": -343.349976 + "x": -783.529968, + "y": -40.16, + "z": 4.92002869 }, - "Rotation": 27.9957886, - "Sides": ["Savage"] + "Rotation": 9.06, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2523,19 +3084,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "58474a2e-3915-4fd5-b6e1-5fc4a581c2f2", + "Id": "594acb82-cc88-43b0-bff1-0199e4195afb", "Infiltration": "Village", "Position": { - "x": 453.490051, - "y": -54.46, - "z": 188.680008 + "x": -58.1954727, + "y": -18.2153969, + "z": -191.7256 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2544,24 +3105,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 5 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "58a5c474-0e2f-4f65-98d0-50106e504300", - "Infiltration": "Riverside", + "Id": "5a7bf62c-c61b-45b5-9ac1-bbfa945c9718", + "Infiltration": "", "Position": { - "x": -783.529968, - "y": -40.16, - "z": 4.92002869 + "x": 122.47, + "y": -48.44106, + "z": 92.81999 }, - "Rotation": 9.06, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneBunkeSniper", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2570,20 +3131,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 25 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "594acb82-cc88-43b0-bff1-0199e4195afb", - "Infiltration": "Village", + "CorePointId": 12, + "DelayToCanSpawnSec": 1700, + "Id": "5b19b22a-c04f-4370-b653-6c6b80247016", + "Infiltration": "", "Position": { - "x": -58.1954727, - "y": -18.2153969, - "z": -191.7256 + "x": -153.28, + "y": -4.86000061, + "z": -269.44 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -2608,8 +3169,60 @@ "y": -29.2193966, "z": -88.5516052 }, - "Rotation": 83.38443, - "Sides": ["Pmc"] + "Rotation": 83.38443, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 45 + } + }, + "CorePointId": 27, + "DelayToCanSpawnSec": 4, + "Id": "5c28c68f-15eb-4a21-98ae-29e4f6439d09", + "Infiltration": "", + "Position": { + "x": -550.27, + "y": -29.54135, + "z": -211.32 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZonePowerStationSniper", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 25 + } + }, + "CorePointId": 10, + "DelayToCanSpawnSec": 1700, + "Id": "5dea0b6d-5d17-4cb0-bc82-a411e87cc99b", + "Infiltration": "", + "Position": { + "x": -232.69, + "y": -29.7583351, + "z": 192.980011 + }, + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -2663,32 +3276,6 @@ "Rotation": 22.96, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneForestGasStation", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 158.9 - } - }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "5e799dee-af2b-4556-9e82-f7d220d45a56", - "Infiltration": "", - "Position": { - "x": -96.84, - "y": -41.01888, - "z": 211.62999 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -2716,7 +3303,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneForestTruck", + "BotZoneName": "ZoneTunnel", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2726,19 +3313,19 @@ "y": 0, "z": 0 }, - "Radius": 165 + "Radius": 100 } }, - "CorePointId": 11, + "CorePointId": 19, "DelayToCanSpawnSec": 4, - "Id": "5f33a25d-c8ea-441b-87ca-5c008b561eb0", + "Id": "5f737470-952a-4e02-88dc-1804c4f07bba", "Infiltration": "", "Position": { - "x": 27.3945618, - "y": -20.5940456, - "z": -211.800018 + "x": 418.5, + "y": -47.68135, + "z": 255.329987 }, - "Rotation": 0, + "Rotation": 200.381073, "Sides": ["Savage"] }, { @@ -2767,32 +3354,6 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZonePort", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 145.2 - } - }, - "CorePointId": 13, - "DelayToCanSpawnSec": 4, - "Id": "60d33a81-33a3-42dd-8f12-309b3d5297f9", - "Infiltration": "", - "Position": { - "x": -358.3532, - "y": -62.0151253, - "z": 555.8658 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -2845,6 +3406,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneMeteoStation", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 30 + } + }, + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "6203ef1f-8baf-42d9-b96e-c3fa79742ba8", + "Infiltration": "", + "Position": { + "x": -527.13, + "y": -26.95135, + "z": 287.35 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -2872,8 +3459,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGreenHouses", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneIsland", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2882,17 +3469,17 @@ "y": 0, "z": 0 }, - "Radius": 5 + "Radius": 117 } }, - "CorePointId": 1, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "625f7a08-0ad7-44bc-a8b3-ef6c43fe1540", + "Id": "62b19ad5-4171-4dd7-88ea-f8682e2e9516", "Infiltration": "", "Position": { - "x": 109.22998, - "y": -48.30135, - "z": 95.87999 + "x": 244.94, + "y": -64.2984848, + "z": 442.58 }, "Rotation": 0, "Sides": ["Savage"] @@ -2913,14 +3500,14 @@ }, "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "6337b9d9-c4c0-4e0a-8258-11b02c683a64", + "Id": "632f1f2d-5a02-4e51-8997-d5171fa26a32", "Infiltration": "", "Position": { - "x": 459.31, - "y": -54.17835, - "z": 55.7920074 + "x": 459.38, + "y": -54.585, + "z": 181.860016 }, - "Rotation": 266.625641, + "Rotation": 91.269104, "Sides": ["Savage"] }, { @@ -2950,7 +3537,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePowerStation", + "BotZoneName": "ZonePassClose", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2960,17 +3547,17 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 170 } }, - "CorePointId": 2, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "63b51a54-a9b3-461b-afb0-89371d617784", + "Id": "6394c2ff-a787-497a-a82b-89bf528f0009", "Infiltration": "", "Position": { - "x": -251.06, - "y": -40.9783936, - "z": 195.32 + "x": -893.32, + "y": -47.8613472, + "z": 35.4900055 }, "Rotation": 0, "Sides": ["Savage"] @@ -3027,6 +3614,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneIsland", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 117 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "653b1a4b-8863-496d-89cf-0bfd8393ba61", + "Infiltration": "", + "Position": { + "x": 199.670013, + "y": -64.42, + "z": 436.79 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3080,7 +3693,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBunker", + "BotZoneName": "ZoneRailWays", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3090,24 +3703,24 @@ "y": 0, "z": 0 }, - "Radius": 98.1 + "Radius": 158.9 } }, - "CorePointId": 15, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "682bc5af-3d71-413f-9394-4c3bec74c1e9", + "Id": "65e6d797-7fed-4ffa-918d-e85d30ffe1d2", "Infiltration": "", "Position": { - "x": -116.02, - "y": -10, - "z": -360.64 + "x": -638.28, + "y": -59.2350578, + "z": 423.48 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBunkeSniper", - "Categories": ["Bot"], + "BotZoneName": "ZoneMeteoStation", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3116,17 +3729,17 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 30 } }, - "CorePointId": 12, - "DelayToCanSpawnSec": 1700, - "Id": "684b9f6e-a3cd-4a5a-8595-fa5303ac2ab4", + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "697c5025-1260-44de-8473-a3603fcee3d1", "Infiltration": "", "Position": { - "x": -153.28, - "y": -4.86000061, - "z": -269.44 + "x": -464.853973, + "y": -25.3133488, + "z": 272.68 }, "Rotation": 0, "Sides": ["Savage"] @@ -3210,8 +3823,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3223,21 +3836,21 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "6cae38ee-8013-49e2-83e6-74e038360c5e", - "Infiltration": "Riverside", + "Id": "6bd9ae1b-dfdc-486a-b3fa-8ea43dafd480", + "Infiltration": "", "Position": { - "x": -817.199951, - "y": -41.24, - "z": 3.97001648 + "x": -623.65, + "y": -26.7413483, + "z": -224.44 }, - "Rotation": 340.76, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZonePowerStation", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3246,20 +3859,20 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6d3f55cd-fe0c-48ad-afea-e50d1e37df80", - "Infiltration": "", + "Id": "6cae38ee-8013-49e2-83e6-74e038360c5e", + "Infiltration": "Riverside", "Position": { - "x": -248.72998, - "y": -40.9998665, - "z": 158.86 + "x": -817.199951, + "y": -41.24, + "z": 3.97001648 }, - "Rotation": 200.5934, - "Sides": ["Savage"] + "Rotation": 340.76, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -3288,34 +3901,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePowerStationSniper", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 25 - } - }, - "CorePointId": 10, - "DelayToCanSpawnSec": 1700, - "Id": "6ed02d54-2936-4785-b2d8-75e6687a5415", - "Infiltration": "", - "Position": { - "x": -220.86, - "y": -29.7583351, - "z": 189.53 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneBusStation", - "Categories": ["Bot"], + "BotZoneName": "ZonePort", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3324,23 +3911,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 95 } }, - "CorePointId": 14, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "702dfabf-5090-464f-9edd-f2e198d67bfd", + "Id": "6fd75375-cc0d-4878-8a20-b0570b76e685", "Infiltration": "", "Position": { - "x": -78.19, - "y": -21.8066673, - "z": -6.08999634 + "x": -323.5232, + "y": -62.0376167, + "z": 498.4858 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneStartVillage", + "BotZoneName": "ZoneBunker", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3350,23 +3937,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 120 } }, - "CorePointId": 6, + "CorePointId": 15, "DelayToCanSpawnSec": 4, - "Id": "716b2933-2a92-4ee4-8c62-e076a37a6e74", + "Id": "7046c91c-594b-40ef-87d9-2e7201f5637b", "Infiltration": "", "Position": { - "x": 459.38, - "y": -54.585, - "z": 181.860016 + "x": -143.76, + "y": -11.7710037, + "z": -343.349976 }, - "Rotation": 91.269104, + "Rotation": 27.9957886, "Sides": ["Savage"] }, { - "BotZoneName": "ZonePort", + "BotZoneName": "ZoneSanatorium1", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3376,24 +3963,24 @@ "y": 0, "z": 0 }, - "Radius": 71.23 + "Radius": 70 } }, - "CorePointId": 13, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "745138f1-3888-4091-8f93-a7b9edeafb01", + "Id": "743b4654-92d0-419c-9a67-ba4ceaf8d76d", "Infiltration": "", "Position": { - "x": -320.104218, - "y": -61.55635, - "z": 487.7708 + "x": -131.652, + "y": -5.080117, + "z": -103.83 }, - "Rotation": 55.15233, + "Rotation": 301.760071, "Sides": ["Savage"] }, { "BotZoneName": "ZoneSanatorium2", - "Categories": ["Bot", "Boss"], + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3402,17 +3989,17 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "7544625e-e3d8-46dd-8e7d-ddecd80682e4", + "Id": "754e02fa-b297-4522-82bc-809ed153f6a2", "Infiltration": "", "Position": { - "x": -325.729, - "y": -3.711999, - "z": -82.48799 + "x": -350.31, + "y": -5.134326, + "z": -175.090012 }, "Rotation": 0, "Sides": ["Savage"] @@ -3444,7 +4031,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBusStation", + "BotZoneName": "ZonePassClose", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3454,19 +4041,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 165 } }, - "CorePointId": 14, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "75e1a10e-bb12-477e-bdc0-2afdaa3a29f6", + "Id": "765e1313-ab5f-49a5-a13c-d7e54a32f8dc", "Infiltration": "", "Position": { - "x": -72.17, - "y": -21.967, - "z": 10.4600067 + "x": -874.03, + "y": -44.55135, + "z": 6.779999 }, - "Rotation": 233.659576, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -3537,12 +4124,12 @@ }, "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "78a16a38-28d6-4fe3-be01-9a42f41b9bf8", + "Id": "78e220d5-bedf-49b0-b637-1f6f19a13fd3", "Infiltration": "", "Position": { - "x": -308.7532, + "x": -358.7232, "y": -62.0376167, - "z": 477.2958 + "z": 523.105835 }, "Rotation": 0, "Sides": ["Savage"] @@ -3573,32 +4160,6 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneRailWays", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 158.9 - } - }, - "CorePointId": 4, - "DelayToCanSpawnSec": 4, - "Id": "7be7f6e4-7e6f-4168-a49d-551dfe72f6e0", - "Infiltration": "", - "Position": { - "x": -665.5697, - "y": -53.87608, - "z": 420.347137 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -3626,7 +4187,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGreenHouses", + "BotZoneName": "ZoneSmuglers", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3636,17 +4197,17 @@ "y": 0, "z": 0 }, - "Radius": 112 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "7c73b7ac-46bc-41a8-9b69-8e42ab472d22", + "Id": "7e1a96fa-8003-40a0-96bb-381e7ae9c00c", "Infiltration": "", "Position": { - "x": 110.25, - "y": -48.48343, - "z": 138.139984 + "x": -604.62, + "y": -29.8313484, + "z": -176.88 }, "Rotation": 0, "Sides": ["Savage"] @@ -3782,8 +4343,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium1", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZonePowerStation", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3792,19 +4353,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 7, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "8164588c-af20-443c-9576-f76ce7dd2a6f", + "Id": "8165dd60-fec8-493f-a745-5761aead7580", "Infiltration": "", "Position": { - "x": -156.265991, - "y": -3.644, - "z": -82.5099945 + "x": -248.72998, + "y": -40.9998665, + "z": 158.86 }, - "Rotation": 19.4150581, + "Rotation": 200.5934, "Sides": ["Savage"] }, { @@ -3938,7 +4499,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGreenHouses", + "BotZoneName": "ZoneSmuglers", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3948,23 +4509,49 @@ "y": 0, "z": 0 }, - "Radius": 112 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "865fe7b3-63e3-459c-9319-60be77c753b5", + "Id": "86cc6aa6-add6-4214-a5c4-bf38417556d9", "Infiltration": "", "Position": { - "x": 122.43399, - "y": -48.48343, - "z": 136.44 + "x": -604.48, + "y": -29.8313484, + "z": -179.41 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneTunnel", + "BotZoneName": "ZoneForestSpawn", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 165 + } + }, + "CorePointId": 9, + "DelayToCanSpawnSec": 4, + "Id": "86f7377d-a5a1-4b38-b15e-57a94d708490", + "Infiltration": "", + "Position": { + "x": 143.34, + "y": -33.54049, + "z": -288.24 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneRailWays", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3974,24 +4561,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 158.9 } }, - "CorePointId": 19, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "86971dff-1846-4912-8071-d5cd8ecdc289", + "Id": "885ee204-a09a-447e-a771-75a29f89c972", "Infiltration": "", "Position": { - "x": 418.5, - "y": -47.68135, - "z": 255.329987 + "x": -621.76, + "y": -59.59, + "z": 496.840027 }, - "Rotation": 200.381073, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSanatorium2", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4003,20 +4590,72 @@ "Radius": 50 } }, - "CorePointId": 7, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "89c56336-22f0-47ea-91e5-6a3866c9c0ed", + "Infiltration": "Village", + "Position": { + "x": 342.320129, + "y": -56.29, + "z": 114.560013 + }, + "Rotation": 271.08, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 30 + } + }, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "8762e6a0-65f4-436d-8429-a54d76d2a004", + "Id": "89cfc8eb-1c43-4866-ba5e-39b520e7f838", "Infiltration": "", "Position": { - "x": -342.65, - "y": -3.711999, - "z": -82.83 + "x": -231.303, + "y": -4.1430006, + "z": -136.390991 }, - "Rotation": 0, + "Rotation": 19.4150581, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneMeteoStation", + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 100 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "8a734ba8-6fa0-4d55-aa5c-ab260a307087", + "Infiltration": "Village", + "Position": { + "x": -23.70848, + "y": -21.1193962, + "z": -130.091614 + }, + "Rotation": 271.08, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneIsland", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4026,23 +4665,49 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 117 } }, - "CorePointId": 5, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "87e97069-aa96-42a2-95fe-3964b0c458d9", + "Id": "8b1ffc39-37ae-4544-ada6-98a0fbd23742", "Infiltration": "", "Position": { - "x": -451.626526, - "y": -25.96373, - "z": 286.029572 + "x": 228.1, + "y": -64.56713, + "z": 425.740021 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneIsland", + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "8b3b39ba-1662-4d2f-9757-9ceca0a1d311", + "Infiltration": "Riverside", + "Position": { + "x": -818.1099, + "y": -41.2, + "z": 2.36000061 + }, + "Rotation": 341.800049, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneSanatorium1", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4052,24 +4717,24 @@ "y": 0, "z": 0 }, - "Radius": 117 + "Radius": 70 } }, - "CorePointId": 17, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "8934a001-2b3e-43ca-88f0-9257c86fa7d3", + "Id": "8ba4ba4f-d64c-4df4-83cf-0187acea72ac", "Infiltration": "", "Position": { - "x": 244.94, - "y": -64.2984848, - "z": 442.58 + "x": -195.01, + "y": -5.16733074, + "z": -113.72 }, - "Rotation": 0, + "Rotation": 19.4150581, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4081,21 +4746,21 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "89c56336-22f0-47ea-91e5-6a3866c9c0ed", - "Infiltration": "Village", + "Id": "8d3e2d25-b7a0-4900-a0d1-a009e8e8aeae", + "Infiltration": "", "Position": { - "x": 342.320129, - "y": -56.29, - "z": 114.560013 + "x": -622.62, + "y": -29.7413483, + "z": -172.66 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4104,24 +4769,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "8a734ba8-6fa0-4d55-aa5c-ab260a307087", - "Infiltration": "Village", + "Id": "8d725d25-76b6-4ced-99ab-f5992222ad85", + "Infiltration": "", "Position": { - "x": -23.70848, - "y": -21.1193962, - "z": -130.091614 + "x": -291.389984, + "y": -5.84999943, + "z": -54.5399933 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSmuglers", - "Categories": ["Bot"], + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4130,24 +4795,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, - "CorePointId": 26, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "8acd0e94-255d-4df7-9df7-a977751037b2", + "Id": "8e586434-022a-4995-a3af-7afd333b4771", "Infiltration": "", "Position": { - "x": -623.65, - "y": -26.7413483, - "z": -224.44 + "x": -135.68, + "y": -5.13, + "z": -171.279984 }, - "Rotation": 0, + "Rotation": 359.157959, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneForestGasStation", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4156,24 +4821,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "8b3b39ba-1662-4d2f-9757-9ceca0a1d311", - "Infiltration": "Riverside", + "Id": "8e938d6c-9539-4e49-8b89-9cc43fe7312e", + "Infiltration": "", "Position": { - "x": -818.1099, - "y": -41.2, - "z": 2.36000061 + "x": -96.84, + "y": -41.01888, + "z": 211.62999 }, - "Rotation": 341.800049, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4182,23 +4847,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 50 } }, - "CorePointId": 20, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "8cc79948-8e65-4ad5-ac8d-b825093deb8b", + "Id": "8fbb5192-327b-4529-aee0-736d4768a6b9", "Infiltration": "", "Position": { - "x": -175.86319, - "y": -55.7017365, - "z": 394.2658 + "x": -342.65, + "y": -3.711999, + "z": -82.83 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGreenHouses", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4208,17 +4873,17 @@ "y": 0, "z": 0 }, - "Radius": 112 + "Radius": 158.9 } }, - "CorePointId": 1, + "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "8d5ee1c7-e08c-40a9-9e96-22c8f8dce1ed", + "Id": "8fdd3b42-e9d6-4423-98af-8e20428693d9", "Infiltration": "", "Position": { - "x": 125.065, - "y": -48.48343, - "z": 136.388 + "x": -215.5632, + "y": -55.7550659, + "z": 407.585815 }, "Rotation": 0, "Sides": ["Savage"] @@ -4249,32 +4914,6 @@ "Rotation": 328.44, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneBusStation", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 130 - } - }, - "CorePointId": 14, - "DelayToCanSpawnSec": 4, - "Id": "9156c388-6cac-4560-b136-8bc266c9b9cb", - "Infiltration": "", - "Position": { - "x": -143.63, - "y": -21.7317162, - "z": -21.1499939 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -4432,8 +5071,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSmuglers", - "Categories": ["Bot"], + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4445,21 +5084,21 @@ "Radius": 30 } }, - "CorePointId": 26, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "95787f2c-27bb-44ed-bc6e-0ba7ea2e86aa", + "Id": "93324554-5b5c-4e70-af80-a3c1dcaab6c9", "Infiltration": "", "Position": { - "x": -655.188, - "y": -26.8373489, - "z": -164.215 + "x": 122.43399, + "y": -48.48343, + "z": 136.44 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4468,24 +5107,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 5 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "963adbd1-9af1-4b86-ad81-c184ce1e88ea", - "Infiltration": "Village", + "Id": "93778564-febf-4ca2-a846-a8ca4bbec91d", + "Infiltration": "", "Position": { - "x": -23.7184753, - "y": -21.1193962, - "z": -131.591614 + "x": 128.37, + "y": -48.44106, + "z": 76.78 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "ZoneSanatorium2", - "Categories": ["Bot", "Boss"], + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4494,21 +5133,47 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "96984f20-0e19-486e-b20a-26ef0171ef65", + "Id": "9387b94c-8b30-473b-9b51-ed923ac35abc", "Infiltration": "", "Position": { - "x": -312.623, - "y": -3.711999, - "z": -83.31999 + "x": -343.06, + "y": -5.16733074, + "z": -113.16 }, - "Rotation": 0, + "Rotation": 19.4150581, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 100 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "963adbd1-9af1-4b86-ad81-c184ce1e88ea", + "Infiltration": "Village", + "Position": { + "x": -23.7184753, + "y": -21.1193962, + "z": -131.591614 + }, + "Rotation": 271.08, + "Sides": ["Pmc"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -4535,6 +5200,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 26, + "DelayToCanSpawnSec": 4, + "Id": "97f3983b-e39a-44b8-85b1-ec54a9a82e5b", + "Infiltration": "", + "Position": { + "x": -644.133, + "y": -26.85735, + "z": -230.226013 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -4627,17 +5318,43 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "993e3fea-466e-4e80-ace0-9ead90996f1d", + "Infiltration": "Village", + "Position": { + "x": 340.8001, + "y": -42.05, + "z": -271.269958 + }, + "Rotation": 349.17, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZonePowerStation", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "993e3fea-466e-4e80-ace0-9ead90996f1d", - "Infiltration": "Village", + "Id": "9945fa3e-bcf2-4174-98d4-462d5eb0082c", + "Infiltration": "", "Position": { - "x": 340.8001, - "y": -42.05, - "z": -271.269958 + "x": -284.300018, + "y": -34.408, + "z": 195.3 }, - "Rotation": 349.17, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4692,8 +5409,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePowerStation", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4702,23 +5419,23 @@ "y": 0, "z": 0 }, - "Radius": 90 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9b858065-6f85-4762-85aa-55329b561bd2", - "Infiltration": "", + "Id": "9c7c5171-f30e-4d4a-958e-04787fcaed11", + "Infiltration": "Village", "Position": { - "x": -217.540009, - "y": -41.0012, - "z": 166.4 + "x": 447.090149, + "y": -54.46, + "z": 143.48 }, - "Rotation": 276.228271, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneMeteoStation", + "BotZoneName": "ZonePort", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -4728,19 +5445,19 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 71.23 } }, - "CorePointId": 5, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "9bf39d67-208d-454f-9d04-f1a911ad3e06", + "Id": "9de2af3e-cc42-4b8e-bc90-4c9591a8b6ab", "Infiltration": "", "Position": { - "x": -443.9, - "y": -25.962225, - "z": 259.87 + "x": -340.0132, + "y": -62.021347, + "z": 500.8758 }, - "Rotation": 0, + "Rotation": 55.15233, "Sides": ["Savage"] }, { @@ -4759,12 +5476,12 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9c7c5171-f30e-4d4a-958e-04787fcaed11", + "Id": "9f4a8692-feee-433b-96ad-e01829182d9e", "Infiltration": "Village", "Position": { - "x": 447.090149, - "y": -54.46, - "z": 143.48 + "x": 442.659973, + "y": -53.73, + "z": -72.3899841 }, "Rotation": 271.08, "Sides": ["Pmc"] @@ -4785,12 +5502,12 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9f4a8692-feee-433b-96ad-e01829182d9e", - "Infiltration": "Village", + "Id": "9fcd3f72-046c-4c1e-a22c-5d07a395f52d", + "Infiltration": "Riverside", "Position": { - "x": 442.659973, - "y": -53.73, - "z": -72.3899841 + "x": -918.179932, + "y": -58.3, + "z": 255.88002 }, "Rotation": 271.08, "Sides": ["Pmc"] @@ -4811,19 +5528,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "9fcd3f72-046c-4c1e-a22c-5d07a395f52d", - "Infiltration": "Riverside", + "Id": "a00348b8-05c3-4ce5-a471-69ced43de90e", + "Infiltration": "Village", "Position": { - "x": -918.179932, - "y": -58.3, - "z": 255.88002 + "x": 444.1402, + "y": -53.76, + "z": -67.969986 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZonePassClose", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4832,20 +5549,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 170 } }, - "CorePointId": 0, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "a00348b8-05c3-4ce5-a471-69ced43de90e", - "Infiltration": "Village", + "Id": "a0b13bdb-28fc-48d7-a823-e3308a1f1e1f", + "Infiltration": "", "Position": { - "x": 444.1402, - "y": -53.76, - "z": -67.969986 + "x": -897.18, + "y": -48.50135, + "z": 44.3399963 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4925,6 +5642,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneGasStation", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 28, + "DelayToCanSpawnSec": 4, + "Id": "a31a56f9-193b-4e89-84ab-86ab0f7ff509", + "Infiltration": "", + "Position": { + "x": -166.7232, + "y": -55.6530457, + "z": 368.7158 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -5029,6 +5772,58 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneGasStation", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 20, + "DelayToCanSpawnSec": 4, + "Id": "a6d117b3-c753-4848-b654-84a0eff51cf9", + "Infiltration": "", + "Position": { + "x": -175.86319, + "y": -55.7017365, + "z": 394.2658 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZonePowerStation", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "a78644ff-720f-45a5-b31f-c4d13a96d3c4", + "Infiltration": "", + "Position": { + "x": -251.06, + "y": -40.9783936, + "z": 195.32 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -5082,8 +5877,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGreenHouses", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5092,24 +5887,24 @@ "y": 0, "z": 0 }, - "Radius": 112 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a82ea519-4676-45b8-a6a9-9e9f8d73cb0f", - "Infiltration": "", + "Id": "a8f40aef-a808-4b51-9961-9d3f9914d22b", + "Infiltration": "Riverside", "Position": { - "x": 123.419983, - "y": -48.44106, - "z": 55.3199921 + "x": -690.6999, + "y": -59.57, + "z": 497.469971 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5121,17 +5916,17 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "a8f40aef-a808-4b51-9961-9d3f9914d22b", - "Infiltration": "Riverside", + "Id": "a9fe2b24-041d-4f60-823b-1daa2c58a2d7", + "Infiltration": "", "Position": { - "x": -690.6999, - "y": -59.57, - "z": 497.469971 + "x": -146.11, + "y": -3.644, + "z": -82.6199951 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 19.4150581, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5212,8 +6007,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSmuglers", - "Categories": ["Bot"], + "BotZoneName": "ZoneForestSpawn", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5222,17 +6017,17 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 165 } }, - "CorePointId": 26, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "b0994adc-9ae8-4270-9c28-b36ffd4220a8", + "Id": "b0a92ac1-3af8-4fd0-92ae-1e34bc84fae6", "Infiltration": "", "Position": { - "x": -632.42, - "y": -26.8423481, - "z": -240.12 + "x": 148.15, + "y": -37.44359, + "z": -256.349976 }, "Rotation": 0, "Sides": ["Savage"] @@ -5256,38 +6051,12 @@ "Id": "b0ca8c3f-6d94-4e03-8e1f-5b3996478e2f", "Infiltration": "Riverside", "Position": { - "x": -666.1799, - "y": -54.56, - "z": 324.74 - }, - "Rotation": 120.843109, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZonePassClose", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 170 - } - }, - "CorePointId": 18, - "DelayToCanSpawnSec": 4, - "Id": "b0ed321e-3cdc-4930-8408-1d62316084db", - "Infiltration": "", - "Position": { - "x": -897.18, - "y": -48.50135, - "z": 44.3399963 + "x": -666.1799, + "y": -54.56, + "z": 324.74 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 120.843109, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -5394,7 +6163,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBunker", + "BotZoneName": "ZoneGreenHouses", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5404,19 +6173,45 @@ "y": 0, "z": 0 }, - "Radius": 98.1 + "Radius": 112 } }, - "CorePointId": 15, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "b417aab5-1733-4e41-886b-810394feefe7", + "Id": "b3c955bd-b0a1-43eb-8141-16d30fb0a07d", "Infiltration": "", "Position": { - "x": -156.61, - "y": -13.4983215, - "z": -343.31 + "x": 78.95999, + "y": -48.4015732, + "z": 91.57999 }, - "Rotation": 44.298996, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 30 + } + }, + "CorePointId": 26, + "DelayToCanSpawnSec": 4, + "Id": "b4bff76c-3f49-49d7-9db4-61cf3a1b9269", + "Infiltration": "", + "Position": { + "x": -659.261, + "y": -26.8373489, + "z": -162.341 + }, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -5445,6 +6240,32 @@ "Rotation": 248.009979, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneBusStation", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 14, + "DelayToCanSpawnSec": 4, + "Id": "b7da9272-2a76-4bc4-862f-c9e5dae5918d", + "Infiltration": "", + "Position": { + "x": -100.12, + "y": -22.2816, + "z": 10.7100067 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -5471,6 +6292,32 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 26, + "DelayToCanSpawnSec": 4, + "Id": "ba3c832a-23bc-4a83-ac4d-483c86999d0a", + "Infiltration": "", + "Position": { + "x": -615.14, + "y": -29.7413483, + "z": -177.85 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -5498,7 +6345,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePassClose", + "BotZoneName": "ZoneGasStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5508,17 +6355,17 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 158.9 } }, - "CorePointId": 18, + "CorePointId": 28, "DelayToCanSpawnSec": 4, - "Id": "be3b0428-2759-42c7-8940-b2033726ada4", + "Id": "bc626601-5b59-423c-a3b6-fcaf7f841bd9", "Infiltration": "", "Position": { - "x": -893.32, - "y": -47.8613472, - "z": 35.4900055 + "x": -192.393188, + "y": -55.693428, + "z": 367.8458 }, "Rotation": 0, "Sides": ["Savage"] @@ -5627,32 +6474,6 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneBunkeSniper", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 25 - } - }, - "CorePointId": 12, - "DelayToCanSpawnSec": 1700, - "Id": "c080ada3-90b6-40f3-972f-063b838bb0c5", - "Infiltration": "", - "Position": { - "x": -151.93, - "y": -4.86000061, - "z": -268.55 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -5706,8 +6527,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneIsland", - "Categories": ["Bot"], + "BotZoneName": "ZoneForestSpawn", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5716,17 +6537,17 @@ "y": 0, "z": 0 }, - "Radius": 117 + "Radius": 170 } }, - "CorePointId": 17, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "c23d0f88-4e27-4550-a89d-d9391a9614af", + "Id": "c10525ce-aa6d-4077-98a6-b7580b0acff0", "Infiltration": "", "Position": { - "x": 206.450012, - "y": -64.8, - "z": 443.370026 + "x": 162.59, + "y": -34.96685, + "z": -296.289978 }, "Rotation": 0, "Sides": ["Savage"] @@ -5758,34 +6579,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBunker", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 120 - } - }, - "CorePointId": 15, - "DelayToCanSpawnSec": 4, - "Id": "c2f8425a-8a7d-4058-9070-ae69677b6729", - "Infiltration": "", - "Position": { - "x": -122.083717, - "y": -9.238266, - "z": -356.685 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneForestSpawn", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5794,23 +6589,23 @@ "y": 0, "z": 0 }, - "Radius": 165 + "Radius": 50 } }, - "CorePointId": 9, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c34cf35a-b5c0-452e-a2b9-008064e3cf65", - "Infiltration": "", + "Id": "c5425f62-ced4-4198-9a77-dc186b09fee9", + "Infiltration": "Riverside", "Position": { - "x": 148.15, - "y": -37.44359, - "z": -256.349976 + "x": -934.2699, + "y": -55.26, + "z": 162.39003 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 30.3, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneMeteoStation", + "BotZoneName": "ZonePort", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5820,47 +6615,21 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 71.23 } }, - "CorePointId": 5, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "c3760608-8817-4038-8929-e5db63dd189e", + "Id": "c5666fb4-802b-4968-bdf8-b32c06ebb168", "Infiltration": "", "Position": { - "x": -443.47998, - "y": -25.283453, - "z": 248.040009 + "x": -320.104218, + "y": -61.55635, + "z": 487.7708 }, - "Rotation": 0, + "Rotation": 55.15233, "Sides": ["Savage"] }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "c5425f62-ced4-4198-9a77-dc186b09fee9", - "Infiltration": "Riverside", - "Position": { - "x": -934.2699, - "y": -55.26, - "z": 162.39003 - }, - "Rotation": 30.3, - "Sides": ["Pmc"] - }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -5914,8 +6683,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium1", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5924,23 +6693,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 100 } }, - "CorePointId": 8, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c6a6bb13-f9af-4286-a9ef-f8841490c48a", - "Infiltration": "", + "Id": "c7cb0954-dda5-42e0-9b79-a46147072046", + "Infiltration": "Riverside", "Position": { - "x": -168.695984, - "y": -3.644, - "z": -83.987 + "x": -470.378479, + "y": -29.2793961, + "z": -88.11162 }, - "Rotation": 19.4150581, - "Sides": ["Savage"] + "Rotation": 83.38443, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePort", + "BotZoneName": "ZoneStartVillage", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5950,19 +6719,19 @@ "y": 0, "z": 0 }, - "Radius": 71.23 + "Radius": 158.9 } }, - "CorePointId": 13, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "c6ed5398-c447-4e19-8098-aba0024b089f", + "Id": "c8604a7e-7edf-4ca6-bd3b-15b1c2a7610c", "Infiltration": "", "Position": { - "x": -340.0132, - "y": -62.021347, - "z": 500.8758 + "x": 458.95, + "y": -54.54093, + "z": 159.47 }, - "Rotation": 55.15233, + "Rotation": 89.74151, "Sides": ["Savage"] }, { @@ -5981,19 +6750,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c7cb0954-dda5-42e0-9b79-a46147072046", + "Id": "c9cf5a12-0263-4478-8f0d-f6c73e39080a", "Infiltration": "Riverside", "Position": { - "x": -470.378479, - "y": -29.2793961, - "z": -88.11162 + "x": -471.468445, + "y": -28.7993965, + "z": -91.53162 }, "Rotation": 83.38443, "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePowerStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneSmuglers", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6002,23 +6771,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 30 } }, - "CorePointId": 16, + "CorePointId": 26, "DelayToCanSpawnSec": 4, - "Id": "c86317fd-4e91-4eaa-a927-acb309310554", + "Id": "caa3664a-b205-46fa-b474-4a427ec98b4b", "Infiltration": "", "Position": { - "x": -284.300018, - "y": -34.408, - "z": 195.3 + "x": -655.188, + "y": -26.8373489, + "z": -164.215 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSmuglers", + "BotZoneName": "ZoneSanatorium1", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6028,24 +6797,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, - "CorePointId": 26, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "c8c42be4-9ee8-47a7-82e0-6242483d1b6b", + "Id": "cbc9edea-585f-441b-bc7d-e1e7ea1b9a7e", "Infiltration": "", "Position": { - "x": -604.48, - "y": -29.8313484, - "z": -179.41 + "x": -170.957, + "y": -5.131999, + "z": -129.347992 }, - "Rotation": 0, + "Rotation": 359.157959, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneMeteoStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6054,24 +6823,24 @@ "y": 0, "z": 0 }, - "Radius": 170 + "Radius": 50 } }, - "CorePointId": 5, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "c9cad217-352f-4be9-8f3a-49d1099aad8b", + "Id": "cc29cf79-1cb2-4d59-9f51-8b28ab60fe92", "Infiltration": "", "Position": { - "x": -520.37, - "y": -25.6599045, - "z": 284.63 + "x": -312.623, + "y": -3.711999, + "z": -83.31999 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6080,24 +6849,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "c9cf5a12-0263-4478-8f0d-f6c73e39080a", - "Infiltration": "Riverside", + "Id": "cc63cf8a-19b7-4e28-a00d-daee97f7744f", + "Infiltration": "", "Position": { - "x": -471.468445, - "y": -28.7993965, - "z": -91.53162 + "x": -325.729, + "y": -3.711999, + "z": -82.48799 }, - "Rotation": 83.38443, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneForestGasStation", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6106,23 +6875,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 50 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ca4c37b5-79a5-4918-aac4-99a2eef4f095", - "Infiltration": "", + "Id": "cd50d306-1cfa-4829-a915-043e547288af", + "Infiltration": "Riverside", "Position": { - "x": -105.990021, - "y": -40.13835, - "z": 244.969986 + "x": -595.16, + "y": -45.0700035, + "z": 159.190018 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 96.22, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePort", + "BotZoneName": "ZoneRailWays", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6132,24 +6901,24 @@ "y": 0, "z": 0 }, - "Radius": 71.23 + "Radius": 158.9 } }, - "CorePointId": 13, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "cc3ff729-5506-4934-ae44-bb6b6bf9a68f", + "Id": "d08c5d12-e998-4805-a39a-072bc774b59f", "Infiltration": "", "Position": { - "x": -358.7232, - "y": -62.0376167, - "z": 523.105835 + "x": -665.5697, + "y": -53.87608, + "z": 420.347137 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneForestGasStation", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneBusStation", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6158,24 +6927,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 130 } }, - "CorePointId": 2, + "CorePointId": 14, "DelayToCanSpawnSec": 4, - "Id": "cd2df98d-5f11-4f2c-bab2-fe3fd54a25f3", + "Id": "d2eada9d-956f-4f1a-bf87-5c1cc813719c", "Infiltration": "", "Position": { - "x": -87.8699951, - "y": -42.39235, - "z": 272.28 + "x": -139.86, + "y": -21.86, + "z": 5.12001038 }, "Rotation": 0, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6189,18 +6958,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "cd50d306-1cfa-4829-a915-043e547288af", - "Infiltration": "Riverside", + "Id": "d3134c35-d002-4460-8770-4521bff63908", + "Infiltration": "Village", "Position": { - "x": -595.16, - "y": -45.0700035, - "z": 159.190018 + "x": -51.72548, + "y": -18.7543964, + "z": -189.127609 }, - "Rotation": 96.22, + "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTunnel", + "BotZoneName": "ZoneForestTruck", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6210,24 +6979,24 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 170 } }, - "CorePointId": 19, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "d11085f3-3c60-44f9-a2a1-7d52781e49fe", + "Id": "d3a45967-46a2-4797-83bd-658ed2863db8", "Infiltration": "", "Position": { - "x": 374.68, - "y": -59.69135, - "z": 314.669983 + "x": 72.59999, + "y": -31.1844521, + "z": -156.3 }, - "Rotation": 277.5449, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSanatorium1", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneTunnel", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6236,24 +7005,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 80 } }, - "CorePointId": 7, + "CorePointId": 19, "DelayToCanSpawnSec": 4, - "Id": "d18a32e4-5fbe-4905-bae4-f0ac1de69114", + "Id": "d4c51ca2-1d8e-496c-9340-ab1d9c4abc31", "Infiltration": "", "Position": { - "x": -146.11, - "y": -3.644, - "z": -82.6199951 + "x": 374.68, + "y": -59.69135, + "z": 314.669983 }, - "Rotation": 19.4150581, + "Rotation": 277.5449, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6262,24 +7031,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 100 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d3134c35-d002-4460-8770-4521bff63908", - "Infiltration": "Village", + "Id": "d635ccc7-2aea-4e5a-aa3d-2418daa3b472", + "Infiltration": "Riverside", "Position": { - "x": -51.72548, - "y": -18.7543964, - "z": -189.127609 + "x": -468.298462, + "y": -27.5993958, + "z": -101.861618 }, - "Rotation": 271.08, + "Rotation": 83.38443, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneForestSpawn", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6288,24 +7057,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 165 } }, - "CorePointId": 0, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "d635ccc7-2aea-4e5a-aa3d-2418daa3b472", - "Infiltration": "Riverside", + "Id": "d64497e5-aa96-44cd-8d36-18e11a777b0a", + "Infiltration": "", "Position": { - "x": -468.298462, - "y": -27.5993958, - "z": -101.861618 + "x": 181.433884, + "y": -37.2266273, + "z": -268.557648 }, - "Rotation": 83.38443, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneStartVillage", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6314,23 +7083,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "d848ab74-083b-4454-94d3-3f5cb54b6f7a", - "Infiltration": "Village", + "Id": "d78fdf91-d022-41d3-b595-5076e00d5517", + "Infiltration": "", "Position": { - "x": 350.5401, - "y": -63.69, - "z": 332.75 + "x": 462.4, + "y": -54.4639664, + "z": 119.560013 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 195.821518, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBusStation", + "BotZoneName": "ZoneTunnel", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6340,19 +7109,19 @@ "y": 0, "z": 0 }, - "Radius": 130 + "Radius": 80 } }, - "CorePointId": 14, + "CorePointId": 19, "DelayToCanSpawnSec": 4, - "Id": "d857382a-90df-4754-bfcf-58eb1eb5cfda", + "Id": "d80093d9-1dee-4d90-8438-38d5f9425ef4", "Infiltration": "", "Position": { - "x": -139.86, - "y": -21.86, - "z": 5.12001038 + "x": 420.2, + "y": -47.58135, + "z": 243.54 }, - "Rotation": 0, + "Rotation": 195.719528, "Sides": ["Savage"] }, { @@ -6371,19 +7140,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d92df5a8-fe9d-4a40-839f-5f6652251b7d", + "Id": "d848ab74-083b-4454-94d3-3f5cb54b6f7a", "Infiltration": "Village", "Position": { - "x": 443.570129, - "y": -53.71, - "z": -75.58998 + "x": 350.5401, + "y": -63.69, + "z": 332.75 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6392,20 +7161,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, - "CorePointId": 0, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "da7f0704-9a32-4743-9249-c0d140624733", - "Infiltration": "Village", + "Id": "d8d720fb-ade2-4fbf-89ab-c448c9676322", + "Infiltration": "", "Position": { - "x": -54.4034729, - "y": -18.5393963, - "z": -192.3936 + "x": -227.107, + "y": -5.082999, + "z": -54.086 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 19.4150581, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -6423,18 +7192,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "dba2b2cf-a399-4193-926d-17dd61d15435", + "Id": "d92df5a8-fe9d-4a40-839f-5f6652251b7d", "Infiltration": "Village", "Position": { - "x": 315.740051, - "y": -54.56, - "z": -142.139984 + "x": 443.570129, + "y": -53.71, + "z": -75.58998 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium1", + "BotZoneName": "ZoneGreenHouses", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6444,23 +7213,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 112 } }, - "CorePointId": 8, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "dc2b3bc6-0c1c-4fa5-ab23-afb4c698be9f", + "Id": "da195f7e-31b2-4e7b-850c-5d107efe3606", "Infiltration": "", "Position": { - "x": -234.599991, - "y": -5.16861629, - "z": -174.900009 + "x": 125.065, + "y": -48.48343, + "z": 136.388 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneSmuglers", + "BotZoneName": "ZoneMeteoStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6470,24 +7239,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 170 } }, - "CorePointId": 26, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "dc6943fc-d800-4876-b64b-048e09172cfb", + "Id": "da3996f5-837c-4663-8182-ec3d78615404", "Infiltration": "", "Position": { - "x": -604.62, - "y": -29.8313484, - "z": -176.88 + "x": -451.626526, + "y": -25.96373, + "z": 286.029572 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZonePassClose", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6496,20 +7265,20 @@ "y": 0, "z": 0 }, - "Radius": 165 + "Radius": 50 } }, - "CorePointId": 18, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "dce68291-02f7-41f7-8ea4-335d34aa4b32", - "Infiltration": "", + "Id": "da7f0704-9a32-4743-9249-c0d140624733", + "Infiltration": "Village", "Position": { - "x": -874.03, - "y": -44.55135, - "z": 6.779999 + "x": -54.4034729, + "y": -18.5393963, + "z": -192.3936 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -6527,19 +7296,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "dd45d07f-ac7b-4aaa-9a2f-643365a0b3d3", - "Infiltration": "Riverside", + "Id": "dba2b2cf-a399-4193-926d-17dd61d15435", + "Infiltration": "Village", "Position": { - "x": -815.559937, - "y": -41.19, - "z": 3.92002869 + "x": 315.740051, + "y": -54.56, + "z": -142.139984 }, - "Rotation": 1.4, + "Rotation": 271.08, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6553,19 +7322,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ddad0594-dea6-446e-8b1e-1de3b7f43677", - "Infiltration": "Village", + "Id": "dd45d07f-ac7b-4aaa-9a2f-643365a0b3d3", + "Infiltration": "Riverside", "Position": { - "x": -61.2084732, - "y": -18.0833969, - "z": -196.8716 + "x": -815.559937, + "y": -41.19, + "z": 3.92002869 }, - "Rotation": 271.08, + "Rotation": 1.4, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneIsland", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6574,20 +7343,20 @@ "y": 0, "z": 0 }, - "Radius": 117 + "Radius": 50 } }, - "CorePointId": 17, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ddff13a6-00cf-485b-aff7-e8f9d7f122a5", - "Infiltration": "", + "Id": "ddad0594-dea6-446e-8b1e-1de3b7f43677", + "Infiltration": "Village", "Position": { - "x": 199.670013, - "y": -64.42, - "z": 436.79 + "x": -61.2084732, + "y": -18.0833969, + "z": -196.8716 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -6709,19 +7478,19 @@ }, "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "e1f2441d-21c1-46fc-98a9-bae9e2593ab8", + "Id": "e1cdf1a6-dd67-4e18-8b00-97556fd2b670", "Infiltration": "", "Position": { - "x": -621.76, - "y": -59.59, - "z": 496.840027 + "x": -663.53, + "y": -59.5880241, + "z": 496.900024 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneTunnel", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6730,24 +7499,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 6, "DelayToCanSpawnSec": 4, - "Id": "e2a13b2e-16d3-420f-af05-905069917b66", - "Infiltration": "Village", + "Id": "e1e1d1e1-2dd3-4d48-9580-9077114da3c0", + "Infiltration": "", "Position": { - "x": 280.770081, - "y": -56.24, - "z": 175.250015 + "x": 446.610016, + "y": -48.09135, + "z": 235.079987 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 210.132233, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneIsland", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6756,20 +7525,20 @@ "y": 0, "z": 0 }, - "Radius": 117 + "Radius": 50 } }, - "CorePointId": 17, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e4809395-3ce8-40b2-b5ab-c678bd4cd7c7", - "Infiltration": "", + "Id": "e2a13b2e-16d3-420f-af05-905069917b66", + "Infiltration": "Village", "Position": { - "x": 203.769989, - "y": -64.57, - "z": 441.370026 + "x": 280.770081, + "y": -56.24, + "z": 175.250015 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -6798,7 +7567,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRailWays", + "BotZoneName": "ZoneBusStation", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6808,47 +7577,21 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 130 } }, - "CorePointId": 4, + "CorePointId": 14, "DelayToCanSpawnSec": 4, - "Id": "e5289fbf-42d4-42b4-a74a-1d7561bd3223", + "Id": "e57506c3-0cb9-43b1-9ac9-7d2f5732fc0f", "Infiltration": "", "Position": { - "x": -638.28, - "y": -59.2350578, - "z": 423.48 + "x": -143.63, + "y": -21.7317162, + "z": -21.1499939 }, "Rotation": 0, "Sides": ["Savage"] }, - { - "BotZoneName": "ZoneTunnel", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 212 - } - }, - "CorePointId": 19, - "DelayToCanSpawnSec": 4, - "Id": "e6c06ccc-11d6-4010-9eaf-081b3ba69cde", - "Infiltration": "", - "Position": { - "x": 357.550018, - "y": -59.62579, - "z": 328.87 - }, - "Rotation": 222.77774, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -6876,7 +7619,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneTunnel", + "BotZoneName": "ZoneIsland", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -6886,24 +7629,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 117 } }, - "CorePointId": 6, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "ea27291c-82b2-4271-8aed-b47b32e91bf4", + "Id": "e85eb615-6087-411a-830e-dece6f8591a3", "Infiltration": "", "Position": { - "x": 446.610016, - "y": -48.09135, - "z": 235.079987 + "x": 212.299988, + "y": -64.98019, + "z": 443.23 }, - "Rotation": 210.132233, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGasStation", - "Categories": ["Bot"], + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6912,17 +7655,17 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 25 } }, - "CorePointId": 20, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "ea576e37-2e1f-46b6-b2d3-b5e96113a3b8", + "Id": "e9ed4b8b-1d3b-451e-b2a5-3b3ae705bb45", "Infiltration": "", "Position": { - "x": -215.5632, - "y": -55.7550659, - "z": 407.585815 + "x": 134.297, + "y": -48.55235, + "z": 53.0139923 }, "Rotation": 0, "Sides": ["Savage"] @@ -6980,33 +7723,7 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePort", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 95 - } - }, - "CorePointId": 13, - "DelayToCanSpawnSec": 4, - "Id": "eab6626b-e220-4211-b803-67898c618b81", - "Infiltration": "", - "Position": { - "x": -323.5232, - "y": -62.0376167, - "z": 498.4858 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneBunker", + "BotZoneName": "ZoneSanatorium1", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -7016,24 +7733,24 @@ "y": 0, "z": 0 }, - "Radius": 98.1 + "Radius": 70 } }, - "CorePointId": 15, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "eb9cc2ab-569f-43e3-9b24-4289533daa38", + "Id": "ebc1a9f2-c27b-49fc-bf03-c3ea42356d9b", "Infiltration": "", "Position": { - "x": -134.798325, - "y": -10.67804, - "z": -351.499146 + "x": -234.599991, + "y": -5.16861629, + "z": -174.900009 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZonePowerStationSniper", - "Categories": ["Bot"], + "BotZoneName": "ZoneGreenHouses", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7042,17 +7759,17 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 5 } }, - "CorePointId": 10, - "DelayToCanSpawnSec": 1700, - "Id": "ee0fb761-cb88-40d7-8a80-052e28db9451", + "CorePointId": 1, + "DelayToCanSpawnSec": 4, + "Id": "ec25a1ad-30c5-412d-bc4f-9d36ced86ee0", "Infiltration": "", "Position": { - "x": -232.69, - "y": -29.7583351, - "z": 192.980011 + "x": 109.22998, + "y": -48.30135, + "z": 95.87999 }, "Rotation": 0, "Sides": ["Savage"] @@ -7068,24 +7785,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 170 } }, "CorePointId": 20, "DelayToCanSpawnSec": 4, - "Id": "ee7aa9cd-02f6-4897-a29f-38e335f6f4e4", + "Id": "ec5cc227-6c8b-43aa-a247-78f47ac5d91d", "Infiltration": "", "Position": { - "x": -218.900024, - "y": -55.6409073, - "z": 379.015839 + "x": -188.5232, + "y": -65.00135, + "z": 447.6358 }, "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneTunnel", - "Categories": ["Bot"], + "BotZoneName": "ZonePort", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7094,19 +7811,19 @@ "y": 0, "z": 0 }, - "Radius": 80 + "Radius": 30 } }, - "CorePointId": 19, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "eefa0cd2-7d19-49d4-8f67-b57ef3862d9d", + "Id": "ec61521c-c1c7-4337-b1d8-f3c61f250dfd", "Infiltration": "", "Position": { - "x": 420.2, - "y": -47.58135, - "z": 243.54 + "x": -356.953217, + "y": -61.85135, + "z": 528.2658 }, - "Rotation": 195.719528, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -7161,6 +7878,58 @@ "Rotation": 271.08, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneSanatorium1", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 8, + "DelayToCanSpawnSec": 4, + "Id": "eff6da9e-20f3-460c-96c8-b78f445f8190", + "Infiltration": "", + "Position": { + "x": -168.695984, + "y": -3.644, + "z": -83.987 + }, + "Rotation": 19.4150581, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 120 + } + }, + "CorePointId": 15, + "DelayToCanSpawnSec": 4, + "Id": "f02a9792-7ea5-451c-bb2c-1bab854912d3", + "Infiltration": "", + "Position": { + "x": -122.083717, + "y": -9.238266, + "z": -356.685 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "ZoneBusStation", "Categories": ["Bot"], @@ -7177,12 +7946,12 @@ }, "CorePointId": 14, "DelayToCanSpawnSec": 4, - "Id": "f16e036e-db41-4453-bb2b-e0b71ee73ada", + "Id": "f1853db8-4c6f-41f8-9998-e8984ff1d71e", "Infiltration": "", "Position": { - "x": -100.12, - "y": -22.2816, - "z": 10.7100067 + "x": -78.19, + "y": -21.8066673, + "z": -6.08999634 }, "Rotation": 0, "Sides": ["Savage"] @@ -7292,8 +8061,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneGreenHouses", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7302,24 +8071,24 @@ "y": 0, "z": 0 }, - "Radius": 112 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f473bfd3-f168-4385-8c00-4a4f12f9cf35", - "Infiltration": "", + "Id": "f79c4cad-9e70-4da7-bae8-19c2ff9bd403", + "Infiltration": "Village", "Position": { - "x": 160.559982, - "y": -48.30135, - "z": 62.09999 + "x": -53.22348, + "y": -18.7573967, + "z": -195.6136 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZonePort", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7328,24 +8097,24 @@ "y": 0, "z": 0 }, - "Radius": 131.2 + "Radius": 50 } }, - "CorePointId": 13, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f6d89cec-f342-4543-b860-bb4e946249bf", - "Infiltration": "", + "Id": "f7d9fd21-aa76-4c4f-ac8e-5019ad44fbed", + "Infiltration": "Village", "Position": { - "x": -292.6332, - "y": -62.0376167, - "z": 493.6858 + "x": -54.0254822, + "y": -18.7153969, + "z": -193.853622 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneSanatorium1", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7354,24 +8123,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, - "CorePointId": 8, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f75776a1-d4af-4e10-87a0-6f8d016851a4", - "Infiltration": "", + "Id": "f883d201-beea-44b0-981b-3e5416ca1d3d", + "Infiltration": "Village", "Position": { - "x": -170.957, - "y": -5.131999, - "z": -129.347992 + "x": 316.06012, + "y": -54.56, + "z": -144.089981 }, - "Rotation": 359.157959, - "Sides": ["Savage"] + "Rotation": 271.08, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Group"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7385,19 +8154,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f79c4cad-9e70-4da7-bae8-19c2ff9bd403", + "Id": "fa5ef3eb-f86a-4f3d-a4b4-11105d318930", "Infiltration": "Village", "Position": { - "x": -53.22348, - "y": -18.7573967, - "z": -195.6136 + "x": 315.860168, + "y": -54.56, + "z": -140.279984 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7406,20 +8175,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, - "CorePointId": 0, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "f7d9fd21-aa76-4c4f-ac8e-5019ad44fbed", - "Infiltration": "Village", + "Id": "fa73db25-31b0-4f1d-8a91-b2ae6f08154c", + "Infiltration": "", "Position": { - "x": -54.0254822, - "y": -18.7153969, - "z": -193.853622 + "x": -299.15, + "y": -5.134326, + "z": -151.41 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -7437,19 +8206,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f883d201-beea-44b0-981b-3e5416ca1d3d", + "Id": "fb7bd71f-8177-4417-8e29-916904ca2d8a", "Infiltration": "Village", "Position": { - "x": 316.06012, - "y": -54.56, - "z": -144.089981 + "x": 341.460022, + "y": -56.29, + "z": 120.560013 }, "Rotation": 271.08, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneSanatorium2", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7458,24 +8227,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 35 } }, - "CorePointId": 0, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "fa5ef3eb-f86a-4f3d-a4b4-11105d318930", - "Infiltration": "Village", + "Id": "fc83f4a2-9434-46ba-828b-d54c8421a6a6", + "Infiltration": "", "Position": { - "x": 315.860168, - "y": -54.56, - "z": -140.279984 + "x": -272.846, + "y": -4.152999, + "z": -133.515 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneForestGasStation", + "Categories": ["Bot", "Boss"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7484,23 +8253,23 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "fb7bd71f-8177-4417-8e29-916904ca2d8a", - "Infiltration": "Village", + "Id": "fcbbf53a-b5ab-4de4-bb5b-0fe490d1614b", + "Infiltration": "", "Position": { - "x": 341.460022, - "y": -56.29, - "z": 120.560013 + "x": -105.990021, + "y": -40.13835, + "z": 244.969986 }, - "Rotation": 271.08, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneGreenHouses", + "BotZoneName": "ZonePort", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -7510,17 +8279,17 @@ "y": 0, "z": 0 }, - "Radius": 112 + "Radius": 71.23 } }, - "CorePointId": 1, + "CorePointId": 13, "DelayToCanSpawnSec": 4, - "Id": "fda8f23d-c141-482a-9861-2d82752c52c1", + "Id": "fdd4ffb4-45df-40eb-8375-074071893683", "Infiltration": "", "Position": { - "x": 78.95999, - "y": -48.4015732, - "z": 91.57999 + "x": -308.7532, + "y": -62.0376167, + "z": 477.2958 }, "Rotation": 0, "Sides": ["Savage"] @@ -7767,350 +8536,41 @@ { "TemplateId": "57347ca924597744596b4e71", "Value": 1 + }, + { + "TemplateId": "634959225289190e5e773b3b", + "Value": 7 } ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "SHO_TRANSIT_24_COND", + "description": "SHO_TRANSIT_24_DESC", + "id": 24, + "location": "Lighthouse", + "name": "SHO_TRANSIT_24", + "target": "5704e4dad2720bb55b8b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": false, + "conditions": "SHO_TRANSIT_25_COND", + "description": "SHO_TRANSIT_25_DESC", + "id": 25, + "location": "Terminal", + "name": "SHO_TRANSIT_25", + "target": "5704e5a4d2720bb45b8b4567", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [ - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 4, - "slots_min": 2, - "time_max": 11, - "time_min": 5 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneIsland", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 1, - "slots_max": 2, - "slots_min": 0, - "time_max": 150, - "time_min": 140 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneGasStation", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 2, - "slots_max": 4, - "slots_min": 1, - "time_max": 11, - "time_min": 5 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneMeteoStation", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 3, - "slots_max": 2, - "slots_min": 1, - "time_max": 168, - "time_min": 160 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZonePowerStation", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 4, - "slots_max": 2, - "slots_min": 1, - "time_max": 11, - "time_min": 5 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneBusStation", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 5, - "slots_max": 2, - "slots_min": 1, - "time_max": 11, - "time_min": 5 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneRailWays", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 6, - "slots_max": 2, - "slots_min": 1, - "time_max": 178, - "time_min": 170 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZonePort", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 7, - "slots_max": 2, - "slots_min": 1, - "time_max": 190, - "time_min": 180 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZonePowerStationSniper", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 9, - "slots_max": 0, - "slots_min": 0, - "time_max": 20, - "time_min": 0 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneBunkeSniper", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 10, - "slots_max": 1, - "slots_min": 0, - "time_max": 20, - "time_min": 0 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZonePort", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 11, - "slots_max": 1, - "slots_min": 0, - "time_max": 1420, - "time_min": 1390 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneIsland", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 12, - "slots_max": 1, - "slots_min": 0, - "time_max": 1500, - "time_min": 1450 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneForestTruck", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 13, - "slots_max": 2, - "slots_min": 0, - "time_max": 50, - "time_min": 0 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneForestSpawn", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 14, - "slots_max": 2, - "slots_min": 0, - "time_max": 50, - "time_min": 0 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 15, - "slots_max": 4, - "slots_min": 2, - "time_max": 300, - "time_min": 200 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 16, - "slots_max": 4, - "slots_min": 1, - "time_max": 1000, - "time_min": 600 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 17, - "slots_max": 4, - "slots_min": 0, - "time_max": 2200, - "time_min": 1300 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 18, - "slots_max": 2, - "slots_min": 1, - "time_max": -1, - "time_min": -1 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 19, - "slots_max": 3, - "slots_min": 0, - "time_max": 1000, - "time_min": 700 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 20, - "slots_max": 4, - "slots_min": 1, - "time_max": 2200, - "time_min": 1300 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 21, - "slots_max": 4, - "slots_min": 2, - "time_max": 600, - "time_min": 200 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 22, - "slots_max": 4, - "slots_min": 2, - "time_max": 11, - "time_min": 0 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 23, - "slots_max": 4, - "slots_min": 2, - "time_max": 800, - "time_min": 400 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 24, - "slots_max": 3, - "slots_min": 1, - "time_max": 2200, - "time_min": 1300 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "SpawnPoints": "ZoneSanatorium1", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 25, - "slots_max": 8, - "slots_min": 3, - "time_max": 300, - "time_min": 150 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSanatorium2", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 26, - "slots_max": 8, - "slots_min": 3, - "time_max": 600, - "time_min": 250 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "SpawnPoints": "ZoneSanatorium1", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 27, - "slots_max": 8, - "slots_min": 2, - "time_max": 1000, - "time_min": 650 - }, - { - "BotPreset": "normal", - "BotSide": "Bear", - "SpawnPoints": "ZoneSanatorium2", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 28, - "slots_max": 8, - "slots_min": 2, - "time_max": 1100, - "time_min": 550 - } - ] + "waves": [] } diff --git a/external-resources/maps/streets.json b/external-resources/maps/streets.json index c452b70b..a408c65a 100644 --- a/external-resources/maps/streets.json +++ b/external-resources/maps/streets.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 100, @@ -42,7 +43,7 @@ ], "BossLocationSpawn": [ { - "BossChance": 37, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "2", "BossEscortDifficult": "normal", @@ -77,7 +78,7 @@ "TriggerName": "" }, { - "BossChance": 37, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "6", "BossEscortDifficult": "normal", @@ -129,6 +130,196 @@ "Time": 99999, "TriggerId": "BossBoarBorn", "TriggerName": "botEvent" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" } ], "BotAssault": 80, @@ -137,8 +328,110 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], + "DistToActivate": 260, + "DistToActivatePvE": 260, + "DistToSleep": 300, + "DistToSleepPvE": 300, "GainSight": 1, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 2200, + "MinExfiltrationTime": 1800, "Scattering": 1, "VisibleDistance": 1 }, @@ -146,7 +439,7 @@ "BotMax": 23, "BotMaxPlayer": 10, "BotMaxPvE": 48, - "BotMaxTimePlayer": 0, + "BotMaxTimePlayer": 1000, "BotNormal": 40, "BotSpawnCountStep": 3, "BotSpawnPeriodCheck": 14, @@ -155,7 +448,7 @@ "BotSpawnTimeOnMax": 360, "BotSpawnTimeOnMin": 290, "BotStart": 122, - "BotStartPlayer": 0, + "BotStartPlayer": 550, "BotStop": 2200, "Description": "The downtown Tarkov with banks, malls, hotels and all the other things a striving modern city could have needed.", "DisabledForScav": false, @@ -165,12 +458,90 @@ "EscapeTimeLimit": 50, "EscapeTimeLimitCoop": 30, "EscapeTimeLimitPVE": 50, - "ExitZones": { - "$oid": "5c82534488a45046451a2386" + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 20 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 80 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 5 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 35 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 60 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 200, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 200, + "ZombieMultiplier": 5 + } }, + "ExitZones": "5c82534488a45046451a2386", + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.37, + "GlobalLootChanceModifier": 0.17, "GlobalLootChanceModifierPvE": 0.37, "IconX": 670, "IconY": 620, @@ -211,15 +582,16 @@ ], "MaxBotPerZone": 5, "MaxCoopGroup": 20, - "MaxDistToFreePoint": 220, + "MaxDistToFreePoint": 250, "MaxPlayers": 16, "MinDistToExitPoint": 10, - "MinDistToFreePoint": 60, + "MinDistToFreePoint": 90, "MinMaxBots": [], "MinPlayerLvlAccessKeys": 0, "MinPlayers": 12, "Name": "Streets of Tarkov", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -1098,11 +1470,11 @@ "Id": "12bb197b-bc6b-449c-9cf1-54ed289a364b", "Infiltration": "E3_4", "Position": { - "x": 228.841, - "y": 0.663, - "z": 173.562 + "x": 228.885, + "y": 4.007, + "z": 176.279 }, - "Rotation": 177.974945, + "Rotation": 243.713043, "Sides": ["All"] }, { @@ -1696,11 +2068,11 @@ "Id": "1fa87642-c899-4952-b848-2401a677f05d", "Infiltration": "E3_4", "Position": { - "x": 228.391, - "y": 0.642, - "z": 171.365 + "x": 227.794, + "y": 3.945, + "z": 174.694 }, - "Rotation": 263.604279, + "Rotation": 270.745667, "Sides": ["All"] }, { @@ -1800,11 +2172,11 @@ "Id": "20a712ad-fd79-4983-89e4-5234075c9638", "Infiltration": "E3_4", "Position": { - "x": 221.194, - "y": 0.646, - "z": 170.919 + "x": 221.598, + "y": 3.94900012, + "z": 175.266 }, - "Rotation": 263.604279, + "Rotation": 188.465591, "Sides": ["All"] }, { @@ -6636,11 +7008,11 @@ "Id": "8eb7065a-df86-48c9-ace7-bc6e59372ad3", "Infiltration": "E3_4", "Position": { - "x": 226.448, - "y": 0.696, - "z": 171.106 + "x": 214.21, + "y": 3.99899983, + "z": 172.474 }, - "Rotation": 263.604279, + "Rotation": 171.956467, "Sides": ["All"] }, { @@ -9731,10 +10103,10 @@ "Infiltration": "E3_4", "Position": { "x": 216.25, - "y": 0.67, - "z": 170.56 + "y": 3.97299981, + "z": 174.019 }, - "Rotation": 263.604279, + "Rotation": 179.878723, "Sides": ["All"] }, { @@ -11841,9 +12213,214 @@ "matching_min_seconds": 60, "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "STR_TRANSIT_3_COND", + "description": "STR_TRANSIT_3_DESC", + "id": 3, + "location": "Sandbox_high", + "name": "STR_TRANSIT_3", + "target": "65b8d6f5cdde2479cb2a3125", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "STR_TRANSIT_4_COND", + "description": "STR_TRANSIT_4_DESC", + "id": 4, + "location": "Interchange", + "name": "STR_TRANSIT_4", + "target": "5714dbc024597771384a510d", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "STR_TRANSIT_5_COND", + "description": "STR_TRANSIT_5_DESC", + "id": 5, + "location": "laboratory", + "name": "STR_TRANSIT_5", + "target": "5b0fc42d86f7744a585f9105", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [] + "waves": [ + { + "BotPreset": "normal", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneSW00", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 0, + "slots_max": 4, + "slots_min": 3, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneCarShowroom", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 1, + "slots_max": 3, + "slots_min": 2, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "normal", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneStilo", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 2, + "slots_max": 4, + "slots_min": 3, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneSnipeStilo", + "WildSpawnType": "marksman", + "isPlayers": false, + "number": 3, + "slots_max": 1, + "slots_min": 1, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneCard1", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 4, + "slots_max": 4, + "slots_min": 2, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneSnipeCard", + "WildSpawnType": "marksman", + "isPlayers": false, + "number": 5, + "slots_max": 1, + "slots_min": 1, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "normal", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneHotel_1", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 6, + "slots_max": 3, + "slots_min": 2, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneSnipeBuilding", + "WildSpawnType": "marksman", + "isPlayers": false, + "number": 7, + "slots_max": 1, + "slots_min": 1, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneSnipeSW01", + "WildSpawnType": "marksman", + "isPlayers": false, + "number": 8, + "slots_max": 1, + "slots_min": 1, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneSW01", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 9, + "slots_max": 4, + "slots_min": 1, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneConstruction", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 10, + "slots_max": 4, + "slots_min": 1, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "normal", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneHotel_2", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 11, + "slots_max": 3, + "slots_min": 2, + "time_max": -1, + "time_min": -1 + }, + { + "BotPreset": "hard", + "BotSide": "Savage", + "SpawnMode": ["regular", "pve"], + "SpawnPoints": "ZoneConcordia_1", + "WildSpawnType": "assault", + "isPlayers": false, + "number": 12, + "slots_max": 4, + "slots_min": 2, + "time_max": -1, + "time_min": -1 + } + ] } diff --git a/external-resources/maps/woods.json b/external-resources/maps/woods.json index 14220f32..25c26d9e 100644 --- a/external-resources/maps/woods.json +++ b/external-resources/maps/woods.json @@ -1,5 +1,6 @@ { "AccessKeys": [], + "AccessKeysPvE": [], "AirdropParameters": [ { "AirdropPointDeactivateDistance": 50, @@ -42,7 +43,28 @@ ], "BossLocationSpawn": [ { - "BossChance": 37, + "BossChance": 30, + "BossDifficult": "normal", + "BossEscortAmount": "0", + "BossEscortDifficult": "normal", + "BossEscortType": "sectantWarrior", + "BossName": "bossPartisan", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": true, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["regular", "pve"], + "Supports": null, + "Time": -1, + "TriggerId": "PARTISAN_TRIGGER", + "TriggerName": "botEvent" + }, + { + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "2", "BossEscortDifficult": "normal", @@ -51,6 +73,8 @@ "BossPlayer": false, "BossZone": "ZoneScavBase2", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": true, @@ -77,7 +101,7 @@ "TriggerName": "" }, { - "BossChance": 37, + "BossChance": 30, "BossDifficult": "normal", "BossEscortAmount": "2", "BossEscortDifficult": "normal", @@ -86,6 +110,8 @@ "BossPlayer": false, "BossZone": "ZoneWoodCutter", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -96,7 +122,7 @@ "TriggerName": "" }, { - "BossChance": 20, + "BossChance": 15, "BossDifficult": "normal", "BossEscortAmount": "4", "BossEscortDifficult": "normal", @@ -105,6 +131,8 @@ "BossPlayer": false, "BossZone": "ZoneMiniHouse,ZoneBrokenVill", "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, "ForceSpawn": false, "IgnoreMaxBots": true, "RandomTimeSpawn": false, @@ -114,6 +142,153 @@ "TriggerId": "", "TriggerName": "" }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcUSEC", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,2,2,2,1,1,1,1,1,0,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 50, + "BossDifficult": "normal", + "BossEscortAmount": "0,0,2,2,2,1,1,1,1,1,0,2,3", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcBEAR", + "BossPlayer": false, + "BossZone": "", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, + { + "BossChance": 75, + "BossDifficult": "normal", + "BossEscortAmount": "0,1,2", + "BossEscortDifficult": "normal", + "BossEscortType": "pmcBEAR", + "BossName": "pmcUSEC", + "BossPlayer": false, + "BossZone": "ZoneBigRocks", + "Delay": 0, + "DependKarma": false, + "DependKarmaPVE": false, + "ForceSpawn": false, + "IgnoreMaxBots": true, + "RandomTimeSpawn": false, + "SpawnMode": ["pve"], + "Supports": null, + "Time": -1, + "TriggerId": "", + "TriggerName": "" + }, { "BossChance": 5, "BossDifficult": "normal", @@ -134,21 +309,121 @@ "BotImpossible": 0, "BotLocationModifier": { "AccuracySpeed": 1, + "AdditionalHostilitySettings": [ + { + "AlwaysEnemies": [ + "pmcBot", + "exUsec", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar", + "bossKnight" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 75, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcBEAR", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcUSEC" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 90, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + }, + { + "AlwaysEnemies": [ + "pmcBot", + "bossBully", + "bossBoar", + "bossTagilla", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossKolontay", + "bossGluhar" + ], + "AlwaysFriends": [ + "bossZryachiy", + "followerZryachiy", + "peacefullZryachiyEvent", + "ravangeZryachiyEvent", + "gifter" + ], + "BearEnemyChance": 90, + "BearPlayerBehaviour": "ChancedEnemies", + "BotRole": "pmcUSEC", + "ChancedEnemies": [ + { + "EnemyChance": 70, + "Role": "assault" + }, + { + "EnemyChance": 70, + "Role": "marksman" + }, + { + "EnemyChance": 75, + "Role": "pmcBEAR" + }, + { + "EnemyChance": 15, + "Role": "exUsec" + }, + { + "EnemyChance": 15, + "Role": "bossKnight" + } + ], + "Neutral": ["sectantPriest", "sectantWarrior"], + "SavagePlayerBehaviour": "Warn", + "UsecEnemyChance": 75, + "UsecPlayerBehaviour": "ChancedEnemies", + "Warn": ["sectactPriestEvent"] + } + ], "DistToActivate": 265, + "DistToActivatePvE": 265, "DistToPersueAxemanCoef": 1.1, "DistToSleep": 300, + "DistToSleepPvE": 300, "GainSight": 1, "KhorovodChance": 0, "MagnetPower": 44, "MarksmanAccuratyCoef": 1, + "MaxExfiltrationTime": 1800, + "MinExfiltrationTime": 1200, "Scattering": 1, "VisibleDistance": 1 }, "BotMarksman": 20, - "BotMax": 23, - "BotMaxPlayer": 0, - "BotMaxPvE": 32, - "BotMaxTimePlayer": 0, + "BotMax": 17, + "BotMaxPlayer": 9, + "BotMaxPvE": 30, + "BotMaxTimePlayer": 1000, "BotNormal": 50, "BotSpawnCountStep": 4, "BotSpawnPeriodCheck": 15, @@ -157,7 +432,7 @@ "BotSpawnTimeOnMax": 320, "BotSpawnTimeOnMin": 260, "BotStart": 10, - "BotStartPlayer": 0, + "BotStartPlayer": 200, "BotStop": 1900, "Description": "The Priozersk Natural Reserve was recently included into the list of state-protected wildlife reserves of the North-Western Federal District.", "DisabledForScav": false, @@ -167,9 +442,89 @@ "EscapeTimeLimit": 40, "EscapeTimeLimitCoop": 30, "EscapeTimeLimitPVE": 40, + "Events": { + "Halloween2024": { + "CrowdAttackBlockRadius": 100, + "CrowdAttackSpawnParams": [ + { + "Difficulty": "easy", + "Role": "infectedAssault", + "Weight": 30 + }, + { + "Difficulty": "normal", + "Role": "infectedAssault", + "Weight": 110 + }, + { + "Difficulty": "hard", + "Role": "infectedAssault", + "Weight": 40 + }, + { + "Difficulty": "easy", + "Role": "infectedPmc", + "Weight": 15 + }, + { + "Difficulty": "normal", + "Role": "infectedPmc", + "Weight": 55 + }, + { + "Difficulty": "hard", + "Role": "infectedPmc", + "Weight": 20 + }, + { + "Difficulty": "easy", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedCivil", + "Weight": 0 + }, + { + "Difficulty": "easy", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "normal", + "Role": "infectedLaborant", + "Weight": 0 + }, + { + "Difficulty": "hard", + "Role": "infectedLaborant", + "Weight": 0 + } + ], + "CrowdCooldownPerPlayerSec": 300, + "CrowdsLimit": 2, + "InfectedLookCoeff": 2, + "InfectionPercentage": 0, + "MaxCrowdAttackSpawnLimit": 18, + "MinInfectionPercentage": 0, + "MinSpawnDistToPlayer": 50, + "TargetPointSearchRadiusLimit": 200, + "ZombieCallDeltaRadius": 20, + "ZombieCallPeriodSec": 1, + "ZombieCallRadiusLimit": 200, + "ZombieMultiplier": 5 + } + }, + "ForceOnlineRaidInPVE": false, "GenerateLocalLootCache": true, "GlobalContainerChanceModifier": 1, - "GlobalLootChanceModifier": 0.95, + "GlobalLootChanceModifier": 0.4, "GlobalLootChanceModifierPvE": 0.95, "IconX": 460, "IconY": 660, @@ -219,6 +574,7 @@ "MinPlayers": 10, "Name": "Woods", "NewSpawn": true, + "NewSpawnForPlayers": true, "NonWaveGroupScenario": { "Chance": 50, "Enabled": true, @@ -227,8 +583,8 @@ }, "OcculsionCullingEnabled": false, "OfflineNewSpawn": true, - "OfflineOldSpawn": false, - "OldSpawn": false, + "OfflineOldSpawn": true, + "OldSpawn": true, "OpenZones": "ZoneClearVill,ZoneHouse,ZoneScavBase2,ZoneHouse,ZoneWoodCutter,ZoneBigRocks,ZoneRoad,ZoneHighRocks,ZoneMiniHouse,ZoneBigRocks", "PlayersRequestCount": -1, "PmcMaxPlayersInGroup": 5, @@ -299,8 +655,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -309,24 +665,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 70 } }, - "CorePointId": 2, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "02070d3d-0bec-4671-9518-d903a211c6a7", - "Infiltration": "", + "Id": "027273fa-04bc-48d1-acfb-74f008bb196c", + "Infiltration": "Old Station", "Position": { - "x": -517.32, - "y": 14.9372711, - "z": -365.990021 + "x": 365.905029, + "y": 13.94, + "z": -698.06604 }, - "Rotation": 106.22, - "Sides": ["Savage"] + "Rotation": 325.167175, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -335,24 +691,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 20 } }, - "CorePointId": 0, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "027273fa-04bc-48d1-acfb-74f008bb196c", - "Infiltration": "Old Station", + "Id": "032dd801-3804-49ed-b9ea-6deee2001c19", + "Infiltration": "", "Position": { - "x": 366, - "y": 13.94, - "z": -698 + "x": -275.781982, + "y": 7.47265148, + "z": -417.592 }, - "Rotation": 325.167175, - "Sides": ["Pmc"] + "Rotation": 5.71200657, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -361,19 +717,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 140 } }, - "CorePointId": 2, + "CorePointId": 15, "DelayToCanSpawnSec": 4, - "Id": "043bc54d-074f-4dd6-bc17-5c7c3378c420", + "Id": "03507eb9-59cd-4b95-b257-d42b6dc5f204", "Infiltration": "", "Position": { - "x": -414.220032, - "y": 16.6903229, - "z": -362.91 + "x": 94.85, + "y": 6.81406, + "z": -203.72 }, - "Rotation": 236.87, + "Rotation": 283.99, "Sides": ["Savage"] }, { @@ -429,8 +785,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneMiniHouse", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -439,19 +795,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 171 } }, - "CorePointId": 3, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "05cd6de2-a55e-4930-98a4-cc6ce6e8d49d", + "Id": "057ba3ae-3fb0-4517-8f7c-a9520fc87072", "Infiltration": "", "Position": { - "x": 280.36, - "y": 8.309144, - "z": -674.51 + "x": 375.81, + "y": -1.05202746, + "z": -115.25 }, - "Rotation": 238.74, + "Rotation": 310.84, "Sides": ["Savage"] }, { @@ -585,8 +941,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -595,24 +951,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0947c04a-676e-4077-bc3e-9cdc2032cedb", - "Infiltration": "", + "Id": "0ba5301a-df26-49b5-8ee5-61bd0c1bd808", + "Infiltration": "Old Station", "Position": { - "x": -441.5, - "y": 0.238876343, - "z": 344.8 + "x": -615, + "y": 14.66, + "z": -328.990021 }, - "Rotation": 164.48, - "Sides": ["Savage"] + "Rotation": 44.72, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -621,19 +977,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 140 } }, - "CorePointId": 4, + "CorePointId": 15, "DelayToCanSpawnSec": 4, - "Id": "0b5ae3cc-8779-4679-bd0f-9e6d322b308f", + "Id": "0bb21a14-ace2-4f7e-b634-a43b86b05358", "Infiltration": "", "Position": { - "x": -540.65, - "y": 5.0159235, - "z": 188.06 + "x": -63.79, + "y": 19.15763, + "z": -233.02002 }, - "Rotation": 76.87, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -652,19 +1008,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0ba5301a-df26-49b5-8ee5-61bd0c1bd808", + "Id": "0ced4119-d0aa-481e-9c45-e93fc820a41f", "Infiltration": "Old Station", "Position": { - "x": -615, - "y": 14.66, - "z": -328.990021 + "x": -519.45, + "y": 12.6323347, + "z": -156.300018 }, - "Rotation": 44.72, + "Rotation": 125.579994, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneMiniHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -673,19 +1029,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 145 } }, - "CorePointId": 1, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "0c28a191-6308-4820-99c0-9d347d09a9ce", + "Id": "0d2d4dbb-f650-4ed1-bbea-a029541a3f66", "Infiltration": "", "Position": { - "x": -84.17999, - "y": 8.84712, - "z": -607.78 + "x": 348.79, + "y": -0.9134421, + "z": -155.92 }, - "Rotation": 181.14, + "Rotation": 335.01, "Sides": ["Savage"] }, { @@ -699,24 +1055,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "0ced4119-d0aa-481e-9c45-e93fc820a41f", - "Infiltration": "Old Station", + "Id": "0dd1d014-6642-4a75-a496-242dd44a855b", + "Infiltration": "House", "Position": { - "x": -519.45, - "y": 12.6323347, - "z": -156.300018 + "x": 518.410034, + "y": -20.94, + "z": 264.3 }, - "Rotation": 125.579994, + "Rotation": 216.79, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneClearVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -725,24 +1081,50 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 60 } }, - "CorePointId": 4, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "0d4e68ed-06f9-47f5-ab00-77ef4534fee2", + "Id": "0f3f06e1-f010-4d02-a126-b97a98aedd7b", "Infiltration": "", "Position": { - "x": -496.5, - "y": 5.55468845, - "z": 81.54 + "x": -517.32, + "y": 14.9372711, + "z": -365.990021 }, - "Rotation": 93.46, + "Rotation": 106.22, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "100d945d-1da3-434e-9a45-5d07c64bc296", + "Infiltration": "Old Station", + "Position": { + "x": -420.16, + "y": 11.2839994, + "z": -519.410034 + }, + "Rotation": 14.210001, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -754,21 +1136,21 @@ "Radius": 60 } }, - "CorePointId": 3, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "0d6c16ec-adc2-4d80-9daf-96caca9a5b75", + "Id": "1208bd00-24de-4947-810a-74b4a79d852f", "Infiltration": "", "Position": { - "x": 268.5, - "y": 17.5370255, - "z": -756.9199 + "x": -174.909973, + "y": 13.6224213, + "z": -649.87 }, - "Rotation": 236.87, + "Rotation": 62.2, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -777,20 +1159,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "0dd1d014-6642-4a75-a496-242dd44a855b", - "Infiltration": "House", + "Id": "12565a8d-e7c3-44fb-b7f9-4085b98bc50f", + "Infiltration": "", "Position": { - "x": 518.410034, - "y": -20.94, - "z": 264.3 + "x": -538.41, + "y": 7.11805344, + "z": 157.71 }, - "Rotation": 216.79, - "Sides": ["Pmc"] + "Rotation": 76.87, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -808,18 +1190,18 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "100d945d-1da3-434e-9a45-5d07c64bc296", + "Id": "158e0a94-64fb-4555-afa0-90109713db91", "Infiltration": "Old Station", "Position": { - "x": -420.16, - "y": 11.2839994, - "z": -519.410034 + "x": -265.82, + "y": 10.58, + "z": -632.22 }, "Rotation": 14.210001, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneClearVill", + "BotZoneName": "ZoneStoneBunker", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -832,21 +1214,21 @@ "Radius": 60 } }, - "CorePointId": 2, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "125759c0-c52e-4ec5-b61a-e11557ac06b5", + "Id": "172b6f37-9e66-4e07-857a-35004ce753b1", "Infiltration": "", "Position": { - "x": -544.32, - "y": 11.0081148, - "z": -438.939972 + "x": -312.915039, + "y": 14.3026514, + "z": -431.189 }, - "Rotation": 72.46, + "Rotation": 236.87, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -855,24 +1237,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 70 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "129e73e2-8660-4f9d-bf32-e2a802612a2a", - "Infiltration": "", + "Id": "17d3fee1-d9bb-4950-80bd-44cd33b12e50", + "Infiltration": "House", "Position": { - "x": -155.220032, - "y": 18.26294, - "z": -620.36 + "x": 231.43, + "y": 26.17, + "z": -314.429962 }, - "Rotation": 120.210007, - "Sides": ["Savage"] + "Rotation": 287.12, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -881,24 +1263,24 @@ "y": 0, "z": 0 }, - "Radius": 192.6 + "Radius": 70 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "12b17d88-bc67-4d6a-82fb-e36afe2aa596", - "Infiltration": "", + "Id": "1804b780-85a9-4eff-a465-82e2fbb88f0c", + "Infiltration": "Old Station", "Position": { - "x": -94.08, - "y": -1.31425381, - "z": 387.77 + "x": -354.73, + "y": 0.950922132, + "z": 239.63 }, - "Rotation": 192.91, - "Sides": ["Savage"] + "Rotation": 129.42, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -907,19 +1289,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 140 } }, - "CorePointId": 1, + "CorePointId": 10, "DelayToCanSpawnSec": 4, - "Id": "13e379d7-fe3a-4005-bac7-b9b9f4a1d589", + "Id": "1912ece1-fa7f-4802-8788-d025cbb8db55", "Infiltration": "", "Position": { - "x": -108.480011, - "y": 10.130621, - "z": -609.9 + "x": 90.27, + "y": -15.8248549, + "z": 116.15 }, - "Rotation": 152.43, + "Rotation": 190.98, "Sides": ["Savage"] }, { @@ -938,19 +1320,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "158e0a94-64fb-4555-afa0-90109713db91", + "Id": "191b6c5a-0fb7-40b2-95b4-3a33397eb872", "Infiltration": "Old Station", "Position": { - "x": -265.82, - "y": 10.58, - "z": -632.22 + "x": -54.1099854, + "y": 8.883999, + "z": -579.439941 }, - "Rotation": 14.210001, + "Rotation": 316.58, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneClearVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -959,24 +1341,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "17d3fee1-d9bb-4950-80bd-44cd33b12e50", - "Infiltration": "House", + "Id": "19d5d7e7-53f2-496f-bdd7-c62dd40e16f5", + "Infiltration": "", "Position": { - "x": 231.43, - "y": 26.17, - "z": -314.429962 + "x": -439.399963, + "y": 15.3167744, + "z": -334.679962 }, - "Rotation": 287.12, - "Sides": ["Pmc"] + "Rotation": 287.409973, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneHighRocks", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -985,24 +1367,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 150 } }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "1804b780-85a9-4eff-a465-82e2fbb88f0c", - "Infiltration": "Old Station", + "CorePointId": 6, + "DelayToCanSpawnSec": 1700, + "Id": "19e5a0cc-239b-4d3b-a4cc-1e5cfd71f61d", + "Infiltration": "", "Position": { - "x": -354.73, - "y": 0.950922132, - "z": 239.63 + "x": -140.8, + "y": 61.4642448, + "z": -206.84 }, - "Rotation": 129.42, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneClearVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1011,23 +1393,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "191b6c5a-0fb7-40b2-95b4-3a33397eb872", - "Infiltration": "Old Station", + "Id": "1a189d11-f56f-4d44-ab00-eecdf630b805", + "Infiltration": "", "Position": { - "x": -54.1099854, - "y": 8.883999, - "z": -579.439941 + "x": -416.2, + "y": 12.9368525, + "z": -468.799957 }, - "Rotation": 316.58, - "Sides": ["Pmc"] + "Rotation": 236.87, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneHouse", + "BotZoneName": "ZoneUsecBase", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -1037,17 +1419,17 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 9, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "1a4a6702-1a25-4301-94f9-a4a0f42886ec", + "Id": "1a6dfbac-9ca3-42e6-b8bd-8dc5ecc047bd", "Infiltration": "", "Position": { - "x": 442.53, - "y": -17.47189, - "z": 261.18 + "x": 299.011, + "y": 23.1686516, + "z": -457.402 }, "Rotation": 236.87, "Sides": ["Savage"] @@ -1183,8 +1565,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1193,24 +1575,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1d485547-36ae-4ed6-a54f-22d4f0cc78fc", - "Infiltration": "", + "Id": "1dfb41ff-4233-47ba-8db1-054dd7923906", + "Infiltration": "Old Station", "Position": { - "x": -174.460022, - "y": 9.385831, - "z": -713.929932 + "x": -331.468018, + "y": 18.5271835, + "z": -138.725983 }, - "Rotation": 29.94, - "Sides": ["Savage"] + "Rotation": 33.6, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1219,19 +1601,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 60 } }, - "CorePointId": 11, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "1d585de4-8d57-4c18-a56e-4ee90750a8df", + "Id": "20d815ea-be95-4cab-bdc7-098d88d6578c", "Infiltration": "", "Position": { - "x": -428.98, - "y": 25.4802856, - "z": -81.73999 + "x": -130.029968, + "y": 9.618751, + "z": -726.5499 }, - "Rotation": 36.98, + "Rotation": 29.94, "Sides": ["Savage"] }, { @@ -1245,24 +1627,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1dfb41ff-4233-47ba-8db1-054dd7923906", - "Infiltration": "Old Station", + "Id": "20ee24e5-1db9-4191-9ba5-444ff4207f2b", + "Infiltration": "House", "Position": { - "x": -331.59, - "y": 18.5271835, - "z": -138.91 + "x": 366.900024, + "y": 18.19, + "z": -598.199951 }, - "Rotation": 33.6, + "Rotation": 268.42, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1271,24 +1653,24 @@ "y": 0, "z": 0 }, - "Radius": 250 + "Radius": 50 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1e4fff1f-f268-4aec-b01a-e2349c4440f4", - "Infiltration": "", + "Id": "219c81c4-5e06-4abe-b971-61728edafde9", + "Infiltration": "House", "Position": { - "x": -390.63, - "y": -8.584538, - "z": 113.78 + "x": 226.43, + "y": -8.698159, + "z": 197.5 }, - "Rotation": 222.64, - "Sides": ["Savage"] + "Rotation": 193.25, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1297,24 +1679,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 100 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "1e884503-3b3b-4e5b-9da6-974752b21cf5", - "Infiltration": "", + "Id": "21c4f855-6ada-4784-aec5-797f78732ed8", + "Infiltration": "House", "Position": { - "x": -181.32, - "y": 34.0571442, - "z": -164.09 + "x": 282.47, + "y": -1.44, + "z": -62.81 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 268.0896, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot"], + "BotZoneName": "ZoneHouse", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1326,16 +1708,16 @@ "Radius": 140 } }, - "CorePointId": 15, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "1f7d566b-5cce-4a9e-8c22-23b5303c02ed", + "Id": "24591071-69d8-4756-83cc-c3e4be5fb086", "Infiltration": "", "Position": { - "x": -12.2900009, - "y": 13.7992649, - "z": -229.31 + "x": 318.82, + "y": -8.43767452, + "z": 352.05 }, - "Rotation": 0, + "Rotation": 151.22, "Sides": ["Savage"] }, { @@ -1354,45 +1736,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "20ee24e5-1db9-4191-9ba5-444ff4207f2b", - "Infiltration": "House", - "Position": { - "x": 366.900024, - "y": 18.19, - "z": -598.199951 - }, - "Rotation": 268.42, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "219c81c4-5e06-4abe-b971-61728edafde9", + "Id": "2533a3ec-8812-4546-9e44-d19ae093ef6b", "Infiltration": "House", "Position": { - "x": 226.43, - "y": -8.698159, - "z": 197.5 + "x": 230.143, + "y": 26.9, + "z": -320.142 }, - "Rotation": 193.25, + "Rotation": 287.12, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1401,24 +1757,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 140 } }, - "CorePointId": 0, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "21c4f855-6ada-4784-aec5-797f78732ed8", - "Infiltration": "House", + "Id": "255e4ae3-d1bd-4814-b2c1-cfe5f9f72c66", + "Infiltration": "", "Position": { - "x": 282.47, - "y": -1.44, - "z": -62.81 + "x": 463.69, + "y": -12.1854525, + "z": 115.73 }, - "Rotation": 268.0896, - "Sides": ["Pmc"] + "Rotation": 282.6, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1427,19 +1783,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 60 } }, - "CorePointId": 7, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "252d5a74-501e-497a-946b-163044adfac2", + "Id": "262b8df9-e07d-4b84-b694-58f0b6b6036b", "Infiltration": "", "Position": { - "x": -199.91, - "y": 33.53726, - "z": -193.46 + "x": 101.130005, + "y": 15.5523014, + "z": -761.98 }, - "Rotation": 0, + "Rotation": 165.36, "Sides": ["Savage"] }, { @@ -1458,19 +1814,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2533a3ec-8812-4546-9e44-d19ae093ef6b", - "Infiltration": "House", + "Id": "2685c5c9-9bde-40c1-bbc2-3a0f3b024106", + "Infiltration": "Old Station", "Position": { - "x": 230.400024, - "y": 26.9, - "z": -320.27 + "x": 61.22003, + "y": 9.033999, + "z": -657.75 }, - "Rotation": 287.12, + "Rotation": 316.58, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1479,24 +1835,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "2685c5c9-9bde-40c1-bbc2-3a0f3b024106", - "Infiltration": "Old Station", + "Id": "275dba7d-7524-4588-9426-45e7f925a08a", + "Infiltration": "", "Position": { - "x": 61.22003, - "y": 9.033999, - "z": -657.75 + "x": -203.55, + "y": 1.13691711, + "z": 417.31 }, - "Rotation": 316.58, - "Sides": ["Pmc"] + "Rotation": 157.57, + "Sides": ["Savage"] }, { "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1510,14 +1866,14 @@ }, "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "278d9b66-49bc-44cc-a70b-308f643b19e9", + "Id": "27af1a16-c5d5-40df-867c-b02e875319fc", "Infiltration": "", "Position": { - "x": -23.7000122, - "y": 9.082792, - "z": -779.76 + "x": -171.68, + "y": 14.8065891, + "z": -617.699951 }, - "Rotation": 10.29, + "Rotation": 120.210007, "Sides": ["Savage"] }, { @@ -1573,8 +1929,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneMiniHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1583,24 +1939,24 @@ "y": 0, "z": 0 }, - "Radius": 145 + "Radius": 60 } }, - "CorePointId": 5, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "2950af48-325b-41af-ac80-fcd87c657688", + "Id": "2a31cc36-9d1e-47a6-a492-f8f05e9511f1", "Infiltration": "", "Position": { - "x": 348.79, - "y": -0.9134421, - "z": -155.92 + "x": -155.220032, + "y": 18.26294, + "z": -620.36 }, - "Rotation": 335.01, + "Rotation": 120.210007, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1609,24 +1965,24 @@ "y": 0, "z": 0 }, - "Radius": 250 + "Radius": 50 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "2a3b365d-78cb-4fe6-9168-e2c7e9099419", - "Infiltration": "", + "Id": "2b2b5b1e-0bfd-4316-af38-bbefa25ac3b2", + "Infiltration": "House", "Position": { - "x": -346.46, - "y": -8.439364, - "z": 131.01 + "x": 280.780029, + "y": -11.9072313, + "z": 319.279022 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 255.300018, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1635,24 +1991,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "2b2b5b1e-0bfd-4316-af38-bbefa25ac3b2", - "Infiltration": "House", + "Id": "2c2c2b74-5af6-4a64-8902-4b1648fab13f", + "Infiltration": "", "Position": { - "x": 280.74, - "y": -11.9072313, - "z": 319.43 + "x": -152.96, + "y": 0.37342453, + "z": 434.83 }, - "Rotation": 255.300018, - "Sides": ["Pmc"] + "Rotation": 218.52, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1661,19 +2017,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 60 } }, - "CorePointId": 7, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "2cc5049f-030c-437b-ab8c-e11fec5b7680", + "Id": "2c407662-ea7d-4069-b555-cad2e5ec6716", "Infiltration": "", "Position": { - "x": -170.87, - "y": 0.9297247, - "z": 431.87 + "x": -174.460022, + "y": 9.385831, + "z": -713.929932 }, - "Rotation": 152.9, + "Rotation": 29.94, "Sides": ["Savage"] }, { @@ -1703,8 +2059,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1713,24 +2069,50 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 50 } }, - "CorePointId": 9, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "2e52ceb4-5491-4a44-bfe4-a658f87271ff", + "Infiltration": "Old Station", + "Position": { + "x": -539.87, + "y": -1.18963408, + "z": 294.67 + }, + "Rotation": 68.9, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "2d8304b8-ea45-42b5-bd50-c9a2703e5828", + "Id": "2e5a6aa2-5b59-4f79-a30e-c7cfeef35138", "Infiltration": "", "Position": { - "x": 463.69, - "y": -12.1854525, - "z": 115.73 + "x": -86.8900146, + "y": 7.94821644, + "z": -752.65 }, - "Rotation": 282.6, + "Rotation": 29.94, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1739,24 +2121,24 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "2e52ceb4-5491-4a44-bfe4-a658f87271ff", - "Infiltration": "Old Station", + "Id": "30578df3-b13d-4b6e-b6d5-0005a0e9c9c3", + "Infiltration": "", "Position": { - "x": -539.87, - "y": -1.18963408, - "z": 294.67 + "x": -103.43, + "y": 23.2189789, + "z": -214.55 }, - "Rotation": 68.9, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1765,19 +2147,19 @@ "y": 0, "z": 0 }, - "Radius": 249.4 + "Radius": 140 } }, - "CorePointId": 5, + "CorePointId": 15, "DelayToCanSpawnSec": 4, - "Id": "2e5c6594-07ea-4dc3-ba81-dc3916e86309", + "Id": "31291952-9354-42d4-a38e-8857ae10117b", "Infiltration": "", "Position": { - "x": 218.6, - "y": -12.2584953, - "z": 279.4 + "x": 25.57, + "y": 11.3200827, + "z": -226.610016 }, - "Rotation": 151.22, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -1833,8 +2215,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1843,24 +2225,50 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 8, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "3245f7f0-21a2-457f-ae32-562f7955d4ae", + "Infiltration": "Old Station", + "Position": { + "x": -92.95001, + "y": -1.12518787, + "z": 385.31 + }, + "Rotation": 224.32, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "3234744e-1181-457a-bcf4-756b35b35bff", + "Id": "32fe4cb8-82bc-43b2-8796-7fa31dde15c8", "Infiltration": "", "Position": { - "x": -277.3, - "y": 30.9032745, - "z": -196.4 + "x": 103.950012, + "y": 17.6159382, + "z": -757.72 }, - "Rotation": 0, + "Rotation": 165.36, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneClearVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1869,20 +2277,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "3245f7f0-21a2-457f-ae32-562f7955d4ae", - "Infiltration": "Old Station", + "Id": "334671d7-7451-4b42-afd8-eb268405696f", + "Infiltration": "", "Position": { - "x": -92.95001, - "y": -1.12518787, - "z": 385.31 + "x": -414.220032, + "y": 16.6903229, + "z": -362.91 }, - "Rotation": 224.32, - "Sides": ["Pmc"] + "Rotation": 236.87, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -1936,6 +2344,84 @@ "Rotation": 53.04, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "3494860c-fa14-4c78-a9eb-db07eb4bdd0e", + "Infiltration": "", + "Position": { + "x": -266.508, + "y": 6.881651, + "z": -406.316 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "34bec394-d71c-4044-9627-479a1f144060", + "Infiltration": "", + "Position": { + "x": -532.56, + "y": -0.4881611, + "z": 254.2 + }, + "Rotation": 83.36, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 40 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "35be8146-9b37-4b8b-8b7d-9a7e521ec1c7", + "Infiltration": "", + "Position": { + "x": 157.48999, + "y": 24.37865, + "z": -690.61 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -1955,16 +2441,16 @@ "Id": "366cec0b-e96a-4706-a8c3-2fada6801993", "Infiltration": "Old Station", "Position": { - "x": -519.08, - "y": 9.627431, - "z": 88.3999939 + "x": -523.6, + "y": 9.853999, + "z": 93.04001 }, "Rotation": 130.67, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "ZoneRoad", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -1973,24 +2459,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 40 } }, "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "37395ddf-7a49-4ea4-9e6b-fe5a32b1adf2", + "Id": "37535e74-a10a-40c7-b8cf-1416a95b48ba", "Infiltration": "", "Position": { - "x": -139.96, - "y": 30.8123264, - "z": -191.76 + "x": -155.17, + "y": -2.07000065, + "z": 181.17 }, - "Rotation": 0, + "Rotation": 212.4, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2002,16 +2488,16 @@ "Radius": 60 } }, - "CorePointId": 2, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "381d4cbc-39c8-4765-8d61-5bfe790f34a6", + "Id": "37c509be-831c-4525-9559-1fd711478a21", "Infiltration": "", "Position": { - "x": -440.01, - "y": 15.5185928, - "z": -325.360016 + "x": -130.62, + "y": 13.0453444, + "z": -623.1699 }, - "Rotation": 287.409973, + "Rotation": 120.210007, "Sides": ["Savage"] }, { @@ -2085,9 +2571,9 @@ "Id": "38df9752-76f3-4206-a46b-d279db55aee3", "Infiltration": "Old Station", "Position": { - "x": -512.65, + "x": -512.942, "y": 12.0778894, - "z": -150.15 + "z": -149.892 }, "Rotation": 125.579994, "Sides": ["Pmc"] @@ -2119,8 +2605,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2129,24 +2615,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 140 } }, - "CorePointId": 0, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "3d17ca8d-3e08-498c-8bcd-01f909c91c19", - "Infiltration": "Old Station", + "Id": "3991850d-4fb1-43e7-bb26-1d4bc86dc460", + "Infiltration": "", "Position": { - "x": -361.25, - "y": 1.0406611, - "z": 237.99 + "x": 442.53, + "y": -17.47189, + "z": 261.18 }, - "Rotation": 129.42, - "Sides": ["Pmc"] + "Rotation": 236.87, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2158,21 +2644,21 @@ "Radius": 158.9 } }, - "CorePointId": 7, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "3e37ed32-9681-4bf9-ae5d-473eefe6d2fc", + "Id": "3a3b94ca-4e46-4d97-98be-cf152b5729ea", "Infiltration": "", "Position": { - "x": -162.85, - "y": 0.7303066, - "z": 435.96 + "x": -526.84, + "y": -2.522231, + "z": 216.27 }, - "Rotation": 182.85, + "Rotation": 76.87, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRoad", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2181,24 +2667,76 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 40 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "3e8f83ba-7706-49ac-b19c-20f90da1309a", - "Infiltration": "Old Station", + "Id": "3c343ce9-5222-4764-8719-6b9109335993", + "Infiltration": "", + "Position": { + "x": -158.7, + "y": -4.339999, + "z": 296.5 + }, + "Rotation": 212.4, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "3d17ca8d-3e08-498c-8bcd-01f909c91c19", + "Infiltration": "Old Station", + "Position": { + "x": -361.25, + "y": 1.0406611, + "z": 237.99 + }, + "Rotation": 129.42, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "3e8f83ba-7706-49ac-b19c-20f90da1309a", + "Infiltration": "Old Station", "Position": { - "x": -256.18, + "x": -256.11, "y": 27.93854, - "z": -204.1 + "z": -203.92099 }, "Rotation": 9.03, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2207,24 +2745,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 65 } }, - "CorePointId": 3, + "CorePointId": 10, "DelayToCanSpawnSec": 4, - "Id": "3fbf597c-f75d-4a08-bc06-aeaf0f2baee8", + "Id": "3fb18f94-b71e-4dd0-b771-03a98275f496", "Infiltration": "", "Position": { - "x": 103.950012, - "y": 17.6159382, - "z": -757.72 + "x": 63.2168045, + "y": -7.55134869, + "z": 35.2158127 }, - "Rotation": 165.36, + "Rotation": 190.98, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneHighRocks", - "Categories": ["Bot"], + "BotZoneName": "ZoneClearVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2233,19 +2771,19 @@ "y": 0, "z": 0 }, - "Radius": 25 + "Radius": 60 } }, - "CorePointId": 6, - "DelayToCanSpawnSec": 1700, - "Id": "40e7ee28-23c3-45a7-9c77-ae40e7750429", + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "40b4cb72-8a28-4514-8c86-b2330d05a72c", "Infiltration": "", "Position": { - "x": -140.8, - "y": 61.4642448, - "z": -206.84 + "x": -413.12, + "y": 16.0042686, + "z": -350.740021 }, - "Rotation": 0, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -2275,8 +2813,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "ZoneRoad", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2285,19 +2823,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 40 } }, "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "42cff02a-5afd-41a6-8492-fe81da880ee6", + "Id": "42e95473-0b1f-4351-b137-77b9e351479f", "Infiltration": "", "Position": { - "x": -103.43, - "y": 23.2189789, - "z": -214.55 + "x": -109.97, + "y": -12.87, + "z": 240.99 }, - "Rotation": 0, + "Rotation": 212.4, "Sides": ["Savage"] }, { @@ -2327,8 +2865,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot"], + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2337,24 +2875,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 45 } }, - "CorePointId": 15, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "4721ad28-1703-47e2-8b22-a8f027c74b0f", + "Id": "46eb8ea0-4c92-4551-893e-7000f43fdb37", "Infiltration": "", "Position": { - "x": -63.79, - "y": 19.15763, - "z": -233.02002 + "x": -544.32, + "y": 11.0081148, + "z": -438.939972 }, - "Rotation": 0, + "Rotation": 72.46, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2363,23 +2901,23 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 9, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "48e43cdb-f0eb-4d12-9973-f0519c61a480", + "Id": "4aca5e29-3ce4-409e-8bb1-43883f8f1cf3", "Infiltration": "", "Position": { - "x": 443.48, - "y": -11.4372435, - "z": 84.1300049 + "x": 135.88, + "y": 8.4578495, + "z": -664.99 }, - "Rotation": 295.57, + "Rotation": 165.36, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneHouse", + "BotZoneName": "ZoneStoneBunker", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -2389,19 +2927,19 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 9, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "4bb373ec-a673-4562-9128-6ba8d009acfa", + "Id": "4bc6a11c-a9c7-4224-a1a4-3757a25459a5", "Infiltration": "", "Position": { - "x": 318.82, - "y": -8.43767452, - "z": 352.05 + "x": -308.169983, + "y": 13.8386507, + "z": -411.28 }, - "Rotation": 151.22, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -2430,6 +2968,32 @@ "Rotation": 316.58, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneUsecBase", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "4d66b2d2-7c6c-4681-ac43-87e46751f1f6", + "Infiltration": "", + "Position": { + "x": 311.259979, + "y": 16.8186512, + "z": -538.23 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -2482,32 +3046,6 @@ "Rotation": 268.46, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 1, - "DelayToCanSpawnSec": 4, - "Id": "5034a1be-bc7c-4c9b-82bc-3fd8661b7a75", - "Infiltration": "", - "Position": { - "x": -117.590027, - "y": 11.9433193, - "z": -729.39 - }, - "Rotation": 29.94, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -2561,34 +3099,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 3, - "DelayToCanSpawnSec": 4, - "Id": "50aec2a0-5dd5-4007-9581-c7d94643e8a7", - "Infiltration": "", - "Position": { - "x": 263.9, - "y": 17.3108673, - "z": -762.5 - }, - "Rotation": 165.36, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2597,19 +3109,19 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 80 } }, - "CorePointId": 5, + "CorePointId": 10, "DelayToCanSpawnSec": 4, - "Id": "50f8a6b8-8fc6-4e3f-8000-39540da348f1", + "Id": "52226f32-afb0-4e86-abfc-d2575d413f6d", "Infiltration": "", "Position": { - "x": 366.78, - "y": 1.09509182, - "z": 0.550003052 + "x": 87.7668, + "y": -15.89571, + "z": 114.385811 }, - "Rotation": 295.57, + "Rotation": 190.98, "Sides": ["Savage"] }, { @@ -2657,42 +3169,16 @@ "Id": "53bc3938-f77c-413f-acd6-9d453925f152", "Infiltration": "Old Station", "Position": { - "x": -335.8, - "y": 19.2544765, - "z": -139.37 + "x": -334.61, + "y": 20.316, + "z": -140.883 }, "Rotation": 51.83, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 158.9 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "53d25c29-09e2-4424-adc2-0b6f3b324af0", - "Infiltration": "", - "Position": { - "x": -171.64, - "y": 1.03652763, - "z": 432.26 - }, - "Rotation": 169.16, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2701,19 +3187,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 40 } }, - "CorePointId": 7, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "557d5203-4e7c-4bb7-bb01-f8f2f792f93e", + "Id": "56185e61-f949-4f55-9ebf-00ce210b1378", "Infiltration": "", "Position": { - "x": -203.55, - "y": 1.13691711, - "z": 417.31 + "x": -272.866028, + "y": 23.9226513, + "z": -497.731 }, - "Rotation": 157.57, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -2795,8 +3281,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2805,24 +3291,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "5beb21e5-df5f-4db0-b607-202cb7a62ecf", - "Infiltration": "Old Station", + "Id": "597eb4f4-df3d-45e6-8742-25a8198390bf", + "Infiltration": "", "Position": { - "x": 59.6199951, - "y": 8.883999, - "z": -659.78 + "x": -108.480011, + "y": 10.130621, + "z": -609.9 }, - "Rotation": 316.58, - "Sides": ["Pmc"] + "Rotation": 152.43, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2831,24 +3317,50 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 4, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "5beb21e5-df5f-4db0-b607-202cb7a62ecf", + "Infiltration": "Old Station", + "Position": { + "x": 59.18402, + "y": 8.883999, + "z": -659.509033 + }, + "Rotation": 316.58, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 45 + } + }, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "5cd6f0cb-e6fd-4455-b370-d855738a434d", + "Id": "5d297c94-555f-4489-9f9e-71f340575be3", "Infiltration": "", "Position": { - "x": -526.84, - "y": -2.522231, - "z": 216.27 + "x": 280.36, + "y": 8.309144, + "z": -674.51 }, - "Rotation": 76.87, + "Rotation": 238.74, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2857,19 +3369,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 35 } }, - "CorePointId": 1, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "5d238d90-a648-4d38-a868-e9eb7add2917", + "Id": "5d2e328c-b4dc-4de5-93b8-35a2755459eb", "Infiltration": "", "Position": { - "x": -130.62, - "y": 13.0453444, - "z": -623.1699 + "x": -267.229, + "y": 24.6826515, + "z": -489.117035 }, - "Rotation": 120.210007, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -2899,8 +3411,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneHouse", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2909,24 +3421,24 @@ "y": 0, "z": 0 }, - "Radius": 250 + "Radius": 140 } }, - "CorePointId": 4, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "6400e0f5-754e-4a02-b93a-74b68dc7c03f", + "Id": "6091f54e-d9a5-43fe-a773-b2445ff82a8e", "Infiltration": "", "Position": { - "x": -352.33, - "y": -8.285932, - "z": 132.14 + "x": 443.48, + "y": -11.4372435, + "z": 84.1300049 }, - "Rotation": 0, + "Rotation": 295.57, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneMiniHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2935,24 +3447,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 155 } }, - "CorePointId": 0, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "6767b1b7-da32-4b62-90f0-0d44712a642b", - "Infiltration": "Old Station", + "Id": "64b54bbb-7bc0-42ec-b8aa-9372870e39bf", + "Infiltration": "", "Position": { - "x": 370.959961, - "y": 13.9, - "z": -699.98 + "x": 187.1, + "y": 3.37974882, + "z": -149.559982 }, - "Rotation": 323.3954, - "Sides": ["Pmc"] + "Rotation": 323.97998, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2964,21 +3476,21 @@ "Radius": 60 } }, - "CorePointId": 2, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "68988ed2-79f2-485d-a0e6-13189d0221d4", + "Id": "64bc1359-c4af-40fd-9590-e464a049a894", "Infiltration": "", "Position": { - "x": -416.2, - "y": 12.9368525, - "z": -468.799957 + "x": 269.67, + "y": 17.0124722, + "z": -758.63 }, "Rotation": 236.87, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -2987,24 +3499,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "69378f13-ba17-464e-8875-618e6219d7e5", - "Infiltration": "Old Station", + "Id": "65756485-8a47-49c0-9d70-6452e3b32f7c", + "Infiltration": "", "Position": { - "x": -28.461, - "y": 22.91, - "z": -302.726 + "x": 9.660004, + "y": 15.707283, + "z": -780.569946 }, - "Rotation": 353.636353, - "Sides": ["Pmc"] + "Rotation": 10.29, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneMiniHouse", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3013,24 +3525,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "6969a351-e6f7-4f1a-a109-1e0d0da8f3e7", - "Infiltration": "", + "Id": "6767b1b7-da32-4b62-90f0-0d44712a642b", + "Infiltration": "Old Station", "Position": { - "x": 242.89, - "y": 1.51325369, - "z": -164.249985 + "x": 370.773, + "y": 13.9, + "z": -700.119 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 323.3954, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3044,19 +3556,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "69a4318c-7522-4738-877a-099b3733ae23", - "Infiltration": "House", + "Id": "69378f13-ba17-464e-8875-618e6219d7e5", + "Infiltration": "Old Station", "Position": { - "x": 369.829956, - "y": 17.62, - "z": -597.53 + "x": -28.461, + "y": 22.91, + "z": -302.726 }, - "Rotation": 268.42, + "Rotation": 353.636353, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3065,20 +3577,20 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 70 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "69a65e45-1180-4aab-9d68-8b60652a68f6", - "Infiltration": "", + "Id": "69a4318c-7522-4738-877a-099b3733ae23", + "Infiltration": "House", "Position": { - "x": -6.42999268, - "y": 10.9864779, - "z": -786.35 + "x": 369.829956, + "y": 17.62, + "z": -597.53 }, - "Rotation": 10.29, - "Sides": ["Savage"] + "Rotation": 268.42, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -3132,6 +3644,32 @@ "Rotation": 14.210001, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "6b20ac35-6306-4c28-b1bb-a489aa4d9852", + "Infiltration": "", + "Position": { + "x": -528.91, + "y": 2.366396, + "z": 233.67 + }, + "Rotation": 76.87, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3159,8 +3697,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3169,24 +3707,24 @@ "y": 0, "z": 0 }, - "Radius": 249.4 + "Radius": 158.9 } }, - "CorePointId": 5, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "6e093e43-1b9d-4934-b779-503b7af772a3", + "Id": "6d19b6a0-d1d5-4fb2-879e-4a25e8858232", "Infiltration": "", "Position": { - "x": 213.47, - "y": -14.6916227, - "z": 291.96 + "x": -231.18, + "y": 1.145359, + "z": 400.86 }, - "Rotation": 151.22, + "Rotation": 157.57, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneUsecBase", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3198,18 +3736,44 @@ "Radius": 60 } }, - "CorePointId": 2, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "6f4332cc-f37d-4125-85b3-0cc6b21708f3", + "Id": "6df80f13-0e3c-4864-8e19-56a0e4dbf589", "Infiltration": "", "Position": { - "x": -413.460022, - "y": 15.1322632, - "z": -428.01004 + "x": 310.521, + "y": 22.96865, + "z": -523.037964 }, "Rotation": 236.87, "Sides": ["Savage"] }, + { + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 40 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 4, + "Id": "6dfc97f8-d2e3-4c7f-95e3-4527540e817d", + "Infiltration": "", + "Position": { + "x": -507, + "y": 24.63865, + "z": -276.79 + }, + "Rotation": 287.409973, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Opposite"], @@ -3262,32 +3826,6 @@ "Rotation": 53.04, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 158.9 - } - }, - "CorePointId": 7, - "DelayToCanSpawnSec": 4, - "Id": "70b81aa2-9bfc-4e17-841c-f38f3b407452", - "Infiltration": "", - "Position": { - "x": -131.71, - "y": 28.4982586, - "z": -197.84 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -3308,15 +3846,15 @@ "Infiltration": "House", "Position": { "x": 443.87, - "y": -20.51736, + "y": -20.4460011, "z": 362.51 }, "Rotation": 230.000015, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3325,24 +3863,50 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "75fe2cc6-b21e-437d-a629-1b56a98d37b3", - "Infiltration": "Old Station", + "Id": "724edbcc-6b53-4a10-ad37-cbe56cd0ab2d", + "Infiltration": "", "Position": { - "x": -229.05, - "y": 3.77, - "z": 105.45 + "x": -52.23999, + "y": 7.8534317, + "z": -763.9 }, - "Rotation": 112.027237, - "Sides": ["Pmc"] + "Rotation": 29.94, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 20 + } + }, + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "72ddb177-424b-476d-bf42-6ed7fe8d955a", + "Infiltration": "", + "Position": { + "x": -271.730042, + "y": 7.44465065, + "z": -418.514984 + }, + "Rotation": 5.71200657, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneUsecBase", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3354,18 +3918,44 @@ "Radius": 60 } }, - "CorePointId": 1, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "760bd407-5519-4c21-a173-b4e04f3467be", + "Id": "75d93744-fa1f-4578-9bd1-ab2f7c5b2a3f", "Infiltration": "", "Position": { - "x": -55.9500122, - "y": 7.597872, - "z": -759.37 + "x": 312.039978, + "y": 22.96865, + "z": -487.319977 }, - "Rotation": 29.94, + "Rotation": 236.87, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 100 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "75fe2cc6-b21e-437d-a629-1b56a98d37b3", + "Infiltration": "Old Station", + "Position": { + "x": -229.05, + "y": 3.77, + "z": 105.45 + }, + "Rotation": 112.027237, + "Sides": ["Pmc"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3392,6 +3982,58 @@ "Rotation": 316.58, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 7, + "DelayToCanSpawnSec": 4, + "Id": "7659728c-89ba-4cc6-9746-a9d64252c068", + "Infiltration": "", + "Position": { + "x": -171.64, + "y": 1.03652763, + "z": 432.26 + }, + "Rotation": 169.16, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 140 + } + }, + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "77c55b59-7bb5-4e16-96e5-68e6655ac439", + "Infiltration": "", + "Position": { + "x": 366.78, + "y": 1.09509182, + "z": 0.550003052 + }, + "Rotation": 295.57, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3445,8 +4087,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3455,19 +4097,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 158.9 } }, - "CorePointId": 2, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "793948e1-ea02-482b-b44b-82e41eaf6410", + "Id": "78ccf1f5-0e41-4e62-97ed-d23830a8f053", "Infiltration": "", "Position": { - "x": -530.77, - "y": 13.7821617, - "z": -404.130035 + "x": -199.91, + "y": 33.53726, + "z": -193.46 }, - "Rotation": 72.46, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -3497,8 +4139,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3510,16 +4152,16 @@ "Radius": 158.9 } }, - "CorePointId": 11, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "7a48cd52-e346-47f1-9f08-b020a6c7dc51", + "Id": "79f29915-48cb-4c15-bc9f-731d045ad6cd", "Infiltration": "", "Position": { - "x": -516.06, - "y": 21.4670029, - "z": -20.0700073 + "x": -181.32, + "y": 34.0571442, + "z": -164.09 }, - "Rotation": 102.45, + "Rotation": 0, "Sides": ["Savage"] }, { @@ -3548,6 +4190,32 @@ "Rotation": 78.41, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "7bf663d3-4424-401a-b15a-2897ba1939ec", + "Infiltration": "", + "Position": { + "x": 281.7, + "y": 8.236985, + "z": -668.62 + }, + "Rotation": 238.74, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -3575,8 +4243,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3585,23 +4253,23 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7c8bdb04-0122-4831-8385-fc2e56500da7", - "Infiltration": "", + "Id": "7d90e1b9-5aa1-4dcb-80ef-37ffcd141528", + "Infiltration": "Old Station", "Position": { - "x": -218.29, - "y": 31.64855, - "z": -202.19 + "x": -615.8, + "y": 14.69, + "z": -333.949982 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 66.96001, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", + "BotZoneName": "ZoneStoneBunker", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -3611,24 +4279,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 15, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "7d5a5e57-9a77-4c10-8fda-7fd32771f9ae", + "Id": "7f6b5546-a76b-4e24-8de5-bd3c1923d89b", "Infiltration": "", "Position": { - "x": 72.91, - "y": 11.85351, - "z": -220.450012 + "x": -256.77002, + "y": 26.77865, + "z": -448.29 }, - "Rotation": 0, + "Rotation": 236.87, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3637,24 +4305,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 100 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "7d90e1b9-5aa1-4dcb-80ef-37ffcd141528", - "Infiltration": "Old Station", + "Id": "7f756f8e-6458-4d82-9135-ef4cc7dbc861", + "Infiltration": "House", "Position": { - "x": -615.8, - "y": 14.69, - "z": -333.949982 + "x": 283.38, + "y": -0.82, + "z": -45.99 }, - "Rotation": 66.96001, + "Rotation": 268.0896, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3663,20 +4331,20 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 40 } }, - "CorePointId": 0, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "7f756f8e-6458-4d82-9135-ef4cc7dbc861", - "Infiltration": "House", + "Id": "7fb51fcf-9c23-4661-b63b-cb24d6890db5", + "Infiltration": "", "Position": { - "x": 283.38, - "y": -0.82, - "z": -45.99 + "x": -561.09, + "y": 15.2086506, + "z": -355.310028 }, - "Rotation": 268.0896, - "Sides": ["Pmc"] + "Rotation": 287.409973, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -3705,8 +4373,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3715,24 +4383,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 15, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "82bc2c5d-303d-4749-9334-6746005fe5ff", + "Id": "812b6e88-b248-4050-ab3c-5557b7987b0f", "Infiltration": "", "Position": { - "x": 102.62, - "y": 7.21457958, - "z": -152.19 + "x": -84.17999, + "y": 8.84712, + "z": -607.78 }, - "Rotation": 114.56, + "Rotation": 181.14, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3741,13 +4409,39 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 140 } }, - "CorePointId": 0, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "831704c9-39ca-4b9c-a23f-c1f4a05f326b", - "Infiltration": "Old Station", + "Id": "81cd4f09-7616-4d57-ae6d-cc7b5dd17a18", + "Infiltration": "", + "Position": { + "x": 457.29, + "y": -10.9947557, + "z": 97.48999 + }, + "Rotation": 295.57, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "831704c9-39ca-4b9c-a23f-c1f4a05f326b", + "Infiltration": "Old Station", "Position": { "x": -334.02, "y": 17.5681324, @@ -3756,6 +4450,32 @@ "Rotation": 47.6100044, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "837436e1-5893-4567-9eba-71a199c5ef03", + "Infiltration": "", + "Position": { + "x": -317.18, + "y": 14.5686512, + "z": -429.819977 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -3782,9 +4502,61 @@ "Rotation": 353.636353, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "85278afc-3be8-4a9a-8d26-b2b06f5e160b", + "Infiltration": "", + "Position": { + "x": 280.46, + "y": 7.95858765, + "z": -665.38 + }, + "Rotation": 238.74, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 140 + } + }, + "CorePointId": 15, + "DelayToCanSpawnSec": 4, + "Id": "87ce9791-7263-4972-9ffb-88dcef06cf07", + "Infiltration": "", + "Position": { + "x": -12.2900009, + "y": 13.7992649, + "z": -229.31 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "ZoneMiniHouse", - "Categories": ["Bot"], + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3798,7 +4570,7 @@ }, "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "861336cc-9822-4c9b-9353-bef50bb5eee3", + "Id": "87ecc7b1-28bb-4f5e-88ca-33436351d266", "Infiltration": "", "Position": { "x": 355.3, @@ -3809,8 +4581,8 @@ "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3819,24 +4591,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 250 } }, - "CorePointId": 4, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "86c03175-87d8-4949-af27-f40fd6e9a3bb", + "Id": "894a51be-7631-48fc-87d0-92fd1e28192e", "Infiltration": "", "Position": { - "x": -540.69, - "y": 5.01928234, - "z": 133.86 + "x": -39.3000031, + "y": -13.4976988, + "z": 348.37 }, - "Rotation": 76.87, + "Rotation": 212.4, "Sides": ["Savage"] }, { "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot", "Boss"], + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -3848,9 +4620,9 @@ "Radius": 140 } }, - "CorePointId": 15, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "89151e94-ff6e-4ef6-a76d-b1599df0aab7", + "Id": "8a07ccb2-7f11-47e4-b7f5-38fce9ef899a", "Infiltration": "", "Position": { "x": 135.05, @@ -3957,65 +4729,13 @@ "Id": "8efb8386-e830-48c3-98ad-088f8fbfbebd", "Infiltration": "House", "Position": { - "x": 226.43, + "x": 226.487976, "y": -8.280846, - "z": 199.06 + "z": 198.979 }, "Rotation": 144.47, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 1, - "DelayToCanSpawnSec": 4, - "Id": "8fe8f516-e398-48de-8881-05ec6e729afd", - "Infiltration": "", - "Position": { - "x": -174.909973, - "y": 13.6224213, - "z": -649.87 - }, - "Rotation": 62.2, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 140 - } - }, - "CorePointId": 10, - "DelayToCanSpawnSec": 4, - "Id": "90dfab11-26b8-472e-bd22-21f6171099a0", - "Infiltration": "", - "Position": { - "x": 90.27, - "y": -15.8248549, - "z": 116.15 - }, - "Rotation": 190.98, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -4069,8 +4789,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4079,24 +4799,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 50 } }, - "CorePointId": 9, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "92b55875-0ec1-4a96-9cc4-72dfbb4befb7", - "Infiltration": "", + "Id": "9332f801-241b-4383-b8cb-25c6278888e1", + "Infiltration": "Old Station", "Position": { - "x": 457.29, - "y": -10.9947557, - "z": 97.48999 + "x": -519.41, + "y": 7.2753315, + "z": 154.59 }, - "Rotation": 295.57, - "Sides": ["Savage"] + "Rotation": 188.21, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4105,47 +4825,21 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 158.9 } }, - "CorePointId": 9, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "92c0f586-3b0e-404a-816c-82531b84c894", + "Id": "93e28c74-ff82-4757-acf2-a516574ca785", "Infiltration": "", "Position": { - "x": 392.98, - "y": -16.8250637, - "z": 362.59 + "x": -131.71, + "y": 28.4982586, + "z": -197.84 }, - "Rotation": 188.07, + "Rotation": 0, "Sides": ["Savage"] }, - { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 50 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "9332f801-241b-4383-b8cb-25c6278888e1", - "Infiltration": "Old Station", - "Position": { - "x": -519.41, - "y": 7.2753315, - "z": 154.59 - }, - "Rotation": 188.21, - "Sides": ["Pmc"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -4199,8 +4893,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4209,24 +4903,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 5, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "9576c513-49fd-4af6-a3f9-dfbea4fa784b", + "Id": "9670bfdc-1f5f-414e-8d52-801a5c23cb9a", "Infiltration": "", "Position": { - "x": 365.98, - "y": 4.369165, - "z": -8.880005 + "x": 2.75, + "y": 14.7908974, + "z": -777.28 }, - "Rotation": 295.57, + "Rotation": 10.29, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4235,19 +4929,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 158.9 } }, - "CorePointId": 3, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "95eed7b0-be7e-4c74-92c4-a18135e3f579", + "Id": "96da11d4-0ae2-4067-913a-3babf0428392", "Infiltration": "", "Position": { - "x": 135.88, - "y": 8.4578495, - "z": -664.99 + "x": -441.5, + "y": 0.238876343, + "z": 344.8 }, - "Rotation": 165.36, + "Rotation": 164.48, "Sides": ["Savage"] }, { @@ -4277,8 +4971,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4287,7 +4981,59 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 40 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 4, + "Id": "97eebe9d-fabe-444e-bb97-509aeb5a8038", + "Infiltration": "", + "Position": { + "x": -473.3, + "y": 22.0786514, + "z": -218.390015 + }, + "Rotation": 287.409973, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "986f2100-4f4e-494d-ba84-408cf0ab4e0d", + "Infiltration": "", + "Position": { + "x": 96.41, + "y": 14.954258, + "z": -761.12 + }, + "Rotation": 165.36, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 } }, "CorePointId": 0, @@ -4302,6 +5048,84 @@ "Rotation": 139.58, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "9b0ca4ef-e3d7-4e9c-a405-459164577b44", + "Infiltration": "", + "Position": { + "x": -294.37, + "y": 13.7586508, + "z": -419.759979 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 40 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 4, + "Id": "9ba27b0d-5676-4a78-9910-11f32903c0b5", + "Infiltration": "", + "Position": { + "x": -442.600037, + "y": 15.3186512, + "z": -180.740021 + }, + "Rotation": 287.409973, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 192.6 + } + }, + "CorePointId": 7, + "DelayToCanSpawnSec": 4, + "Id": "9bc88a9d-842a-4198-9be2-e9c869989a46", + "Infiltration": "", + "Position": { + "x": -94.08, + "y": -1.31425381, + "z": 387.77 + }, + "Rotation": 192.91, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -4329,8 +5153,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "ZoneUsecBase", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4339,24 +5163,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 60 } }, - "CorePointId": 7, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "9dab1746-6ac8-4860-abde-784643946d87", + "Id": "9caecf22-4b61-4744-bb33-4662a04b5071", "Infiltration": "", "Position": { - "x": -152.96, - "y": 0.37342453, - "z": 434.83 + "x": 299.449982, + "y": 12.6146507, + "z": -565.998047 }, - "Rotation": 218.52, + "Rotation": 236.87, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4365,19 +5189,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 50 } }, - "CorePointId": 3, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "9e45bfc7-c9bc-42aa-82fe-72c232e39370", + "Id": "9d66306c-cbd1-4a2d-8a48-43b5555d5a2d", "Infiltration": "", "Position": { - "x": 280.46, - "y": 7.95858765, - "z": -665.38 + "x": -416.220032, + "y": 15.7661858, + "z": -434.29 }, - "Rotation": 238.74, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -4406,6 +5230,32 @@ "Rotation": 353.636353, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 1, + "DelayToCanSpawnSec": 4, + "Id": "9ef38d71-b41b-4320-ad27-c346c0a709f9", + "Infiltration": "", + "Position": { + "x": -55.9500122, + "y": 7.597872, + "z": -759.37 + }, + "Rotation": 29.94, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -4459,8 +5309,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4469,20 +5319,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "a0962412-c584-4809-be76-b7a5c78cb855", - "Infiltration": "Old Station", + "Id": "a0463071-ceb5-4d1f-8968-33c66ed263ba", + "Infiltration": "", "Position": { - "x": -616.79, - "y": 14.49, - "z": -324.47 + "x": -23.7000122, + "y": 9.082792, + "z": -779.76 }, - "Rotation": 66.96001, - "Sides": ["Pmc"] + "Rotation": 10.29, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -4500,19 +5350,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a112057b-e7f1-4e10-b8e4-ec7d678b8b70", + "Id": "a0962412-c584-4809-be76-b7a5c78cb855", "Infiltration": "Old Station", "Position": { - "x": -516.73, - "y": 9.348391, - "z": 89.04001 + "x": -616.79, + "y": 14.49, + "z": -324.47 }, - "Rotation": 130.67, + "Rotation": 66.96001, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4521,20 +5371,20 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "a139ae8f-1e50-43c9-8459-026081336b7b", - "Infiltration": "", + "Id": "a112057b-e7f1-4e10-b8e4-ec7d678b8b70", + "Infiltration": "Old Station", "Position": { - "x": -231.18, - "y": 1.145359, - "z": 400.86 + "x": -529.6, + "y": 11.2739992, + "z": 85.98001 }, - "Rotation": 157.57, - "Sides": ["Savage"] + "Rotation": 130.67, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -4693,8 +5543,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneMiniHouse", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4703,19 +5553,45 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 249.4 } }, - "CorePointId": 4, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "a82f494f-2f4c-4edc-ba0a-66a504500ce3", + "Id": "a73ee418-361e-4513-a631-a8b2a24a85c4", "Infiltration": "", "Position": { - "x": -486.63, - "y": 0.248063087, - "z": 330.58 + "x": 307.94, + "y": -0.59301734, + "z": -159.809982 }, - "Rotation": 164.48, + "Rotation": 1.62999988, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneWoodCutter", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 18, + "DelayToCanSpawnSec": 4, + "Id": "a77f891e-8470-4be2-ba24-5ff0bdae422a", + "Infiltration": "", + "Position": { + "x": 125.9, + "y": 0.277326226, + "z": 4.92 + }, + "Rotation": 101.91, "Sides": ["Savage"] }, { @@ -4764,7 +5640,7 @@ "Infiltration": "Old Station", "Position": { "x": -21.7, - "y": 22.91, + "y": 23.29, "z": -301.63 }, "Rotation": 353.636353, @@ -4772,7 +5648,7 @@ }, { "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4786,14 +5662,14 @@ }, "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "ab81316f-b469-41a4-80f4-471e80c5da4a", + "Id": "ac5e45e7-1908-4a6a-9d14-ab7549880e02", "Infiltration": "", "Position": { - "x": -532.56, - "y": -0.4881611, - "z": 254.2 + "x": -496.5, + "y": 5.55468845, + "z": 81.54 }, - "Rotation": 83.36, + "Rotation": 93.46, "Sides": ["Savage"] }, { @@ -4823,8 +5699,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneScavBase2", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4836,10 +5712,62 @@ "Radius": 50 } }, - "CorePointId": 0, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "b0365322-2ae6-4748-9689-d644d2177c73", - "Infiltration": "Old Station", + "Id": "af2fcb45-fb5f-4826-9e87-e4c2a93d0183", + "Infiltration": "", + "Position": { + "x": 178.999985, + "y": 18.13865, + "z": -771.420044 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 140 + } + }, + "CorePointId": 15, + "DelayToCanSpawnSec": 4, + "Id": "af83d40a-a377-488d-a923-a75c9b1bd027", + "Infiltration": "", + "Position": { + "x": 72.91, + "y": 11.85351, + "z": -220.450012 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "b0365322-2ae6-4748-9689-d644d2177c73", + "Infiltration": "Old Station", "Position": { "x": -494.04, "y": 20.5889053, @@ -4848,6 +5776,32 @@ "Rotation": 0, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 249.4 + } + }, + "CorePointId": 5, + "DelayToCanSpawnSec": 4, + "Id": "b08c4b36-5e7f-481e-8a2a-cb9dfbf7e1c8", + "Infiltration": "", + "Position": { + "x": 213.47, + "y": -14.6916227, + "z": 291.96 + }, + "Rotation": 151.22, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -4874,6 +5828,32 @@ "Rotation": 353.636353, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 16, + "DelayToCanSpawnSec": 4, + "Id": "b0ea4e50-f36c-4ebf-8f3d-95407babd393", + "Infiltration": "", + "Position": { + "x": -270.100037, + "y": 20.6486511, + "z": -439.83 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -4893,16 +5873,16 @@ "Id": "b10e6b2c-93fb-44af-ac24-a016042c03ea", "Infiltration": "Old Station", "Position": { - "x": -520.11, - "y": 10.3401012, - "z": 85.86 + "x": -522.07, + "y": 8.263999, + "z": 97.21001 }, "Rotation": 130.67, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4911,24 +5891,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 140 } }, - "CorePointId": 3, + "CorePointId": 9, "DelayToCanSpawnSec": 4, - "Id": "b1755e13-12e8-4a82-a899-8fb0f1f4d535", + "Id": "b15bf85f-b3b5-40fc-8edd-9e6946dd9a51", "Infiltration": "", "Position": { - "x": 269.67, - "y": 17.0124722, - "z": -758.63 + "x": 471.95, + "y": -18.3825169, + "z": 229.48 }, - "Rotation": 236.87, + "Rotation": 321.01, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4937,24 +5917,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 40 } }, - "CorePointId": 0, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "b3697fa5-29af-4a4e-afd1-3cf837b1fdae", - "Infiltration": "Old Station", + "Id": "b1953b64-37ea-484c-9e1e-123972a53ee9", + "Infiltration": "", "Position": { - "x": -280.28, - "y": -0.8622794, - "z": 332.87 + "x": -301.8, + "y": 14.938652, + "z": -393.71 }, - "Rotation": 193.46, - "Sides": ["Pmc"] + "Rotation": 236.87, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -4963,21 +5943,47 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 158.9 } }, - "CorePointId": 2, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "b3a5c785-d6cc-4559-acb2-ddc69b22515a", + "Id": "b3040f75-9e3e-4676-8014-d0636abbac8b", "Infiltration": "", "Position": { - "x": -416.220032, - "y": 15.7661858, - "z": -434.29 + "x": -516.06, + "y": 21.4670029, + "z": -20.0700073 }, - "Rotation": 236.87, + "Rotation": 102.45, "Sides": ["Savage"] }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "b3697fa5-29af-4a4e-afd1-3cf837b1fdae", + "Infiltration": "Old Station", + "Position": { + "x": -280.28, + "y": -0.8622794, + "z": 332.87 + }, + "Rotation": 193.46, + "Sides": ["Pmc"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -5004,6 +6010,32 @@ "Rotation": 14.210001, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 250 + } + }, + "CorePointId": 4, + "DelayToCanSpawnSec": 4, + "Id": "b46a69e1-1ff9-43da-bc8c-e3ce961acc58", + "Infiltration": "", + "Position": { + "x": -352.33, + "y": -8.285932, + "z": 132.14 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -5109,8 +6141,216 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneUsecBase", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "b8405637-6ee3-40ec-8fe7-f69eedd62bb3", + "Infiltration": "", + "Position": { + "x": 307.81, + "y": 12.6186514, + "z": -553.24 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneScavBase2", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 3, + "DelayToCanSpawnSec": 4, + "Id": "b935be58-2fbb-41c6-bb6c-16ed756e52fc", + "Infiltration": "", + "Position": { + "x": 263.9, + "y": 17.3108673, + "z": -762.5 + }, + "Rotation": 165.36, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "b93d8187-0ae2-4971-be9c-7839721aeece", + "Infiltration": "House", + "Position": { + "x": 487.412, + "y": -18.4096375, + "z": 334.496 + }, + "Rotation": 240.480011, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "ba05b27c-b857-4d25-9fea-c20a4d7d8ce5", + "Infiltration": "Old Station", + "Position": { + "x": -621, + "y": 14.91, + "z": -328.73 + }, + "Rotation": 66.96001, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 158.9 + } + }, + "CorePointId": 8, + "DelayToCanSpawnSec": 4, + "Id": "ba534ae2-9122-46c5-96eb-7a717dbb4be6", + "Infiltration": "", + "Position": { + "x": -293.67, + "y": 28.9518757, + "z": -199.67 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 40 + } + }, + "CorePointId": 13, + "DelayToCanSpawnSec": 4, + "Id": "bbeb51de-3986-480c-b678-e37416ad0ded", + "Infiltration": "", + "Position": { + "x": -517.12, + "y": 14.1786509, + "z": -160.300018 + }, + "Rotation": 287.409973, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 50 + } + }, + "CorePointId": 2, + "DelayToCanSpawnSec": 4, + "Id": "bce98e55-4df0-4032-9deb-6a0f21c0dfac", + "Infiltration": "", + "Position": { + "x": -389.720032, + "y": 14.5486507, + "z": -423.34 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "bd0c617a-4288-47f9-ab50-25848294a38e", + "Infiltration": "House", + "Position": { + "x": 465.27002, + "y": -15.150856, + "z": 177.84 + }, + "Rotation": 239.859985, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5119,20 +6359,20 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 70 } }, - "CorePointId": 10, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b759747e-e91d-4427-a2da-28802a35fa33", - "Infiltration": "", + "Id": "bdcfc53f-69f8-44fb-9be1-238bab9c2629", + "Infiltration": "House", "Position": { - "x": 125.9, - "y": 0.277326226, - "z": 4.92 + "x": 464.24, + "y": -14.9513435, + "z": 176.19 }, - "Rotation": 101.91, - "Sides": ["Savage"] + "Rotation": 239.859985, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -5145,19 +6385,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 50 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "b93d8187-0ae2-4971-be9c-7839721aeece", - "Infiltration": "House", + "Id": "be022f29-5b2b-4e94-893c-26d18fb3f61d", + "Infiltration": "Old Station", "Position": { - "x": 487.358643, - "y": -18.4096375, - "z": 334.589966 + "x": -524.17, + "y": -2.57875681, + "z": 220.33 }, - "Rotation": 240.480011, + "Rotation": 0, "Sides": ["Pmc"] }, { @@ -5176,19 +6416,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ba05b27c-b857-4d25-9fea-c20a4d7d8ce5", - "Infiltration": "Old Station", + "Id": "be2be8fa-4a03-4c1e-b8d7-85d702cf42f6", + "Infiltration": "House", "Position": { - "x": -621, - "y": 14.91, - "z": -328.73 + "x": 487.358643, + "y": -18.8088722, + "z": 332.61 }, - "Rotation": 66.96001, + "Rotation": 245.390015, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneClearVill", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5200,21 +6440,21 @@ "Radius": 60 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "bae81a81-6114-4f13-8fd9-c273f49962b1", + "Id": "be65242c-12dd-40c8-84a1-7f6337fc84e0", "Infiltration": "", "Position": { - "x": -171.68, - "y": 14.8065891, - "z": -617.699951 + "x": -530.77, + "y": 13.7821617, + "z": -404.130035 }, - "Rotation": 120.210007, + "Rotation": 72.46, "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5223,19 +6463,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 100 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "bd0c617a-4288-47f9-ab50-25848294a38e", - "Infiltration": "House", + "Id": "beefc821-7b82-4489-a064-a43fc1f752b2", + "Infiltration": "Old Station", "Position": { - "x": 465.27002, - "y": -15.150856, - "z": 177.84 + "x": -228.55, + "y": 3.13, + "z": 110.76 }, - "Rotation": 239.859985, + "Rotation": 112.027237, "Sides": ["Pmc"] }, { @@ -5254,14 +6494,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "bdcfc53f-69f8-44fb-9be1-238bab9c2629", - "Infiltration": "House", + "Id": "bf2a6323-087e-4d49-a160-ea86b8295ac0", + "Infiltration": "Old Station", "Position": { - "x": 464.24, - "y": -14.9513435, - "z": 176.19 + "x": 63.3200073, + "y": 8.99399948, + "z": -661.4 }, - "Rotation": 239.859985, + "Rotation": 316.58, "Sides": ["Pmc"] }, { @@ -5275,19 +6515,19 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "be022f29-5b2b-4e94-893c-26d18fb3f61d", - "Infiltration": "Old Station", + "Id": "c047a076-7425-4c63-ac40-75be5226847c", + "Infiltration": "House", "Position": { - "x": -524.17, - "y": -2.57875681, - "z": 220.33 + "x": 391.61, + "y": 13.62, + "z": -400.750031 }, - "Rotation": 0, + "Rotation": 287.12, "Sides": ["Pmc"] }, { @@ -5306,14 +6546,14 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "be2be8fa-4a03-4c1e-b8d7-85d702cf42f6", + "Id": "c053faa2-0f4e-4508-ac35-230ff6aa6a74", "Infiltration": "House", "Position": { - "x": 487.358643, - "y": -18.8088722, - "z": 332.61 + "x": 234.299988, + "y": 26.98, + "z": -317.97 }, - "Rotation": 245.390015, + "Rotation": 287.12, "Sides": ["Pmc"] }, { @@ -5332,19 +6572,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "beefc821-7b82-4489-a064-a43fc1f752b2", + "Id": "c0b93127-2d2f-4129-96e1-0d4dcc18a722", "Infiltration": "Old Station", "Position": { - "x": -228.55, + "x": -222.23, "y": 3.13, - "z": 110.76 + "z": 110.95 }, "Rotation": 112.027237, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5353,24 +6593,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 158.9 } }, - "CorePointId": 15, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "bf135b79-4b10-4d78-8a1b-573eb800444d", + "Id": "c0fc88a1-591a-4ccd-8b6f-eb85d8f35b63", "Infiltration": "", "Position": { - "x": 25.57, - "y": 11.3200827, - "z": -226.610016 + "x": -486.63, + "y": 0.248063087, + "z": 330.58 }, - "Rotation": 0, + "Rotation": 164.48, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5379,23 +6619,23 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "bf2a6323-087e-4d49-a160-ea86b8295ac0", - "Infiltration": "Old Station", + "Id": "c2949d57-c244-4752-a803-c920577516e3", + "Infiltration": "", "Position": { - "x": 63.3200073, - "y": 8.99399948, - "z": -661.4 + "x": 102.62, + "y": 7.21457958, + "z": -152.19 }, - "Rotation": 316.58, - "Sides": ["Pmc"] + "Rotation": 114.56, + "Sides": ["Savage"] }, { - "BotZoneName": "ZoneWoodCutter", + "BotZoneName": "ZoneStoneBunker", "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", @@ -5405,19 +6645,19 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 60 } }, - "CorePointId": 15, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "bfe4231f-a0bc-4bc4-b427-b98285523269", + "Id": "c2f8e4de-487a-49b8-80d2-1caacf118487", "Infiltration": "", "Position": { - "x": 94.85, - "y": 6.81406, - "z": -203.72 + "x": -253.652039, + "y": 26.7736511, + "z": -431.906036 }, - "Rotation": 283.99, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -5436,19 +6676,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c047a076-7425-4c63-ac40-75be5226847c", - "Infiltration": "House", + "Id": "c5021df7-1750-44ff-ae44-137022a8bdac", + "Infiltration": "Old Station", "Position": { - "x": 391.61, - "y": 13.62, - "z": -400.750031 + "x": 365.55, + "y": 13.35, + "z": -700.829956 }, - "Rotation": 287.12, + "Rotation": 310.421173, "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Player"], + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5457,19 +6697,19 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 100 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c053faa2-0f4e-4508-ac35-230ff6aa6a74", - "Infiltration": "House", + "Id": "c58f8bd9-ff28-48d3-a8e8-dbad862698a8", + "Infiltration": "Old Station", "Position": { - "x": 234.299988, - "y": 26.98, - "z": -317.97 + "x": -222.56, + "y": 3.13, + "z": 105.69 }, - "Rotation": 287.12, + "Rotation": 112.027237, "Sides": ["Pmc"] }, { @@ -5488,19 +6728,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c0b93127-2d2f-4129-96e1-0d4dcc18a722", + "Id": "c6f6dcc4-17ef-4842-83ab-124e34dfa53e", "Infiltration": "Old Station", "Position": { - "x": -222.23, - "y": 3.13, - "z": 110.95 + "x": -225.79, + "y": 4.98, + "z": 85.72 }, "Rotation": 112.027237, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5509,24 +6749,24 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 158.9 } }, - "CorePointId": 9, + "CorePointId": 11, "DelayToCanSpawnSec": 4, - "Id": "c0c439df-041c-4b0b-9956-b074a3bca17e", + "Id": "c82451b7-0f24-4ea7-a00c-fd681c66005d", "Infiltration": "", "Position": { - "x": 471.95, - "y": -18.3825169, - "z": 229.48 + "x": -428.98, + "y": 25.4802856, + "z": -81.73999 }, - "Rotation": 321.01, + "Rotation": 36.98, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneHouse", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Opposite"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5535,20 +6775,20 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 100 } }, - "CorePointId": 9, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c3c6b35b-4a1b-40ae-af6d-b32fa522aa27", - "Infiltration": "", + "Id": "c82d2b76-ad46-4624-825e-975a6d40fcf4", + "Infiltration": "Old Station", "Position": { - "x": 365.34, - "y": -13.4270735, - "z": 360.13 + "x": -229.28, + "y": 5.19, + "z": 86.93 }, - "Rotation": 201.28, - "Sides": ["Savage"] + "Rotation": 112.027237, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -5566,19 +6806,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c5021df7-1750-44ff-ae44-137022a8bdac", + "Id": "c880793b-d822-4677-870e-6ffa1c05abd7", "Infiltration": "Old Station", "Position": { - "x": 365.55, - "y": 13.35, - "z": -700.829956 + "x": -359.75, + "y": 0.8591096, + "z": 239.67 }, - "Rotation": 310.421173, + "Rotation": 129.42, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5587,24 +6827,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "c58f8bd9-ff28-48d3-a8e8-dbad862698a8", - "Infiltration": "Old Station", + "Id": "c8d1f5f7-cdad-4d5a-be9f-e17ba03d0983", + "Infiltration": "", "Position": { - "x": -222.56, - "y": 3.13, - "z": 105.69 + "x": -540.65, + "y": 5.0159235, + "z": 188.06 }, - "Rotation": 112.027237, - "Sides": ["Pmc"] + "Rotation": 76.87, + "Sides": ["Savage"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5613,24 +6853,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c6f6dcc4-17ef-4842-83ab-124e34dfa53e", - "Infiltration": "Old Station", + "Id": "c93838d9-3ec1-47b9-b5da-db2eb0fbec46", + "Infiltration": "House", "Position": { - "x": -225.79, - "y": 4.98, - "z": 85.72 + "x": 389.72998, + "y": 13.24, + "z": -403.929962 }, - "Rotation": 112.027237, + "Rotation": 287.12, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5639,24 +6879,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 70 } }, - "CorePointId": 3, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c804e60e-3965-4745-975a-31056939f58e", - "Infiltration": "", + "Id": "ca70d792-4fc8-47d8-a70a-e08bc2598448", + "Infiltration": "House", "Position": { - "x": 281.7, - "y": 8.236985, - "z": -668.62 + "x": 367.37, + "y": 17.74, + "z": -594.9099 }, - "Rotation": 238.74, - "Sides": ["Savage"] + "Rotation": 268.42, + "Sides": ["Pmc"] }, { "BotZoneName": "", - "Categories": ["Coop", "Opposite"], + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5665,24 +6905,24 @@ "y": 0, "z": 0 }, - "Radius": 100 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "c82d2b76-ad46-4624-825e-975a6d40fcf4", - "Infiltration": "Old Station", + "Id": "cb602055-146b-4bd4-b43b-4df81301d046", + "Infiltration": "House", "Position": { - "x": -229.28, - "y": 5.19, - "z": 86.93 + "x": 373.61, + "y": -1.92541981, + "z": -76.16 }, - "Rotation": 112.027237, + "Rotation": 0, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneMiniHouse", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5691,24 +6931,24 @@ "y": 0, "z": 0 }, - "Radius": 249.4 + "Radius": 60 } }, - "CorePointId": 5, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "c852e0c0-3bda-4acd-adb3-533373fb342f", + "Id": "cb93a2b5-3568-467a-b797-b37f26606dd1", "Infiltration": "", "Position": { - "x": 307.94, - "y": -0.59301734, - "z": -159.809982 + "x": -49.76001, + "y": 8.014783, + "z": -766.39 }, - "Rotation": 1.62999988, + "Rotation": 29.94, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5717,24 +6957,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "c880793b-d822-4677-870e-6ffa1c05abd7", - "Infiltration": "Old Station", + "Id": "cbb701fb-daff-4080-8c0e-c93f00fcacaa", + "Infiltration": "", "Position": { - "x": -359.75, - "y": 0.8591096, - "z": 239.67 + "x": -6.42999268, + "y": 10.9864779, + "z": -786.35 }, - "Rotation": 129.42, - "Sides": ["Pmc"] + "Rotation": 10.29, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5743,20 +6983,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "c93838d9-3ec1-47b9-b5da-db2eb0fbec46", - "Infiltration": "House", + "Id": "cc7d6ae1-7d0c-4b86-a598-df0fda6b55f3", + "Infiltration": "", "Position": { - "x": 389.72998, - "y": 13.24, - "z": -403.929962 + "x": -218.29, + "y": 31.64855, + "z": -202.19 }, - "Rotation": 287.12, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5774,19 +7014,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "ca70d792-4fc8-47d8-a70a-e08bc2598448", + "Id": "ce2a9b2d-260a-4eb4-b0b1-239a10eab0cc", "Infiltration": "House", "Position": { - "x": 367.37, - "y": 17.74, - "z": -594.9099 + "x": 487.358643, + "y": -18.615778, + "z": 330.75 }, - "Rotation": 268.42, + "Rotation": 228.71, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBrokenVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5795,24 +7035,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 1, "DelayToCanSpawnSec": 4, - "Id": "cb602055-146b-4bd4-b43b-4df81301d046", - "Infiltration": "House", + "Id": "ce650b81-d07c-4b2d-b401-a38cb77b7a47", + "Infiltration": "", "Position": { - "x": 373.61, - "y": -1.92541981, - "z": -76.16 + "x": -117.590027, + "y": 11.9433193, + "z": -729.39 }, - "Rotation": 0, - "Sides": ["Pmc"] + "Rotation": 29.94, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneMiniHouse", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5821,20 +7061,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "ce2a9b2d-260a-4eb4-b0b1-239a10eab0cc", - "Infiltration": "House", + "Id": "ce7f06bd-cad3-45ab-9d45-4ff4cfa42521", + "Infiltration": "", "Position": { - "x": 487.358643, - "y": -18.615778, - "z": 330.75 + "x": 242.89, + "y": 1.51325369, + "z": -164.249985 }, - "Rotation": 228.71, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -5941,8 +7181,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -5951,19 +7191,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 158.9 } }, - "CorePointId": 3, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "cf001f8e-fb62-4e75-ba73-2c01516c9cd1", + "Id": "cf611793-6d9e-4036-a8c0-a9076390c5b9", "Infiltration": "", "Position": { - "x": 101.130005, - "y": 15.5523014, - "z": -761.98 + "x": -162.85, + "y": 0.7303066, + "z": 435.96 }, - "Rotation": 165.36, + "Rotation": 182.85, "Sides": ["Savage"] }, { @@ -6037,13 +7277,39 @@ "Id": "d1b20f00-8c54-4ff5-afd6-b3e1035de6d5", "Infiltration": "House", "Position": { - "x": 231.13, + "x": 231.075989, "y": 26.48, - "z": -317.429962 + "z": -317.413 }, "Rotation": 287.12, "Sides": ["Pmc"] }, + { + "BotZoneName": "ZoneWoodCutter", + "Categories": ["Player", "Bot"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 140 + } + }, + "CorePointId": 15, + "DelayToCanSpawnSec": 4, + "Id": "d1f5a6f5-854e-491a-814c-616a6f237f32", + "Infiltration": "", + "Position": { + "x": -60.28, + "y": 18.8811035, + "z": -230.12 + }, + "Rotation": 0, + "Sides": ["Savage"] + }, { "BotZoneName": "", "Categories": ["Player"], @@ -6097,8 +7363,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6107,19 +7373,19 @@ "y": 0, "z": 0 }, - "Radius": 140 + "Radius": 25 } }, - "CorePointId": 10, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "d42a7e44-fd07-4c42-bb3e-1b5ddd2d0394", + "Id": "d60fe5f9-d16f-4a4d-b254-29a90e2d5198", "Infiltration": "", "Position": { - "x": 87.78, - "y": -15.89571, - "z": 114.65 + "x": -298.830017, + "y": 15.94865, + "z": -388.750031 }, - "Rotation": 190.98, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -6149,8 +7415,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneMiniHouse", - "Categories": ["Bot", "Boss"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6159,20 +7425,20 @@ "y": 0, "z": 0 }, - "Radius": 171 + "Radius": 50 } }, - "CorePointId": 5, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "d91c4717-0dd8-48b6-98a7-7eb7219a9647", - "Infiltration": "", + "Id": "da037755-e7ae-4738-8be9-be02991b422b", + "Infiltration": "Old Station", "Position": { - "x": 375.81, - "y": -1.05202746, - "z": -115.25 + "x": -254.053009, + "y": 27.412447, + "z": -204.690979 }, - "Rotation": 310.84, - "Sides": ["Savage"] + "Rotation": 23.36, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -6185,24 +7451,50 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 70 } }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "da037755-e7ae-4738-8be9-be02991b422b", + "Id": "da22cead-d753-44c4-b44e-131a3d9690b7", "Infiltration": "Old Station", "Position": { - "x": -254.13, - "y": 27.412447, - "z": -204.87 + "x": -59.6399841, + "y": 9.093999, + "z": -577.11 + }, + "Rotation": 316.58, + "Sides": ["Pmc"] + }, + { + "BotZoneName": "", + "Categories": ["Player"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 70 + } + }, + "CorePointId": 0, + "DelayToCanSpawnSec": 4, + "Id": "da89268f-c6c8-4689-a9d5-5be89a23740f", + "Infiltration": "Old Station", + "Position": { + "x": -92.29001, + "y": -0.6761878, + "z": 380.44 }, - "Rotation": 23.36, + "Rotation": 224.32, "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneUsecBase", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6211,24 +7503,24 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 60 } }, - "CorePointId": 0, + "CorePointId": 17, "DelayToCanSpawnSec": 4, - "Id": "da22cead-d753-44c4-b44e-131a3d9690b7", - "Infiltration": "Old Station", + "Id": "dac5c349-4b8a-4f95-9928-16763a8f9901", + "Infiltration": "", "Position": { - "x": -59.6399841, - "y": 9.093999, - "z": -577.11 + "x": 309.93, + "y": 14.5686512, + "z": -576.86 }, - "Rotation": 316.58, - "Sides": ["Pmc"] + "Rotation": 236.87, + "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6237,20 +7529,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 8, "DelayToCanSpawnSec": 4, - "Id": "da89268f-c6c8-4689-a9d5-5be89a23740f", - "Infiltration": "Old Station", + "Id": "dccba1cc-d462-4aa2-9c24-01e060f5b826", + "Infiltration": "", "Position": { - "x": -92.29001, - "y": -0.6761878, - "z": 380.44 + "x": -277.3, + "y": 30.9032745, + "z": -196.4 }, - "Rotation": 224.32, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -6383,8 +7675,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6393,24 +7685,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e0a100fe-5ab6-46f9-a799-3fe3b40be35c", - "Infiltration": "", + "Id": "e0fb7ebc-0a4c-45a3-b5a3-ba5e6b1456ba", + "Infiltration": "Old Station", "Position": { - "x": -130.65, - "y": -1.33261585, - "z": 415.53 + "x": 64.6600342, + "y": 9.084, + "z": -656.64 }, - "Rotation": 218.52, - "Sides": ["Savage"] + "Rotation": 284.39, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6419,20 +7711,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 250 } }, - "CorePointId": 0, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "e0fb7ebc-0a4c-45a3-b5a3-ba5e6b1456ba", - "Infiltration": "Old Station", + "Id": "e14fbe89-b4fd-470a-b5ea-9ef029743815", + "Infiltration": "", "Position": { - "x": 64.6600342, - "y": 9.084, - "z": -656.64 + "x": -346.46, + "y": -8.439364, + "z": 131.01 }, - "Rotation": 284.39, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -6487,34 +7779,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 70 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "e46cc7ed-cb3b-46cf-a822-ecca3fc36638", - "Infiltration": "Old Station", - "Position": { - "x": -28.69, - "y": 22.963, - "z": -305.98 - }, - "Rotation": 353.636353, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneStoneBunker", + "Categories": ["Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6526,21 +7792,21 @@ "Radius": 60 } }, - "CorePointId": 1, + "CorePointId": 16, "DelayToCanSpawnSec": 4, - "Id": "e46e996a-cd72-45c4-a311-a324d7144373", + "Id": "e29301b5-4739-4de0-bb4b-8541b3f1d534", "Infiltration": "", "Position": { - "x": 9.660004, - "y": 15.707283, - "z": -780.569946 + "x": -308.06, + "y": 13.8386507, + "z": -410.29 }, - "Rotation": 10.29, + "Rotation": 236.87, "Sides": ["Savage"] }, { - "BotZoneName": "", - "Categories": ["Coop", "Group"], + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6549,20 +7815,20 @@ "y": 0, "z": 0 }, - "Radius": 70 + "Radius": 249.4 } }, - "CorePointId": 0, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "e48a6b22-ef3f-4c2b-96ef-1a36803af60d", - "Infiltration": "Old Station", + "Id": "e2fe413c-7f94-4102-b29b-36a726ad6bb1", + "Infiltration": "", "Position": { - "x": -21.816, - "y": 23.211, - "z": -303.139 + "x": 218.6, + "y": -12.2584953, + "z": 279.4 }, - "Rotation": 353.636353, - "Sides": ["Pmc"] + "Rotation": 151.22, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -6580,45 +7846,19 @@ }, "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e4f280f7-ba13-4fa1-83ec-fac99e8f66b5", + "Id": "e46cc7ed-cb3b-46cf-a822-ecca3fc36638", "Infiltration": "Old Station", "Position": { - "x": -26.16, - "y": 22.91, - "z": -302.47 + "x": -28.69, + "y": 22.963, + "z": -305.98 }, "Rotation": 353.636353, "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 1, - "DelayToCanSpawnSec": 4, - "Id": "e54f65a2-bd3f-46d2-806e-5eab29876ea8", - "Infiltration": "", - "Position": { - "x": -52.23999, - "y": 7.8534317, - "z": -763.9 - }, - "Rotation": 29.94, - "Sides": ["Savage"] - }, - { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6627,24 +7867,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 140 } }, - "CorePointId": 1, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "e5754fee-15cb-428d-bf4e-b0e1ae2eaeaf", + "Id": "e46ed7fd-a0b8-412a-b3e0-5d4407bfe431", "Infiltration": "", "Position": { - "x": 2.75, - "y": 14.7908974, - "z": -777.28 + "x": -139.96, + "y": 30.8123264, + "z": -191.76 }, - "Rotation": 10.29, + "Rotation": 0, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6653,24 +7893,24 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 8, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e57bbb92-6313-4b7e-8274-6f0ba1638d59", - "Infiltration": "", + "Id": "e48a6b22-ef3f-4c2b-96ef-1a36803af60d", + "Infiltration": "Old Station", "Position": { - "x": -293.67, - "y": 28.9518757, - "z": -199.67 + "x": -21.816, + "y": 23.211, + "z": -303.139 }, - "Rotation": 0, - "Sides": ["Savage"] + "Rotation": 353.636353, + "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Coop", "Group"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6679,20 +7919,20 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 70 } }, - "CorePointId": 4, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e62228ab-2453-4e59-b594-b283c787333c", - "Infiltration": "", + "Id": "e4f280f7-ba13-4fa1-83ec-fac99e8f66b5", + "Infiltration": "Old Station", "Position": { - "x": -538.41, - "y": 7.11805344, - "z": 157.71 + "x": -26.16, + "y": 22.91, + "z": -302.47 }, - "Rotation": 76.87, - "Sides": ["Savage"] + "Rotation": 353.636353, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -6773,8 +8013,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6783,24 +8023,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 50 } }, - "CorePointId": 1, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "e8156138-015c-415c-b993-1c72383ad070", - "Infiltration": "", + "Id": "e94aee7d-4b61-4214-a68c-498eebdd6574", + "Infiltration": "House", "Position": { - "x": -130.029968, - "y": 9.618751, - "z": -726.5499 + "x": 279.900024, + "y": -12.0694313, + "z": 317.73 }, - "Rotation": 29.94, - "Sides": ["Savage"] + "Rotation": 237.94, + "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], + "BotZoneName": "ZoneBigRocks", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -6809,20 +8049,20 @@ "y": 0, "z": 0 }, - "Radius": 50 + "Radius": 158.9 } }, - "CorePointId": 0, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "e94aee7d-4b61-4214-a68c-498eebdd6574", - "Infiltration": "House", + "Id": "e9877e48-6079-4f78-add4-6e42caf9df06", + "Infiltration": "", "Position": { - "x": 279.900024, - "y": -12.0694313, - "z": 317.73 + "x": -147.94, + "y": 31.125742, + "z": -189.35 }, - "Rotation": 237.94, - "Sides": ["Pmc"] + "Rotation": 0, + "Sides": ["Savage"] }, { "BotZoneName": "", @@ -6895,9 +8135,9 @@ "Id": "eb67cff0-571a-4d65-b9be-766d1a58aafc", "Infiltration": "Old Station", "Position": { - "x": -522.32, - "y": 10.8116693, - "z": 86.6199951 + "x": -526.74, + "y": 11.2439995, + "z": 86.8600159 }, "Rotation": 130.67, "Sides": ["Pmc"] @@ -6928,32 +8168,6 @@ "Rotation": 223.42, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneWoodCutter", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 140 - } - }, - "CorePointId": 15, - "DelayToCanSpawnSec": 4, - "Id": "ec0e1791-8b0f-4e7f-b31d-f3ab6be28990", - "Infiltration": "", - "Position": { - "x": -60.28, - "y": 18.8811035, - "z": -230.12 - }, - "Rotation": 0, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Player"], @@ -7006,32 +8220,6 @@ "Rotation": 0.08, "Sides": ["Pmc"] }, - { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 60 - } - }, - "CorePointId": 2, - "DelayToCanSpawnSec": 4, - "Id": "ee66e640-13cb-4b34-b743-339f3a16e73a", - "Infiltration": "", - "Position": { - "x": -413.12, - "y": 16.0042686, - "z": -350.740021 - }, - "Rotation": 236.87, - "Sides": ["Savage"] - }, { "BotZoneName": "", "Categories": ["Coop", "Group"], @@ -7059,8 +8247,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneRedHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneWoodCutter", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7069,19 +8257,19 @@ "y": 0, "z": 0 }, - "Radius": 158.9 + "Radius": 40 } }, - "CorePointId": 4, + "CorePointId": 18, "DelayToCanSpawnSec": 4, - "Id": "ef01d04a-1194-4c95-9487-d699247dc7b6", + "Id": "f069be88-fcfd-4313-bffa-a990777b71e2", "Infiltration": "", "Position": { - "x": -528.91, - "y": 2.366396, - "z": 233.67 + "x": -2.308197, + "y": -1.44134891, + "z": -74.57119 }, - "Rotation": 76.87, + "Rotation": 101.91, "Sides": ["Savage"] }, { @@ -7111,8 +8299,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot", "Boss"], + "BotZoneName": "ZoneRoad", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7121,19 +8309,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 158.9 } }, - "CorePointId": 1, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "f1d7faef-6e94-4ae6-ae13-dc909266ce5e", + "Id": "f277e2a5-1f9f-43c0-b146-7098cdc8d37a", "Infiltration": "", "Position": { - "x": -49.76001, - "y": 8.014783, - "z": -766.39 + "x": -170.87, + "y": 0.9297247, + "z": 431.87 }, - "Rotation": 29.94, + "Rotation": 152.9, "Sides": ["Savage"] }, { @@ -7155,9 +8343,9 @@ "Id": "f2ae3edb-47f9-402e-8e4f-de47df81c9ce", "Infiltration": "Old Station", "Position": { - "x": -329.24, + "x": -329.148, "y": 18.8058033, - "z": -141.908661 + "z": -141.793 }, "Rotation": 38.5499954, "Sides": ["Pmc"] @@ -7189,34 +8377,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "", - "Categories": ["Player"], - "ColliderParams": { - "_parent": "SpawnSphereParams", - "_props": { - "Center": { - "x": 0, - "y": 0, - "z": 0 - }, - "Radius": 70 - } - }, - "CorePointId": 0, - "DelayToCanSpawnSec": 4, - "Id": "f4963cf2-9c80-4a14-b300-eac6102fd51d", - "Infiltration": "House", - "Position": { - "x": 487.358643, - "y": -18.0551147, - "z": 328.52 - }, - "Rotation": 230.000015, - "Sides": ["Pmc"] - }, - { - "BotZoneName": "ZoneBrokenVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneClearVill", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7225,24 +8387,24 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 40 } }, - "CorePointId": 1, + "CorePointId": 2, "DelayToCanSpawnSec": 4, - "Id": "f4971ab1-d1a8-4e2a-ba0c-8773de2bc543", + "Id": "f3ee4377-7c67-4d5b-a3a5-1e25c68e8a21", "Infiltration": "", "Position": { - "x": -86.8900146, - "y": 7.94821644, - "z": -752.65 + "x": -439.99, + "y": 15.5185928, + "z": -325.17 }, - "Rotation": 29.94, + "Rotation": 287.409973, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneRoad", - "Categories": ["Bot"], + "BotZoneName": "", + "Categories": ["Player"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7251,20 +8413,20 @@ "y": 0, "z": 0 }, - "Radius": 250 + "Radius": 70 } }, - "CorePointId": 7, + "CorePointId": 0, "DelayToCanSpawnSec": 4, - "Id": "f4aad71b-7d2f-4d14-90f4-cf400e721ada", - "Infiltration": "", + "Id": "f4963cf2-9c80-4a14-b300-eac6102fd51d", + "Infiltration": "House", "Position": { - "x": -39.3000031, - "y": -13.4976988, - "z": 348.37 + "x": 487.358643, + "y": -18.0551147, + "z": 328.52 }, - "Rotation": 212.4, - "Sides": ["Savage"] + "Rotation": 230.000015, + "Sides": ["Pmc"] }, { "BotZoneName": "", @@ -7311,9 +8473,9 @@ "Id": "f520eec3-2fe1-4538-9e85-2997336fa667", "Infiltration": "Old Station", "Position": { - "x": -524.56, - "y": 11.3427467, - "z": 84.5 + "x": -525.27, + "y": 10.7439995, + "z": 88.43001 }, "Rotation": 130.67, "Sides": ["Pmc"] @@ -7371,8 +8533,34 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneBigRocks", - "Categories": ["Bot"], + "BotZoneName": "ZoneUsecBase", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "f72710eb-a9c1-4e01-89d3-127288a2e9bf", + "Infiltration": "", + "Position": { + "x": 297.18, + "y": 23.02765, + "z": -434.389984 + }, + "Rotation": 236.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneRedHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7384,16 +8572,42 @@ "Radius": 158.9 } }, - "CorePointId": 7, + "CorePointId": 4, "DelayToCanSpawnSec": 4, - "Id": "f98e30ff-a233-4f02-8588-2e02a4d42ac8", + "Id": "f829bb1a-9eda-44cf-912c-a8cac4b7af12", "Infiltration": "", "Position": { - "x": -147.94, - "y": 31.125742, - "z": -189.35 + "x": -540.69, + "y": 5.01928234, + "z": 133.86 }, - "Rotation": 0, + "Rotation": 76.87, + "Sides": ["Savage"] + }, + { + "BotZoneName": "ZoneUsecBase", + "Categories": ["Bot", "Boss"], + "ColliderParams": { + "_parent": "SpawnSphereParams", + "_props": { + "Center": { + "x": 0, + "y": 0, + "z": 0 + }, + "Radius": 60 + } + }, + "CorePointId": 17, + "DelayToCanSpawnSec": 4, + "Id": "f876a55b-76a7-43fb-92c9-1be38069449b", + "Infiltration": "", + "Position": { + "x": 311.72998, + "y": 22.96865, + "z": -490.08 + }, + "Rotation": 236.87, "Sides": ["Savage"] }, { @@ -7423,8 +8637,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneScavBase2", - "Categories": ["Bot"], + "BotZoneName": "ZoneHouse", + "Categories": ["Player", "Bot"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7433,19 +8647,19 @@ "y": 0, "z": 0 }, - "Radius": 60 + "Radius": 140 } }, - "CorePointId": 3, + "CorePointId": 5, "DelayToCanSpawnSec": 4, - "Id": "fb56a4ee-ecf3-4329-ad07-06d5f3b1a371", + "Id": "fbd25b6f-97ce-4982-906e-9a91e3ce8763", "Infiltration": "", "Position": { - "x": 96.41, - "y": 14.954258, - "z": -761.12 + "x": 365.98, + "y": 4.369165, + "z": -8.880005 }, - "Rotation": 165.36, + "Rotation": 295.57, "Sides": ["Savage"] }, { @@ -7475,8 +8689,8 @@ "Sides": ["Pmc"] }, { - "BotZoneName": "ZoneMiniHouse", - "Categories": ["Bot"], + "BotZoneName": "ZoneRoad", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7485,24 +8699,24 @@ "y": 0, "z": 0 }, - "Radius": 155 + "Radius": 40 } }, - "CorePointId": 10, + "CorePointId": 7, "DelayToCanSpawnSec": 4, - "Id": "fe5769b5-fb63-42e2-a388-fd84044c08a9", + "Id": "fed02c94-65f2-48fd-8e17-8ce0b66612b4", "Infiltration": "", "Position": { - "x": 187.1, - "y": 3.37974882, - "z": -149.559982 + "x": -298.29, + "y": 0.07000065, + "z": 205.650009 }, - "Rotation": 323.97998, + "Rotation": 212.4, "Sides": ["Savage"] }, { - "BotZoneName": "ZoneClearVill", - "Categories": ["Bot"], + "BotZoneName": "ZoneScavBase2", + "Categories": ["All"], "ColliderParams": { "_parent": "SpawnSphereParams", "_props": { @@ -7514,16 +8728,16 @@ "Radius": 60 } }, - "CorePointId": 2, + "CorePointId": 3, "DelayToCanSpawnSec": 4, - "Id": "ff7aa61d-d6f0-42c9-8e35-f3c49e33b6a2", + "Id": "ff8bd8ee-1d0e-4934-93ad-e8c39541e60a", "Infiltration": "", "Position": { - "x": -439.399963, - "y": 15.3167744, - "z": -334.679962 + "x": 268.699982, + "y": 17.5370255, + "z": -756.9 }, - "Rotation": 287.409973, + "Rotation": 236.87, "Sides": ["Savage"] } ], @@ -7701,6 +8915,27 @@ "PlayersCount": 0, "PlayersCountPVE": 0, "RequirementTip": "" + }, + { + "Chance": 100, + "ChancePVE": 100, + "Count": 0, + "CountPVE": 0, + "EntryPoints": "House,Old Station", + "EventAvailable": false, + "ExfiltrationTime": 8, + "ExfiltrationTimePVE": 8, + "ExfiltrationType": "Individual", + "Id": "", + "MaxTime": 0, + "MaxTimePVE": 0, + "MinTime": 0, + "MinTimePVE": 0, + "Name": "wood_sniper_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequirementTip": "" } ], "filter_ex": [], @@ -7712,286 +8947,52 @@ } ], "matching_min_seconds": 60, - "maxItemCountInLocation": [], + "maxItemCountInLocation": [ + { + "TemplateId": "634959225289190e5e773b3b", + "Value": 6 + } + ], "sav_summon_seconds": 60, "tmp_location_field_remove_me": 0, + "transits": [ + { + "activateAfterSec": 60, + "active": true, + "conditions": "WOO_TRANSIT_15_COND", + "description": "WOO_TRANSIT_15_DESC", + "id": 15, + "location": "factory4_day", + "name": "WOO_TRANSIT_15", + "target": "55f2d3fd4bdc2d5f408b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "WOO_TRANSIT_16_COND", + "description": "WOO_TRANSIT_16_DESC", + "id": 16, + "location": "RezervBase", + "name": "WOO_TRANSIT_16", + "target": "5704e5fad2720bc05b8b4567", + "time": 30 + }, + { + "activateAfterSec": 60, + "active": true, + "conditions": "WOO_TRANSIT_17_COND", + "description": "WOO_TRANSIT_17_DESC", + "id": 17, + "location": "Lighthouse", + "name": "WOO_TRANSIT_17", + "target": "5704e4dad2720bb55b8b4567", + "time": 30 + } + ], "users_gather_seconds": 0, "users_spawn_seconds_n": 120, "users_spawn_seconds_n2": 200, "users_summon_seconds": 0, - "waves": [ - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneClearVill", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 2, - "slots_min": 1, - "time_max": 100, - "time_min": 55 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneHouse", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 1, - "slots_max": 2, - "slots_min": 0, - "time_max": 125, - "time_min": 120 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneScavBase2", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 2, - "slots_max": 2, - "slots_min": 0, - "time_max": 499, - "time_min": 288 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneHouse", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 3, - "slots_max": 2, - "slots_min": 1, - "time_max": 700, - "time_min": 400 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneWoodCutter", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 4, - "slots_max": 1, - "slots_min": 0, - "time_max": 800, - "time_min": 700 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneHouse", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 5, - "slots_max": 1, - "slots_min": 0, - "time_max": 1000, - "time_min": 800 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneWoodCutter", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 6, - "slots_max": 0, - "slots_min": 0, - "time_max": 1300, - "time_min": 1000 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneBigRocks", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 7, - "slots_max": 0, - "slots_min": 0, - "time_max": 60, - "time_min": 30 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneRoad", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 8, - "slots_max": 0, - "slots_min": 0, - "time_max": 9, - "time_min": 0 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneHighRocks", - "WildSpawnType": "marksman", - "isPlayers": false, - "number": 9, - "slots_max": 1, - "slots_min": 1, - "time_max": 31, - "time_min": 20 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneMiniHouse", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 2, - "slots_min": 0, - "time_max": 160, - "time_min": 140 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneBigRocks", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 1, - "slots_min": 0, - "time_max": 400, - "time_min": 350 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "ZoneRoad", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 3, - "slots_min": 0, - "time_max": 250, - "time_min": 180 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 3, - "slots_min": 2, - "time_max": 120, - "time_min": 0 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 5, - "slots_min": 2, - "time_max": 180, - "time_min": 150 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 6, - "slots_min": 2, - "time_max": 210, - "time_min": 180 - }, - { - "BotPreset": "easy", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 6, - "slots_min": 2, - "time_max": 600, - "time_min": 400 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 6, - "slots_min": 2, - "time_max": 800, - "time_min": 600 - }, - { - "BotPreset": "hard", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 5, - "slots_min": 0, - "time_max": 1100, - "time_min": 900 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": true, - "number": 0, - "slots_max": 5, - "slots_min": 1, - "time_max": 420, - "time_min": 400 - }, - { - "BotPreset": "normal", - "BotSide": "Savage", - "OpenZones": "", - "SpawnPoints": "", - "WildSpawnType": "assault", - "isPlayers": false, - "number": 0, - "slots_max": 1, - "slots_min": 0, - "time_max": -1, - "time_min": -1 - } - ] + "waves": [] } From fdc6a09641eaa9b1fe0b203aaaafae91078efdaf Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 13:18:27 +0100 Subject: [PATCH 006/203] fix: bump sptVersion for 3.10.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae55b3a6..4c5c4cdb 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "main": "src/mod.js", "license": "MIT", "author": "Trap", - "sptVersion": "3.9.x", + "sptVersion": "3.10.x", "scripts": { "dev:install": "npm run build && npm run build:client && npm run prepare:files && node scripts/install-files.js", "git:check:status": "bash scripts/check-git-status.sh", From 65f1d0958ddccdd21eae458657a063fdd45583d8 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 13:20:40 +0100 Subject: [PATCH 007/203] fix: migration of code for 3.10.x --- src/fix-repeatable-quests.ts | 4 +- src/helpers.ts | 15 +++--- src/path-to-tarkov-controller.ts | 81 ++++++++++++++++---------------- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/fix-repeatable-quests.ts b/src/fix-repeatable-quests.ts index a590aee2..33320531 100644 --- a/src/fix-repeatable-quests.ts +++ b/src/fix-repeatable-quests.ts @@ -1,5 +1,5 @@ import type { RepeatableQuestGenerator } from '@spt/generators/RepeatableQuestGenerator'; -import type { TraderInfo } from '@spt/models/eft/common/tables/IBotBase'; +import type { ITraderInfo } from '@spt/models/eft/common/tables/IBotBase'; import type { IRepeatableQuest } from '@spt/models/eft/common/tables/IRepeatableQuests'; import type { IRepeatableQuestConfig } from '@spt/models/spt/config/IQuestConfig'; import type { IQuestTypePool } from '@spt/models/spt/repeatable/IQuestTypePool'; @@ -18,7 +18,7 @@ export const fixRepeatableQuests = (container: DependencyContainer): void => { repeatableQuestGenerator.generateRepeatableQuest = ( pmcLevel: number, - pmcTradersInfo: Record, + pmcTradersInfo: Record, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig, ): IRepeatableQuest => { diff --git a/src/helpers.ts b/src/helpers.ts index 8e74fe91..70b864ad 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,5 +1,5 @@ import type { RouteAction } from '@spt/di/Router'; -import type { Exit, SpawnPointParam } from '@spt/models/eft/common/ILocationBase'; +import type { IExit, ISpawnPointParam } from '@spt/models/eft/common/ILocationBase'; import type { IHideoutArea } from '@spt/models/eft/hideout/IHideoutArea'; import type { DatabaseServer } from '@spt/servers/DatabaseServer'; import type { StaticRouterModService } from '@spt/services/mod/staticRouter/StaticRouterModService'; @@ -13,7 +13,7 @@ import { VANILLA_STASH_IDS, } from './config'; import { isDigit, isLetter } from './utils'; -import type { Item } from '@spt/models/eft/common/tables/IItem'; +import type { IItem } from '@spt/models/eft/common/tables/IItem'; export function checkAccessVia(access_via: AccessVia, value: string): boolean { return access_via === '*' || access_via[0] === '*' || access_via.includes(value); @@ -35,7 +35,7 @@ export const createSpawnPoint = ( pos: SpawnPoint['Position'], rot: number, spawnId: string, -): SpawnPointParam => { +): ISpawnPointParam => { return { Id: spawnId, Position: getPosition(pos), @@ -60,7 +60,7 @@ export const createSpawnPoint = ( }; }; -export const createExitPoint = (name: string): Exit => { +export const createExitPoint = (name: string): IExit => { const Chance = 100; const Count = 0; const ExfiltrationTime = 10; @@ -104,7 +104,8 @@ export const changeRestrictionsInRaid = (config: Config, db: DatabaseServer): vo globals?.config.RestrictionsInRaid.forEach(payload => { if (restrictionsConfig[payload.TemplateId]) { - payload.Value = restrictionsConfig[payload.TemplateId].Value; + payload.MaxInRaid = restrictionsConfig[payload.TemplateId].Value; + payload.MaxInLobby = Math.max(payload.MaxInRaid, payload.MaxInLobby); } }); }; @@ -242,7 +243,7 @@ export const isVanillaSptId = (id: string): boolean => { return true; }; -const isStashLink = (item: Item): boolean => { +const isStashLink = (item: IItem): boolean => { return ( Boolean(item._id) && Boolean(item._tpl) && @@ -251,7 +252,7 @@ const isStashLink = (item: Item): boolean => { ); }; -export const retrieveMainStashIdFromItems = (items: Item[]): string | null => { +export const retrieveMainStashIdFromItems = (items: IItem[]): string | null => { for (const item of items) { if (isStashLink(item) && isVanillaSptId(item._id)) { return item._id; diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 15ecd5e1..f21a1b94 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -25,17 +25,17 @@ import { deepClone, shuffle } from './utils'; import { resolveMapNameFromLocation } from './map-name-resolver'; import type { ILocationsGenerateAllResponse, - Path, + IPath, } from '@spt/models/eft/common/ILocationsSourceDestinationBase'; import type { ILocations } from '@spt/models/spt/server/ILocations'; -import type { IGetLocationRequestData } from '@spt/models/eft/location/IGetLocationRequestData'; +// import type { IGetLocationRequestData } from '@spt/models/eft/location/IGetLocationRequestData'; import type { DataCallbacks } from '@spt/callbacks/DataCallbacks'; import type { IEmptyRequestData } from '@spt/models/eft/common/IEmptyRequestData'; import type { ITemplateItem } from '@spt/models/eft/common/tables/ITemplateItem'; import type { IHideoutArea } from '@spt/models/eft/hideout/IHideoutArea'; -import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; +// import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBodyResponseData'; -import type { Inventory } from '@spt/models/eft/common/tables/IBotBase'; +import type { IInventory } from '@spt/models/eft/common/tables/IBotBase'; import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; @@ -117,7 +117,7 @@ export class PathToTarkovController { */ cleanupLegacySecondaryStashesLink(sessionId: string): void { const profile: Profile = this.saveServer.getProfile(sessionId); - const inventory = profile.characters.pmc.Inventory as Inventory | undefined; + const inventory = profile.characters.pmc.Inventory as IInventory | undefined; const secondaryStashIds: string[] = [ EMPTY_STASH.id, ...this.getConfig(sessionId).hideout_secondary_stashes.map(config => config.id), @@ -276,36 +276,37 @@ export class PathToTarkovController { } }); - const newPaths: Path[] = []; // TODO: keep the original path (with filter on locked maps) + const newPaths: IPath[] = []; // TODO: keep the original path (with filter on locked maps) return { ...result, locations, paths: newPaths }; }; } - private createGetLocation( - originalFn: ( - url: string, - info: IGetLocationRequestData, - sessionId: string, - ) => IGetBodyResponseData, - ) { - return ( - url: string, - info: IGetLocationRequestData, - sessionId: string, - ): IGetBodyResponseData => { - const offraidPosition = this.getOffraidPosition(sessionId); - const rawLocationBase = originalFn(url, info, sessionId) as any as string; - const parsed = JSON.parse(rawLocationBase); - const locationBase: ILocationBase = parsed.data; - - // This will handle spawnpoints and exfils for SPT - // For fika, check the other call of `updateSpawnPoints` - this.updateSpawnPoints(locationBase, offraidPosition, sessionId); - this.updateLocationBaseExits(locationBase, sessionId); - - return JSON.stringify(parsed) as any; - }; - } + // private createGetLocation( + // originalFn: ( + // url: string, + // info: IEmptyRequestData, + // sessionId: string, + // ) => IGetBodyResponseData, + // ) { + // return ( + // url: string, + // info: IEmptyRequestData, + // sessionId: string, + // ): IGetBodyResponseData => { + // const offraidPosition = this.getOffraidPosition(sessionId); + // const rawLocationBase = originalFn(url, info, sessionId) as any as string; + // const parsed = JSON.parse(rawLocationBase); + // const locationResponse: ILocationsGenerateAllResponse = parsed.data; + + // // TODO: iterate over MAPLIST to get locations + // // This will handle spawnpoints and exfils for SPT + // // For fika, check the other call of `updateSpawnPoints` + // this.updateSpawnPoints(locationResponse.locations, offraidPosition, sessionId); + // this.updateLocationBaseExits(locationBase, sessionId); + + // return JSON.stringify(parsed) as any; + // }; + // } private createGetTemplateItems( originalFn: (url: string, info: IEmptyRequestData, sessionId: string) => string, @@ -438,16 +439,16 @@ export class PathToTarkovController { { frequency: 'Always' }, ); - this.container.afterResolution( - 'LocationCallbacks', - (_t, result): void => { - const locationCallbacks = Array.isArray(result) ? result[0] : result; + // this.container.afterResolution( + // 'LocationCallbacks', + // (_t, result): void => { + // const locationCallbacks = Array.isArray(result) ? result[0] : result; - const originalGet = locationCallbacks.getLocation.bind(locationCallbacks); - locationCallbacks.getLocation = this.createGetLocation(originalGet); - }, - { frequency: 'Always' }, - ); + // const originalGet = locationCallbacks.getLocationData.bind(locationCallbacks); + // locationCallbacks.getLocationData = this.createGetLocation(originalGet); + // }, + // { frequency: 'Always' }, + // ); this.container.afterResolution( 'DataCallbacks', From f886cc22c04c7ef526fb164f388d68c7dfca16e6 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 13:20:58 +0100 Subject: [PATCH 008/203] fix: disable remporary the fir tweak --- src/keep-fir-tweak.ts | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/keep-fir-tweak.ts b/src/keep-fir-tweak.ts index 06c911fc..9fccdf2d 100644 --- a/src/keep-fir-tweak.ts +++ b/src/keep-fir-tweak.ts @@ -1,6 +1,6 @@ -import type { MatchController } from '@spt/controllers/MatchController'; -import type { IPmcData } from '@spt/models/eft/common/IPmcData'; -import type { Item } from '@spt/models/eft/common/tables/IItem'; +// import type { MatchController } from '@spt/controllers/MatchController'; +// import type { IPmcData } from '@spt/models/eft/common/IPmcData'; +import type { IItem } from '@spt/models/eft/common/tables/IItem'; import type { SaveServer } from '@spt/servers/SaveServer'; import type { DependencyContainer } from 'tsyringe'; @@ -10,7 +10,7 @@ type PTTInstance = { readonly debug: (data: string) => void; }; -const setSpawnedInSessionOnAllItems = (items: Item[]): number => { +const setSpawnedInSessionOnAllItems = (items: IItem[]): number => { let counter = 0; items.forEach(item => { @@ -31,22 +31,26 @@ const setSpawnedInSessionOnAllItems = (items: Item[]): number => { export const enableKeepFoundInRaidTweak = (ptt: PTTInstance): void => { const saveServer = ptt.container.resolve('SaveServer'); - ptt.container.afterResolution( - 'MatchController', - (_t, result): void => { - const matchController = Array.isArray(result) ? result[0] : result; + // TODO: fix + void saveServer; + void setSpawnedInSessionOnAllItems; - const originalEndOfflineRaid = matchController.endOfflineRaid.bind(matchController); + // ptt.container.afterResolution( + // 'MatchController', + // (_t, result): void => { + // const matchController = Array.isArray(result) ? result[0] : result; - matchController.endOfflineRaid = (info, sessionId) => { - originalEndOfflineRaid(info, sessionId); + // const originalEndOfflineRaid = matchController.endOfflineRaid.bind(matchController); - const profile = saveServer.getProfile(sessionId); - const pmcData: IPmcData = profile.characters.pmc; - const count = setSpawnedInSessionOnAllItems(pmcData.Inventory.items); - ptt.debug(`added 'SpawnedInSession' flag on ${count} items`); - }; - }, - { frequency: 'Always' }, - ); + // matchController.endOfflineRaid = (info, sessionId) => { + // originalEndOfflineRaid(info, sessionId); + + // const profile = saveServer.getProfile(sessionId); + // const pmcData: IPmcData = profile.characters.pmc; + // const count = setSpawnedInSessionOnAllItems(pmcData.Inventory.items); + // ptt.debug(`added 'SpawnedInSession' flag on ${count} items`); + // }; + // }, + // { frequency: 'Always' }, + // ); }; From a1184cca4a3a9610a1b0d0e47727780c7b7859d5 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 14:02:06 +0100 Subject: [PATCH 009/203] refactor: remove unused getAllStashByIds method --- src/stash-controller.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/stash-controller.ts b/src/stash-controller.ts index 49fc0e2b..7bd886f8 100644 --- a/src/stash-controller.ts +++ b/src/stash-controller.ts @@ -14,8 +14,6 @@ import { deepClone } from './utils'; export const getTemplateIdFromStashId = (stashId: string): string => `template_${stashId}`; const getGridIdFromStashId = (stashId: string): string => `grid_${stashId}`; -type IndexedStashByIds = Record; - export class StashController { constructor( private getConfig: ConfigGetter, @@ -126,20 +124,6 @@ export class StashController { ); } - private getAllStashByIds( - profile: Profile, - stashConfigs: Omit[], - ): IndexedStashByIds { - const initialAcc: IndexedStashByIds = { [getMainStashId(profile)]: true }; - - return stashConfigs.reduce((acc, stashConfig) => { - return { - ...acc, - [stashConfig.id]: true, - }; - }, initialAcc); - } - updateStash(offraidPosition: string, sessionId: string): void { const mainStashAvailable = this.getMainStashAvailable(offraidPosition, sessionId); const secondaryStash = this.getSecondaryStash(offraidPosition, sessionId); From c9f17f762c9a23d12da0fa03b0990d9d5566ad7f Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 14:18:46 +0100 Subject: [PATCH 010/203] refactor: no need to expose prepareGroundZeroHigh function --- src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 79b12298..d30ca881 100644 --- a/src/config.ts +++ b/src/config.ts @@ -224,7 +224,7 @@ export const MAPLIST = [ ]; // sandbox_high is a special map for high level players (> 20) -export const prepareGroundZeroHigh = (maps: ByMap): ByMap => { +const prepareGroundZeroHigh = (maps: ByMap): ByMap => { if (maps.sandbox && !maps.sandbox_high) { return { ...maps, From 9c9fee9ecc81d6c6acb1fbd75faac61ec260ae09 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 15:57:13 +0100 Subject: [PATCH 011/203] fix: migrate stash configs to work with mongo ids --- package.json | 2 +- src/config-analysis.ts | 14 ++++----- src/config.ts | 49 ++++++++++++++++++++++++----- src/helpers.ts | 45 +++++++++------------------ src/mod.ts | 5 --- src/path-to-tarkov-controller.ts | 44 +++----------------------- src/stash-controller.ts | 29 ++++++++--------- src/utils.ts | 53 ++++++++++++++++++++++++++++++-- tests/utils.test.ts | 32 +++++++++++++++++++ 9 files changed, 165 insertions(+), 108 deletions(-) create mode 100644 tests/utils.test.ts diff --git a/package.json b/package.json index 4c5c4cdb..9508cd8f 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "build:client": "cd PTT-Extracts && dotnet.exe build", "clean:client": "cd PTT-Extracts && dotnet.exe clean && rimraf bin obj", "test:all": "npm run lint:all && npm run test && npm run build:release", - "test": "npx jest", + "test": "npx jest --verbose", "test:watch": "npx jest --watch", "test:ci": "npm run build && npm run test && npm run lint:all && npm run build:doc:all-exfils" }, diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 000f0128..8c40d15a 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -85,7 +85,7 @@ const getErrorsForOffraidPositions = (config: Config): string[] => { config.hideout_secondary_stashes.forEach(secondaryStashConfig => { errors.push( ...checkAccessViaErrors( - `hideout_secondary_stashes.${secondaryStashConfig.id}.access_via`, + `hideout_secondary_stashes.${secondaryStashConfig.name}.access_via`, secondaryStashConfig.access_via, config, ), @@ -153,19 +153,19 @@ const getErrorsForExfils = (config: Config): string[] => { // Note: offraidPosition is already checked by `getErrorsForOffraidPositions` const getErrorsSecondaryStashes = (config: Config): string[] => { const errors: string[] = []; - const ids: Set = new Set(); + const names: Set = new Set(); config.hideout_secondary_stashes.forEach(stashConfig => { - if (stashConfig.id === EMPTY_STASH.id) { + if (stashConfig.name === EMPTY_STASH.name) { errors.push( - `secondary stash ${stashConfig.id} is a special reserved name, please choose another.`, + `secondary stash ${stashConfig.name} is a special reserved name, please choose another.`, ); } - if (ids.has(stashConfig.id)) { - errors.push(`duplicated secondary stash ${stashConfig.id} found`); + if (names.has(stashConfig.name)) { + errors.push(`duplicated secondary stash ${stashConfig.name} found`); } - ids.add(stashConfig.id); + names.add(stashConfig.name); }); return errors; diff --git a/src/config.ts b/src/config.ts index d30ca881..0ff2e147 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,6 @@ import type { ISptProfile } from '@spt/models/eft/profile/ISptProfile'; import { join } from 'path'; -import { deepClone, fileExists, readJsonFile, writeJsonFile } from './utils'; +import { deepClone, fileExists, getPTTMongoId, readJsonFile, writeJsonFile } from './utils'; type ByMap = { factory4_day: T; @@ -47,6 +47,15 @@ export type SpawnConfig = ByMap<{ * config.json */ export type StashConfig = { + mongoId: string; // generated from name + mongoGridId: string; // generated from name + mongoTemplateId: string; // generated from name + name: string; // should be uniq + size: number; + access_via: AccessVia; +}; + +export type RawStashConfig = { id: string; size: number; access_via: AccessVia; @@ -129,7 +138,7 @@ export type OverrideByProfiles = ByProfileId<{ hideout_main_stash_access_via?: AccessVia; }>; -export type Config = { +type RawConfig = { enabled: boolean; debug?: boolean; override_by_profiles?: OverrideByProfiles; @@ -148,13 +157,17 @@ export type Config = { restrictions_in_raid: Record; offraid_regen_config: OffraidRegenConfig; hideout_main_stash_access_via: AccessVia; - hideout_secondary_stashes: StashConfig[]; + hideout_secondary_stashes: RawStashConfig[]; traders_access_restriction: boolean; traders_config: TradersConfig; exfiltrations: Exfiltrations; infiltrations: Infiltrations; }; +export type Config = Omit & { + hideout_secondary_stashes: StashConfig[]; +}; + export type PathToTarkovReloadedTooltipsConfig = { language?: string; moddedTraderCompat?: boolean; @@ -199,10 +212,27 @@ export const VANILLA_STASH_IDS = [ '6602bcf19cc643f44a04274b', // Unheard ]; -export const EMPTY_STASH: Omit = { +const toStashConfig = (rawStashConfig: RawStashConfig): StashConfig => { + const name = rawStashConfig.id; // the id is actually the name (this is to avoid breaking changes in the ptt configs) + const mongoId = getPTTMongoId(name); + const mongoTemplateId = getPTTMongoId(`template_${name}`); + const mongoGridId = getPTTMongoId(`grid_${name}`); + + return { + name, + size: rawStashConfig.size, + access_via: rawStashConfig.access_via, + mongoId, + mongoTemplateId, + mongoGridId, + }; +}; + +export const EMPTY_STASH = toStashConfig({ id: 'PathToTarkov_Empty_Stash', size: 0, -}; + access_via: [], // not used but this simplify typing +}); export const SLOT_ID_HIDEOUT = 'hideout'; export const SLOT_ID_LOCKED_STASH = 'ptt_locked_stash'; @@ -235,7 +265,7 @@ const prepareGroundZeroHigh = (maps: ByMap): ByMap => { return maps; }; -export const processConfig = (originalConfig: Config): Config => { +export const processConfig = (originalConfig: RawConfig): Config => { const config = deepClone(originalConfig); config.exfiltrations = prepareGroundZeroHigh(config.exfiltrations); @@ -246,7 +276,12 @@ export const processConfig = (originalConfig: Config): Config => { ); }); - return config; + const stashConfigs: StashConfig[] = config.hideout_secondary_stashes.map(toStashConfig); + + return { + ...config, + hideout_secondary_stashes: stashConfigs, + }; }; export const processSpawnConfig = (spawnConfig: SpawnConfig): SpawnConfig => { diff --git a/src/helpers.ts b/src/helpers.ts index 70b864ad..4084fd74 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -5,14 +5,7 @@ import type { DatabaseServer } from '@spt/servers/DatabaseServer'; import type { StaticRouterModService } from '@spt/services/mod/staticRouter/StaticRouterModService'; import type { AccessVia, Config, PositionXYZ, Profile, SpawnPoint, StashConfig } from './config'; -import { - EMPTY_STASH, - SLOT_ID_HIDEOUT, - SLOT_ID_LOCKED_STASH, - STANDARD_STASH_ID, - VANILLA_STASH_IDS, -} from './config'; -import { isDigit, isLetter } from './utils'; +import { EMPTY_STASH, SLOT_ID_HIDEOUT, SLOT_ID_LOCKED_STASH, VANILLA_STASH_IDS } from './config'; import type { IItem } from '@spt/models/eft/common/tables/IItem'; export function checkAccessVia(access_via: AccessVia, value: string): boolean { @@ -199,7 +192,7 @@ const getAllStashByIds = ( return stashConfigs.reduce((acc, stashConfig) => { return { ...acc, - [stashConfig.id]: true, + [stashConfig.mongoId]: true, }; }, initialAcc); }; @@ -224,25 +217,6 @@ export const setInventorySlotIds = ( }); }; -// the length should be 24 -const SPT_ID_LENGTH = STANDARD_STASH_ID.length; - -export const isVanillaSptId = (id: string): boolean => { - if (id.length !== SPT_ID_LENGTH) { - return false; - } - - for (const char of id) { - const isValidChar = isLetter(char) || isDigit(char); - - if (!isValidChar) { - return false; - } - } - - return true; -}; - const isStashLink = (item: IItem): boolean => { return ( Boolean(item._id) && @@ -252,9 +226,20 @@ const isStashLink = (item: IItem): boolean => { ); }; -export const retrieveMainStashIdFromItems = (items: IItem[]): string | null => { +const isPTTMongoId = (id: string, stashes: StashConfig[]): boolean => { + const foundId = stashes.find(stash => { + return id === stash.mongoId || id === stash.mongoTemplateId || id === stash.mongoGridId; + }); + + return Boolean(foundId); +}; + +export const retrieveMainStashIdFromItems = ( + items: IItem[], + stashes: StashConfig[], +): string | null => { for (const item of items) { - if (isStashLink(item) && isVanillaSptId(item._id)) { + if (isStashLink(item) && !isPTTMongoId(item._id, stashes)) { return item._id; } } diff --git a/src/mod.ts b/src/mod.ts index 0ba4a22c..5c534ff0 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -141,7 +141,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { this.container = container; const db = container.resolve('DatabaseServer'); const saveServer = container.resolve('SaveServer'); - const profiles = saveServer.getProfiles(); const quests = db.getTables()?.templates?.quests; if (!quests) { @@ -185,10 +184,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { this.pathToTarkovController.tradersController.initTraders(this.config); - Object.keys(profiles).forEach(profileId => { - this.pathToTarkovController.cleanupLegacySecondaryStashesLink(profileId); - }); - const nbAddedTemplates = this.pathToTarkovController.stashController.initSecondaryStashTemplates( this.config.hideout_secondary_stashes, diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index f21a1b94..db911d51 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -6,7 +6,7 @@ import type { DatabaseServer } from '@spt/servers/DatabaseServer'; import type { SaveServer } from '@spt/servers/SaveServer'; import type { Config, ConfigGetter, MapName, Profile, SpawnConfig } from './config'; -import { EMPTY_STASH, MAPLIST, VANILLA_STASH_IDS } from './config'; +import { MAPLIST, VANILLA_STASH_IDS } from './config'; import { changeRestrictionsInRaid, @@ -17,7 +17,7 @@ import { PTT_INFILTRATION, } from './helpers'; -import { getTemplateIdFromStashId, StashController } from './stash-controller'; +import { StashController } from './stash-controller'; import { TradersController } from './traders-controller'; import type { DependencyContainer } from 'tsyringe'; import type { LocationController } from '@spt/controllers/LocationController'; @@ -35,7 +35,6 @@ import type { ITemplateItem } from '@spt/models/eft/common/tables/ITemplateItem' import type { IHideoutArea } from '@spt/models/eft/hideout/IHideoutArea'; // import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBodyResponseData'; -import type { IInventory } from '@spt/models/eft/common/tables/IBotBase'; import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; @@ -112,41 +111,6 @@ export class PathToTarkovController { this.spawnConfig = spawnConfig; } - /** - * This is for upgrading profiles for PTT versions < 5.2.0 - */ - cleanupLegacySecondaryStashesLink(sessionId: string): void { - const profile: Profile = this.saveServer.getProfile(sessionId); - const inventory = profile.characters.pmc.Inventory as IInventory | undefined; - const secondaryStashIds: string[] = [ - EMPTY_STASH.id, - ...this.getConfig(sessionId).hideout_secondary_stashes.map(config => config.id), - ]; - - if (!inventory) { - return; - } - - let stashLinkRemoved = 0; - - inventory.items = inventory.items.filter(item => { - if ( - secondaryStashIds.includes(item._id) && - item._tpl !== getTemplateIdFromStashId(item._id) - ) { - stashLinkRemoved = stashLinkRemoved + 1; - return false; - } - - return true; - }); - - if (stashLinkRemoved > 0) { - this.debug(`[${sessionId}] cleaned up ${stashLinkRemoved} legacy stash links`); - this.saveServer.saveProfile(sessionId); - } - } - // on game start (or profile creation) initPlayer(sessionId: string, _isFreshProfile: boolean): void { // warning: this is not dynamic because of the mutation of the db @@ -281,6 +245,7 @@ export class PathToTarkovController { }; } + // TODO: iterate over MAPLIST to get locations // private createGetLocation( // originalFn: ( // url: string, @@ -297,8 +262,7 @@ export class PathToTarkovController { // const rawLocationBase = originalFn(url, info, sessionId) as any as string; // const parsed = JSON.parse(rawLocationBase); // const locationResponse: ILocationsGenerateAllResponse = parsed.data; - - // // TODO: iterate over MAPLIST to get locations + // // // This will handle spawnpoints and exfils for SPT // // For fika, check the other call of `updateSpawnPoints` // this.updateSpawnPoints(locationResponse.locations, offraidPosition, sessionId); diff --git a/src/stash-controller.ts b/src/stash-controller.ts index 7bd886f8..c3cfcc60 100644 --- a/src/stash-controller.ts +++ b/src/stash-controller.ts @@ -5,15 +5,11 @@ import { EMPTY_STASH, STANDARD_STASH_ID } from './config'; import { checkAccessVia, getMainStashId, - isVanillaSptId, retrieveMainStashIdFromItems, setInventorySlotIds, } from './helpers'; import { deepClone } from './utils'; -export const getTemplateIdFromStashId = (stashId: string): string => `template_${stashId}`; -const getGridIdFromStashId = (stashId: string): string => `grid_${stashId}`; - export class StashController { constructor( private getConfig: ConfigGetter, @@ -32,19 +28,18 @@ export class StashController { let nbAddedTemplates = 0; - stashConfigs.forEach(({ id, size }) => { + stashConfigs.forEach(({ name, mongoTemplateId, mongoGridId, size }) => { const newTemplate = deepClone(standardTemplate); - const templateId = getTemplateIdFromStashId(id); - newTemplate._id = templateId; - newTemplate._name = `${id} of size ${size}`; + newTemplate._id = mongoTemplateId; + newTemplate._name = `${name} of size ${size}`; const grid = newTemplate?._props?.Grids?.[0]; const gridProps = grid?._props; if (gridProps) { - grid._id = getGridIdFromStashId(id); - grid._parent = templateId; + grid._id = mongoGridId; + grid._parent = mongoTemplateId; gridProps.cellsV = size; } else { throw new Error('Path To Tarkov: cannot set size on custom stash template'); @@ -71,8 +66,9 @@ export class StashController { const initialMainStashId = profile.PathToTarkov.mainStashId; - if (!initialMainStashId || !isVanillaSptId(initialMainStashId)) { - const mainStashId = retrieveMainStashIdFromItems(pmc.Inventory.items); + if (!initialMainStashId) { + const allStashConfigs = [EMPTY_STASH, ...this.getConfig(sessionId).hideout_secondary_stashes]; + const mainStashId = retrieveMainStashIdFromItems(pmc.Inventory.items, allStashConfigs); profile.PathToTarkov.mainStashId = mainStashId ?? pmc.Inventory.stash; } } @@ -84,12 +80,13 @@ export class StashController { inventory.stash = mainStashId; } - private setSecondaryStash(stashId: string, profile: Profile): void { + private setSecondaryStash(stash: Omit, profile: Profile): void { + const stashId = stash.mongoId; + const templateId = stash.mongoTemplateId; + const inventory = profile.characters.pmc.Inventory; inventory.stash = stashId; - const templateId = getTemplateIdFromStashId(stashId); - if (!inventory.items.find(item => item._id === stashId && item._tpl === templateId)) { inventory.items.push({ _id: stashId, _tpl: templateId }); } @@ -132,7 +129,7 @@ export class StashController { if (mainStashAvailable) { this.setMainStash(profile); } else { - this.setSecondaryStash(secondaryStash.id, profile); + this.setSecondaryStash(secondaryStash, profile); } const inventory = profile.characters.pmc.Inventory; diff --git a/src/utils.ts b/src/utils.ts index f15ebfc5..fa64daf1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,5 @@ import { readFileSync, existsSync, writeFileSync } from 'fs'; +import { createHash } from 'crypto'; export const fileExists = (path: string): boolean => { return existsSync(path); @@ -106,14 +107,22 @@ export const isEmptyArray = (arr: T[] | undefined): boolean => { return Boolean(arr && arr.length > 0); }; -export const isLetter = (char: string): boolean => { +export const isLetterChar = (char: string): boolean => { return char.length === 1 && char.toUpperCase() !== char.toLowerCase(); }; -export const isDigit = (char: string): boolean => { +export const isLowerLetterChar = (char: string): boolean => { + return isLetterChar(char) && char.toLowerCase() === char; +}; + +export const isDigitChar = (char: string): boolean => { return char.length === 1 && char >= '0' && char <= '9'; }; +export const isHexaChar = (char: string): boolean => { + return isDigitChar(char) || (char.length === 1 && char >= 'a' && char <= 'f'); +}; + export const ensureArray = (x: T | T[]): T[] => { if (Array.isArray(x)) { return x; @@ -121,3 +130,43 @@ export const ensureArray = (x: T | T[]): T[] => { return [x]; }; + +/** + * Mongo Ids + */ +const MONGO_ID_LENGTH = 24; + +export const isValidMongoId = (id: string): boolean => { + if (id.length !== MONGO_ID_LENGTH) { + return false; + } + + for (const char of id) { + const isValidChar = isHexaChar(char); + + if (!isValidChar) { + return false; + } + } + + return true; +}; + +const sha1 = (data: string): string => { + const hash = createHash('sha1'); + hash.update(data); + return hash.digest('hex'); +}; + +export const MONGO_ID_PTT_PREFIX = 'deadbeef'; + +/** + * This function is used to generate predictible mongo ids + * a "deadbeef" prefix is added to help debugging profiles + */ +export const getPTTMongoId = (data: string): string => { + const stripLength = MONGO_ID_LENGTH - MONGO_ID_PTT_PREFIX.length; + const strippedHash = sha1(data).substring(0, stripLength); + + return MONGO_ID_PTT_PREFIX + strippedHash; +}; diff --git a/tests/utils.test.ts b/tests/utils.test.ts new file mode 100644 index 00000000..248ef2bc --- /dev/null +++ b/tests/utils.test.ts @@ -0,0 +1,32 @@ +import { getPTTMongoId, isValidMongoId } from '../src/utils'; + +describe('PTT utils', () => { + describe('getPTTMongoId', () => { + it('should get a string of length 24', () => { + expect(getPTTMongoId('').length).toBe(24); + expect(getPTTMongoId('test').length).toBe(24); + }); + + it('should get a valid mongo id', () => { + const mongoId = getPTTMongoId('test'); + expect(isValidMongoId(mongoId)).toBe(true); + }); + + it('should check that ids are not equals for 2 different inputs data', () => { + const mongoId1 = getPTTMongoId('test1'); + const mongoId2 = getPTTMongoId('test2'); + expect(mongoId1).not.toBe(mongoId2); + }); + + it('should check that the function is pure', () => { + expect(getPTTMongoId('test')).toBe(getPTTMongoId('test')); + expect(getPTTMongoId('test1')).toBe(getPTTMongoId('test1')); + expect(getPTTMongoId('test2')).toBe(getPTTMongoId('test2')); + expect(getPTTMongoId('test3')).toBe(getPTTMongoId('test3')); + }); + + it('should check that the id start with "PTT" preefix', () => { + expect(getPTTMongoId('test').startsWith('deadbeef')).toBe(true); + }); + }); +}); From ecca9778b9df9e2619080412fe68ce575e0092a8 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 30 Nov 2024 19:19:48 +0100 Subject: [PATCH 012/203] fix: migrate event-watch to work with the new MatchController --- src/event-watcher.ts | 145 +++++++++++++++++++++++++------------------ src/mod.ts | 2 +- 2 files changed, 87 insertions(+), 60 deletions(-) diff --git a/src/event-watcher.ts b/src/event-watcher.ts index 4abb800d..ad58ebec 100644 --- a/src/event-watcher.ts +++ b/src/event-watcher.ts @@ -1,12 +1,14 @@ import type { StaticRoutePeeker } from './helpers'; import type { EndOfRaidPayload, PTTInstance } from './end-of-raid-controller'; import type { SaveServer } from '@spt/servers/SaveServer'; +import type { IStartLocalRaidRequestData } from '@spt/models/eft/match/IStartLocalRaidRequestData'; +import type { IEndLocalRaidRequestData } from '@spt/models/eft/match/IEndLocalRaidRequestData'; +import type { MatchController } from '@spt/controllers/MatchController'; +import type { DependencyContainer } from 'tsyringe'; type EndOfRaidCallback = (payload: EndOfRaidPayload) => void; type RaidCache = { - saved: boolean; - endOfRaid: boolean; sessionId: string | null; currentLocationName: string | null; exitName: string | null | undefined; @@ -14,12 +16,11 @@ type RaidCache = { }; const createInitialRaidCache = (sessionId: string): RaidCache => ({ - saved: false, - endOfRaid: false, sessionId: sessionId, currentLocationName: null, exitName: undefined, isPlayerScav: null, + // TODO: add the exitStatus }); export class EventWatcher { @@ -53,7 +54,7 @@ export class EventWatcher { } private watchOnGameStart(staticRoutePeeker: StaticRoutePeeker): void { - staticRoutePeeker.watchRoute('/client/game/start', (url, info: unknown, sessionId) => { + staticRoutePeeker.watchRoute('/client/game/start', (url, data: unknown, sessionId) => { this.initRaidCache(sessionId); const profile = this.saveServer.getProfile(sessionId); @@ -75,7 +76,7 @@ export class EventWatcher { } private watchOnProfileCreated(staticRoutePeeker: StaticRoutePeeker): void { - staticRoutePeeker.watchRoute('/client/game/profile/create', (url, info: unknown, sessionId) => { + staticRoutePeeker.watchRoute('/client/game/profile/create', (url, data: unknown, sessionId) => { this.initRaidCache(sessionId); this.ptt.pathToTarkovController.initPlayer(sessionId, true); @@ -85,73 +86,99 @@ export class EventWatcher { }); } - private watchStartOfRaid(staticRoutePeeker: StaticRoutePeeker): void { - staticRoutePeeker.watchRoute( - '/client/raid/configuration', - (url, info: { location: string }, sessionId) => { - this.initRaidCache(sessionId); - const raidCache = this.getRaidCache(sessionId); + private watchStartOfRaid(container: DependencyContainer): void { + container.afterResolution( + 'MatchController', + (_t, result): void => { + const matchController = Array.isArray(result) ? result[0] : result; + const originalStartLocalRaid = matchController.startLocalRaid.bind(matchController); - if (!raidCache) { - return; - } + matchController.startLocalRaid = (sessionId: string, data: IStartLocalRaidRequestData) => { + const originalResult = originalStartLocalRaid(sessionId, data); - raidCache.currentLocationName = info.location; - this.ptt.debug( - `offline raid started on location '${info.location}' with sessionId '${sessionId}'`, - ); + this.initRaidCache(sessionId); + const raidCache = this.getRaidCache(sessionId); + + if (!raidCache) { + this.ptt.logger.error(`no PTT raid cache found when starting the raid`); + return originalResult; + } + + // TODO: remove those lines ? + this.ptt.debug(`playerSide = ${data.playerSide}`); + this.ptt.debug(`mode = ${data.mode}`); + + // TODO: find a way to detect if it's a scav raid + raidCache.isPlayerScav = false; + raidCache.currentLocationName = data.location; + + this.ptt.debug( + `offline raid started on location '${data.location}' with sessionId '${sessionId}'`, + ); + + return originalResult; + }; }, + { frequency: 'Always' }, ); } - private watchSave(staticRoutePeeker: StaticRoutePeeker): void { - staticRoutePeeker.watchRoute( - '/raid/profile/save', - (url, info: { isPlayerScav: boolean }, sessionId: string) => { - const raidCache = this.getRaidCache(sessionId); + // private watchSave(staticRoutePeeker: StaticRoutePeeker): void { + // staticRoutePeeker.watchRoute( + // '/raid/profile/save', + // (url, data: { isPlayerScav: boolean }, sessionId: string) => { + // const raidCache = this.getRaidCache(sessionId); - if (!raidCache) { - return; - } + // if (!raidCache) { + // return; + // } - raidCache.saved = true; - raidCache.isPlayerScav = info.isPlayerScav; + // raidCache.saved = true; + // raidCache.isPlayerScav = data.isPlayerScav; - this.ptt.debug(`profile saved: raidCache.isPlayerScav=${info.isPlayerScav}`); + // this.ptt.debug(`profile saved: raidCache.isPlayerScav=${data.isPlayerScav}`); - if (!raidCache.endOfRaid) { - this.ptt.debug('end of raid: callback execution delayed...'); - return; - } + // if (!raidCache.endOfRaid) { + // this.ptt.debug('end of raid: callback execution delayed...'); + // return; + // } - return this.runEndOfRaidCallback(sessionId); - }, - ); - } + // return this.runEndOfRaidCallback(sessionId); + // }, + // ); + // } + + private watchEndOfRaid(container: DependencyContainer): void { + container.afterResolution( + 'MatchController', + (_t, result): void => { + const matchController = Array.isArray(result) ? result[0] : result; + const originalEndLocalRaid = matchController.endLocalRaid.bind(matchController); + + matchController.endLocalRaid = (sessionId: string, data: IEndLocalRaidRequestData) => { + const originalResult = originalEndLocalRaid(sessionId, data); - private watchEndOfRaid(staticRoutePeeker: StaticRoutePeeker): void { - staticRoutePeeker.watchRoute( - '/client/match/offline/end', - (url, info: { exitName: string | null }, sessionId: string) => { - const raidCache = this.getRaidCache(sessionId); + const raidCache = this.getRaidCache(sessionId); - if (!raidCache) { - return; - } + if (!raidCache) { + this.ptt.logger.error(`no PTT raid cache found`); + return; + } - raidCache.endOfRaid = true; - raidCache.sessionId = sessionId; - raidCache.exitName = info.exitName; + raidCache.sessionId = sessionId; + raidCache.exitName = data.results.exitName; - this.ptt.debug(`end of raid detected for exit '${info.exitName}'`); + const exitStatus = data.results.result; - if (!raidCache.saved) { - this.ptt.debug('end of raid: callback execution delayed on profile save...'); - return; - } + this.ptt.debug( + `end of raid detected for exit '${data.results.exitName}' with status '${exitStatus}'`, + ); + this.runEndOfRaidCallback(sessionId); - return this.runEndOfRaidCallback(sessionId); + return originalResult; + }; }, + { frequency: 'Always' }, ); } @@ -209,12 +236,12 @@ export class EventWatcher { this.endOfRaidCallback = cb; } - public register(staticRoutePeeker: StaticRoutePeeker): void { + public register(staticRoutePeeker: StaticRoutePeeker, container: DependencyContainer): void { this.watchOnGameStart(staticRoutePeeker); this.watchOnProfileCreated(staticRoutePeeker); - this.watchStartOfRaid(staticRoutePeeker); - this.watchSave(staticRoutePeeker); - this.watchEndOfRaid(staticRoutePeeker); + // this.watchSave(staticRoutePeeker); + this.watchStartOfRaid(container); + this.watchEndOfRaid(container); staticRoutePeeker.register(); } diff --git a/src/mod.ts b/src/mod.ts index 5c534ff0..50ebd19a 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -122,7 +122,7 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { const endOfRaidController = new EndOfRaidController(this); eventWatcher.onEndOfRaid(payload => endOfRaidController.end(payload)); - eventWatcher.register(createStaticRoutePeeker(staticRouter)); + eventWatcher.register(createStaticRoutePeeker(staticRouter), container); const tweakFoundInRaid = !this.config.bypass_keep_found_in_raid_tweak; From ca86717a9195174dcb609743b4ed4c32cd4ea109 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 14:26:25 +0100 Subject: [PATCH 013/203] fix: broken spawn points + disable transits --- src/config.ts | 1 + src/event-watcher.ts | 33 +++---------- src/helpers.ts | 1 - src/path-to-tarkov-controller.ts | 80 ++++++++++++++++++++++---------- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/src/config.ts b/src/config.ts index 0ff2e147..59e7041d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -151,6 +151,7 @@ type RawConfig = { workbench_always_enabled: boolean; vanilla_exfils_requirements?: boolean; bypass_exfils_override?: boolean; + bypass_transits_override?: boolean; bypass_uninstall_procedure: boolean; enable_run_through?: boolean; enable_legacy_ptt_api?: boolean; diff --git a/src/event-watcher.ts b/src/event-watcher.ts index ad58ebec..485a7c18 100644 --- a/src/event-watcher.ts +++ b/src/event-watcher.ts @@ -5,6 +5,8 @@ import type { IStartLocalRaidRequestData } from '@spt/models/eft/match/IStartLoc import type { IEndLocalRaidRequestData } from '@spt/models/eft/match/IEndLocalRaidRequestData'; import type { MatchController } from '@spt/controllers/MatchController'; import type { DependencyContainer } from 'tsyringe'; +import type { ILocationBase } from '@spt/models/eft/common/ILocationBase'; +import { deepClone } from './utils'; type EndOfRaidCallback = (payload: EndOfRaidPayload) => void; @@ -94,7 +96,9 @@ export class EventWatcher { const originalStartLocalRaid = matchController.startLocalRaid.bind(matchController); matchController.startLocalRaid = (sessionId: string, data: IStartLocalRaidRequestData) => { - const originalResult = originalStartLocalRaid(sessionId, data); + const originalResult = deepClone(originalStartLocalRaid(sessionId, data)); + const locationBase: ILocationBase = originalResult.locationLoot; + this.ptt.pathToTarkovController.onRaidStarted(locationBase, sessionId); this.initRaidCache(sessionId); const raidCache = this.getRaidCache(sessionId); @@ -104,6 +108,8 @@ export class EventWatcher { return originalResult; } + // void data.mode; // => "" + // void data.playerSide; // => "" | "" // TODO: remove those lines ? this.ptt.debug(`playerSide = ${data.playerSide}`); this.ptt.debug(`mode = ${data.mode}`); @@ -123,31 +129,6 @@ export class EventWatcher { ); } - // private watchSave(staticRoutePeeker: StaticRoutePeeker): void { - // staticRoutePeeker.watchRoute( - // '/raid/profile/save', - // (url, data: { isPlayerScav: boolean }, sessionId: string) => { - // const raidCache = this.getRaidCache(sessionId); - - // if (!raidCache) { - // return; - // } - - // raidCache.saved = true; - // raidCache.isPlayerScav = data.isPlayerScav; - - // this.ptt.debug(`profile saved: raidCache.isPlayerScav=${data.isPlayerScav}`); - - // if (!raidCache.endOfRaid) { - // this.ptt.debug('end of raid: callback execution delayed...'); - // return; - // } - - // return this.runEndOfRaidCallback(sessionId); - // }, - // ); - // } - private watchEndOfRaid(container: DependencyContainer): void { container.afterResolution( 'MatchController', diff --git a/src/helpers.ts b/src/helpers.ts index 4084fd74..e2a7f48e 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -78,7 +78,6 @@ export const createExitPoint = (name: string): IExit => { PassageRequirement, RequirementTip, EventAvailable: true, - // the following properties are not used but needed to make TypeScript happy ChancePVE: Chance, CountPVE: Count, ExfiltrationTimePVE: ExfiltrationTime, diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index db911d51..043715b8 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -28,19 +28,19 @@ import type { IPath, } from '@spt/models/eft/common/ILocationsSourceDestinationBase'; import type { ILocations } from '@spt/models/spt/server/ILocations'; -// import type { IGetLocationRequestData } from '@spt/models/eft/location/IGetLocationRequestData'; import type { DataCallbacks } from '@spt/callbacks/DataCallbacks'; import type { IEmptyRequestData } from '@spt/models/eft/common/IEmptyRequestData'; import type { ITemplateItem } from '@spt/models/eft/common/tables/ITemplateItem'; import type { IHideoutArea } from '@spt/models/eft/hideout/IHideoutArea'; -// import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBodyResponseData'; import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; +// import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; type IndexedLocations = Record; // indexed by mapName +// Warning: do not re-use, it should only be use by the `generateAll` override const getIndexedLocations = (locations: ILocations): IndexedLocations => { // WARNING: type lies here // TODO: improve type @@ -152,6 +152,15 @@ export class PathToTarkovController { return null; } + /** + * Warning: this function will mutate the given locationBase + */ + onRaidStarted(locationBase: ILocationBase, sessionId: string): void { + const offraidPosition = this.getOffraidPosition(sessionId); + this.updateSpawnPoints(locationBase, offraidPosition, sessionId); + this.updateLocationBaseTransits(locationBase, sessionId); + } + private getRespawnOffraidPosition = (sessionId: string): string => { const profile: Profile = this.saveServer.getProfile(sessionId); const profileTemplateId = profile.info.edition; @@ -233,10 +242,13 @@ export class PathToTarkovController { locationBase.Locked = locked; locationBase.Enabled = !locked; - - // necessary for Fika - this.updateSpawnPoints(locationBase, offraidPosition, sessionId); this.updateLocationBaseExits(locationBase, sessionId); + + /** + * This was necessary before for Fika (3.9.x fix) + * spawn points update is now handled at the `startLocalRaid` layer + */ + // this.updateSpawnPoints(locationBase, offraidPosition, sessionId); } }); @@ -245,8 +257,8 @@ export class PathToTarkovController { }; } - // TODO: iterate over MAPLIST to get locations - // private createGetLocation( + // the 3.9.x way (TODO: remove this) + // private createGetLocationData( // originalFn: ( // url: string, // info: IEmptyRequestData, @@ -261,12 +273,21 @@ export class PathToTarkovController { // const offraidPosition = this.getOffraidPosition(sessionId); // const rawLocationBase = originalFn(url, info, sessionId) as any as string; // const parsed = JSON.parse(rawLocationBase); - // const locationResponse: ILocationsGenerateAllResponse = parsed.data; - // - // // This will handle spawnpoints and exfils for SPT - // // For fika, check the other call of `updateSpawnPoints` - // this.updateSpawnPoints(locationResponse.locations, offraidPosition, sessionId); - // this.updateLocationBaseExits(locationBase, sessionId); + // const locationsResponse: ILocationsGenerateAllResponse = parsed.data; + // const indexedLocations = getIndexedLocations(locationsResponse.locations); + + // this.debug('getLocationData called!'); + + // // const db = this.container.resolve('DatabaseServer'); + + // MAPLIST.forEach(mapName => { + // const locationBase = indexedLocations[mapName]; + // if (locationBase) { + // void offraidPosition; + // this.updateSpawnPoints(locationBase, offraidPosition, sessionId); + // this.updateLocationBaseExits(locationBase, sessionId); + // } + // }); // return JSON.stringify(parsed) as any; // }; @@ -409,7 +430,7 @@ export class PathToTarkovController { // const locationCallbacks = Array.isArray(result) ? result[0] : result; // const originalGet = locationCallbacks.getLocationData.bind(locationCallbacks); - // locationCallbacks.getLocationData = this.createGetLocation(originalGet); + // locationCallbacks.getLocationData = this.createGetLocationData(originalGet); // }, // { frequency: 'Always' }, // ); @@ -439,11 +460,10 @@ export class PathToTarkovController { private removePlayerSpawnsForLocation(locationBase: ILocationBase): void { locationBase.SpawnPointParams = locationBase.SpawnPointParams.filter(params => { - // remove Player from Categories array - params.Categories = params.Categories.filter(cat => cat !== 'Player'); + const playerCategoryFound = params.Categories.find(cat => cat === 'Player'); - if (!params.Categories.length) { - // remove the spawn point if Categories is empty + // remove the spawn point if Category is related to player + if (playerCategoryFound) { return false; } @@ -487,7 +507,7 @@ export class PathToTarkovController { this.logger.warning(`=> PathToTarkov: spawn '${spawnId}' has no Infiltration`); } - locationBase?.SpawnPointParams.push(spawnPoint); + locationBase.SpawnPointParams.push(spawnPoint); this.debug(`[${sessionId}] player spawn '${spawnId}' added for location ${mapName}`); } }); @@ -502,16 +522,28 @@ export class PathToTarkovController { return false; } - private updateLocationBaseExits(locationBase: ILocationBase, sessionId: string): boolean { + private updateLocationBaseTransits(locationBase: ILocationBase, sessionId: string): void { + const config = this.getConfig(sessionId); + + if (config.bypass_exfils_override || config.bypass_transits_override) { + return; + } + + // TODO: handle transits + locationBase.transits = []; + this.debug(`all transits wiped for map "${locationBase.Name}"`); + } + + private updateLocationBaseExits(locationBase: ILocationBase, sessionId: string): void { const config = this.getConfig(sessionId); if (config.bypass_exfils_override) { - return false; + return; } // this will ignore unavailable maps (like terminal) if (!this.isLocationBaseAvailable(locationBase)) { - return false; + return; } const mapName = resolveMapNameFromLocation(locationBase.Id); @@ -520,7 +552,7 @@ export class PathToTarkovController { if (extractPoints.length === 0) { this.logger.error(`Path To Tarkov: no exfils found for map '${mapName}'!`); - return false; + return; } if (config.vanilla_exfils_requirements) { @@ -556,8 +588,6 @@ export class PathToTarkovController { // erase all exits and create custom exit points without requirements locationBase.exits = extractPoints.map(createExitPoint); } - - return true; } private getInitialOffraidPosition = (sessionId: string): string => { From 350bbe0441aae40c0df0f4d028d287baae59d60c Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 14:42:18 +0100 Subject: [PATCH 014/203] fix: player scav detection --- src/event-watcher.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/event-watcher.ts b/src/event-watcher.ts index 485a7c18..c9383370 100644 --- a/src/event-watcher.ts +++ b/src/event-watcher.ts @@ -108,14 +108,9 @@ export class EventWatcher { return originalResult; } - // void data.mode; // => "" - // void data.playerSide; // => "" | "" - // TODO: remove those lines ? - this.ptt.debug(`playerSide = ${data.playerSide}`); - this.ptt.debug(`mode = ${data.mode}`); - - // TODO: find a way to detect if it's a scav raid - raidCache.isPlayerScav = false; + // void data.mode; // => "PVE_OFFLINE" + // void data.playerSide; // => "Pmc" | "Savage" + raidCache.isPlayerScav = data.playerSide === 'Savage'; raidCache.currentLocationName = data.location; this.ptt.debug( From eda47906290cb5f5b511461fa8c6dc13b114827c Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 14:50:28 +0100 Subject: [PATCH 015/203] refactor: introduce syncLocationBase instead of onRaidStarted --- src/event-watcher.ts | 2 +- src/path-to-tarkov-controller.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/event-watcher.ts b/src/event-watcher.ts index c9383370..a7b674ee 100644 --- a/src/event-watcher.ts +++ b/src/event-watcher.ts @@ -98,7 +98,7 @@ export class EventWatcher { matchController.startLocalRaid = (sessionId: string, data: IStartLocalRaidRequestData) => { const originalResult = deepClone(originalStartLocalRaid(sessionId, data)); const locationBase: ILocationBase = originalResult.locationLoot; - this.ptt.pathToTarkovController.onRaidStarted(locationBase, sessionId); + this.ptt.pathToTarkovController.syncLocationBase(locationBase, sessionId); this.initRaidCache(sessionId); const raidCache = this.getRaidCache(sessionId); diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 043715b8..7cbf59d4 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -155,10 +155,11 @@ export class PathToTarkovController { /** * Warning: this function will mutate the given locationBase */ - onRaidStarted(locationBase: ILocationBase, sessionId: string): void { + syncLocationBase(locationBase: ILocationBase, sessionId: string): void { const offraidPosition = this.getOffraidPosition(sessionId); this.updateSpawnPoints(locationBase, offraidPosition, sessionId); - this.updateLocationBaseTransits(locationBase, sessionId); + this.updateLocationBaseExits(locationBase, sessionId); + // this.updateLocationBaseTransits(locationBase, sessionId); } private getRespawnOffraidPosition = (sessionId: string): string => { @@ -242,7 +243,7 @@ export class PathToTarkovController { locationBase.Locked = locked; locationBase.Enabled = !locked; - this.updateLocationBaseExits(locationBase, sessionId); + this.syncLocationBase(locationBase, sessionId); /** * This was necessary before for Fika (3.9.x fix) From 98692efc3d4abb74f0be37c94db88a64d6a7793e Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 16:10:58 +0100 Subject: [PATCH 016/203] fix: broken client because of circle of cultist that cannot be disabled --- src/helpers.ts | 3 +++ src/path-to-tarkov-controller.ts | 6 ++---- src/utils.ts | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/helpers.ts b/src/helpers.ts index e2a7f48e..ad9672fd 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -139,6 +139,9 @@ export const isIgnoredArea = (area: IHideoutArea, isWorkbenchAlwaysEnabled: bool } else if (area.type === 21) { // christmas tree return true; + } else if (area.type === 27) { + // circle of cultist + return true; } return false; diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 7cbf59d4..01b8ad7d 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -443,13 +443,11 @@ export class PathToTarkovController { // override getTemplateItems const originalGetTemplateItems = dataCallbacks.getTemplateItems.bind(dataCallbacks); - dataCallbacks.getTemplateItems = this.createGetTemplateItems(originalGetTemplateItems); // override getHideoutAreas - const originalGetHideoutAreas = dataCallbacks.getHideoutAreas.bind(dataCallbacks); - - dataCallbacks.getHideoutAreas = this.createGetHideoutAreas(originalGetHideoutAreas); + // const originalGetHideoutAreas = dataCallbacks.getHideoutAreas.bind(dataCallbacks); + // dataCallbacks.getHideoutAreas = this.createGetHideoutAreas(originalGetHideoutAreas); // override getGlobals const originalGetGlobals = dataCallbacks.getGlobals.bind(dataCallbacks); diff --git a/src/utils.ts b/src/utils.ts index fa64daf1..2426da0e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -161,7 +161,7 @@ const sha1 = (data: string): string => { export const MONGO_ID_PTT_PREFIX = 'deadbeef'; /** - * This function is used to generate predictible mongo ids + * This function is used to generate predictable mongo ids * a "deadbeef" prefix is added to help debugging profiles */ export const getPTTMongoId = (data: string): string => { From 3373a8cc94545b3b97aa67561e2db5d1ad57c762 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 17:28:14 +0100 Subject: [PATCH 017/203] fix: proper disable of transits --- src/path-to-tarkov-controller.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 01b8ad7d..1facd858 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -159,7 +159,7 @@ export class PathToTarkovController { const offraidPosition = this.getOffraidPosition(sessionId); this.updateSpawnPoints(locationBase, offraidPosition, sessionId); this.updateLocationBaseExits(locationBase, sessionId); - // this.updateLocationBaseTransits(locationBase, sessionId); + this.updateLocationBaseTransits(locationBase, sessionId); } private getRespawnOffraidPosition = (sessionId: string): string => { @@ -528,9 +528,22 @@ export class PathToTarkovController { return; } - // TODO: handle transits - locationBase.transits = []; - this.debug(`all transits wiped for map "${locationBase.Name}"`); + if (!locationBase.transits) { + this.logger.error( + `WTF there is not transits on this location base: ${JSON.stringify(locationBase, undefined, 2)}`, + ); + return; + } + + let nbTransitsWiped = 0; + locationBase.transits.forEach(transit => { + transit.active = false; + nbTransitsWiped += 1; + }); + + if (nbTransitsWiped) { + this.debug(`${nbTransitsWiped} transits disabled for map "${locationBase.Name}"`); + } } private updateLocationBaseExits(locationBase: ILocationBase, sessionId: string): void { From dfb901953cbff86742d8fa7bd80c6049fd0b0999 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 17:43:28 +0100 Subject: [PATCH 018/203] fix: end of raid detection with fika --- src/event-watcher.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/event-watcher.ts b/src/event-watcher.ts index a7b674ee..7df0ddff 100644 --- a/src/event-watcher.ts +++ b/src/event-watcher.ts @@ -7,6 +7,7 @@ import type { MatchController } from '@spt/controllers/MatchController'; import type { DependencyContainer } from 'tsyringe'; import type { ILocationBase } from '@spt/models/eft/common/ILocationBase'; import { deepClone } from './utils'; +import type { MatchCallbacks } from '@spt/callbacks/MatchCallbacks'; type EndOfRaidCallback = (payload: EndOfRaidPayload) => void; @@ -125,20 +126,24 @@ export class EventWatcher { } private watchEndOfRaid(container: DependencyContainer): void { - container.afterResolution( - 'MatchController', + container.afterResolution( + 'MatchCallbacks', (_t, result): void => { - const matchController = Array.isArray(result) ? result[0] : result; - const originalEndLocalRaid = matchController.endLocalRaid.bind(matchController); + const matchCallbacks = Array.isArray(result) ? result[0] : result; + const originalEndLocalRaid = matchCallbacks.endLocalRaid.bind(matchCallbacks); - matchController.endLocalRaid = (sessionId: string, data: IEndLocalRaidRequestData) => { - const originalResult = originalEndLocalRaid(sessionId, data); + matchCallbacks.endLocalRaid = ( + url: string, + data: IEndLocalRaidRequestData, + sessionId: string, + ) => { + const originalResult = originalEndLocalRaid(url, data, sessionId); const raidCache = this.getRaidCache(sessionId); if (!raidCache) { this.ptt.logger.error(`no PTT raid cache found`); - return; + return originalResult; } raidCache.sessionId = sessionId; From 0dab27cc44b4bdd18e74090111abef9689f7b86e Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 17:45:56 +0100 Subject: [PATCH 019/203] chore: cleanup --- src/path-to-tarkov-controller.ts | 51 ++------------------------------ 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 1facd858..5d711776 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -244,12 +244,6 @@ export class PathToTarkovController { locationBase.Locked = locked; locationBase.Enabled = !locked; this.syncLocationBase(locationBase, sessionId); - - /** - * This was necessary before for Fika (3.9.x fix) - * spawn points update is now handled at the `startLocalRaid` layer - */ - // this.updateSpawnPoints(locationBase, offraidPosition, sessionId); } }); @@ -258,42 +252,6 @@ export class PathToTarkovController { }; } - // the 3.9.x way (TODO: remove this) - // private createGetLocationData( - // originalFn: ( - // url: string, - // info: IEmptyRequestData, - // sessionId: string, - // ) => IGetBodyResponseData, - // ) { - // return ( - // url: string, - // info: IEmptyRequestData, - // sessionId: string, - // ): IGetBodyResponseData => { - // const offraidPosition = this.getOffraidPosition(sessionId); - // const rawLocationBase = originalFn(url, info, sessionId) as any as string; - // const parsed = JSON.parse(rawLocationBase); - // const locationsResponse: ILocationsGenerateAllResponse = parsed.data; - // const indexedLocations = getIndexedLocations(locationsResponse.locations); - - // this.debug('getLocationData called!'); - - // // const db = this.container.resolve('DatabaseServer'); - - // MAPLIST.forEach(mapName => { - // const locationBase = indexedLocations[mapName]; - // if (locationBase) { - // void offraidPosition; - // this.updateSpawnPoints(locationBase, offraidPosition, sessionId); - // this.updateLocationBaseExits(locationBase, sessionId); - // } - // }); - - // return JSON.stringify(parsed) as any; - // }; - // } - private createGetTemplateItems( originalFn: (url: string, info: IEmptyRequestData, sessionId: string) => string, ) { @@ -528,15 +486,10 @@ export class PathToTarkovController { return; } - if (!locationBase.transits) { - this.logger.error( - `WTF there is not transits on this location base: ${JSON.stringify(locationBase, undefined, 2)}`, - ); - return; - } + const transits = locationBase.transits ?? []; // fallback on empty array because the type can lie (for `terminal` map) let nbTransitsWiped = 0; - locationBase.transits.forEach(transit => { + transits.forEach(transit => { transit.active = false; nbTransitsWiped += 1; }); From 79eb0801d392f0007893de5088d7e0486a5a3801 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 17:57:49 +0100 Subject: [PATCH 020/203] feat(fir): dynamic implementation of the fir tweak --- src/end-of-raid-controller.ts | 7 ++++++- src/keep-fir-tweak.ts | 37 +++++++++++++---------------------- src/mod.ts | 8 -------- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/end-of-raid-controller.ts b/src/end-of-raid-controller.ts index d49ff2bf..8a025f5c 100644 --- a/src/end-of-raid-controller.ts +++ b/src/end-of-raid-controller.ts @@ -2,6 +2,8 @@ import type { MapName } from './config'; import type { ILogger } from '@spt/models/spt/utils/ILogger'; import type { PathToTarkovController } from './path-to-tarkov-controller'; import { resolveMapNameFromLocation } from './map-name-resolver'; +import { applyKeepFoundInRaidTweak } from './keep-fir-tweak'; +import type { DependencyContainer } from 'tsyringe'; export type EndOfRaidPayload = { sessionId: string; @@ -11,6 +13,7 @@ export type EndOfRaidPayload = { }; export type PTTInstance = { + readonly container: DependencyContainer; readonly pathToTarkovController: PathToTarkovController; readonly executeOnStartAPICallbacks: (sessionId: string) => void; readonly logger: ILogger; @@ -22,8 +25,10 @@ export class EndOfRaidController { public end(payload: EndOfRaidPayload): void { const { sessionId, locationName, exitName, isPlayerScav } = payload; - const mapName = resolveMapNameFromLocation(locationName) as MapName; + applyKeepFoundInRaidTweak(this.ptt, sessionId); + + const mapName = resolveMapNameFromLocation(locationName) as MapName; if (!mapName) { this.ptt.logger.error( `Path To Tarkov Error: cannot resolve map name from location '${locationName}'`, diff --git a/src/keep-fir-tweak.ts b/src/keep-fir-tweak.ts index 9fccdf2d..5ea8d16a 100644 --- a/src/keep-fir-tweak.ts +++ b/src/keep-fir-tweak.ts @@ -1,12 +1,15 @@ // import type { MatchController } from '@spt/controllers/MatchController'; // import type { IPmcData } from '@spt/models/eft/common/IPmcData'; +import type { IPmcData } from '@spt/models/eft/common/IPmcData'; import type { IItem } from '@spt/models/eft/common/tables/IItem'; import type { SaveServer } from '@spt/servers/SaveServer'; import type { DependencyContainer } from 'tsyringe'; +import type { PathToTarkovController } from './path-to-tarkov-controller'; type PTTInstance = { readonly container: DependencyContainer; + readonly pathToTarkovController: PathToTarkovController; readonly debug: (data: string) => void; }; @@ -28,29 +31,17 @@ const setSpawnedInSessionOnAllItems = (items: IItem[]): number => { return counter; }; -export const enableKeepFoundInRaidTweak = (ptt: PTTInstance): void => { - const saveServer = ptt.container.resolve('SaveServer'); - - // TODO: fix - void saveServer; - void setSpawnedInSessionOnAllItems; - - // ptt.container.afterResolution( - // 'MatchController', - // (_t, result): void => { - // const matchController = Array.isArray(result) ? result[0] : result; +export const applyKeepFoundInRaidTweak = (ptt: PTTInstance, sessionId: string): void => { + const config = ptt.pathToTarkovController.getConfig(sessionId); + const bypassTweak = config.bypass_keep_found_in_raid_tweak; - // const originalEndOfflineRaid = matchController.endOfflineRaid.bind(matchController); + if (bypassTweak) { + return; + } - // matchController.endOfflineRaid = (info, sessionId) => { - // originalEndOfflineRaid(info, sessionId); - - // const profile = saveServer.getProfile(sessionId); - // const pmcData: IPmcData = profile.characters.pmc; - // const count = setSpawnedInSessionOnAllItems(pmcData.Inventory.items); - // ptt.debug(`added 'SpawnedInSession' flag on ${count} items`); - // }; - // }, - // { frequency: 'Always' }, - // ); + const saveServer = ptt.container.resolve('SaveServer'); + const profile = saveServer.getProfile(sessionId); + const pmcData: IPmcData = profile.characters.pmc; + const count = setSpawnedInSessionOnAllItems(pmcData.Inventory.items); + ptt.debug(`added 'SpawnedInSession' flag on ${count} items`); }; diff --git a/src/mod.ts b/src/mod.ts index 50ebd19a..442ac50a 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -21,7 +21,6 @@ import { } from './config'; import { EventWatcher } from './event-watcher'; import { createStaticRoutePeeker, disableRunThrough } from './helpers'; -import { enableKeepFoundInRaidTweak } from './keep-fir-tweak'; import { PathToTarkovController } from './path-to-tarkov-controller'; import { purgeProfiles } from './uninstall'; @@ -124,13 +123,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { eventWatcher.onEndOfRaid(payload => endOfRaidController.end(payload)); eventWatcher.register(createStaticRoutePeeker(staticRouter), container); - const tweakFoundInRaid = !this.config.bypass_keep_found_in_raid_tweak; - - if (tweakFoundInRaid) { - enableKeepFoundInRaidTweak(this); - this.debug('option keep_found_in_raid_tweak enabled'); - } - if (this.config.traders_access_restriction) { fixRepeatableQuests(container); this.debug('Apply fix for unavailable repeatable quests (due to locked traders)'); From d88a8ee8946fdf09a171564d1c3428c169c836f9 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 18:13:59 +0100 Subject: [PATCH 021/203] fix: disable fir tweak --- src/end-of-raid-controller.ts | 3 -- src/keep-fir-tweak.ts | 74 ++++++++++++++--------------------- src/mod.ts | 15 +++++++ 3 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/end-of-raid-controller.ts b/src/end-of-raid-controller.ts index 8a025f5c..ed9253d9 100644 --- a/src/end-of-raid-controller.ts +++ b/src/end-of-raid-controller.ts @@ -2,7 +2,6 @@ import type { MapName } from './config'; import type { ILogger } from '@spt/models/spt/utils/ILogger'; import type { PathToTarkovController } from './path-to-tarkov-controller'; import { resolveMapNameFromLocation } from './map-name-resolver'; -import { applyKeepFoundInRaidTweak } from './keep-fir-tweak'; import type { DependencyContainer } from 'tsyringe'; export type EndOfRaidPayload = { @@ -26,8 +25,6 @@ export class EndOfRaidController { public end(payload: EndOfRaidPayload): void { const { sessionId, locationName, exitName, isPlayerScav } = payload; - applyKeepFoundInRaidTweak(this.ptt, sessionId); - const mapName = resolveMapNameFromLocation(locationName) as MapName; if (!mapName) { this.ptt.logger.error( diff --git a/src/keep-fir-tweak.ts b/src/keep-fir-tweak.ts index 5ea8d16a..df26a805 100644 --- a/src/keep-fir-tweak.ts +++ b/src/keep-fir-tweak.ts @@ -1,47 +1,31 @@ -// import type { MatchController } from '@spt/controllers/MatchController'; -// import type { IPmcData } from '@spt/models/eft/common/IPmcData'; -import type { IPmcData } from '@spt/models/eft/common/IPmcData'; -import type { IItem } from '@spt/models/eft/common/tables/IItem'; -import type { SaveServer } from '@spt/servers/SaveServer'; - import type { DependencyContainer } from 'tsyringe'; -import type { PathToTarkovController } from './path-to-tarkov-controller'; - -type PTTInstance = { - readonly container: DependencyContainer; - readonly pathToTarkovController: PathToTarkovController; - readonly debug: (data: string) => void; -}; - -const setSpawnedInSessionOnAllItems = (items: IItem[]): number => { - let counter = 0; - - items.forEach(item => { - if (item.upd) { - if (!item.upd.SpawnedInSession) { - item.upd.SpawnedInSession = true; - counter = counter + 1; - } - } else { - item.upd = { SpawnedInSession: true }; - counter = counter + 1; - } - }); - - return counter; -}; - -export const applyKeepFoundInRaidTweak = (ptt: PTTInstance, sessionId: string): void => { - const config = ptt.pathToTarkovController.getConfig(sessionId); - const bypassTweak = config.bypass_keep_found_in_raid_tweak; - - if (bypassTweak) { - return; - } - - const saveServer = ptt.container.resolve('SaveServer'); - const profile = saveServer.getProfile(sessionId); - const pmcData: IPmcData = profile.characters.pmc; - const count = setSpawnedInSessionOnAllItems(pmcData.Inventory.items); - ptt.debug(`added 'SpawnedInSession' flag on ${count} items`); +import type { ConfigServer } from '@spt/servers/ConfigServer'; +import type { ConfigTypes } from '@spt/models/enums/ConfigTypes'; +import type { IInRaidConfig } from '@spt/models/spt/config/IInRaidConfig'; + +// TODO: filter to get only items that are in the player equipment (need to use "equipment" field as a parentId) +// const setSpawnedInSessionOnAllItems = (items: IItem[]): number => { +// let counter = 0; + +// items.forEach(item => { +// if (item.upd) { +// if (!item.upd.SpawnedInSession) { +// item.upd.SpawnedInSession = true; +// counter = counter + 1; +// } +// } else { +// item.upd = { SpawnedInSession: true }; +// counter = counter + 1; +// } +// }); + +// return counter; +// }; + +export const applyKeepFoundInRaidTweak = (container: DependencyContainer): void => { + const configServer = container.resolve('ConfigServer'); + const inRaidConfig = configServer.getConfig('spt-inraid' as ConfigTypes.IN_RAID); + + // this does not work + inRaidConfig.alwaysKeepFoundInRaidonRaidEnd = true; }; diff --git a/src/mod.ts b/src/mod.ts index 442ac50a..d6c1dc84 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -32,6 +32,7 @@ import { pathToTarkovReloadedTooltipsConfigCompat } from './pttr-tooltips'; import path from 'path'; import { analyzeConfig } from './config-analysis'; import { TradersAvailabilityService } from './services/TradersAvailabilityService'; +import { applyKeepFoundInRaidTweak } from './keep-fir-tweak'; const getTooltipsConfig = ( userConfig: UserConfig, @@ -129,6 +130,14 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { } } + public postDBLoad(container: DependencyContainer): void { + if (!this.config.enabled) { + return; + } + + void container; + } + public postSptLoad(container: DependencyContainer): void { this.container = container; const db = container.resolve('DatabaseServer'); @@ -153,6 +162,12 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { return; } + if (!this.config.bypass_keep_found_in_raid_tweak) { + applyKeepFoundInRaidTweak(container); + // this.debug('keep FIR tweak applied'); + this.logger.warning('keep FIR tweak does not work on this verison'); + } + this.pathToTarkovController.tradersAvailabilityService.init(quests); if (this.tooltipsConfig) { From 1d8c3b3d59c05c1c7f4ea0f44cb4e81d7693e0f0 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 19:15:10 +0100 Subject: [PATCH 022/203] feat: promote the Narcotic's config to be the default one --- .../Customs_TarkovDev/Customs_TarkovDev.jsonc | 0 .../Factory_TarkovDev/Factory_TarkovDev.jsonc | 0 .../GroundZero_TarkovDev.jsonc | 0 .../Interchange_TarkovDev.jsonc | 0 .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 0 .../Lighthouse_TarkovData.jsonc | 0 .../Reserve_TarkovData.jsonc | 0 .../Shoreline_TarkovData.jsonc | 0 .../Streets_TarkovData.jsonc | 0 .../Woods_TarkovData/Woods_TarkovData.jsonc | 0 .../Instructions.txt | 0 .../TarkovMapV2.jpg | Bin configs/Default/Tooltips.json | 240 +++- configs/Default/config.json | 1223 +++++++++++++---- configs/Default/player_spawnpoints.json | 353 +++-- .../PathToTarkov-1.png | Bin .../PathToTarkov.png | Bin configs/LegacyPathToTarkovV5/Tooltips.json | 96 ++ configs/LegacyPathToTarkovV5/config.json | 427 ++++++ .../player_spawnpoints.json | 374 +++++ .../Customs_TarkovDev/Customs_TarkovDev.jsonc | 691 ++++++++++ .../Factory_TarkovDev/Factory_TarkovDev.jsonc | 215 +++ .../GroundZero_TarkovDev.jsonc | 207 +++ .../Interchange_TarkovDev.jsonc | 627 +++++++++ .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 283 ++++ .../Lighthouse_TarkovData.jsonc | 320 +++++ .../Reserve_TarkovData.jsonc | 556 ++++++++ .../Shoreline_TarkovData.jsonc | 548 ++++++++ .../Streets_TarkovData.jsonc | 1092 +++++++++++++++ .../Woods_TarkovData/Woods_TarkovData.jsonc | 216 +++ .../Instructions.txt | 5 + .../OriginalNarcoticsConfig/TarkovMapV2.jpg | Bin 0 -> 1214077 bytes .../Tooltips.json | 0 .../config.json | 31 - .../player_spawnpoints.json | 0 tests/configs.test.ts | 8 +- 36 files changed, 7043 insertions(+), 469 deletions(-) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc (100%) rename configs/{NarcoticsConfig => Default}/DynamicMaps compatibility/Instructions.txt (100%) rename configs/{NarcoticsConfig => Default}/TarkovMapV2.jpg (100%) rename configs/{Default => LegacyPathToTarkovV5}/PathToTarkov-1.png (100%) rename configs/{Default => LegacyPathToTarkovV5}/PathToTarkov.png (100%) create mode 100644 configs/LegacyPathToTarkovV5/Tooltips.json create mode 100644 configs/LegacyPathToTarkovV5/config.json create mode 100644 configs/LegacyPathToTarkovV5/player_spawnpoints.json create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc create mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt create mode 100644 configs/OriginalNarcoticsConfig/TarkovMapV2.jpg rename configs/{NarcoticsConfig => OriginalNarcoticsConfig}/Tooltips.json (100%) rename configs/{NarcoticsConfig => OriginalNarcoticsConfig}/config.json (95%) rename configs/{NarcoticsConfig => OriginalNarcoticsConfig}/player_spawnpoints.json (100%) diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc b/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc rename to configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc diff --git a/configs/NarcoticsConfig/DynamicMaps compatibility/Instructions.txt b/configs/Default/DynamicMaps compatibility/Instructions.txt similarity index 100% rename from configs/NarcoticsConfig/DynamicMaps compatibility/Instructions.txt rename to configs/Default/DynamicMaps compatibility/Instructions.txt diff --git a/configs/NarcoticsConfig/TarkovMapV2.jpg b/configs/Default/TarkovMapV2.jpg similarity index 100% rename from configs/NarcoticsConfig/TarkovMapV2.jpg rename to configs/Default/TarkovMapV2.jpg diff --git a/configs/Default/Tooltips.json b/configs/Default/Tooltips.json index 78080e84..c002a68a 100644 --- a/configs/Default/Tooltips.json +++ b/configs/Default/Tooltips.json @@ -5,92 +5,218 @@ "language": "english", - "moddedTraderCompat": false, - "additionalLocalesToggle": false, + "moddedTraderCompat": true, + "additionalLocalesToggle": true, "moddedTraderExtracts": [ - "Saferoom Exfil", - "Saferoom (Goblin King)", - "EXFIL_ZB013", - "ZB-1013 Storage Bunker (Broker)" + "Trailer Park Workers Shack", + "Trailer Park Workers' Shack (Legs)", + "Scav_Hideout_at_the_grotto", + "Hideout at the Grotto (Artem)", + "Railroad To Tarkov", + "RR to Tarkov (Painter/Streets/Interchange)", + "NW Exfil", + "Railway (Painter/Customs/Woods/Streets)", + "PP Exfil", + "Power Station SUV (Painter/Streets/Woods/GZ)", + "E4", + "Crash Site (Painter/Customs/Interchange)", + "ZB-014", + "ZB-014 (Scorpion)", + "EXFIL_Bunker", + "Bunker Hermetic Door (Scorpion/Woods*)", + "SE Exfil", + "Emercom Checkpoint (Lotus/Customs)", + "Crossroads", + "Crossroads (Lotus/Interchange/Shoreline*)", + "Nakatani_stairs_free_exit", + "Nakatani Basement Stairs (Coyote/Streets/Labs)", + "scav_e1", + "Basement Descent (Coyote/Labs/Ground Zero)", + "lab_Elevator_Cargo", + "Cargo Elevator (Coyote/Streets/Ground Zero)", + "E3", + "Ruined House (Hephaestus)", + "EXFIL_Vent", + "Manhole (Sally/Streets)", + "scav_e4", + "Manhole (Sally/Reserve)" ], - "localesToChangeAdditional": [], + "localesToChangeAdditional": ["Saferoom Exfil", "Saferoom (Flea Market)"], "localesToChange": [ - "Gate 3", - "Gate 3 to Customs - Mechanic (Hideout)", - "Office Window", - "Office Window to woods - Jeager", + "East Gate", + "Scav Bunker (Prapor)", + "Unity_free_exit", + "Emercom Checkpoint (Therapist)", + "Warehouse 17", + "Warehouse 17 (Skier)", + "Mountain Stash", + "Mountain Stash (Jaeger)", + "Interchange Cooperation", + "Scav Camp (Ragman/Customs)", + "Trailer Park", + "Trailer Park (Ragman/Interchange)", + "EXFIL_Bunker_D2", + "D-2 (Peacekeeper/Shoreline*)", + "South Fence Passage", + "Old Bunker (Peacekeeper)", + "Camera Bunker Door", + "Camera Bunker Door (Mechanic)", + "Railroad To Port", + "RR to Port (Ref/Shoreline)", + "Road_at_railbridge", + "Railbridge (Ref/Customs)", "Gate 3", - "Gate 3 to Customs - Mechanic (Hideout)", + "Gate 3 (Woods, ZB-1016)", + "Gate m", + "Med Tent Gates (Customs, ZB-1012)", + "Gate 0", + "Gate 0 (Customs, ZB-1011)", + "Cellars", + "Cellars (Customs, ZB-1013)", "Office Window", - "Office Window to woods - Jeager", + "Office Window (Customs/Woods)", - "Railroad To Tarkov", - "Railroad To Tarkov to Streets, GZ - Therapist, ", - "Railroad To Military Base", - "Railroad To Military Base to Reserve - Skier", "ZB-1011", - "ZB-1011 to Factory - Mechanic (Hideout)", + "ZB-1011 (Hideout/Factory)", + "ZB-1012", + "ZB-1012 (Factory, Med Tent Gates)", + "EXFIL_ZB013", + "ZB-1013 (Factory, Cellars)", + "Military Checkpoint", + "Scav Checkpoint (Woods/Lighthouse)", + "Sniper Roadblock", + "Sniper Roadblock (Reserve*/Shoreline)", + "Smuggler's Boat", + "Smuggler's Boat (Lighthouse*/Shoreline/Woods*", + "Dorms V-Ex", + "Dorms SUV (Shoreline, North Fence SUV)", + "RUAF Roadblock", + "RUAF Roadblock (Woods, UN Roadblock)", "Old Azs Gate", - "Old Gas Station Gate to Interchange - Ragman", + "Old Gas Gate (Factory/Woods)", + "Shack", + "Military Base Checkpoint (Reserve, Scav lands)", + "Crossroads", + "Crossroads (Interchange/Shoreline*)", + "Railroad To Military Base", + "RR to Military Base (Reserve, Scav land rails*)", + "Factory Far Corner", + "Factory Corner (Woods, RUAF Gate)", + "Railroad To Tarkov", + "RR to Tarkov (Streets/Interchange)", - "Factory Gate", - "Factory Gate to Factory - Jeager", + "un-sec", + "North UN Roadblock (Customs, RUAF Roadblock*)", + "Factory gate", + "Factory Gate (Customs, Old Gas Gate)", + "ZB-016", + "ZB-016 (Factory, Gate 3)", + "Outskirts", + "Outskirts (Customs/Lighthouse)", + "UN Roadblock", + "UN Roadblock (Customs/Interchange)", "South V-Ex", - "South V-Ex to Shoreline", + "Bridge SUV (Streets/Interchange/GZ)", + "RUAF Gate", + "RUAF Gate (Customs, Factory Corner)", "EXFIL_ScavCooperation", - "Scav Lands to Customs - Skier", + "Scav lands (Customs, Military Base CP)", + "EXFIL_Train", + "Armored Train (all maps besides GZ*)", + "Exit1", + "Hole in the Wall (Customs, Dorms Car*)", "Exit4", - "Checkpoint Fence to Lighthouse", - "EXFIL_Bunker_D2", - "D-2 to interchange", + "Checkpoint Fence (Lighthouse, Northeast Mountains*)", + "Alpinist", + "Cliff Descent (Shoreline, Climber's Trail)", + "EXFIL_Vent", + "Manhole (Streets, Manhole)", + "EXFIL_Bunker", + "Bunker Hermetic Door (Woods, ZB-014*)", + "SE Exfil", + "Emercom Checkpoint (Customs, Crossroads)", "NW Exfil", - "Railway Exfil to Customs - Ragman", - "Saferoom Exfil", - "Saferoom to Reserve, Shoreline", + "Railway (Customs/Woods/Streets)", "PP Exfil", - "Power Station V-Ex to Customs, Streets, GZ, Labs - Prapor", + "Power Station SUV (Streets/Woods/GZ)", + + "E1", + "Sylobate Elevator (Labs, Main Elevator)", + "E2", + "Sewer River (Labs, Sewage Conduit)", + "E4", + "Crash Site (Customs/Interchange)", + "E7", + "Expo Checkpoint (Ground Zero, Scav Camp)", + "E7_car", + "Primorsky Ave Taxi (Woods/Interchange/GZ)", + "E9_sniper", + "Klimov Ave (Ground Zero, Mira Ave)", + "scav_e1", + "Basement Descent (Labs/Ground Zero)", + "scav_e2", + "Entrance to Catacombs (Labs, Hangar Gate)", + "scav_e3", + "Vent Shaft (Lab, Vents)", + "scav_e4", + "Manhole (Reserve, Manhole)", + "Road to Customs", + "Road to Customs (Customs, Sniper Roadblock*)", + "Pier Boat", + "Pier Boat (Lighthouse*/Customs/Woods*)", "Tunnel", - "Tunnel to Lighthouse - Peacekeeper", + "Tunnel (Lighthouse, Side Tunnel)", + "Wrecked Road", + "Ruined Road (Lighthouse, Southern Road)", + "Smugglers_Trail_coop", + "Smuggler's Path (Customs/Reserve*)", "Shorl_V-Ex", - "Road to North V-Ex to Woods", - "South Fence Passage", - "Old Bunker to Reserve, Interchange", - - "Coastal_South_Road", - "Southern Road to Shoreline - Peacekeeper", - " V-Ex_light", - "Road to Military Base V-Ex to Reserve", + "North Fence SUV (Customs, Dorms SUV)", + "Lighthouse_pass", + "Path to Lighthouse", + "RedRebel_alp", + "Climber's Trail (Reserve, Cliff Descent)", - "E5", - "Collapsed Crane to Customs, GZ - Therapist", - "E7_car", - "Primorsky Ave Taxi V-Ex to Customs, Interchange, GZ, Labs - Prapor", + "Nothern_Checkpoint", + "Northern Checkpoint (Woods/Customs)", + " V-ex_light", + "Military Base SUV (Reserve, CP Fence)", + "Shorl_free", + "Path to Shoreline", + "Coastal_South_road", + "Southern Road (Shoreline, Ruined Road)", + "Alpinist_light", + "Mountain Pass (Shoreline, Path to Shoreline*)", + "Tunnel_Shared", + "Side Tunnel (Shoreline, Tunnel)", + "EXFIL_Train", + "Armored Train (all maps besides GZ*)", - "lab_Parking_Gate", - "Parking Gate", + "lab_Elevator_Cargo", + "Cargo Elevator (Streets/Ground Zero)", + "lab_Elevator_Main", + "Main Elevator (Streets, Sylobate Elevator)", "lab_Hangar_Gate", - "Hangar Gate", - "lab_Elevator_Med", - "Medical Block Elevator", + "Hangar Gate (Streets, Catacombs)", "lab_Under_Storage_Collector", - "Sewage Conduit", - "lab_Elevator_Main", - "Main Elevator", + "Sewage Conduit (Streets, Sewer River)", "lab_Vent", - "Ventilation Shaft", - "lab_Elevator_Cargo", - "Cargo Elevator", + "Vents (Streets, Vent Shaft)", - "Scav_coop_exit", - "Scav Checkpoint to Customs, Streets - Therapist", "Sandbox_VExit", - "Police Cordon V-Ex to Customs, Interchange, Streets, Labs - Prapor" + "Police Car (Woods/Interchange/Streets)", + "Nakatani_stairs_free_exit", + "Nakatani Basement Stairs (Streets/Labs)", + "Sniper_exit", + "Mira Ave (Streets, Klimov Ave)", + "Scav_coop_exit", + "Scav Checkpoint (Streets, Expo CP)" ] } diff --git a/configs/Default/config.json b/configs/Default/config.json index bc6c7b35..86b91d71 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -1,15 +1,14 @@ { "enabled": true, "debug": true, - "override_by_profiles": {}, - "initial_offraid_position": "MechanicStash", - "respawn_at": ["MechanicStash"], + "initial_offraid_position": "FactoryZB-1011", "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, + "vanilla_exfils_requirements": true, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, + "bypass_transits_override": false, "bypass_keep_found_in_raid_tweak": false, "bypass_uninstall_procedure": false, "restrictions_in_raid": { @@ -28,241 +27,409 @@ }, "offraid_regen_config": { "hydration": { - "access_via": ["*"] + "access_via": ["FactoryZB-1011", "FactoryZB-1012", "FactoryZB-013", "FactoryZB-016"] }, "energy": { - "access_via": ["*"] + "access_via": ["FactoryZB-1011", "FactoryZB-1012", "FactoryZB-013", "FactoryZB-016"] }, "health": { - "access_via": ["*"] + "access_via": [ + "FactoryZB-1011", + "FactoryZB-1012", + "FactoryZB-013", + "FactoryZB-016", + "TherapistHideout" + ] } }, - "hideout_main_stash_access_via": ["MechanicStash"], + "hideout_main_stash_access_via": [ + "FactoryZB-1011", + "FactoryZB-1012", + "FactoryZB-013", + "FactoryZB-016", + "TherapistHideout" + ], "hideout_secondary_stashes": [ - { - "id": "PathToTarkov_Therapist_stash", - "size": 22, - "access_via": ["TherapistStash"] - }, { "id": "PathToTarkov_Prapor_stash", - "size": 22, - "access_via": ["PraporStash"] + "size": 48, + "access_via": ["PraporHideout"] }, { "id": "PathToTarkov_Mechanic_stash", - "size": 22, - "access_via": ["MechanicStash"] + "size": 48, + "access_via": ["MechanicHideout"] }, { - "id": "PathToTarkov_Ragman_stash", - "size": 22, - "access_via": ["RagmanStash"] + "id": "PathToTarkov_Skier_stash", + "size": 48, + "access_via": ["SkierHideout"] }, { - "id": "PathToTarkov_Skier_stash", - "size": 22, - "access_via": ["SkierStash"] + "id": "PathToTarkov_Jaeger_stash", + "size": 48, + "access_via": ["JaegerHideout"] }, { "id": "PathToTarkov_Peacekeeper_stash", - "size": 22, - "access_via": ["PeacekeeperStash"] + "size": 48, + "access_via": ["PeacekeeperHideout"] }, { - "id": "PathToTarkov_Jaeger_stash", - "size": 22, - "access_via": ["JaegerStash"] + "id": "PathToTarkov_Ref_stash", + "size": 48, + "access_via": ["PortRR", "RailwayBridge"] + }, + { + "id": "PathToTarkov_Lotus_stash", + "size": 48, + "access_via": ["Crossroads", "Emercom"] + }, + { + "id": "PathToTarkov_Artem_stash", + "size": 48, + "access_via": ["ArtemHideout"] + }, + { + "id": "PathToTarkov_Legs_stash", + "size": 48, + "access_via": ["LegsHideout"] + }, + { + "id": "PathToTarkov_Scorpion_stash", + "size": 48, + "access_via": ["ReserveZB-014"] + }, + { + "id": "PathToTarkov_Coyote_stash", + "size": 48, + "access_via": ["BasementDescent"] + }, + { + "id": "PathToTarkov_Hephaestus_stash", + "size": 48, + "access_via": ["RuinedHouse"] + }, + { + "id": "PathToTarkov_Sally_stash", + "size": 48, + "access_via": ["Manhole"] + }, + { + "id": "PathToTarkov_Saferoom_stash", + "size": 48, + "access_via": ["SafeRoom"] + }, + { + "id": "PathToTarkov_CustomsNorth_stash", + "size": 32, + "access_via": [ + "FactoryCorner", + "RUAFWoods", + "GasGate", + "RUAFCustoms", + "UNRoadblock", + "NorthUNRoadblock" + ] + }, + { + "id": "PathToTarkov_CustomsSouth_stash", + "size": 32, + "access_via": [ + "MilBaseCP", + "ScavLands", + "MilBaseRR", + "HoleinWall", + "SniperRB", + "SmugglersPath", + "RoadtoCustoms" + ] + }, + { + "id": "PathToTarkov_CustomsEast_stash", + "size": 48, + "access_via": ["TarkovRR", "CrashSite", "Railway", "ScavCamp", "TrailerPark"] + }, + { + "id": "PathToTarkov_CustomsWest_stash", + "size": 32, + "access_via": ["ScavCP", "Outskirts", "NorthernCP"] + }, + { + "id": "PathToTarkov_ShoreLightPath_stash", + "size": 16, + "access_via": ["LighthousePath", "ShorelinePath", "MountainPass"] + }, + { + "id": "PathToTarkov_ShorelineWest_stash", + "size": 16, + "access_via": ["Tunnel", "SideTunnel", "RuinedRoad", "SouthernRoad"] + }, + { + "id": "PathToTarkov_ShorelineNorth_stash", + "size": 16, + "access_via": ["ClimbersTrail", "CliffDescent"] + }, + { + "id": "PathToTarkov_GZStreets_stash", + "size": 32, + "access_via": ["ExpoCP", "KlimovStreet"] + }, + { + "id": "PathToTarkov_NorthCar_stash", + "size": 4, + "access_via": ["WoodsCar", "InterchangeCar", "StreetsCar", "GZCar"] + }, + { + "id": "PathToTarkov_SouthCar_stash", + "size": 4, + "access_via": ["DormsCar", "ShorelineCar"] + }, + { + "id": "PathToTarkov_MilCar_stash", + "size": 4, + "access_via": ["LighthouseCar"] + }, + { + "id": "PathToTarkov_SmugglersBoat_stash", + "size": 4, + "access_via": ["SmugglersBoat"] + }, + { + "id": "PathToTarkov_PierBoat_stash", + "size": 8, + "access_via": ["PierBoat"] + }, + { + "id": "PathToTarkov_ArmoredTrain_stash", + "size": 16, + "access_via": ["ReserveTrain", "LighthouseTrain"] }, { - "id": "PathToTarkov_MilitaryLighthouse_stash", - "size": 22, - "access_via": ["MilitaryLighthouseStash"] + "id": "PathToTarkov_VentShaft_stash", + "size": 4, + "access_via": ["VentShaft"] }, { - "id": "PathToTarkov_ReserveBunker_stash", - "size": 22, - "access_via": ["ReserveBunkerStash"] + "id": "PathToTarkov_SewerRiver_stash", + "size": 4, + "access_via": ["SewerRiver"] }, { - "id": "PathToTarkov_Car_stash", - "size": 22, - "access_via": ["ShorelineWoodsStash"] + "id": "PathToTarkov_SylobateElevator_stash", + "size": 4, + "access_via": ["SylobateElevator"] }, { - "id": "PathToTarkov_Klimov_stash", - "size": 22, - "access_via": ["KlimovStash"] + "id": "PathToTarkov_Catacombs_stash", + "size": 16, + "access_via": ["Catacombs"] } ], "traders_config": { "54cb50c76803fa8b248b4571": { "// Trader name": "Prapor", - "override_description": false, + "insurance_always_enabled": true, + "insurance_config": { + "insurance_price_coef": 50, + "min_payment": 0, + "min_return_hour": 0, + "max_return_hour": 0, + "max_storage_time": 480, + "return_chance_percent": 85 + }, + "override_description": true, "location_description": { - "ch": "In his car, he hangs around the city", - "cz": "In his car, he hangs around the city", - "en": "In his car, he hangs around the city", - "es-mx": "In his car, he hangs around the city", - "es": "In his car, he hangs around the city", - "fr": "Dans sa voiture, il traine en ville", - "ge": "In his car, he hangs around the city", - "hu": "In his car, he hangs around the city", - "it": "In his car, he hangs around the city", - "jp": "In his car, he hangs around the city", - "kr": "In his car, he hangs around the city", - "pl": "In his car, he hangs around the city", - "po": "In his car, he hangs around the city", - "ru": "In his car, he hangs around the city" + "ch": "Woods", + "cz": "Woods", + "en": "Woods", + "es-mx": "Woods", + "es": "Woods", + "fr": "Woods", + "ge": "Woods", + "hu": "Woods", + "it": "Woods", + "jp": "Woods", + "kr": "Woods", + "pl": "Woods", + "po": "Woods", + "ru": "Woods" }, - "access_via": ["PraporStash"] + "access_via": ["PraporHideout"] }, "54cb57776803fa99248b456e": { "// Trader name": "Therapist", - "override_description": false, + "insurance_always_enabled": true, + "insurance_config": { + "insurance_price_coef": 25, + "min_payment": 0, + "min_return_hour": 0, + "max_return_hour": 0, + "max_storage_time": 480, + "return_chance_percent": 75 + }, + "override_description": true, "location_description": { - "ch": "in the city", - "cz": "In the city", - "en": "In the city", - "es-mx": "In the city", - "es": "In the city", - "fr": "En ville", - "ge": "In the city", - "hu": "In the city", - "it": "In the city", - "jp": "In the city", - "kr": "In the city", - "pl": "In the city", - "po": "In the city", - "ru": "In the city" + "ch": "Ground Zero", + "cz": "Ground Zero", + "en": "Ground Zero", + "es-mx": "Ground Zero", + "es": "Ground Zero", + "fr": "Ground Zero", + "ge": "Ground Zero", + "hu": "Ground Zero", + "it": "Ground Zero", + "jp": "Ground Zero", + "kr": "Ground Zero", + "pl": "Ground Zero", + "po": "Ground Zero", + "ru": "Ground Zero" }, - "access_via": ["TherapistStash"] + "access_via": ["TherapistHideout"] + }, + "6617beeaa9cfa777ca915b7c": { + "// Trader name": "Ref", + "override_description": true, + "location_description": { + "ch": "Shoreline/Customs", + "cz": "Shoreline/Customs", + "en": "Shoreline/Customs", + "es-mx": "Shoreline/Customs", + "es": "Shoreline/Customs", + "fr": "Shoreline/Customs", + "ge": "Shoreline/Customs", + "hu": "Shoreline/Customs", + "it": "Shoreline/Customs", + "jp": "Shoreline/Customs", + "kr": "Shoreline/Customs", + "pl": "Shoreline/Customs", + "po": "Shoreline/Customs", + "ru": "Shoreline/Customs" + }, + "access_via": ["RailwayBridge", "PortRR"] }, "5a7c2eca46aef81a7ca2145d": { "// Trader name": "Mechanic", - "override_description": false, + "override_description": true, "location_description": { - "ch": "inside the factory (at home)", - "cz": "inside the factory (at home)", - "en": "inside the factory (at home)", - "es-mx": "inside the factory (at home)", - "es": "inside the factory (at home)", - "fr": "Dans l'usine (à la maison)", - "ge": "inside the factory (at home)", - "hu": "inside the factory (at home)", - "it": "inside the factory (at home)", - "jp": "inside the factory (at home)", - "kr": "inside the factory (at home)", - "pl": "inside the factory (at home)", - "po": "inside the factory (at home)", - "ru": "inside the factory (at home)" + "ch": "Factory", + "cz": "Factory", + "en": "Factory", + "es-mx": "Factory", + "es": "Factory", + "fr": "Factory", + "ge": "Factory", + "hu": "Factory", + "it": "Factory", + "jp": "Factory", + "kr": "Factory", + "pl": "Factory", + "po": "Factory", + "ru": "Factory" }, - "access_via": ["MechanicStash"] + "access_via": ["MechanicHideout"] }, "58330581ace78e27b8b10cee": { "// Trader name": "Skier", - "override_description": false, + "insurance_always_enabled": true, + "insurance_config": { + "insurance_price_coef": 100, + "min_payment": 0, + "min_return_hour": 0, + "max_return_hour": 0, + "max_storage_time": 480, + "return_chance_percent": 100 + }, + "override_description": true, "location_description": { - "ch": "To customs", - "cz": "To customs", - "en": "To customs", - "es-mx": "To customs", - "es": "To customs", - "fr": "Vers les douanes", - "ge": "To customs", - "hu": "To customs", - "it": "To customs", - "jp": "To customs", - "kr": "To customs", - "pl": "To customs", - "po": "To customs", - "ru": "To customs" + "ch": "Customs", + "cz": "Customs", + "en": "Customs", + "es-mx": "Customs", + "es": "Customs", + "fr": "Customs", + "ge": "Customs", + "hu": "Customs", + "it": "Customs", + "jp": "Customs", + "kr": "Customs", + "pl": "Customs", + "po": "Customs", + "ru": "Customs" }, - "access_via": ["SkierStash"] + "access_via": ["SkierHideout"] }, "5ac3b934156ae10c4430e83c": { "// Trader name": "Ragman", - "override_description": false, + "insurance_always_enabled": true, + "insurance_config": { + "insurance_price_coef": 75, + "min_payment": 0, + "min_return_hour": 0, + "max_return_hour": 0, + "max_storage_time": 480, + "return_chance_percent": 85 + }, + "override_description": true, "location_description": { - "ch": "To interchange", - "cz": "To interchange", - "en": "To interchange", - "es-mx": "To interchange", - "es": "To interchange", - "fr": "Vers l'échangeur", - "ge": "To interchange", - "hu": "To interchange", - "it": "To interchange", - "jp": "To interchange", - "kr": "To interchange", - "pl": "To interchange", - "po": "To interchange", - "ru": "To interchange" + "ch": "Interchange/Customs", + "cz": "Interchange/Customs", + "en": "Interchange/Customs", + "es-mx": "Interchange/Customs", + "es": "Interchange/Customs", + "fr": "Interchange/Customs", + "ge": "Interchange/Customs", + "hu": "Interchange/Customs", + "it": "Interchange/Customs", + "jp": "Interchange/Customs", + "kr": "Interchange/Customs", + "pl": "Interchange/Customs", + "po": "Interchange/Customs", + "ru": "Interchange/Customs" }, - "access_via": ["RagmanStash"] + "access_via": ["TrailerPark", "ScavCamp"] }, "5c0647fdd443bc2504c2d371": { "// Trader name": "Jaeger", - "override_description": false, + "override_description": true, "location_description": { - "ch": "In the woods, not far from the factory", - "cz": "In the woods, not far from the factory", - "en": "In the woods, not far from the factory", - "es-mx": "In the woods, not far from the factory", - "es": "In the woods, not far from the factory", - "fr": "Dans les bois, pas loin de l'usine", - "ge": "In the woods, not far from the factory", - "hu": "In the woods, not far from the factory", - "it": "In the woods, not far from the factory", - "jp": "In the woods, not far from the factory", - "kr": "In the woods, not far from the factory", - "pl": "In the woods, not far from the factory", - "po": "In the woods, not far from the factory", - "ru": "In the woods, not far from the factory" + "ch": "Woods", + "cz": "Woods", + "en": "Woods", + "es-mx": "Woods", + "es": "Woods", + "fr": "Woods", + "ge": "Woods", + "hu": "Woods", + "it": "Woods", + "jp": "Woods", + "kr": "Woods", + "pl": "Woods", + "po": "Woods", + "ru": "Woods" }, - "access_via": ["JaegerStash"] + "access_via": ["JaegerHideout"] }, "5935c25fb3acc3127c3d8cd9": { "// Trader name": "Peacekeeper", "override_description": true, "location_description": { - "ch": "In the tunnel between the shoreline and the lighthouse", - "cz": "In the tunnel between the shoreline and the lighthouse", - "en": "In the tunnel between the shoreline and the lighthouse", - "es-mx": "In the tunnel between the shoreline and the lighthouse", - "es": "In the tunnel between the shoreline and the lighthouse", - "fr": "Dans le tunnel entre le littoral et le phare", - "ge": "In the tunnel between the shoreline and the lighthouse", - "hu": "In the tunnel between the shoreline and the lighthouse", - "it": "In the tunnel between the shoreline and the lighthouse", - "jp": "In the tunnel between the shoreline and the lighthouse", - "kr": "In the tunnel between the shoreline and the lighthouse", - "pl": "In the tunnel between the shoreline and the lighthouse", - "po": "In the tunnel between the shoreline and the lighthouse", - "ru": "In the tunnel between the shoreline and the lighthouse" - }, - "access_via": ["PeacekeeperStash"] - }, - "6617beeaa9cfa777ca915b7c": { - "// Trader name": "Arena (Ref)", - "override_description": true, - "location_description": { - "ch": "To customs", - "cz": "To customs", - "en": "To customs", - "es-mx": "To customs", - "es": "To customs", - "fr": "Vers les douanes", - "ge": "To customs", - "hu": "To customs", - "it": "To customs", - "jp": "To customs", - "kr": "To customs", - "pl": "To customs", - "po": "To customs", - "ru": "To customs" + "ch": "Shoreline/Reserve", + "cz": "Shoreline/Reserve", + "en": "Shoreline/Reserve", + "es-mx": "Shoreline/Reserve", + "es": "Shoreline/Reserve", + "fr": "Shoreline/Reserve", + "ge": "Shoreline/Reserve", + "hu": "Shoreline/Reserve", + "it": "Shoreline/Reserve", + "jp": "Shoreline/Reserve", + "kr": "Shoreline/Reserve", + "pl": "Shoreline/Reserve", + "po": "Shoreline/Reserve", + "ru": "Shoreline/Reserve" }, - "access_via": ["SkierStash"] + "access_via": ["PeacekeeperHideout"] }, "579dc571d53a0658a154fbec": { "// Trader name": "Fence", @@ -270,158 +437,680 @@ "access_via": "*", "insurance_always_enabled": true, "insurance_config": { - "insurance_price_coef": 100, + "insurance_price_coef": 25, "min_payment": 0, - "min_return_hour": 1, - "max_return_hour": 2, + "min_return_hour": 0, + "max_return_hour": 0, "max_storage_time": 480, - "return_chance_percent": 100 + "return_chance_percent": 50 }, "repair_always_enabled": true, "repair_config": { "quality": 1, "currency": "5449016a4bdc2d6f028b456f", "currency_coefficient": 12, - "repair_price_coef": 100 + "repair_price_coef": 0 }, "heal_always_enabled": true }, + "Priscilu": { + "// mod integration for Priscilu": true, + "// Priscilu is available after extracting from Outskirts (woods map)": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Woods", + "cz": "Woods", + "en": "Woods", + "es-mx": "Woods", + "es": "Woods", + "fr": "Woods", + "ge": "Woods", + "hu": "Woods", + "it": "Woods", + "jp": "Woods", + "kr": "Woods", + "pl": "Woods", + "po": "Woods", + "ru": "Woods" + }, + "access_via": ["Outskirts"] + }, + "Legs": { + "// mod integration for Legs the Trader": true, + "// Gunsmith is available after extracting from Tunnel (shoreline map) or Lighthouse Tunnel (lighthouse map)": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Customs", + "cz": "Customs", + "en": "Customs", + "es-mx": "Customs", + "es": "Customs", + "fr": "Customs", + "ge": "Customs", + "hu": "Customs", + "it": "Customs", + "jp": "Customs", + "kr": "Customs", + "pl": "Customs", + "po": "Customs", + "ru": "Customs" + }, + "access_via": ["LegsHideout"] + }, + "HarryHideout": { + "// mod integration for HarryHideout": true, + "// HarryHideout is available at PlayerHideout": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Hideout", + "cz": "Hideout", + "en": "Hideout", + "es-mx": "Hideout", + "es": "Hideout", + "fr": "Hideout", + "ge": "Hideout", + "hu": "Hideout", + "it": "Hideout", + "jp": "Hideout", + "kr": "Hideout", + "pl": "Hideout", + "po": "Hideout", + "ru": "Hideout" + }, + "access_via": ["FactoryZB-1011"] + }, + "ArtemTrader": { + "// mod integration for ArtemTrader": true, + "// ArtemTrader is available at ArtemHideout": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Lighthouse", + "cz": "Lighthouse", + "en": "Lighthouse", + "es-mx": "Lighthouse", + "es": "Lighthouse", + "fr": "Lighthouse", + "ge": "Lighthouse", + "hu": "Lighthouse", + "it": "Lighthouse", + "jp": "Lighthouse", + "kr": "Lighthouse", + "pl": "Lighthouse", + "po": "Lighthouse", + "ru": "Lighthouse" + }, + "access_via": ["ArtemHideout"] + }, + "hephaestus_alxk": { + "// mod integration for Hephaestus": true, + "// Hephaestus is available at Streets": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Streets", + "cz": "Streets", + "en": "Streets", + "es-mx": "Streets", + "es": "Streets", + "fr": "Streets", + "ge": "Streets", + "hu": "Streets", + "it": "Streets", + "jp": "Streets", + "kr": "Streets", + "pl": "Streets", + "po": "Streets", + "ru": "Streets" + }, + "access_via": ["RuinedHouse"] + }, + "lotus": { + "// mod integration for lotus": true, + "// lotus is available at Emercom": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Interchange/Customs", + "cz": "Interchange/Customs", + "en": "Interchange/Customs", + "es-mx": "Interchange/Customs", + "es": "Interchange/Customs", + "fr": "Interchange/Customs", + "ge": "Interchange/Customs", + "hu": "Interchange/Customs", + "it": "Interchange/Customs", + "jp": "Interchange/Customs", + "kr": "Interchange/Customs", + "pl": "Interchange/Customs", + "po": "Interchange/Customs", + "ru": "Interchange/Customs" + }, + "access_via": ["Emercom", "Crossroads"] + }, + "Coyote": { + "// mod integration for Coyote": true, + "// Coyote is available at BasementDescent": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Ground Zero/Labs/Streets", + "cz": "Ground Zero/Labs/Streets", + "en": "Ground Zero/Labs/Streets", + "es-mx": "Ground Zero/Labs/Streets", + "es": "Ground Zero/Labs/Streets", + "fr": "Ground Zero/Labs/Streets", + "ge": "Ground Zero/Labs/Streets", + "hu": "Ground Zero/Labs/Streets", + "it": "Ground Zero/Labs/Streets", + "jp": "Ground Zero/Labs/Streets", + "kr": "Ground Zero/Labs/Streets", + "pl": "Ground Zero/Labs/Streets", + "po": "Ground Zero/Labs/Streets", + "ru": "Ground Zero/Labs/Streets" + }, + "access_via": ["BasementDescent"] + }, + "6688d464bc40c867f60e7d7e": { + "// mod integration for Scorpion": true, + "// Scorpion is available at ReserveZB-014": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Woods/Reserve", + "cz": "Woods/Reserve", + "en": "Woods/Reserve", + "es-mx": "Woods/Reserve", + "es": "Woods/Reserve", + "fr": "Woods/Reserve", + "ge": "Woods/Reserve", + "hu": "Woods/Reserve", + "it": "Woods/Reserve", + "jp": "Woods/Reserve", + "kr": "Woods/Reserve", + "pl": "Woods/Reserve", + "po": "Woods/Reserve", + "ru": "Woods/Reserve" + }, + "access_via": ["ReserveZB-014"] + }, "Sally": { - "// Trader name": "Sally", + "// mod integration for Sally": true, + "// Sally is available at Manhole": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Reserve/Streets", + "cz": "Reserve/Streets", + "en": "Reserve/Streets", + "es-mx": "Reserve/Streets", + "es": "Reserve/Streets", + "fr": "Reserve/Streets", + "ge": "Reserve/Streets", + "hu": "Reserve/Streets", + "it": "Reserve/Streets", + "jp": "Reserve/Streets", + "kr": "Reserve/Streets", + "pl": "Reserve/Streets", + "po": "Reserve/Streets", + "ru": "Reserve/Streets" + }, + "access_via": ["Manhole"] + }, + "668aaff35fd574b6dcc4a686": { + "// mod integration for PAINTER": true, + "// PAINTERSHOP is available at Car": false, + "disable_warning": true, "override_description": true, "location_description": { - "ch": "Somewhere in the Military reserve", - "cz": "Somewhere in the Military reserve", - "en": "Somewhere in the Military reserve", - "es-mx": "Somewhere in the Military reserve", - "es": "Somewhere in the Military reserve", - "fr": "Quelque part dans la réserve militaire", - "ge": "Somewhere in the Military reserve", - "hu": "Somewhere in the Military reserve", - "it": "Somewhere in the Military reserve", - "jp": "Somewhere in the Military reserve", - "kr": "Somewhere in the Military reserve", - "pl": "Somewhere in the Military reserve", - "po": "Somewhere in the Military reserve", - "ru": "Somewhere in the Military reserve" + "ch": "Customs/Streets/Interchange", + "cz": "Customs/Streets/Interchange", + "en": "Customs/Streets/Interchange", + "es-mx": "Customs/Streets/Interchange", + "es": "Customs/Streets/Interchange", + "fr": "Customs/Streets/Interchange", + "ge": "Customs/Streets/Interchange", + "hu": "Customs/Streets/Interchange", + "it": "Customs/Streets/Interchange", + "jp": "Customs/Streets/Interchange", + "kr": "Customs/Streets/Interchange", + "pl": "Customs/Streets/Interchange", + "po": "Customs/Streets/Interchange", + "ru": "Customs/Streets/Interchange" }, - "access_via": ["ReserveBunkerStash"] + "access_via": ["TarkovRR", "CrashSite", "Railway"] } }, "exfiltrations": { "factory4_day": { - "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate 3": "FactoryZB-016", + "Gate m": "FactoryZB-1012", + "Cellars": "FactoryZB-013", + "Camera Bunker Door": "MechanicHideout", + "Gate 0": "FactoryZB-1011", + "Office Window": "GasGate" }, "factory4_night": { - "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate 3": "FactoryZB-016", + "Gate m": "FactoryZB-1012", + "Cellars": "FactoryZB-013", + "Camera Bunker Door": "MechanicHideout", + "Gate 0": "FactoryZB-1011", + "Office Window": "GasGate" }, "bigmap": { - "Railroad To Tarkov": "TherapistStash", - "Railroad To Military Base": "SkierStash", - "ZB-1011": "MechanicStash", - "Old Azs Gate": "RagmanStash" + "Military Checkpoint": "ScavCP", + "EXFIL_ZB013": "FactoryZB-013", + "ZB-1012": "FactoryZB-1012", + "ZB-1011": "FactoryZB-1011", + "Dorms V-Ex": "DormsCar", + "Sniper Roadblock": "SniperRB", + "Smuggler's Boat": "SmugglersBoat", + "RUAF Roadblock": "RUAFCustoms", + "Crossroads": "Crossroads", + "Old Azs Gate": "GasGate", + "Railroad To Tarkov": "TarkovRR", + "Shack": "MilBaseCP", + "Warehouse 17": "SkierHideout", + "Trailer Park": "TrailerPark", + "Railroad To Military Base": "MilBaseRR", + "Railroad To Port": "PortRR", + "Factory Far Corner": "FactoryCorner", + "Trailer Park Workers Shack": "LegsHideout" }, "woods": { - "Factory Gate": "JaegerStash", - "South V-Ex": "ShorelineWoodsStash" + "un-sec": "NorthUNRoadblock", + "Factory Gate": "FactoryGate", + "East Gate": "PraporHideout", + "ZB-016": "FactoryZB-016", + "ZB-014": "ReserveZB-014", + "Outskirts": "Outskirts", + "UN Roadblock": "UNRoadblock", + "South V-Ex": "WoodsCar", + "RUAF Gate": "RUAFWoods", + "Mountain Stash": "JaegerHideout" }, "rezervbase": { - "EXFIL_ScavCooperation": "SkierStash", - "Exit4": "MilitaryLighthouseStash", - "EXFIL_Bunker_D2": "ReserveBunkerStash" + "EXFIL_ScavCooperation": "ScavLands", + "EXFIL_Train": "ReserveTrain", + "EXFIL_Bunker": "ReserveZB-014", + "Exit1": "HoleinWall", + "Exit4": "CPFence", + "Alpinist": "CliffDescent", + "EXFIL_Bunker_D2": "PeacekeeperHideout", + "EXFIL_vent": "Manhole" }, "interchange": { - "NW Exfil": "RagmanStash", - "Saferoom Exfil": "ReserveBunkerStash", - "PP Exfil": "PraporStash" + "PP Exfil": "InterchangeCar", + "Saferoom Exfil": "SafeRoom", + "NW Exfil": "Railway", + "SE Exfil": "Emercom", + "Interchange Cooperation": "ScavCamp" }, "shoreline": { - "Tunnel": "PeacekeeperStash", - "Shorl_V-Ex": "ShorelineWoodsStash", - "South Fence Passage": "ReserveBunkerStash" + "RedRebel_alp": "ClimbersTrail", + "Road to Customs": "RoadtoCustoms", + "Pier Boat": "PierBoat", + "Tunnel": "Tunnel", + "Wrecked Road": "RuinedRoad", + "Lighthouse_pass": "LighthousePath", + "Smugglers_Trail_coop": "SmugglersPath", + "South Fence Passage": "PeacekeeperHideout", + "Shorl_V-Ex": "ShorelineCar", + "Road_at_railbridge": "RailwayBridge" }, "lighthouse": { - "Coastal_South_Road": "PeacekeeperStash", - " V-Ex_light": "MilitaryLighthouseStash" + " V-Ex_light": "LighthouseCar", + "Shorl_free": "ShorelinePath", + "Coastal_South_Road": "SouthernRoad", + "Scav_Hideout_at_the_grotto": "ArtemHideout", + "EXFIL_Train": "LighthouseTrain", + "Nothern_Checkpoint": "NorthernCP", + "Alpinist_light": "MountainPass", + "tunnel_shared": "SideTunnel" }, "tarkovstreets": { - "E5": "TherapistStash", - "E7_car": "PraporStash", - "E9_sniper": "KlimovStash" + "E1": "SylobateElevator", + "scav_e3": "VentShaft", + "E3": "RuinedHouse", + "E4": "CrashSite", + "E7_car": "StreetsCar", + "E9_sniper": "KlimovStreet", + "scav_e1": "BasementDescent", + "scav_e2": "Catacombs", + "scav_e4": "Manhole", + "E2": "SewerRiver", + "E7": "ExpoCP" }, "laboratory": { - "lab_Parking_Gate": "PraporStash", - "lab_Hangar_Gate": "PraporStash", - "lab_Elevator_Med": "PraporStash", - "lab_Under_Storage_Collector": "PraporStash", - "lab_Elevator_Main": "PraporStash", - "lab_Vent": "PraporStash", - "lab_Elevator_Cargo": "PraporStash" + "lab_Hangar_Gate": "Catacombs", + "lab_Under_Storage_Collector": "SewerRiver", + "lab_Elevator_Main": "SylobateElevator", + "lab_Elevator_Cargo": "BasementDescent", + "lab_Vent": "VentShaft" }, "sandbox": { - "Scav_coop_exit": "TherapistStash", - "Sandbox_VExit": "PraporStash" + "Unity_free_exit": "TherapistHideout", + "Sandbox_VExit": "GZCar", + "Nakatani_stairs_free_exit": "BasementDescent", + "Sniper_exit": "KlimovStreet", + "Scav_coop_exit": "ExpoCP" } }, "infiltrations": { - "TherapistStash": { + "PraporHideout": { + "woods": ["Scav Bunker"] + }, + "SkierHideout": { + "bigmap": ["Warehouse 17"] + }, + "JaegerHideout": { + "woods": ["Mountain Stash"] + }, + "PeacekeeperHideout": { + "shoreline": ["Old Bunker"] + }, + "LegsHideout": { + "bigmap": ["Trailer Park Workers Shack"] + }, + "Emercom": { "bigmap": ["Crossroads"], - "sandbox": ["GZ Scav checkpoint"], - "tarkovstreets": ["Zmeevsky Alley"] + "interchange": ["Emercom"], + "shoreline": ["Road to Customs"] }, - "PraporStash": { - "tarkovstreets": ["Primorsky Vehicle Extract"], - "sandbox": ["Police Car"], - "laboratory": [ - "Cargo Elevator", - "Hangar Gate", - "Lab Sewage Conduit", - "Lab Vents", - "Main Elevator", - "Med Block Elevator", - "Parking Gate" - ], - "interchange": ["Car at Power Station"] - }, - "MechanicStash": { + "TherapistHideout": { + "sandbox": ["EmercomGZ"] + }, + "MechanicHideout": { + "factory4_day": ["Camera Bunker Door"], + "factory4_night": ["Camera Bunker Door"] + }, + "ArtemHideout": { + "lighthouse": ["Grotto"] + }, + "FactoryZB-016": { + "woods": ["ZB-016"], "factory4_day": ["Gate 3"], - "factory4_night": ["Gate 3"], - "bigmap": ["ZB-1011"] + "factory4_night": ["Gate 3"] + }, + "FactoryZB-013": { + "bigmap": ["ZB-1013"], + "factory4_day": ["Cellars"], + "factory4_night": ["Cellars"] + }, + "FactoryZB-1012": { + "bigmap": ["ZB-1012"], + "factory4_day": ["Med tent gates"], + "factory4_night": ["Med tent gates"] + }, + "FactoryZB-1011": { + "bigmap": ["ZB-1011"], + "factory4_day": ["Gate 0"], + "factory4_night": ["Gate 0"] }, - "RagmanStash": { + "ScavCP": { + "bigmap": ["Scav CP"], + "lighthouse": ["Northern CP"], + "woods": ["Outskirts"] + }, + "DormsCar": { + "bigmap": ["Dorms Car"], + "shoreline": ["North Fence Passage"] + }, + "SniperRB": { + "bigmap": ["Sniper Roadblock"], + "rezervbase": ["Hole In Wall"], + "shoreline": ["Smugglers Path"] + }, + "SmugglersBoat": { + "bigmap": ["Smugglers Boat"], + "woods": ["Sawmill River"], + "shoreline": ["Climbers Trail"], + "lighthouse": ["Southern Road Water"] + }, + "RUAFCustoms": { + "bigmap": ["RUAF Roadblock"], + "woods": ["UN Roadblock"] + }, + "Crossroads": { + "bigmap": ["Crossroads"], + "interchange": ["Emercom"], + "shoreline": ["Road to Customs"] + }, + "GasGate": { "bigmap": ["Old Gas Scav"], - "interchange": ["Railway"] + "woods": ["Factory Gate"], + "factory4_day": ["Office Window"], + "factory4_night": ["Office Window"] + }, + "TarkovRR": { + "bigmap": ["RR to Tarkov"], + "interchange": ["Railway"], + "tarkovstreets": ["Crash Site"] + }, + "PortRR": { + "bigmap": ["RR to Port"], + "shoreline": ["Railway Bridge"] }, - "SkierStash": { - "bigmap": ["Railroad To Military Base"], + "MilBaseRR": { + "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] }, - "PeacekeeperStash": { - "lighthouse": ["Lighthouse tunnel"], - "shoreline": ["Tunnel"] + "MilBaseCP": { + "bigmap": ["Military Base CP"], + "rezervbase": ["Scav lands"] }, - "JaegerStash": { - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"], - "woods": ["Factory Gate", "RUAFRoadblock", "UN Roadblock"] + "TrailerPark": { + "bigmap": ["Trailer Park"], + "interchange": ["Scav Camp"] }, - "MilitaryLighthouseStash": { - "lighthouse": ["Lighthouse Vehicle Extract"], - "rezervbase": ["CP Fence"] + "FactoryCorner": { + "bigmap": ["Factory Far Corner"], + "woods": ["RUAF Gate"] }, - "ReserveBunkerStash": { - "rezervbase": ["D-2"], - "interchange": ["Safe Room"], - "shoreline": ["North Fence Passage"] + "NorthUNRoadblock": { + "bigmap": ["RUAF Roadblock"], + "woods": ["Northern UN Roadblock"] + }, + "FactoryGate": { + "bigmap": ["Old Gas Scav"], + "woods": ["Factory Gate"] + }, + "Outskirts": { + "bigmap": ["Scav CP"], + "lighthouse": ["Northern CP"], + "woods": ["Outskirts"] + }, + "UNRoadblock": { + "bigmap": ["RUAF Roadblock"], + "woods": ["UN Roadblock"], + "interchange": ["Railway"] + }, + "WoodsCar": { + "tarkovstreets": ["Streets Vehicle Extract"], + "interchange": ["Interchange Vehicle Extract"], + "sandbox": ["Police Car"], + "woods": ["Woods Vehicle Extract"] + }, + "RUAFWoods": { + "bigmap": ["Factory Far Corner"], + "woods": ["RUAF Gate"] + }, + "ReserveZB-014": { + "woods": ["ZB-014"] + }, + "ScavLands": { + "bigmap": ["Military Base CP"], + "rezervbase": ["Scav lands"] + }, + "ReserveTrain": { + "bigmap": ["RR to Military Base"], + "woods": ["Factory Gate"], + "lighthouse": ["Armored Train LH"], + "shoreline": ["Railway Bridge"], + "interchange": ["Railway"], + "rezervbase": ["Train Station"], + "tarkovstreets": ["Crash Site"] }, - "ShorelineWoodsStash": { + "HoleinWall": { + "bigmap": ["Dorms Car"], + "rezervbase": ["Hole In Wall"] + }, + "CPFence": { + "rezervbase": ["Checkpoint Fence"], + "lighthouse": ["Northeast Mountains"] + }, + "CliffDescent": { + "rezervbase": ["Cliff"], + "shoreline": ["Climbers Trail"] + }, + "Manhole": { + "rezervbase": ["Reserve Manhole"], + "tarkovstreets": ["Streets Manhole"] + }, + "InterchangeCar": { + "tarkovstreets": ["Streets Vehicle Extract"], + "interchange": ["Interchange Vehicle Extract"], + "sandbox": ["Police Car"], + "woods": ["Woods Vehicle Extract"] + }, + "SafeRoom": { + "interchange": ["Safe Room"] + }, + "Railway": { + "interchange": ["Railway"], + "woods": ["UN Roadblock"], + "tarkovstreets": ["Crash Site"] + }, + "ScavCamp": { + "interchange": ["Scav Camp"], + "bigmap": ["Trailer Park"] + }, + "ClimbersTrail": { + "rezervbase": ["Cliff"], + "shoreline": ["Climbers Trail"] + }, + "RoadtoCustoms": { + "bigmap": ["Sniper Roadblock"], "shoreline": ["Road to Customs"], - "woods": ["Bridge Car"] + "interchange": ["Emercom"] + }, + "PierBoat": { + "bigmap": ["Smugglers Boat"], + "shoreline": ["Pier Boat"], + "lighthouse": ["Southern Road Water"], + "woods": ["Sawmill River"] + }, + "Tunnel": { + "shoreline": ["Shoreline Tunnel"], + "lighthouse": ["Lighthouse Tunnel"] }, - "KlimovStash": { + "RuinedRoad": { + "shoreline": ["Ruined Road"], + "lighthouse": ["Southern Road"] + }, + "ShorelinePath": { + "shoreline": ["Path to Lighthouse"], + "lighthouse": ["Path to Shoreline"] + }, + "SmugglersPath": { + "shoreline": ["Smugglers Path"], + "bigmap": ["Sniper Roadblock"], + "rezervbase": ["Hole In Wall"] + }, + "ShorelineCar": { + "bigmap": ["Dorms Car"], + "shoreline": ["North Fence Passage"] + }, + "RailwayBridge": { + "bigmap": ["RR to Port"], + "shoreline": ["Railway Bridge"] + }, + "LighthouseCar": { + "rezervbase": ["Checkpoint Fence"], + "lighthouse": ["Lighthouse Vehicle Extract"] + }, + "LighthousePath": { + "shoreline": ["Path to Lighthouse"], + "lighthouse": ["Path to Shoreline"] + }, + "SouthernRoad": { + "shoreline": ["Ruined Road"], + "lighthouse": ["Southern Road"] + }, + "LighthouseTrain": { + "bigmap": ["RR to Military Base"], + "woods": ["Factory Gate"], + "lighthouse": ["Armored Train LH"], + "shoreline": ["Railway Bridge"], + "interchange": ["Railway"], + "rezervbase": ["Train Station"], + "tarkovstreets": ["Crash Site"] + }, + "NorthernCP": { + "bigmap": ["Scav CP"], + "lighthouse": ["Northern CP"], + "woods": ["Outskirts"] + }, + "MountainPass": { + "shoreline": ["Path to Lighthouse"], + "lighthouse": ["Mountain Pass"] + }, + "SideTunnel": { + "shoreline": ["Shoreline Tunnel"], + "lighthouse": ["Lighthouse Tunnel"] + }, + "BasementDescent": { + "sandbox": ["Nakatani Basement Stairs"], + "tarkovstreets": ["Basement Descent"], + "laboratory": ["Cargo Elevator"] + }, + "RuinedHouse": { + "tarkovstreets": ["Streets Ruined House"] + }, + "ExpoCP": { + "sandbox": ["Scav Hideout"], + "tarkovstreets": ["Expo Checkpoint"] + }, + "KlimovStreet": { + "sandbox": ["Mira Ave"], "tarkovstreets": ["Klimov Street"] + }, + "VentShaft": { + "tarkovstreets": ["Streets Vents"], + "laboratory": ["Lab Vents"] + }, + "SewerRiver": { + "tarkovstreets": ["Sewer River"], + "laboratory": ["Lab Sewage Conduit"] + }, + "SylobateElevator": { + "tarkovstreets": ["Sylobate Elevator"], + "laboratory": ["Main Elevator"] + }, + "CrashSite": { + "tarkovstreets": ["Evacuation Zone"], + "interchange": ["Railway"], + "woods": ["Woods Vehicle Extract"] + }, + "Catacombs": { + "tarkovstreets": ["Catacombs"], + "laboratory": ["Hangar Gate"] + }, + "StreetsCar": { + "tarkovstreets": ["Streets Vehicle Extract"], + "interchange": ["Interchange Vehicle Extract"], + "sandbox": ["Police Car"], + "woods": ["Woods Vehicle Extract"] + }, + "GZCar": { + "tarkovstreets": ["Streets Vehicle Extract"], + "interchange": ["Interchange Vehicle Extract"], + "sandbox": ["Police Car"], + "woods": ["Woods Vehicle Extract"] } } } diff --git a/configs/Default/player_spawnpoints.json b/configs/Default/player_spawnpoints.json index cffa610a..d3b9a5fb 100644 --- a/configs/Default/player_spawnpoints.json +++ b/configs/Default/player_spawnpoints.json @@ -1,97 +1,63 @@ { + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "factory4_day": { "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, + "Position": [-52.5704842, 1.25745475, 55.06734], "Rotation": 93.18849 }, "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, + "Position": [58.67002, 0.233123064, 57.4049568], "Rotation": 129.412323 }, "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, + "Position": [-18.9917545, 0.229607314, -46.5803642], "Rotation": 19.03057 }, "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, + "Position": [66.78813, -2.63332653, -30.9360619], "Rotation": 231.811646 }, + "Camera Bunker Door": { + "Position": [-20.8695526, -2.63423038, 34.9322433], + "Rotation": 0.891350448 + }, "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, + "Position": [17.66614, 8.210876, 40.92688], "Rotation": 158.9888 } }, "factory4_night": { "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, + "Position": [-52.5704842, 1.25745475, 55.06734], "Rotation": 93.18849 }, "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, + "Position": [58.67002, 0.233123064, 57.4049568], "Rotation": 129.412323 }, "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, + "Position": [-18.9917545, 0.229607314, -46.5803642], "Rotation": 19.03057 }, "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, + "Position": [66.78813, -2.63332653, -30.9360619], "Rotation": 231.811646 }, + "Camera Bunker Door": { + "Position": [-20.8695526, -2.63423038, 34.9322433], + "Rotation": 0.891350448 + }, "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, + "Position": [17.66614, 8.210876, 40.92688], "Rotation": 158.9888 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "bigmap": { "Military Base CP": { "Position": [674.5625, 5.60742664, 123.641823], "Rotation": 238.056732 }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, "ZB-1011": { "Position": [629.4296, -2.77441788, -127.8221], "Rotation": 97.17987 @@ -108,11 +74,19 @@ "Position": [-324.1054, -0.317715019, -91.3120041], "Rotation": 31.98688 }, + "Trailer Park": { + "Position": [-310.01, 0.89, -215.43], + "Rotation": 31.98688 + }, + "Trailer Park Workers Shack": { + "Position": [-251.01, 0.89, -227.43], + "Rotation": 31.98688 + }, "RUAF Roadblock": { "Position": [-3.56247973, 1.08614612, -132.9248], "Rotation": 54.44671 }, - "Smuggler's Boat": { + "Smugglers Boat": { "Position": [-28.292078, -11.5068331, 109.108429], "Rotation": 187.815948 }, @@ -120,45 +94,65 @@ "Position": [30.446312, -0.259777457, 118.656456], "Rotation": 327.517334 }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 + "Factory Far Corner": { + "Position": [647.2151, 1.12474906, -150.711029], + "Rotation": 331.2538 }, "Old Gas Scav": { "Position": [302.545, 2.91025, -185.017761], "Rotation": 202.349335 }, - "MallTrain": { - "Position": [-154.6799, 2.266766, -221.5874], - "Rotation": 327.8281 + "RR to Military Base": { + "Position": [458.392639, 4.95283127, 181.01564], + "Rotation": 256.057983 + }, + "RR to Port": { + "Position": [-150.3853, 2.62803984, 23.7549515], + "Rotation": 1.93337643 }, - "PraveenGasoline": { - "Position": [354.8507, 1.106263, -191.5768], - "Rotation": 23.4955 + "RR to Tarkov": { + "Position": [-165.420151, 3.40357137, -200.949509], + "Rotation": 6.05172825 }, - "OfficePath": { - "Position": [655.933, 1.098399, -166.3037], - "rotation": 302.8839 + "Warehouse 17": { + "Position": [48.11184, 1.10045552, -84.83577], + "Rotation": 155.8685 }, - "RUAFAdmin": { - "Position": [667.3405, 1.064447, -58.31626], - "rotation": 287.2482 + "Dorms Car": { + "Position": [191.627884, -2.16589069, 208.912079], + "Rotation": 278.0221 + }, + "Scav CP": { + "Position": [647.141, -0.3182248, -25.9616776], + "Rotation": 307.1494 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "woods": { - "UN Roadblock": { - "Comment": "UN Roadblock", - "Position": [-543.3435, 9.776281, -78.09744], - "Rotation": 228.816986 + "Northern UN Roadblock": { + "Position": [-555.2336, 9.391193, -76.86284], + "Rotation": 138.160156 }, "Factory Gate": { "Position": [-346.51947, -2.32620764, 353.3336], "Rotation": 174.779083 }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], + "RUAF Gate": { + "Position": [-146.51947, 1.22620764, 425.6336], + "Rotation": 162.779083 + }, + "ZB-014": { + "Position": [447.93, -14.25, 67.26], "Rotation": 285.467377 }, + "ZB-016": { + "Position": [-388.16, 3.25, 20.05], + "Rotation": 115.467377 + }, + "Sawmill River": { + "Position": [-649.91, 8.61, -272.75], + "Rotation": 138.160156 + }, "Outskirts": { "Position": [334.693359, -11.418191, 327.578033], "Rotation": 160.7393 @@ -167,15 +161,36 @@ "Position": [190.682846, -14.9319124, 219.147934], "Rotation": 227.765961 }, - "Bridge Car": { + "Mountain Stash": { + "Position": [-215.205872, 31.7007847, -209.631348], + "Rotation": 335.046753 + }, + "Sniper Rock Bunker": { + "Position": [-155.286, 50.95411, -277.7933], + "Rotation": 345.938324 + }, + "UN Roadblock": { + "Position": [-521.465332, -1.258715, 288.813171], + "Rotation": 76.4774246 + }, + "Scav Bridge": { + "Position": [98.54763, 16.67556, -843.773254], + "Rotation": -843.773254 + }, + "Woods Vehicle Extract": { "Position": [-487.348541, 15.0604687, -497.965179], "Rotation": 24.781599 }, - "RUAFRoadblock": { - "Position": [-129.7272, -1.194496, 415.476], - "Rotation": 146.2519 + "Old Station": { + "Position": [-504.468628, 7.252748, 151.354584], + "Rotation": 134.066681 + }, + "Scav Bunker": { + "Position": [224.07019, 20.14909, -708.5178], + "Rotation": 104.772415 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "rezervbase": { "Scav lands": { "Position": [-120.954071, -6.94097, -129.4829], @@ -189,55 +204,85 @@ "Position": [-15.9683733, 18.4609661, 195.898743], "Rotation": 190.4635 }, - "CP Fence": { + "Checkpoint Fence": { "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 + "Position": [56.2388641, -6.94445145, 90.22048], + "Rotation": 287.982239 }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 + "Bunker Hermetic": { + "Position": [64.5668, -6.95917463, -190.306641], + "Rotation": 280.9828 }, "Depot Hermetic": { "Position": [118.866768, -12.2845945, -119.324211], "Rotation": 299.889923 }, + "Heating Pipe": { + "Position": [-9.3644, -5.60308161, -186.8873], + "Rotation": 330.65134 + }, "Hole In Wall": { "Position": [-262.3644, -6.20308161, 47.7328873], "Rotation": 89.65134 }, + "Reserve Manhole": { + "Position": [50.6118279, -6.97395849, 73.78378], + "Rotation": 213.616745 + }, "Train Station": { "Position": [166.653687, -5.19410563, -144.143341], "Rotation": 191.8541 + }, + "D-2": { + "Position": [-116.999077, -18.3659115, 169.5836], + "Rotation": 128.773651 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "interchange": { - "Car at Power Station": { + "Interchange Vehicle Extract": { "Position": [-242.849625, 21.32544, -372.680878], "Rotation": 52.06011 }, + "Fence Gap": { + "Position": [-220.849625, 21.35, -40.680878], + "Rotation": 52.06011 + }, "Railway": { "Position": [473.177979, 18.4533634, -390.7554], "Rotation": 281.3094 }, + "Emercom": { + "Position": [-328.429871, 21.3254356, 260.571655], + "Rotation": 73.0782242 + }, + "Scav Camp": { + "Position": [283.740051, 21.3254337, -34.4532776], + "Rotation": 138.160156 + }, + "FromCrossroads": { + "Position": [283.740051, 21.3254337, 265.4532776], + "Rotation": 100.086945 + }, "Safe Room": { "Position": [-49.4776039, 21.3254585, 47.4479179], "Rotation": 344.7888 - }, - "EmercomMall": { - "Position": [-313.2805, 21.32544, 254.3763], - "Rotation": 105.2137 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "shoreline": { "North Fence Passage": { "Position": [-510.430939, -11.9056053, -373.174316], "Rotation": 41.4962769 }, + "Old Bunker": { + "Position": [-390.330939, -5.4056053, -374.74316], + "Rotation": 41.4962769 + }, + "Climbers Trail": { + "Position": [-198.30939, -11.2056053, -360.54316], + "Rotation": 56.4962769 + }, "Road to Customs": { "Position": [-864.0486, -43.44637, 16.5865173], "Rotation": 18.213295 @@ -246,15 +291,40 @@ "Position": [-311.829468, -64.56999, 559.7176], "Rotation": 210.594009 }, - "Tunnel": { + "Shoreline Tunnel": { "Position": [356.304871, -59.9092941, 313.181915], "Rotation": 274.0321 }, + "Ruined Road": { + "Position": [350.51, -59.67, 324.86], + "Rotation": 55.0321 + }, + "Admin Basement": { + "Position": [-252.256073, -7.096292, -145.4518], + "Rotation": 359.0387 + }, + "CCP Temporary": { + "Position": [-967.462463, -59.678566, 375.060669], + "Rotation": 166.59436 + }, + "Shoreline Northern Cliffs": { + "Position": [-174.818451, -11.1724739, -364.436646], + "Rotation": 330.086456 + }, + "Railway Bridge": { + "Position": [-1023.37292, -60.67251, 314.364075], + "Rotation": 24.1157665 + }, "Path to Lighthouse": { "Position": [362.138428, -54.85863, -181.549271], "Rotation": 335.1047 + }, + "Smugglers Path": { + "Position": [-700.538428, -25.45863, -242.9271], + "Rotation": 335.1047 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "lighthouse": { "Path to Shoreline": { "Position": [-284.0998, 14.4007835, -161.669266], @@ -264,19 +334,52 @@ "Position": [-316.70462, 15.1516333, -784.0004], "Rotation": 37.57063 }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 + "Industrial Gates": { + "Position": [-155.70462, 14.1516333, -789.0004], + "Rotation": 347.57063 + }, + "Lighthouse Tunnel": { + "Position": [-54.28882, 5.95763159, 327.053345], + "Rotation": 106.236305 + }, + "Armored Train LH": { + "Position": [10.0, 11.97, -870.85], + "Rotation": 180.236305 + }, + "Northeast Mountains": { + "Position": [-362.13, 26.1, -535.54], + "Rotation": 85.936305 + }, + "Southern Road Water": { + "Position": [-225.77, 0.02, 442.06], + "Rotation": 120.936305 + }, + "Grotto": { + "Position": [194.516525, -0.48209092, -491.773224], + "Rotation": 182.743759 + }, + "Northern CP": { + "Position": [115.480957, 4.61967325, -980.5756], + "Rotation": 347.679443 }, "Lighthouse Docks Boat": { "Position": [164.16626, 0.317433029, -163.23497], "Rotation": 285.558533 + }, + "Mountain Pass": { + "Position": [-147.143173, 30.5996075, -4.088336], + "Rotation": 74.17951 + }, + "Southern Road": { + "Position": [-215.268738, 5.94645643, 419.227417], + "Rotation": 77.76075 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 + "Streets Vehicle Extract": { + "Position": [-8.757395, 2.31632733, 458.126923], + "Rotation": 177.1993 }, "Basement Descent": { "Position": [73.63199, -2.13371778, 56.0767555], @@ -318,11 +421,32 @@ "Position": [176.868683, 0.7778812, 172.814636], "Rotation": 304.3322 }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 + "Expo Checkpoint": { + "Position": [215, -1.93, -88.75], + "Rotation": 304.3322 + }, + "Cardinal Appartments Parking": { + "Position": [103.6, -1.9, -155.3], + "Rotation": 304.3322 + }, + "Cardinal Appartments": { + "Position": [82.8, 3.97, -175.4], + "Rotation": 304.3322 + }, + "Crash Site": { + "Position": [269.3, 3.4, 427.25], + "Rotation": 87.62667 + }, + "Kamchatskya Arch": { + "Position": [260.6, -4.5, 49.6], + "Rotation": 304.3322 + }, + "Sylobate Elevator": { + "Position": [-47.23, 9.6, -68.04], + "Rotation": 15.33 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "laboratory": { "Cargo Elevator": { "Position": [-114.2475, 4.101831, -408.6356], @@ -353,22 +477,27 @@ "Rotation": 14.0038671 } }, + "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "sandbox": { - "Nakatani Basement": { + "Nakatani Basement Stairs": { "Position": [5.295958, 22.73891, 331.8584], "Rotation": 132.0392 }, "Mira Ave": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "GZ Scav checkpoint": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 + "Position": [215.1694, 16.01762, 40.5], + "Rotation": 0.7702 }, "Police Car": { "Position": [-12.97, 22.6, 116.99], "Rotation": 90.0 + }, + "Scav Hideout": { + "Position": [31.74341, 22.59711, -85.79424], + "Rotation": 43.04764 + }, + "EmercomGZ": { + "Position": [152.5, 24.1, -89.4], + "Rotation": 0.85 } } } diff --git a/configs/Default/PathToTarkov-1.png b/configs/LegacyPathToTarkovV5/PathToTarkov-1.png similarity index 100% rename from configs/Default/PathToTarkov-1.png rename to configs/LegacyPathToTarkovV5/PathToTarkov-1.png diff --git a/configs/Default/PathToTarkov.png b/configs/LegacyPathToTarkovV5/PathToTarkov.png similarity index 100% rename from configs/Default/PathToTarkov.png rename to configs/LegacyPathToTarkovV5/PathToTarkov.png diff --git a/configs/LegacyPathToTarkovV5/Tooltips.json b/configs/LegacyPathToTarkovV5/Tooltips.json new file mode 100644 index 00000000..78080e84 --- /dev/null +++ b/configs/LegacyPathToTarkovV5/Tooltips.json @@ -0,0 +1,96 @@ +{ + "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", + "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", + "comment": "If you are using the standard config, this should be set to false", + + "language": "english", + + "moddedTraderCompat": false, + "additionalLocalesToggle": false, + + "moddedTraderExtracts": [ + "Saferoom Exfil", + "Saferoom (Goblin King)", + "EXFIL_ZB013", + "ZB-1013 Storage Bunker (Broker)" + ], + + "localesToChangeAdditional": [], + + "localesToChange": [ + "Gate 3", + "Gate 3 to Customs - Mechanic (Hideout)", + "Office Window", + "Office Window to woods - Jeager", + + "Gate 3", + "Gate 3 to Customs - Mechanic (Hideout)", + "Office Window", + "Office Window to woods - Jeager", + + "Railroad To Tarkov", + "Railroad To Tarkov to Streets, GZ - Therapist, ", + "Railroad To Military Base", + "Railroad To Military Base to Reserve - Skier", + "ZB-1011", + "ZB-1011 to Factory - Mechanic (Hideout)", + "Old Azs Gate", + "Old Gas Station Gate to Interchange - Ragman", + + "Factory Gate", + "Factory Gate to Factory - Jeager", + "South V-Ex", + "South V-Ex to Shoreline", + + "EXFIL_ScavCooperation", + "Scav Lands to Customs - Skier", + "Exit4", + "Checkpoint Fence to Lighthouse", + "EXFIL_Bunker_D2", + "D-2 to interchange", + + "NW Exfil", + "Railway Exfil to Customs - Ragman", + "Saferoom Exfil", + "Saferoom to Reserve, Shoreline", + "PP Exfil", + "Power Station V-Ex to Customs, Streets, GZ, Labs - Prapor", + + "Tunnel", + "Tunnel to Lighthouse - Peacekeeper", + "Shorl_V-Ex", + "Road to North V-Ex to Woods", + "South Fence Passage", + "Old Bunker to Reserve, Interchange", + + "Coastal_South_Road", + "Southern Road to Shoreline - Peacekeeper", + " V-Ex_light", + "Road to Military Base V-Ex to Reserve", + + "E5", + "Collapsed Crane to Customs, GZ - Therapist", + "E7_car", + "Primorsky Ave Taxi V-Ex to Customs, Interchange, GZ, Labs - Prapor", + + "lab_Parking_Gate", + "Parking Gate", + "lab_Hangar_Gate", + "Hangar Gate", + "lab_Elevator_Med", + "Medical Block Elevator", + "lab_Under_Storage_Collector", + "Sewage Conduit", + "lab_Elevator_Main", + "Main Elevator", + "lab_Vent", + "Ventilation Shaft", + "lab_Elevator_Cargo", + "Cargo Elevator", + + "Scav_coop_exit", + "Scav Checkpoint to Customs, Streets - Therapist", + "Sandbox_VExit", + "Police Cordon V-Ex to Customs, Interchange, Streets, Labs - Prapor" + ] +} diff --git a/configs/LegacyPathToTarkovV5/config.json b/configs/LegacyPathToTarkovV5/config.json new file mode 100644 index 00000000..bc6c7b35 --- /dev/null +++ b/configs/LegacyPathToTarkovV5/config.json @@ -0,0 +1,427 @@ +{ + "enabled": true, + "debug": true, + "override_by_profiles": {}, + "initial_offraid_position": "MechanicStash", + "respawn_at": ["MechanicStash"], + "reset_offraid_position_on_player_die": true, + "traders_access_restriction": true, + "hideout_multistash_enabled": true, + "vanilla_exfils_requirements": false, + "player_scav_move_offraid_position": false, + "workbench_always_enabled": true, + "bypass_keep_found_in_raid_tweak": false, + "bypass_uninstall_procedure": false, + "restrictions_in_raid": { + "5449016a4bdc2d6f028b456f": { + "// type = roubles": true, + "Value": 10000000 + }, + "5696686a4bdc2da3298b456a": { + "// type = dollars": true, + "Value": 100000 + }, + "569668774bdc2da2298b4568": { + "// type = euros": true, + "Value": 100000 + } + }, + "offraid_regen_config": { + "hydration": { + "access_via": ["*"] + }, + "energy": { + "access_via": ["*"] + }, + "health": { + "access_via": ["*"] + } + }, + "hideout_main_stash_access_via": ["MechanicStash"], + "hideout_secondary_stashes": [ + { + "id": "PathToTarkov_Therapist_stash", + "size": 22, + "access_via": ["TherapistStash"] + }, + { + "id": "PathToTarkov_Prapor_stash", + "size": 22, + "access_via": ["PraporStash"] + }, + { + "id": "PathToTarkov_Mechanic_stash", + "size": 22, + "access_via": ["MechanicStash"] + }, + { + "id": "PathToTarkov_Ragman_stash", + "size": 22, + "access_via": ["RagmanStash"] + }, + { + "id": "PathToTarkov_Skier_stash", + "size": 22, + "access_via": ["SkierStash"] + }, + { + "id": "PathToTarkov_Peacekeeper_stash", + "size": 22, + "access_via": ["PeacekeeperStash"] + }, + { + "id": "PathToTarkov_Jaeger_stash", + "size": 22, + "access_via": ["JaegerStash"] + }, + { + "id": "PathToTarkov_MilitaryLighthouse_stash", + "size": 22, + "access_via": ["MilitaryLighthouseStash"] + }, + { + "id": "PathToTarkov_ReserveBunker_stash", + "size": 22, + "access_via": ["ReserveBunkerStash"] + }, + { + "id": "PathToTarkov_Car_stash", + "size": 22, + "access_via": ["ShorelineWoodsStash"] + }, + { + "id": "PathToTarkov_Klimov_stash", + "size": 22, + "access_via": ["KlimovStash"] + } + ], + "traders_config": { + "54cb50c76803fa8b248b4571": { + "// Trader name": "Prapor", + "override_description": false, + "location_description": { + "ch": "In his car, he hangs around the city", + "cz": "In his car, he hangs around the city", + "en": "In his car, he hangs around the city", + "es-mx": "In his car, he hangs around the city", + "es": "In his car, he hangs around the city", + "fr": "Dans sa voiture, il traine en ville", + "ge": "In his car, he hangs around the city", + "hu": "In his car, he hangs around the city", + "it": "In his car, he hangs around the city", + "jp": "In his car, he hangs around the city", + "kr": "In his car, he hangs around the city", + "pl": "In his car, he hangs around the city", + "po": "In his car, he hangs around the city", + "ru": "In his car, he hangs around the city" + }, + "access_via": ["PraporStash"] + }, + "54cb57776803fa99248b456e": { + "// Trader name": "Therapist", + "override_description": false, + "location_description": { + "ch": "in the city", + "cz": "In the city", + "en": "In the city", + "es-mx": "In the city", + "es": "In the city", + "fr": "En ville", + "ge": "In the city", + "hu": "In the city", + "it": "In the city", + "jp": "In the city", + "kr": "In the city", + "pl": "In the city", + "po": "In the city", + "ru": "In the city" + }, + "access_via": ["TherapistStash"] + }, + "5a7c2eca46aef81a7ca2145d": { + "// Trader name": "Mechanic", + "override_description": false, + "location_description": { + "ch": "inside the factory (at home)", + "cz": "inside the factory (at home)", + "en": "inside the factory (at home)", + "es-mx": "inside the factory (at home)", + "es": "inside the factory (at home)", + "fr": "Dans l'usine (à la maison)", + "ge": "inside the factory (at home)", + "hu": "inside the factory (at home)", + "it": "inside the factory (at home)", + "jp": "inside the factory (at home)", + "kr": "inside the factory (at home)", + "pl": "inside the factory (at home)", + "po": "inside the factory (at home)", + "ru": "inside the factory (at home)" + }, + "access_via": ["MechanicStash"] + }, + "58330581ace78e27b8b10cee": { + "// Trader name": "Skier", + "override_description": false, + "location_description": { + "ch": "To customs", + "cz": "To customs", + "en": "To customs", + "es-mx": "To customs", + "es": "To customs", + "fr": "Vers les douanes", + "ge": "To customs", + "hu": "To customs", + "it": "To customs", + "jp": "To customs", + "kr": "To customs", + "pl": "To customs", + "po": "To customs", + "ru": "To customs" + }, + "access_via": ["SkierStash"] + }, + "5ac3b934156ae10c4430e83c": { + "// Trader name": "Ragman", + "override_description": false, + "location_description": { + "ch": "To interchange", + "cz": "To interchange", + "en": "To interchange", + "es-mx": "To interchange", + "es": "To interchange", + "fr": "Vers l'échangeur", + "ge": "To interchange", + "hu": "To interchange", + "it": "To interchange", + "jp": "To interchange", + "kr": "To interchange", + "pl": "To interchange", + "po": "To interchange", + "ru": "To interchange" + }, + "access_via": ["RagmanStash"] + }, + "5c0647fdd443bc2504c2d371": { + "// Trader name": "Jaeger", + "override_description": false, + "location_description": { + "ch": "In the woods, not far from the factory", + "cz": "In the woods, not far from the factory", + "en": "In the woods, not far from the factory", + "es-mx": "In the woods, not far from the factory", + "es": "In the woods, not far from the factory", + "fr": "Dans les bois, pas loin de l'usine", + "ge": "In the woods, not far from the factory", + "hu": "In the woods, not far from the factory", + "it": "In the woods, not far from the factory", + "jp": "In the woods, not far from the factory", + "kr": "In the woods, not far from the factory", + "pl": "In the woods, not far from the factory", + "po": "In the woods, not far from the factory", + "ru": "In the woods, not far from the factory" + }, + "access_via": ["JaegerStash"] + }, + "5935c25fb3acc3127c3d8cd9": { + "// Trader name": "Peacekeeper", + "override_description": true, + "location_description": { + "ch": "In the tunnel between the shoreline and the lighthouse", + "cz": "In the tunnel between the shoreline and the lighthouse", + "en": "In the tunnel between the shoreline and the lighthouse", + "es-mx": "In the tunnel between the shoreline and the lighthouse", + "es": "In the tunnel between the shoreline and the lighthouse", + "fr": "Dans le tunnel entre le littoral et le phare", + "ge": "In the tunnel between the shoreline and the lighthouse", + "hu": "In the tunnel between the shoreline and the lighthouse", + "it": "In the tunnel between the shoreline and the lighthouse", + "jp": "In the tunnel between the shoreline and the lighthouse", + "kr": "In the tunnel between the shoreline and the lighthouse", + "pl": "In the tunnel between the shoreline and the lighthouse", + "po": "In the tunnel between the shoreline and the lighthouse", + "ru": "In the tunnel between the shoreline and the lighthouse" + }, + "access_via": ["PeacekeeperStash"] + }, + "6617beeaa9cfa777ca915b7c": { + "// Trader name": "Arena (Ref)", + "override_description": true, + "location_description": { + "ch": "To customs", + "cz": "To customs", + "en": "To customs", + "es-mx": "To customs", + "es": "To customs", + "fr": "Vers les douanes", + "ge": "To customs", + "hu": "To customs", + "it": "To customs", + "jp": "To customs", + "kr": "To customs", + "pl": "To customs", + "po": "To customs", + "ru": "To customs" + }, + "access_via": ["SkierStash"] + }, + "579dc571d53a0658a154fbec": { + "// Trader name": "Fence", + "// Fence is accessible everywhere": true, + "access_via": "*", + "insurance_always_enabled": true, + "insurance_config": { + "insurance_price_coef": 100, + "min_payment": 0, + "min_return_hour": 1, + "max_return_hour": 2, + "max_storage_time": 480, + "return_chance_percent": 100 + }, + "repair_always_enabled": true, + "repair_config": { + "quality": 1, + "currency": "5449016a4bdc2d6f028b456f", + "currency_coefficient": 12, + "repair_price_coef": 100 + }, + "heal_always_enabled": true + }, + "Sally": { + "// Trader name": "Sally", + "override_description": true, + "location_description": { + "ch": "Somewhere in the Military reserve", + "cz": "Somewhere in the Military reserve", + "en": "Somewhere in the Military reserve", + "es-mx": "Somewhere in the Military reserve", + "es": "Somewhere in the Military reserve", + "fr": "Quelque part dans la réserve militaire", + "ge": "Somewhere in the Military reserve", + "hu": "Somewhere in the Military reserve", + "it": "Somewhere in the Military reserve", + "jp": "Somewhere in the Military reserve", + "kr": "Somewhere in the Military reserve", + "pl": "Somewhere in the Military reserve", + "po": "Somewhere in the Military reserve", + "ru": "Somewhere in the Military reserve" + }, + "access_via": ["ReserveBunkerStash"] + } + }, + "exfiltrations": { + "factory4_day": { + "Gate 3": "MechanicStash", + "Office Window": "JaegerStash" + }, + "factory4_night": { + "Gate 3": "MechanicStash", + "Office Window": "JaegerStash" + }, + "bigmap": { + "Railroad To Tarkov": "TherapistStash", + "Railroad To Military Base": "SkierStash", + "ZB-1011": "MechanicStash", + "Old Azs Gate": "RagmanStash" + }, + "woods": { + "Factory Gate": "JaegerStash", + "South V-Ex": "ShorelineWoodsStash" + }, + "rezervbase": { + "EXFIL_ScavCooperation": "SkierStash", + "Exit4": "MilitaryLighthouseStash", + "EXFIL_Bunker_D2": "ReserveBunkerStash" + }, + "interchange": { + "NW Exfil": "RagmanStash", + "Saferoom Exfil": "ReserveBunkerStash", + "PP Exfil": "PraporStash" + }, + "shoreline": { + "Tunnel": "PeacekeeperStash", + "Shorl_V-Ex": "ShorelineWoodsStash", + "South Fence Passage": "ReserveBunkerStash" + }, + "lighthouse": { + "Coastal_South_Road": "PeacekeeperStash", + " V-Ex_light": "MilitaryLighthouseStash" + }, + "tarkovstreets": { + "E5": "TherapistStash", + "E7_car": "PraporStash", + "E9_sniper": "KlimovStash" + }, + "laboratory": { + "lab_Parking_Gate": "PraporStash", + "lab_Hangar_Gate": "PraporStash", + "lab_Elevator_Med": "PraporStash", + "lab_Under_Storage_Collector": "PraporStash", + "lab_Elevator_Main": "PraporStash", + "lab_Vent": "PraporStash", + "lab_Elevator_Cargo": "PraporStash" + }, + "sandbox": { + "Scav_coop_exit": "TherapistStash", + "Sandbox_VExit": "PraporStash" + } + }, + "infiltrations": { + "TherapistStash": { + "bigmap": ["Crossroads"], + "sandbox": ["GZ Scav checkpoint"], + "tarkovstreets": ["Zmeevsky Alley"] + }, + "PraporStash": { + "tarkovstreets": ["Primorsky Vehicle Extract"], + "sandbox": ["Police Car"], + "laboratory": [ + "Cargo Elevator", + "Hangar Gate", + "Lab Sewage Conduit", + "Lab Vents", + "Main Elevator", + "Med Block Elevator", + "Parking Gate" + ], + "interchange": ["Car at Power Station"] + }, + "MechanicStash": { + "factory4_day": ["Gate 3"], + "factory4_night": ["Gate 3"], + "bigmap": ["ZB-1011"] + }, + "RagmanStash": { + "bigmap": ["Old Gas Scav"], + "interchange": ["Railway"] + }, + "SkierStash": { + "bigmap": ["Railroad To Military Base"], + "rezervbase": ["Scav lands rail"] + }, + "PeacekeeperStash": { + "lighthouse": ["Lighthouse tunnel"], + "shoreline": ["Tunnel"] + }, + "JaegerStash": { + "factory4_day": ["Office Window"], + "factory4_night": ["Office Window"], + "woods": ["Factory Gate", "RUAFRoadblock", "UN Roadblock"] + }, + "MilitaryLighthouseStash": { + "lighthouse": ["Lighthouse Vehicle Extract"], + "rezervbase": ["CP Fence"] + }, + "ReserveBunkerStash": { + "rezervbase": ["D-2"], + "interchange": ["Safe Room"], + "shoreline": ["North Fence Passage"] + }, + "ShorelineWoodsStash": { + "shoreline": ["Road to Customs"], + "woods": ["Bridge Car"] + }, + "KlimovStash": { + "tarkovstreets": ["Klimov Street"] + } + } +} diff --git a/configs/LegacyPathToTarkovV5/player_spawnpoints.json b/configs/LegacyPathToTarkovV5/player_spawnpoints.json new file mode 100644 index 00000000..cffa610a --- /dev/null +++ b/configs/LegacyPathToTarkovV5/player_spawnpoints.json @@ -0,0 +1,374 @@ +{ + "factory4_day": { + "Gate 0": { + "Position": { + "x": -52.5704842, + "y": 1.25745475, + "z": 55.06734 + }, + "Rotation": 93.18849 + }, + "Gate 3": { + "Position": { + "x": 58.67002, + "y": 0.233123064, + "z": 57.4049568 + }, + "Rotation": 129.412323 + }, + "Med tent gates": { + "Position": { + "x": -18.9917545, + "y": 0.229607314, + "z": -46.5803642 + }, + "Rotation": 19.03057 + }, + "Cellars": { + "Position": { + "x": 66.78813, + "y": -2.63332653, + "z": -30.9360619 + }, + "Rotation": 231.811646 + }, + "Office Window": { + "Position": { + "x": 17.66614, + "y": 8.210876, + "z": 40.92688 + }, + "Rotation": 158.9888 + } + }, + "factory4_night": { + "Gate 0": { + "Position": { + "x": -52.5704842, + "y": 1.25745475, + "z": 55.06734 + }, + "Rotation": 93.18849 + }, + "Gate 3": { + "Position": { + "x": 58.67002, + "y": 0.233123064, + "z": 57.4049568 + }, + "Rotation": 129.412323 + }, + "Med tent gates": { + "Position": { + "x": -18.9917545, + "y": 0.229607314, + "z": -46.5803642 + }, + "Rotation": 19.03057 + }, + "Cellars": { + "Position": { + "x": 66.78813, + "y": -2.63332653, + "z": -30.9360619 + }, + "Rotation": 231.811646 + }, + "Office Window": { + "Position": { + "x": 17.66614, + "y": 8.210876, + "z": 40.92688 + }, + "Rotation": 158.9888 + } + }, + "bigmap": { + "Military Base CP": { + "Position": [674.5625, 5.60742664, 123.641823], + "Rotation": 238.056732 + }, + "Railroad To Military Base": { + "Position": [489.120117, 1.40883172, 207.272552], + "Rotation": 228.254486 + }, + "ZB-1011": { + "Position": [629.4296, -2.77441788, -127.8221], + "Rotation": 97.17987 + }, + "ZB-1012": { + "Position": [464.075, -2.68441629, -112.424088], + "Rotation": 96.69592 + }, + "ZB-1013": { + "Position": [199.2377, -2.81965065, -145.043625], + "Rotation": 341.8522 + }, + "Crossroads": { + "Position": [-324.1054, -0.317715019, -91.3120041], + "Rotation": 31.98688 + }, + "RUAF Roadblock": { + "Position": [-3.56247973, 1.08614612, -132.9248], + "Rotation": 54.44671 + }, + "Smuggler's Boat": { + "Position": [-28.292078, -11.5068331, 109.108429], + "Rotation": 187.815948 + }, + "Sniper Roadblock": { + "Position": [30.446312, -0.259777457, 118.656456], + "Rotation": 327.517334 + }, + "Dorms Car": { + "Position": [191.627884, -2.16589069, 208.912079], + "Rotation": 278.774384 + }, + "Old Gas Scav": { + "Position": [302.545, 2.91025, -185.017761], + "Rotation": 202.349335 + }, + "MallTrain": { + "Position": [-154.6799, 2.266766, -221.5874], + "Rotation": 327.8281 + }, + "PraveenGasoline": { + "Position": [354.8507, 1.106263, -191.5768], + "Rotation": 23.4955 + }, + "OfficePath": { + "Position": [655.933, 1.098399, -166.3037], + "rotation": 302.8839 + }, + "RUAFAdmin": { + "Position": [667.3405, 1.064447, -58.31626], + "rotation": 287.2482 + } + }, + "woods": { + "UN Roadblock": { + "Comment": "UN Roadblock", + "Position": [-543.3435, 9.776281, -78.09744], + "Rotation": 228.816986 + }, + "Factory Gate": { + "Position": [-346.51947, -2.32620764, 353.3336], + "Rotation": 174.779083 + }, + "ZB-1014": { + "Position": [447.4841, -14.2453938, 69.34354], + "Rotation": 285.467377 + }, + "Outskirts": { + "Position": [334.693359, -11.418191, 327.578033], + "Rotation": 160.7393 + }, + "The Boat": { + "Position": [190.682846, -14.9319124, 219.147934], + "Rotation": 227.765961 + }, + "Bridge Car": { + "Position": [-487.348541, 15.0604687, -497.965179], + "Rotation": 24.781599 + }, + "RUAFRoadblock": { + "Position": [-129.7272, -1.194496, 415.476], + "Rotation": 146.2519 + } + }, + "rezervbase": { + "Scav lands": { + "Position": [-120.954071, -6.94097, -129.4829], + "Rotation": 260.069275 + }, + "Scav lands rail": { + "Position": [-196.7502, -5.37225676, -114.267555], + "Rotation": 93.10983 + }, + "Cliff": { + "Position": [-15.9683733, 18.4609661, 195.898743], + "Rotation": 190.4635 + }, + "CP Fence": { + "Comment": "RezervBase_cp_fence (exit4)", + "Position": [53.0388641, -6.82445145, 133.46048], + "Rotation": 263.982239 + }, + "D-2": { + "Position": [-116.999077, -18.3659115, 169.5836], + "Rotation": 128.773651 + }, + "Reserve Manhole": { + "Position": [50.6118279, -6.97395849, 73.78378], + "Rotation": 213.616745 + }, + "Depot Hermetic": { + "Position": [118.866768, -12.2845945, -119.324211], + "Rotation": 299.889923 + }, + "Hole In Wall": { + "Position": [-262.3644, -6.20308161, 47.7328873], + "Rotation": 89.65134 + }, + "Train Station": { + "Position": [166.653687, -5.19410563, -144.143341], + "Rotation": 191.8541 + } + }, + "interchange": { + "Car at Power Station": { + "Position": [-242.849625, 21.32544, -372.680878], + "Rotation": 52.06011 + }, + "Railway": { + "Position": [473.177979, 18.4533634, -390.7554], + "Rotation": 281.3094 + }, + "Safe Room": { + "Position": [-49.4776039, 21.3254585, 47.4479179], + "Rotation": 344.7888 + }, + "EmercomMall": { + "Position": [-313.2805, 21.32544, 254.3763], + "Rotation": 105.2137 + } + }, + "shoreline": { + "North Fence Passage": { + "Position": [-510.430939, -11.9056053, -373.174316], + "Rotation": 41.4962769 + }, + "Road to Customs": { + "Position": [-864.0486, -43.44637, 16.5865173], + "Rotation": 18.213295 + }, + "Pier Boat": { + "Position": [-311.829468, -64.56999, 559.7176], + "Rotation": 210.594009 + }, + "Tunnel": { + "Position": [356.304871, -59.9092941, 313.181915], + "Rotation": 274.0321 + }, + "Path to Lighthouse": { + "Position": [362.138428, -54.85863, -181.549271], + "Rotation": 335.1047 + } + }, + "lighthouse": { + "Path to Shoreline": { + "Position": [-284.0998, 14.4007835, -161.669266], + "Rotation": 126.306564 + }, + "Lighthouse Vehicle Extract": { + "Position": [-316.70462, 15.1516333, -784.0004], + "Rotation": 37.57063 + }, + "Lighthouse tunnel": { + "Position": [-65.93657, 5.95763254, 328.924927], + "Rotation": 101.297722 + }, + "Lighthouse Docks Boat": { + "Position": [164.16626, 0.317433029, -163.23497], + "Rotation": 285.558533 + } + }, + "tarkovstreets": { + "Primorsky Vehicle Extract": { + "Position": [-5.0, 3.8, 459.9], + "Rotation": 0.0 + }, + "Basement Descent": { + "Position": [73.63199, -2.13371778, 56.0767555], + "Rotation": 326.0107 + }, + "Catacombs": { + "Position": [-243.837051, 0.6605578, 243.027969], + "Rotation": 124.062996 + }, + "Evacuation Zone": { + "Position": [161.997284, 3.35329342, 419.626373], + "Rotation": 241.142944 + }, + "Klimov Street": { + "Position": [-152.4702, 0.8981548, 76.18395], + "Rotation": 10.636034 + }, + "Sewer River": { + "Position": [-263.4596, -2.58167219, 216.658859], + "Rotation": 151.635468 + }, + "Streets Manhole": { + "Position": [279.991425, 3.43549061, 349.09433], + "Rotation": 268.153534 + }, + "Streets Ruined House": { + "Position": [-244.822723, 6.355562, 344.1349], + "Rotation": 87.62667 + }, + "Streets Vents": { + "Position": [-123.828979, 2.30664325, 432.900574], + "Rotation": 244.029388 + }, + "Underpass": { + "Position": [-2.86661983, -3.73687434, 6.0282855], + "Rotation": 2.20911074 + }, + "Zmeevsky Alley": { + "Position": [176.868683, 0.7778812, 172.814636], + "Rotation": 304.3322 + }, + "Crane": { + "Position": [212.0187, 3.098404, 252.7016], + "Rotation": 270.9422 + } + }, + "laboratory": { + "Cargo Elevator": { + "Position": [-114.2475, 4.101831, -408.6356], + "Rotation": 270.727661 + }, + "Hangar Gate": { + "Position": [-170.346313, 0.07315855, -249.111542], + "Rotation": 208.741516 + }, + "Lab Sewage Conduit": { + "Position": [-123.794968, -4.985455, -260.754242], + "Rotation": 185.730515 + }, + "Lab Vents": { + "Position": [-142.8083, -4.053963, -400.147034], + "Rotation": 38.8127365 + }, + "Main Elevator": { + "Position": [-279.4339, -4.050967, -334.7585], + "Rotation": 73.58874 + }, + "Med Block Elevator": { + "Position": [-114.566971, -4.05397, -343.565735], + "Rotation": 275.983582 + }, + "Parking Gate": { + "Position": [-231.813736, 0.0220247321, -426.099579], + "Rotation": 14.0038671 + } + }, + "sandbox": { + "Nakatani Basement": { + "Position": [5.295958, 22.73891, 331.8584], + "Rotation": 132.0392 + }, + "Mira Ave": { + "Position": [233.1694, 16.01762, 56.08633], + "Rotation": 251.7702 + }, + "GZ Scav checkpoint": { + "Position": [31.74341, 22.59711, -85.79424], + "Rotation": 43.04764 + }, + "Police Car": { + "Position": [-12.97, 22.6, 116.99], + "Rotation": 90.0 + } + } +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc new file mode 100644 index 00000000..67f3c3a9 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc @@ -0,0 +1,691 @@ +{ + "DisplayName": "Customs (TarkovDev)", + "Author": "Tarkov.dev", + "AuthorLink": "https://tarkov.dev", + "MapInternalNames": ["bigmap"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -372, "y": -306 }, + "Max": { "x": 698, "y": 235 }, + }, + "DefaultLevel": 0, + "Layers": { + "Underground": { + "Level": -1, + "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_-1.png", + "ImageBounds": { + "Min": { "x": -372, "y": -306 }, + "Max": { "x": 698, "y": 235 }, + }, + "GameBounds": [ + { + // zb-1011 + "Min": { "x": 620, "y": -137, "z": -100 }, + "Max": { "x": 635, "y": -125, "z": 0.5 }, + }, + { + // zb-1012 + "Min": { "x": 458, "y": -122, "z": -100 }, + "Max": { "x": 473, "y": -110, "z": 0.5 }, + }, + { + // old gas + "Min": { "x": 308, "y": -184, "z": -100 }, + "Max": { "x": 314, "y": -173, "z": 0.5 }, + }, + { + // switch basement + "Min": { "x": 323, "y": -88, "z": -100 }, + "Max": { "x": 349, "y": -32, "z": 0.5 }, + }, + { + // zb-013 + "Min": { "x": 193, "y": -158, "z": -100 }, + "Max": { "x": 219, "y": -137, "z": 0.5 }, + }, + ], + }, + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_0.png", + "ImageBounds": { + "Min": { "x": -372, "y": -306 }, + "Max": { "x": 698, "y": 235 }, + }, + "GameBounds": [ + { + "Min": { "x": -372, "y": -306, "z": -100 }, + "Max": { "x": 698, "y": 235, "z": 100 }, + }, + ], + }, + "2nd Floor": { + "Level": 1, + "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_1.png", + "ImageBounds": { + "Min": { "x": -372, "y": -306 }, + "Max": { "x": 698, "y": 235 }, + }, + "GameBounds": [ + { + // dorms + "Min": { "x": 165, "y": 125, "z": 2.7 }, + "Max": { "x": 243, "y": 190, "z": 5.0 }, + }, + { + // mechanic + "Min": { "x": 72, "y": -170, "z": 2.7 }, + "Max": { "x": 116, "y": -83, "z": 6.5 }, + }, + { + // switch 2nd + "Min": { "x": 341, "y": -84, "z": 2.7 }, + "Max": { "x": 356, "y": -30, "z": 6.5 }, + }, + { + // switch 2nd + "Min": { "x": 321, "y": -59, "z": 2.7 }, + "Max": { "x": 334, "y": -52, "z": 6.5 }, + }, + { + // scav checkpoint + "Min": { "x": 577, "y": -1, "z": 2.7 }, + "Max": { "x": 589, "y": 10, "z": 6.5 }, + }, + { + // dead scav warehouse + "Min": { "x": 532, "y": -134, "z": 2.7 }, + "Max": { "x": 580, "y": -104, "z": 100 }, + }, + { + // pump 2nd + "Min": { "x": 599, "y": -139, "z": 2.7 }, + "Max": { "x": 625, "y": -120, "z": 100 }, + }, + { + // big red 2nd + "Min": { "x": -223, "y": -131, "z": 5.7 }, + "Max": { "x": -199, "y": -90, "z": 100 }, + }, + { + // skeleton + "Min": { "x": 169, "y": -160, "z": 5.7 }, + "Max": { "x": 239, "y": 3, "z": 100 }, + }, + { + // switch sniper + "Min": { "x": 316, "y": -95, "z": 5.7 }, + "Max": { "x": 336, "y": -56, "z": 100 }, + }, + { + // USEC 2nd + "Min": { "x": 556, "y": -92, "z": 5.7 }, + "Max": { "x": 584, "y": -46, "z": 100 }, + }, + { + // construction 2nd + "Min": { "x": 65, "y": -22, "z": 5.7 }, + "Max": { "x": 93, "y": 0, "z": 100 }, + }, + { + // chemical warehouse sniper scav + "Min": { "x": 450, "y": -90, "z": 14 }, + "Max": { "x": 497, "y": -44, "z": 15 }, + }, + ], + }, + "3rd Floor": { + "Level": 2, + "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_2.png", + "ImageBounds": { + "Min": { "x": -372, "y": -306 }, + "Max": { "x": 698, "y": 235 }, + }, + "GameBounds": [ + { + // dorms + "Min": { "x": 165, "y": 125, "z": 5.0 }, + "Max": { "x": 234, "y": 190, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + // all of these labels are from Tarkov.dev map data under MIT license + { + "Text": "Big Red", + "Position": { "x": -215, "y": -119, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Dorms", + "Position": { "x": 200, "y": 150, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "New Gas", + "Position": { "x": 404, "y": 31, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Old Gas", + "Position": { "x": 331, "y": -173, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Fortress", + "Position": { "x": 201, "y": -127, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Crackhouse", + "Position": { "x": 83, "y": -153, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Streamer House", + "Position": { "x": 567, "y": -67, "z": 0 }, + }, + { + "Text": "Main Bridge", + "Position": { "x": -69, "y": 7, "z": 0 }, + "FontSize": 16, + "DegreesRotation": 6, + }, + { + "Text": "Sniper Hill", + "Position": { "x": 110, "y": 85, "z": 0 }, + }, + { + "Text": "Storage", + "Position": { "x": -288, "y": -134, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Trailer Park", + "Position": { "x": -211, "y": -219, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Junk Bridge", + "Position": { "x": -66, "y": 46, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Repair Shop", + "Position": { "x": 106, "y": -90, "z": 0 }, + }, + { + "Text": "Sniper Ridge", + "Position": { "x": 491, "y": 63, "z": 0 }, + "DegreesRotation": 5, + }, + { + "Text": "Old Construction", + "Position": { "x": 75, "y": -9, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Skeleton", + "Position": { "x": 200, "y": -13, "z": 0 }, + "FontSize": 16, + "DegreesRotation": -9, + }, + { + "Text": "Warehouse 3", + "Position": { "x": 390, "y": -94, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Depot", + "Position": { "x": 472, "y": -67, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Warehouse 7", + "Position": { "x": 555, "y": -118, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Military Checkpoint", + "Position": { "x": 572, "y": 0, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Bus Station", + "Position": { "x": 238, "y": 53, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Warehouse 4", + "Position": { "x": 333, "y": -67, "z": 1 }, + "FontSize": 16, + }, + { + "Text": "Powerline Tower", + "Position": { "x": 497, "y": 110, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Warehouse 17", + "Position": { "x": 46, "y": -59, "z": 0 }, + "FontSize": 16, + }, + ], + "StaticMarkers": [ + { + "Text": "ZB-013 Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": 352.230316, "y": -40.8052826, "z": 2.61458874 }, + "Category": "Switch", + }, + { + "Text": "Military Base CP (Reserve, Scav Lands)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 643.3982, "y": 126.869247, "z": 2.400003 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Railroad to Military Base (Reserve, Scav Land rails*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 489.058228, "y": 221.391266, "z": 3.950006 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Sniper Roadblock (Reserve*/Shoreline)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 15.3699341, "y": 127.94, "z": 0.139977932 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Railroad to Port (Ref/Shoreline)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -142.550232, "y": 46.9100037, "z": -0.629980564 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Trailer Park Workers' Shack (Legs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -248.540222, "y": -232.9901, "z": 2.550012 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Railroad to Tarkov (Painter/Streets/Interchange)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -166.020264, "y": -218.380112, "z": 2.42000723 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Warehouse 17 (Skier)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 45.9998779, "y": -78.43004, "z": 3.61000967 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Old Gas Station Gate (Woods/Factory)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 301.639923, "y": -197.940048, "z": 3.469995 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Factory Far Corner (Woods, RUAF Gate)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 654.53, "y": -160.49, "z": 3.19999838 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Scav Checkpoint (Woods/Lighthouse)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 652.24, "y": -27.1200027, "z": 1.00499988 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "ZB-013 (Factory, Cellars)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 200.9755, "y": -153.086456, "z": -1.1484108 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, + }, + { + "Text": "Dorms SUV (Shoreline, North Fence SUV)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 181.08, "y": 213.25, "z": -0.71 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "ZB-1011 (Hideout/Factory)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 621.4368, "y": -127.700775, "z": -2.65 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, + }, + { + "Text": "Crossroads (Lotus/Interchange/Shoreline*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -335.120239, "y": -73.98008, "z": -3.97000742 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Trailer Park (Ragman/Interchange)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -313.720276, "y": -233.2801, "z": -1.72000742 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "RUAF Roadblock (Woods, UN Roadblock)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -14.5001221, "y": -138.450043, "z": 1.92000723 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Smuggler's Boat (Lighthouse*/Shoreline/Woods*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -43.11017, "y": 119.40004, "z": -14.2250118 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 1.0, "a": 1.0 }, + }, + { + "Text": "ZB-1012 (Hideout/Factory)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 459.427826, "y": -111.042969, "z": -2.31699228 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, + }, + { + "Text": "Tarcone Director's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -205.499237, "y": -109.994392, "z": 8.110943 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780d0532459777a5108b9a2", + }, + { + "Text": "Portable Cabin", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -251.320953, "y": -221.941071, "z": 3.85700083 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780d07a2459777de4559324", + }, + { + "Text": "Trailer Park Portable Cabin", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -194.560135, "y": -207.398911, "z": 2.34600019 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5913611c86f77479e0084092", + }, + { + "Text": "Factory Shortcut", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 356.052551, "y": -14.5693512, "z": 2.34000182 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + }, + { + "Text": "Unknown Cabin", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 370.014923, "y": -50.08902, "z": 2.15399933 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "593962ca86f774068014d9af", + }, + { + "Text": "Factory Shortcut", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 356.957367, "y": -8.079105, "z": 2.14515162 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + }, + { + "Text": "Dorm 114", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 233.549591, "y": 159.682587, "z": 0.889000237 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "59387a4986f77401cc236e62", + }, + { + "Text": "Dorm 206", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 230.641281, "y": 138.671631, "z": 3.86939716 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5938603e86f77435642354f4", + }, + { + "Text": "Dorm 105", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 227.877258, "y": 135.61264, "z": 0.8901995 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "591382d986f774465a6413a7", + }, + { + "Text": "Dorm 110", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 231.0886, "y": 159.435349, "z": 0.910999358 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "59136e1e86f774432f15d133", + }, + { + "Text": "Dorm 104", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 230.101257, "y": 134.913879, "z": 0.8860002 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "591383f186f7744a4c5edcf3", + }, + { + "Text": "Dorm Guard Desk", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 225.517273, "y": 138.366241, "z": 0.8858002 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "59136a4486f774447a1ed172", + }, + { + "Text": "Dorm 204", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 173.379211, "y": 150.356216, "z": 3.83760285 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "59148c8a86f774197930e983", + }, + { + "Text": "Dorm 108", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 177.473969, "y": 178.489075, "z": 0.8406372 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5914578086f774123569ffa4", + }, + { + "Text": "Dorm 314 Marked Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 180.671432, "y": 183.722443, "z": 6.84058475 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cf7f2459777de4559322", + }, + { + "Text": "Dorm 218", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 190.192383, "y": 175.3542, "z": 3.84178257 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cf9e2459777df90dcb73", + }, + { + "Text": "Dorm 118", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 194.794083, "y": 174.546783, "z": 0.830601 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5672c92d4bdc2d180f8b4567", + }, + { + "Text": "Dorm 220", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 193.957886, "y": 174.821625, "z": 3.831203 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cfa52459777dfb276eb1", + }, + { + "Text": "Dorm 308", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 177.4756, "y": 178.488113, "z": 6.850606 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cf722459777a5108b9a1", + }, + { + "Text": "Dorm 315", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 179.284683, "y": 174.810455, "z": 6.830814 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cf692459777de4559321", + }, + { + "Text": "Dorm 214", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 178.105484, "y": 183.746643, "z": 3.83598375 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cf942459777df90dcb72", + }, + { + "Text": "Dorm 203", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 176.041077, "y": 150.26828, "z": 3.83258247 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5938504186f7740991483f30", + }, + { + "Text": "Dorm 103", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 175.734467, "y": 149.366577, "z": 0.820169449 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5938994586f774523a425196", + }, + { + "Text": "Dorm 306", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 174.544632, "y": 157.45575, "z": 6.828404 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780cda02459777b272ede61", + }, + { + "Text": "Dorm 303", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 176.039612, "y": 150.268463, "z": 6.82898426 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "593aa4be86f77457f56379f8", + }, + { + "Text": "Gas Station Storage Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 415.416443, "y": 35.6602058, "z": 2.18918633 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5913877a86f774432f15d444", + }, + { + "Text": "Gas Station Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 415.779572, "y": 38.5554962, "z": 2.17909455 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5780d0652459777df90dcb74", + }, + { + "Text": "USEC Stash", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 562.780945, "y": -58.9465332, "z": 2.216738 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5da743f586f7744014504f72", + }, + { + "Text": "USEC Stash", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 568.747131, "y": -50.85814, "z": 2.193743 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5da743f586f7744014504f72", + }, + { + "Text": "Orange Tanker Truck", + "ImagePath": "Markers/car_door.png", + "Position": { "x": 101.818916, "y": -5.54527664, "z": 3.44780731 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5937ee6486f77408994ba448", + }, + { + "Text": "Military Checkpoint", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 577.6575, "y": 4.049543, "z": 0.8078748 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5913915886f774123603c392", + }, + { + "Text": "ZB-013", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 198.927917, "y": -146.172791, "z": -1.779768 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + }, + { + "Text": "Portable Bunkhouse", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 202.664337, "y": 11.72344, "z": 4.73085976 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5938144586f77473c2087145", + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc new file mode 100644 index 00000000..74966341 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc @@ -0,0 +1,215 @@ +{ + "DisplayName": "Factory (TarkovDev)", + "Author": "Tarkov.dev", + "AuthorLink": "https://tarkov.dev", + "MapInternalNames": ["factory4_day", "factory4_night"], + "CoordinateRotation": 90, + "Bounds": { + "Min": { "x": -65, "y": -64.5 }, + "Max": { "x": 77.6, "y": 67.2 }, + }, + "DefaultLevel": 0, + "Layers": { + "Tunnels": { + "Level": -1, + "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_-1.png", + "ImageBounds": { + "Min": { "x": -65, "y": -64.5 }, + "Max": { "x": 77.6, "y": 67.2 }, + }, + "GameBounds": [ + { + "Min": { "x": -65, "y": -64.5, "z": -100 }, + "Max": { "x": 77.6, "y": 67.2, "z": -1 }, + }, + ], + }, + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_0.png", + "ImageBounds": { + "Min": { "x": -65, "y": -64.5 }, + "Max": { "x": 77.6, "y": 67.2 }, + }, + "GameBounds": [ + { + "Min": { "x": -65, "y": -64.5, "z": -1 }, + "Max": { "x": 77.6, "y": 67.2, "z": 3 }, + }, + ], + }, + "2nd Floor": { + "Level": 1, + "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_1.png", + "ImageBounds": { + "Min": { "x": -65, "y": -64.5 }, + "Max": { "x": 77.6, "y": 67.2 }, + }, + "GameBounds": [ + { + "Min": { "x": -65, "y": -64.5, "z": 3 }, + "Max": { "x": 77.6, "y": 67.2, "z": 6 }, + }, + ], + }, + "3rd Floor": { + "Level": 2, + "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_2.png", + "ImageBounds": { + "Min": { "x": -65, "y": -64.5 }, + "Max": { "x": 77.6, "y": 67.2 }, + }, + "GameBounds": [ + { + "Min": { "x": -65, "y": -64.5, "z": 6 }, + "Max": { "x": 77.6, "y": 67.2, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "Office Building", + "Position": { "x": 21, "y": 39, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Med Tent", + "Position": { "x": -17.5, "y": -28, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Silos", + "Position": { "x": 4.5, "y": 10.5, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Heli Crash", + "Position": { "x": 30, "y": -8.5, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Scav Bunker", + "Position": { "x": -20.5, "y": 23, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Blue Containers", + "Position": { "x": -18, "y": 50, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Glass Hall", + "Position": { "x": 69.3, "y": -20, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Boilers", + "Position": { "x": 58, "y": 6.3, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Forklifts", + "Position": { "x": 66, "y": -42, "z": 0 }, + "FontSize": 14, + }, + ], + "StaticMarkers": [ + { + "Text": "Camera Bunker Door (Mechanic)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -14.5749989, "y": 40.36, "z": -2.086 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Office Window (Woods/Factory)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 17.8332214, "y": 39.8851128, "z": 8.730333 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Cellars (Customs, ZB-1013)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 77.529, "y": -28.891, "z": -4.657 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Gate 3 (Woods, ZB-016)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 58.709, "y": 64.112, "z": 0.84 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Gate 0 (Customs, ZB-1011)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -63.7400055, "y": 55.902, "z": 1.749 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Med Tent Gate (Customs, ZB-1012)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -18.4857769, "y": -60.1718826, "z": 1.16133332 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Locked Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 29.2459984, "y": 36.52492, "z": 9.155067 }, + "Category": "LockedDoor", + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, + }, + { + "Text": "Pumping Station", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 43.1875839, "y": -14.1608534, "z": 1.01413012 }, + "Category": "LockedDoor", + "AssociatedItemId": "57a349b2245977762b199ec7", + "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, + }, + { + "Text": "Gate 0", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -53.754, "y": 58.93033, "z": 2.33300042 }, + "Category": "LockedDoor", + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, + }, + { + "Text": "Cellars", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 66.42518, "y": -29.8983536, "z": -1.53579187 }, + "Category": "LockedDoor", + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, + }, + { + "Text": "Pumping Station", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 40.9448547, "y": -6.261415, "z": 0.9631303 }, + "Category": "LockedDoor", + "AssociatedItemId": "593858c486f774253a24cb52", + "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, + }, + { + "Text": "Med Tent", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -20.3113289, "y": -49.138, "z": 1.27600038 }, + "Category": "LockedDoor", + "AssociatedItemId": "5448ba0b4bdc2d02308b456c", + "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc new file mode 100644 index 00000000..61890086 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc @@ -0,0 +1,207 @@ +{ + "DisplayName": "Ground Zero (TarkovDev)", + "Author": "Tarkov.dev", + "AuthorLink": "https://tarkov.dev", + "MapInternalNames": ["Sandbox", "Sandbox_high"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -99, "y": -124 }, + "Max": { "x": 249, "y": 364 }, + }, + "DefaultLevel": 0, + "Layers": { + "Garage": { + "Level": -1, + "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_-1.png", + "ImageBounds": { + "Min": { "x": -99, "y": -124 }, + "Max": { "x": 249, "y": 364 }, + }, + "GameBounds": [ + { + // garage + "Min": { "x": 43, "y": -100, "z": -100 }, + "Max": { "x": 117, "y": 190, "z": 21 }, + }, + { + // underpass + "Min": { "x": 117, "y": 49, "z": -100 }, + "Max": { "x": 143, "y": 80, "z": 21 }, + }, + ], + }, + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_0.png", + "ImageBounds": { + "Min": { "x": -99, "y": -124 }, + "Max": { "x": 249, "y": 364 }, + }, + "GameBounds": [ + { + "Min": { "x": -99, "y": -124, "z": -100 }, + "Max": { "x": 249, "y": 364, "z": 100 }, + }, + ], + }, + "2nd Floor": { + "Level": 1, + "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_1.png", + "ImageBounds": { + "Min": { "x": -99, "y": -124 }, + "Max": { "x": 249, "y": 364 }, + }, + "GameBounds": [ + { + // rest of 2nd floor + "Min": { "x": -99, "y": -124, "z": 28 }, + "Max": { "x": 249, "y": 364, "z": 32.3 }, + }, + { + // m showroom + "Min": { "x": 91, "y": 216, "z": 26 }, + "Max": { "x": 98, "y": 228, "z": 31 }, + }, + ], + }, + "3rd Floor": { + "Level": 2, + "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_2.png", + "ImageBounds": { + "Min": { "x": -99, "y": -124 }, + "Max": { "x": 249, "y": 364 }, + }, + "GameBounds": [ + { + "Min": { "x": -99, "y": -124, "z": 32.3 }, + "Max": { "x": 249, "y": 364, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "TerraGroup", + "Position": { "x": -50, "y": 0, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Skyside", + "Position": { "x": 150, "y": 1, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Fusion", + "Position": { "x": 141, "y": 142, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Empire", + "Position": { "x": 14, "y": 201, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Capital Insight", + "Position": { "x": 115, "y": 285, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Nakatani", + "Position": { "x": 2, "y": 324, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Elemental Global", + "Position": { "x": 80, "y": -118, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Oasis", + "Position": { "x": 115, "y": 104, "z": 22 }, + "FontSize": 16, + }, + { + "Text": "ASAP Winery", + "Position": { "x": 115, "y": 30, "z": 22 }, + "FontSize": 12, + }, + { + "Text": "Tarbank", + "Position": { "x": 43, "y": 150, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "GAGRIN Hotel", + "Position": { "x": 58, "y": 234, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "M Showroom", + "Position": { "x": 97, "y": 223, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Science Offices", + "Position": { "x": -13, "y": 48, "z": 29 }, + "FontSize": 12, + }, + ], + "StaticMarkers": [ + { + "Text": "Scav Checkpoint (Streets, Expo CP)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 26.1550121, "y": -82.52659, "z": 24.5091858 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Police Cordon SUV (Woods/Interchange/Streets)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -19.5134068, "y": 114.942139, "z": 23.7110023 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Emercom Checkpoint (Therapist)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 151.625, "y": -97.45658, "z": 24.662056 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Nakatani Basement Stairs (Coyote/Streets/Labs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -16.1249924, "y": 335.063416, "z": 14.7620564 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Mira Ave (Streets, Klimov Ave)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 218.225, "y": -38.5065842, "z": 17.9920559 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Underground Parking Utility Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 107.056, "y": 50.6362534, "z": 13.499 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "658199972dc4e60f6d556a2f", + }, + { + "Text": "TerraGroup Science Offices", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -17.975647, "y": 58.5532341, "z": 30.7062054 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "658199aa38c79576a2569e13", + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc new file mode 100644 index 00000000..a88eb483 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc @@ -0,0 +1,627 @@ +{ + "DisplayName": "Interchange (TarkovDev)", + "Author": "Tarkov.dev", + "AuthorLink": "https://tarkov.dev", + "MapInternalNames": ["Interchange"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -364, "y": -443 }, + "Max": { "x": 534, "y": 452 }, + }, + "DefaultLevel": 0, + "Layers": { + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_0.png", + "ImageBounds": { + "Min": { "x": -364, "y": -443 }, + "Max": { "x": 534, "y": 452 }, + }, + "GameBounds": [ + { + "Min": { "x": -364, "y": -443, "z": -100 }, + "Max": { "x": 534, "y": 452, "z": 100 }, + }, + ], + }, + "2nd Floor": { + "Level": 1, + "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_1.png", + "ImageBounds": { + "Min": { "x": -364, "y": -443 }, + "Max": { "x": 534, "y": 452 }, + }, + "GameBounds": [ + { + // mall + "Min": { "x": -222, "y": -327, "z": 25 }, + "Max": { "x": 120, "y": 218, "z": 34 }, + }, + ], + }, + "3rd Floor": { + "Level": 2, + "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_2.png", + "ImageBounds": { + "Min": { "x": -364, "y": -443 }, + "Max": { "x": 534, "y": 452 }, + }, + "GameBounds": [ + { + // mall + "Min": { "x": -222, "y": -443, "z": 34 }, + "Max": { "x": 120, "y": 218, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "Power Station", + "Position": { "x": -186.4, "y": -318.7, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Go Kart", + "Position": { "x": 155, "y": -253, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Four Camp", + "Position": { "x": 158, "y": -78.5, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Cargo Containers", + "Position": { "x": 68.2, "y": 312.9, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Wall Break", + "Position": { "x": -260.2, "y": 123.8, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Ramps", + "Position": { "x": -175.5, "y": 145.1, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "OLI Tower", + "Position": { "x": 202.3, "y": 219.4, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "IDEA Tower", + "Position": { "x": 46.5, "y": -358.5, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Scav Camp", + "Position": { "x": 263.2, "y": -11.1, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Highway Construction", + "Position": { "x": 373.5, "y": -391.2, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Garage A", + "Position": { "x": 33, "y": -222, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Garage B", + "Position": { "x": 47, "y": -112, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Garage C", + "Position": { "x": 0, "y": 47, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Garage D", + "Position": { "x": 28, "y": 138, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "IDEA", + "Position": { "x": -34, "y": -235, "z": 26 }, + "FontSize": 14, + }, + { + "Text": "Goshan", + "Position": { "x": -115, "y": -45, "z": 26 }, + "FontSize": 14, + }, + { + "Text": "OLI", + "Position": { "x": -28, "y": 140, "z": 26 }, + "FontSize": 14, + }, + { + "Text": "Nortex", + "Position": { "x": 87, "y": -165, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "TRend", + "Position": { "x": 60, "y": -152, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Mode7", + "Position": { "x": 69.5, "y": -134, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "TTS", + "Position": { "x": 19, "y": -129, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Book Store", + "Position": { "x": -38, "y": -129, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Dino Clothes", + "Position": { "x": 91, "y": -119, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "EMERCOM", + "Position": { "x": 18, "y": -103, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Kostin", + "Position": { "x": -28, "y": -103, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Bizarro", + "Position": { "x": -65, "y": -103, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Spiel", + "Position": { "x": 92, "y": -87, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Voyage", + "Position": { "x": -18, "y": -87, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Viking", + "Position": { "x": 57, "y": -66, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Mantis", + "Position": { "x": 13, "y": -66, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "German", + "Position": { "x": -18, "y": -72, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "The National", + "Position": { "x": 57, "y": -32, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Brutal", + "Position": { "x": 13, "y": -32, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Kiba", + "Position": { "x": -18, "y": -25, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Pretty Lights", + "Position": { "x": -34, "y": -20, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Telespot", + "Position": { "x": 92, "y": -18, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Revis", + "Position": { "x": 62, "y": -12, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "ADIK", + "Position": { "x": 19, "y": -6, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Generic", + "Position": { "x": -28, "y": 0.5, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Top Brand", + "Position": { "x": 92, "y": 15, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Sports", + "Position": { "x": 61, "y": 15, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Yushka", + "Position": { "x": 70, "y": 32, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Rasmussen", + "Position": { "x": 19.5, "y": 26, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Avokado", + "Position": { "x": -37, "y": 26, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Boots 4 Life", + "Position": { "x": 91, "y": 55, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Texho", + "Position": { "x": 61, "y": 50, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Dom", + "Position": { "x": 6, "y": 49, "z": 26 }, + "FontSize": 10, + }, + { + "Text": "Father & Sons", + "Position": { "x": 38, "y": -170, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Tarkovstar", + "Position": { "x": 69, "y": -150, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Eastland", + "Position": { "x": 26, "y": -149, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Arena", + "Position": { "x": 71, "y": -130, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "ТАРЗДРАВ", + "Position": { "x": 54, "y": -128, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "МЕБЕЛЬ МК", + "Position": { "x": 20, "y": -128, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Intourist", + "Position": { "x": 69, "y": -116, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Burger Spot", + "Position": { "x": -27, "y": -103, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "FCK", + "Position": { "x": 70, "y": -94, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "McDaniels", + "Position": { "x": 70, "y": -87, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Tarducks", + "Position": { "x": 64, "y": -69, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Coffee Joy", + "Position": { "x": 43, "y": -69, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Jacob & Jacob", + "Position": { "x": 15, "y": -74, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "ПУШКИН", + "Position": { "x": -34, "y": -79, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Sushi Huyushi", + "Position": { "x": 64, "y": -34, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Underway", + "Position": { "x": -17, "y": -32, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Burger House", + "Position": { "x": 67, "y": -23.5, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Philly Cute", + "Position": { "x": -34, "y": -24, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Shiccos", + "Position": { "x": 67, "y": -16, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "УЗЕЙ ИСТОРИИ", + "Position": { "x": 17, "y": 0, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Papillon", + "Position": { "x": 92, "y": 17, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "ЗАКРЫТО НА РЕМОНТ", + "Position": { "x": 58, "y": 13, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "НА-СВЯЗИ", + "Position": { "x": 70, "y": 27, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "СКОРО ОТКРЫТИЕ", + "Position": { "x": 54, "y": 24, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Figaro", + "Position": { "x": 19, "y": 26, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "АПТЕКА", + "Position": { "x": 71, "y": 47, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "SARA", + "Position": { "x": 53, "y": 47, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Urban Clothes", + "Position": { "x": 26, "y": 46, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "TECHLIGHT", + "Position": { "x": 91, "y": 54, "z": 35 }, + "FontSize": 10, + }, + { + "Text": "Fashion Store", + "Position": { "x": 39, "y": 67, "z": 35 }, + "FontSize": 10, + }, + ], + "StaticMarkers": [ + { + "Text": "Main Power Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -201.108, "y": -357.8291, "z": 23.1857 }, + "Category": "Switch", + }, + { + "Text": "Saferoom Urinal Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -51.547, "y": -125.440712, "z": 36.86 }, + "Category": "Switch", + }, + { + "Text": "2nd Floor Alarm Console", + "ImagePath": "Markers/lever.png", + "Position": { "x": -46.555, "y": -55.202, "z": 37.347 }, + "Category": "Switch", + }, + { + "Text": "1st Floor Alarm Console", + "ImagePath": "Markers/lever.png", + "Position": { "x": -67.1342545, "y": 53.7422676, "z": 27.9506 }, + "Category": "Switch", + }, + { + "Text": "Inside Saferoom Exfil Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -50.6210022, "y": 45.617, "z": 22.632 }, + "Category": "Switch", + }, + { + "Text": "Object 14 Container Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -47.698, "y": 42.6198, "z": 22.891 }, + "Category": "Switch", + }, + { + "Text": "Emercom Checkpoint (Lotus/Customs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -317.21, "y": 267.94, "z": 21.94955 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Railway (Painter/Customs/Woods/Streets)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 474.67, "y": -436.09, "z": 20.92 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Power Station SUV (Painter/Streets/Woods/GZ)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -251.93, "y": -366.99, "z": 21.7130013 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Scav Camp (Ragman/Customs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 284.442, "y": -27.493, "z": 21.94955 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Saferoom (Flea Market)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -47.73, "y": 44.055, "z": 22.97 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Power Substation Utility Cabin", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -223.115845, "y": -271.3501, "z": 22.55412 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5d49886f77455f9731921", + }, + { + "Text": "ULTRA Medical Storage", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 67.55801, "y": 40.891, "z": 37.60174 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5e42c71586f7747f245e1343", + }, + { + "Text": "Kiba Arms Inner Grate", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -9.887001, "y": -33.76517, "z": 28.241 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5addaffe86f77470b455f900", + }, + { + "Text": "Kiba Arms Outer Door", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -9.444001, "y": -33.709, "z": 28.241 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5d7d286f77450166e0a89", + }, + { + "Text": "Object #11SR Saferoom", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -51.9328041, "y": 45.8337746, "z": 22.35359 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5e42c81886f7742a01529f57", + }, + { + "Text": "Object #21WS", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 140.195663, "y": 263.315277, "z": 25.2079964 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5e42c83786f7742a021fdf3c", + }, + { + "Text": "NecrusPharm Pharmacy", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 68.53804, "y": -255.424225, "z": 22.4947357 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5d64486f774079b080af8", + }, + { + "Text": "Emercom Medical Unit", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 24.136982, "y": -112.8551, "z": 28.4790325 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5db3786f7743568421cce", + }, + { + "Text": "Emercom Medical Unit", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 34.14116, "y": -108.287651, "z": 28.4790325 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5db3786f7743568421cce", + }, + { + "Text": "Emercom Medical Unit", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 6.732233, "y": -107.304314, "z": 28.4790344 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5db3786f7743568421cce", + }, + { + "Text": "OLI Logistics Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 83.1990051, "y": 115.673004, "z": 28.1199989 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5cfbd86f7742c825d6104", + }, + { + "Text": "OLI Outlet Utility Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -102.823967, "y": 80.48102, "z": 28.12 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5d20586f77449be26d877", + }, + { + "Text": "OLI Admin Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 85.18402, "y": 104.638214, "z": 28.1199989 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ad5ccd186f774446d5706e9", + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc new file mode 100644 index 00000000..afad85d9 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc @@ -0,0 +1,283 @@ +{ + "DisplayName": "Labs (TarkovDev)", + "Author": "Tarkov.dev", + "AuthorLink": "https://tarkov.dev", + "MapInternalNames": ["laboratory"], + "CoordinateRotation": 270, + "Bounds": { + "Min": { "x": -292, "y": -441 }, + "Max": { "x": -96, "y": -223 }, + }, + "DefaultLevel": 0, + "Layers": { + "Technical": { + "Level": -1, + "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_-1.png", + "ImageBounds": { + "Min": { "x": -292, "y": -441 }, + "Max": { "x": -96, "y": -223 }, + }, + "GameBounds": [ + { + "Min": { "x": -292, "y": -441, "z": -100 }, + "Max": { "x": -96, "y": -223, "z": -0.9 }, + }, + ], + }, + "First Level": { + "Level": 0, + "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_0.png", + "ImageBounds": { + "Min": { "x": -292, "y": -441 }, + "Max": { "x": -96, "y": -223 }, + }, + "GameBounds": [ + { + "Min": { "x": -292, "y": -441, "z": -0.9 }, + "Max": { "x": -96, "y": -223, "z": 3 }, + }, + ], + }, + "Second Level": { + "Level": 1, + "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_1.png", + "ImageBounds": { + "Min": { "x": -292, "y": -441 }, + "Max": { "x": -96, "y": -223 }, + }, + "GameBounds": [ + { + "Min": { "x": -271, "y": -422, "z": 3 }, + "Max": { "x": -101, "y": -270, "z": 100 }, + }, + ], + }, + }, + "Labels": [], + "StaticMarkers": [ + { + "Text": "Cargo Elevator (Coyote/Streets/Ground Zero)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -112.152, "y": -408.64, "z": 5.376 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Main Elevator (Streets, Sylobate Elevator)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -282.304016, "y": -334.896, "z": -3.631999 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Ventilation Shaft (Streets, Vent Shaft)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -144.866, "y": -399.385, "z": -2.424 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Sewage Conduit (Streets, Sewer River)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -123.711, "y": -255.3735, "z": -3.6609993 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Hangar Gate (Streets, Catacombs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -170.66, "y": -240.77, "z": 2.08 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Medical Block Elevator Power", + "ImagePath": "Markers/lever.png", + "Position": { "x": -124.758, "y": -313.806, "z": -2.31599617 }, + "Category": "Switch", + }, + // { // main elevator + // "Text": "call_button", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -281.022, "y": -335.477, "z": -2.83799934 }, + // "Category": "Switch" + // }, + // { // medical block call button + // "Text": "call_button", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -114.112, "y": -343.2, "z": -2.84599972 }, + // "Category": "Switch" + // }, + // { // cargo elevator + // "Text": "call_button (1)", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -114.037, "y": -406.427979, "z": 5.31399727 }, + // "Category": "Switch" + // }, + // { // cargo elevator + // "Text": "floor_button (1)", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -112.378006, "y": -406.806, "z": 5.353998 }, + // "Category": "Switch" + // }, + { + "Text": "Main Elevator Power Button", + "ImagePath": "Markers/lever.png", + "Position": { "x": -271.439, "y": -366.10498, "z": -2.380001 }, + "Category": "Switch", + }, + // { // main elevator + // "Text": "floor_button", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -282.361, "y": -335.86, "z": -2.91199875 }, + // "Category": "Switch" + // }, + { + "Text": "Open Parking Gate", + "ImagePath": "Markers/lever.png", + "Position": { "x": -243.443, "y": -382.513, "z": 5.076 }, + "Category": "Switch", + }, + { + "Text": "Water Level Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -136.76, "y": -254.510513, "z": -2.825999 }, + "Category": "Switch", + }, + // { // not sure, located in sterile lab? + // "Text": "Power", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -121.007996, "y": -353.548, "z": -2.83698225 }, + // "Category": "Switch" + // }, + // { // medical block elevator + // "Text": "floor_button", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": -112.802, "y": -342.762, "z": -2.84599972 }, + // "Category": "Switch" + // }, + { + "Text": "Disable Parking Gate Alarm", + "ImagePath": "Markers/lever.png", + "Position": { "x": -220.756, "y": -381.263, "z": 5.249 }, + "Category": "Switch", + }, + { + "Text": "TerraGroup Manager's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -165.246277, "y": -349.197, "z": 5.131374 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1e2a1e86f77431ea0ea84c", + }, + { + "Text": "TerraGroup Manager's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -165.242874, "y": -338.086, "z": 5.135374 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1e2a1e86f77431ea0ea84c", + }, + { + "Text": "Weapon Testing Area", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -181.966461, "y": -318.226044, "z": 1.37873685 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1e2d1f86f77431e9280bee", + }, + { + "Text": "Weapon Testing Area", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -179.862, "y": -310.3296, "z": 1.37899876 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1e2d1f86f77431e9280bee", + }, + { + "Text": "Infirmary (Blue)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -123.229095, "y": -406.524384, "z": 1.03631592 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0c5f86f7744bb2683cf0", + }, + { + "Text": "Sterile Lab (Green)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -135.89798, "y": -346.9675, "z": 5.185806 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0dc586f7744baf2e7b79", + }, + { + "Text": "Sterile Lab (Green)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -138.6131, "y": -346.966125, "z": 5.25222349 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0dc586f7744baf2e7b79", + }, + { + "Text": "Card with a Blue Marking", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -130.268463, "y": -339.944275, "z": 5.15560675 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5efde6b4f5448336730dbd61", + }, + { + "Text": "Security #2 (Yellow)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -212.695, "y": -376.538, "z": 5.145301 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0d6d86f7744bb2683e1f", + }, + { + "Text": "Test Room (Black)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -132.893, "y": -348.72, "z": 1.43501759 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0f4986f7744bb01837fa", + }, + { + "Text": "Test Room (Black)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -128.794, "y": -349.91507, "z": 1.43701744 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0f4986f7744bb01837fa", + }, + { + "Text": "Security Office (Violet)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -261.993, "y": -317.240021, "z": 5.147805 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1e495a86f7743109743dfb", + }, + { + "Text": "Security Office (Red)", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -257.222015, "y": -322.925018, "z": 5.24803066 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1d0efb86f7744baf2e7b7b", + }, + { + "Text": "Arsenal Storage", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -250.839066, "y": -326.758667, "z": 5.097125 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5c1f79a086f7746ed066fb8f", + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc new file mode 100644 index 00000000..61e9e94f --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc @@ -0,0 +1,320 @@ +{ + "DisplayName": "Lighthouse (TarkovData)", + "Author": "Shebuka", + "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", + "MapInternalNames": ["Lighthouse"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -545, "y": -998 }, + "Max": { "x": 512, "y": 721 }, + }, + "DefaultLevel": 0, + "Layers": { + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/Lighthouse_TarkovData/Layers/lighthouse_layer_0.png", + "ImageBounds": { + "Min": { "x": -545, "y": -998 }, + "Max": { "x": 512, "y": 721 }, + }, + "GameBounds": [ + { + "Min": { "x": -545, "y": -998, "z": -100 }, + "Max": { "x": 512, "y": 721, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "Train Yard", + "Position": { "x": -30, "y": -882, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Drug Lab", + "Position": { "x": -120, "y": -841, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Water Treatment", + "Position": { "x": -65, "y": -600, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Plant 1", + "Position": { "x": 40, "y": -618, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Plant 2", + "Position": { "x": -98, "y": -742, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Plant 3", + "Position": { "x": -189, "y": -665, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Pipes", + "Position": { "x": -182, "y": -552, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Gunner Nest", + "Position": { "x": 18, "y": -453, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Island", + "Position": { "x": -177, "y": -356, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Cabins", + "Position": { "x": -278, "y": -323, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Cottages", + "Position": { "x": -162, "y": -225, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Convenience", + "Position": { "x": -55, "y": -288, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Red Brick", + "Position": { "x": -75, "y": -284, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Hillside", + "Position": { "x": -147, "y": -247, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Boathouses", + "Position": { "x": 125, "y": -153, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Dead Tree", + "Position": { "x": 62, "y": -60, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Construction", + "Position": { "x": 0, "y": -188, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Pikes Peak Resort", + "Position": { "x": -107, "y": -53, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Grand Chalet", + "Position": { "x": -133, "y": 100, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Tennis Court", + "Position": { "x": -70, "y": 129, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Lightkeeper Island", + "Position": { "x": 382, "y": 496, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Crash Site", + "Position": { "x": -125, "y": 296, "z": 0 }, + "FontSize": 16, + }, + ], + "StaticMarkers": [ + { + "Text": "Side Tunnel (Shoreline, Tunnel)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -68.3, "y": 318.11, "z": 6.83 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Scav Hideout at the Grotto (Artem)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 180.66, "y": -485.94, "z": 1.18 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Road to Military Base SUV (Reserve, CP Fence*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -328.951263, "y": -784.3581, "z": 16.73 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Mountain Pass (Shoreline, Path to Lighthouse*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -172.35, "y": -6.39, "z": 41.89 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Path to Shoreline", + "ImagePath": "Markers/exit.png", + "Position": { "x": -364.4, "y": -121.4, "z": 28.758 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Northern Checkpoint (Woods/Customs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 111.943, "y": -991.981, "z": 11.86 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Southern Road (Shoreline, Ruined Road)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -295.8, "y": 420.6, "z": 11.86 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Armored Train (all maps besides GZ*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 6.27001953, "y": -873.78, "z": 14.1133 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + // { + // "Text": "OuterSwitcher", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": 445.3035, "y": 457.5599, "z": 33.391 }, + // "Category": "Switch" + // }, + // { + // "Text": "InnerSwitcher", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": 444.6317, "y": 457.6145, "z": 33.391 }, + // "Category": "Switch" + // }, + // { + // "Text": "railing_door 1", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": 445.426117, "y": 458.187561, "z": 32.1270027 }, + // "Category": "Switch" + // }, + { + "Text": "Convenience Store Storage Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -58.5892944, "y": -292.9962, "z": 6.55390024 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "61a64428a8c6aa1b795f0ba1", + }, + { + "Text": "Shared Bedroom", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 328.6411, "y": 487.244019, "z": 6.041643 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "62987dfc402c7f69bf010923", + }, + { + "Text": "Conference Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 333.8, "y": 519.1168, "z": 6.0705 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "62987cb98081af308d7558c8", + }, + { + "Text": "Merin Trunk", + "ImagePath": "Markers/car_door.png", + "Position": { "x": 91.1099854, "y": -130.918991, "z": 8.382999 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "61aa5b518f5e7a39b41416e2", + }, + { + "Text": "Radar Station Commandant Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 355.204, "y": 549.386963, "z": 16.545002 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "62987c658081af308d7558c6", + }, + { + "Text": "Hillside House", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -147.043427, "y": -243.326172, "z": 12.66918 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "61a6444b8c141d68246e2d2f", + }, + { + "Text": "Operating Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 32.899, "y": -636.186, "z": 5.93999767 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "62987da96188c076bc0d8c51", + }, + { + "Text": "Water Treatment Plant Storage Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -120.901962, "y": -736.4641, "z": 5.938982 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "62987e26a77ec735f90a2995", + }, + { + "Text": "Rogue USEC Barrack", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -176.519043, "y": -654.164063, "z": 5.939995 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "62a9cb937377a65d7b070cef", + }, + { + "Text": "Police Car", + "ImagePath": "Markers/car_door.png", + "Position": { "x": 83.79875, "y": -553.2562, "z": 6.61099958 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "61aa5aed32a4743c3453d319", + }, + { + "Text": "Rogue USEC Workshop", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -168.6745, "y": -497.287079, "z": 5.798998 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "61aa81fcb225ac1ead7957c3", + }, + { + "Text": "Rogue USEC Stash", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 47.3759, "y": -553.3956, "z": 5.67344 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "61a64492ba05ef10d62adcc1", + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc new file mode 100644 index 00000000..87f17ccb --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc @@ -0,0 +1,556 @@ +{ + "DisplayName": "Reserve (TarkovData)", + "Author": "Shebuka", + "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", + "MapInternalNames": ["RezervBase"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -303.5, "y": -275 }, + "Max": { "x": 292, "y": 271.5 }, + }, + "DefaultLevel": 0, + "Layers": { + "Bunkers": { + "Level": -1, + "ImagePath": "Maps/Reserve_TarkovData/Layers/reserve_layer_-1.png", + "ImageBounds": { + "Min": { "x": -303.5, "y": -275 }, + "Max": { "x": 292, "y": 271.5 }, + }, + "GameBounds": [ + { + "Min": { "x": -303.5, "y": -275, "z": -100 }, + "Max": { "x": 292, "y": 271.5, "z": -8 }, + }, + ], + }, + "Ground Level": { + "Level": 0, + "ImagePath": "Maps/Reserve_TarkovData/Layers/reserve_layer_0.png", + "ImageBounds": { + "Min": { "x": -303.5, "y": -275 }, + "Max": { "x": 292, "y": 271.5 }, + }, + "GameBounds": [ + { + "Min": { "x": -303.5, "y": -275, "z": -8 }, + "Max": { "x": 292, "y": 271.5, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "K Buildings", + "Position": { "x": 31, "y": -104, "z": 0 }, + "FontSize": 16, + "DegreesRotation": 14.5, + }, + { + "Text": "White Queen", + "Position": { "x": -25, "y": 180, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "White Pawn", + "Position": { "x": -104, "y": 93, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "Black Bishop", + "Position": { "x": -140, "y": -14.5, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "White Bishop", + "Position": { "x": -67, "y": -30, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "White King", + "Position": { "x": -49.5, "y": 15.5, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "Black Knight", + "Position": { "x": 14.5, "y": -10.8, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "White Knight", + "Position": { "x": 82.2, "y": -30.2, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "White Rook", + "Position": { "x": 149, "y": -124, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "Train Station", + "Position": { "x": 161, "y": -149, "z": 0 }, + "FontSize": 16, + "DegreesRotation": 14.5, + }, + { + "Text": "Black Pawn", + "Position": { "x": -165, "y": 57, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "Barracks", + "Position": { "x": 165, "y": -215, "z": 0 }, + "FontSize": 16, + "DegreesRotation": 14.5, + }, + { + "Text": "E1 Bunkers", + "Position": { "x": -220, "y": -13, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "E2 Bunkers", + "Position": { "x": 173, "y": -3, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "д - Warehouse Bunkers", + "Position": { "x": 82, "y": -170, "z": 0 }, + "FontSize": 16, + "DegreesRotation": 14.5, + }, + { + "Text": "Garage", + "Position": { "x": 98.5, "y": 29.5, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "Mechanic", + "Position": { "x": 55.5, "y": 60.6, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "Gas Station", + "Position": { "x": 29.7, "y": 29.5, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 14.5, + }, + { + "Text": "Shipping Yard", + "Position": { "x": -31, "y": -150, "z": 0 }, + "FontSize": 16, + "DegreesRotation": 14.5, + }, + { + "Text": "K1", + "Position": { "x": 8, "y": -76, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "K2", + "Position": { "x": 65.5, "y": -92, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "K3", + "Position": { "x": 2, "y": -96.5, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "K4", + "Position": { "x": 60, "y": -112, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "K5", + "Position": { "x": -4, "y": -118, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "K6", + "Position": { "x": 54, "y": -133, "z": 0 }, + "FontSize": 12, + "DegreesRotation": 14.5, + }, + { + "Text": "Dome", + "Position": { "x": -8.5, "y": 175, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Tarmac", + "Position": { "x": -120, "y": 37, "z": 0 }, + "FontSize": 16, + }, + ], + "StaticMarkers": [ + { + "Text": "Scav Lands (Customs, Military Base CP)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -124.67, "y": -144.92, "z": -3.28 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Hole in the Wall (Customs, Dorms Car*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -261.41, "y": 47.95, "z": -6.033997 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Checkpoint Fence (Lighthouse, Northeast Mountains*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 66.76, "y": 138.26, "z": -4.43 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "D-2 (Peacekeeper/Shoreline*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -121.479065, "y": 172.24913, "z": -17.0010071 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Bunker Hermetic Door (Scorpion/Woods*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 62.3918457, "y": -194.269928, "z": -5.257 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Cliff Descent (Shoreline, Climber's Trail)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -12.8, "y": 206.78, "z": 20.93 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Sewer Manhole (Sally/Streets)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 40.18, "y": 76.45, "z": -5.12 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Armored Train (all maps besides GZ*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 144.986, "y": -147.352, "z": -3.92 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Bunker Hermetic Door Power", + "ImagePath": "Markers/lever.png", + "Position": { "x": -60.7597275, "y": 78.22821, "z": -5.55217171 }, + "Category": "Switch", + }, + { + "Text": "D-2 Power Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -117.184174, "y": 22.6676826, "z": -12.954 }, + "Category": "Switch", + }, + // { // near bunker hermetic door + // "Text": "Reset", + // "ImagePath": "Markers/lever.png", + // "Position": { "x": 65.71171, "y": -190.604248, "z": -6.683 }, + // "Category": "Switch" + // }, + { + "Text": "D-2 Open Switch", + "ImagePath": "Markers/lever.png", + "Position": { "x": -117.449867, "y": 168.546936, "z": -16.9842987 }, + "Category": "Switch", + }, + { + "Text": "RB-AO", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 194.756973, "y": -203.553268, "z": -5.801999 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c66d86f774405611c7d6", + }, + { + "Text": "RB-VO Marked Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 189.6508, "y": -224.790009, "z": -5.8030014 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c62a86f7744036212b3f", + }, + { + "Text": "RB-KPRL", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -40.4498749, "y": 173.891434, "z": 19.66215 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d8e0e0e86f774321140eb56", + }, + { + "Text": "RB-KPRL", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -44.2896843, "y": 171.655853, "z": 19.6481476 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d8e0e0e86f774321140eb56", + }, + { + "Text": "RB-ST", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 100.7764, "y": 43.67282, "z": -6.714003 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d9f1fa686f774726974a992", + }, + { + "Text": "RB-SMP", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -78.7131653, "y": -29.4600983, "z": -3.78035355 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d947d3886f774447b415893", + }, + { + "Text": "RB-KSM", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -60.01116, "y": -34.5081, "z": -3.78035355 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d947d4e86f774447b415895", + }, + { + "Text": "RB-PSP1", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 71.1095, "y": -146.997528, "z": -11.128006 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80cb3886f77440556dbf09", + }, + { + "Text": "RB-PSP2", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 83.5344238, "y": -100.622009, "z": -11.1000061 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d95d6fa86f77424484aa5e9", + }, + { + "Text": "RB-PSV2", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 42.9962158, "y": -114.069916, "z": -11.1259995 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d95d6be86f77424444eb3a7", + }, + { + "Text": "RB-PSV1", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 50.81842, "y": -91.86203, "z": -11.1000061 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80cb5686f77440545d1286", + }, + { + "Text": "RB-PSP1", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 80.91522, "y": -124.236908, "z": -11.128006 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80cb3886f77440556dbf09", + }, + { + "Text": "RB-PSV2", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 38.3938, "y": -138.232147, "z": -11.128006 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d95d6be86f77424444eb3a7", + }, + { + "Text": "RB-AK", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -134.622513, "y": -12.8279257, "z": -2.13919544 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c78786f774403a401e3e", + }, + { + "Text": "RB-AM", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -133.289352, "y": -16.0929947, "z": -5.13899755 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c88d86f77440556dbf07", + }, + { + "Text": "RB-TB", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -162.7683, "y": 65.7317047, "z": -8.171001 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c6fc86f774403a401e3c", + }, + { + "Text": "RB-ORB2", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -123.018578, "y": 98.53613, "z": -2.36699772 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80ccdd86f77474f7575e02", + }, + { + "Text": "RB-OB", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -167.807968, "y": 34.4820557, "z": 0.525999069 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c6c586f77440351beef1", + }, + { + "Text": "RB-ORB3", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -170.236115, "y": 33.9814758, "z": -2.36400938 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80cd1a86f77402aa362f42", + }, + { + "Text": "RB-ORB1", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -122.855316, "y": 97.5226746, "z": 3.43500519 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80ccac86f77470841ff452", + }, + { + "Text": "RB-BK Marked Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -157.878387, "y": 72.86379, "z": -8.188297 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c60f86f77440373c4ece", + }, + { + "Text": "RB-RH", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -51.4290428, "y": 19.6974564, "z": 0.3399992 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5da5cdcd86f774529238fb9b", + }, + { + "Text": "RB-OP", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -68.47772, "y": 22.4145622, "z": -9.729001 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c8f586f77440373c4ed0", + }, + { + "Text": "RB-GN", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -62.8870544, "y": 31.4578876, "z": -9.723853 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d8e3ecc86f774414c78d05e", + }, + { + "Text": "RB-KORL", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -2.507956, "y": 174.912, "z": 23.420002 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d8e0db586f7744450412a42", + }, + { + "Text": "RB-RS", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -0.7069602, "y": 182.247, "z": 23.42 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5da46e3886f774653b7a83fe", + }, + { + "Text": "RB-RLSA", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -10.9659786, "y": 180.645, "z": 23.420002 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ede7b0c6d23e5473e6e8c66", + }, + { + // seems to be straight on MP22 but the floor below + "Text": "RB-MP13", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 87.58351, "y": -37.0245056, "z": -5.82550049 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80cbd886f77470855c26c2", + }, + { + "Text": "RB-MP21", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 10.9685087, "y": -7.38929558, "z": -2.99313354 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80ca9086f774403a401e40", + }, + { + "Text": "RB-MP11", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 8.245274, "y": -17.522274, "z": -5.851448 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c95986f77440351beef3", + }, + { + "Text": "RB-MP12", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 8.266094, "y": -17.478508, "z": -3.00213623 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80c93086f7744036212b41", + }, + { + "Text": "RB-MP22", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 87.5893555, "y": -37.00447, "z": -2.98300171 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d80cab086f77440535be201", + }, + { + "Text": "RB-PKPM Marked Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -120.251823, "y": 27.7044983, "z": -13.483 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5ede7a8229445733cb4c18e2", + }, + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc new file mode 100644 index 00000000..92c858e4 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc @@ -0,0 +1,548 @@ +{ + "DisplayName": "Shoreline (TarkovData)", + "Author": "Shebuka", + "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", + "MapInternalNames": ["Shoreline"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -1060, "y": -415 }, + "Max": { "x": 508, "y": 622 }, + }, + "DefaultLevel": 0, + "Layers": { + "Underground": { + "Level": -1, + "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_-1.png", + "ImageBounds": { + "Min": { "x": -1060, "y": -415 }, + "Max": { "x": 508, "y": 622 }, + }, + "GameBounds": [ + { + // west wing + "Min": { "x": -237, "y": -104, "z": -100 }, + "Max": { "x": -137, "y": -68, "z": -5 }, + }, + { + // admin + "Min": { "x": -268, "y": -163, "z": -100 }, + "Max": { "x": -234, "y": -134, "z": -5 }, + }, + ], + }, + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_0.png", + "ImageBounds": { + "Min": { "x": -1060, "y": -415 }, + "Max": { "x": 508, "y": 622 }, + }, + "GameBounds": [ + { + "Min": { "x": -1060, "y": -415, "z": -100 }, + "Max": { "x": 508, "y": 622, "z": 100 }, + }, + ], + }, + "2nd Floor": { + "Level": 1, + "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_1.png", + "ImageBounds": { + "Min": { "x": -1060, "y": -415 }, + "Max": { "x": 508, "y": 622 }, + }, + "GameBounds": [ + { + "Min": { "x": -375, "y": -178, "z": -1 }, + "Max": { "x": -128, "y": -55, "z": 2 }, + }, + ], + }, + "3rd Floor": { + "Level": 2, + "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_2.png", + "ImageBounds": { + "Min": { "x": -1060, "y": -415 }, + "Max": { "x": 508, "y": 622 }, + }, + "GameBounds": [ + { + "Min": { "x": -375, "y": -178, "z": 2 }, + "Max": { "x": -128, "y": -55, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "Resort", + "Position": { "x": -252, "y": -71.2, "z": -3 }, + "FontSize": 16, + }, + { + "Text": "Power Station", + "Position": { "x": -215.8, "y": 178.4, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Gas Station", + "Position": { "x": -189.3, "y": 420, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Weather Station", + "Position": { "x": -496, "y": 257, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Radio Tower", + "Position": { "x": -708.9, "y": 93.9, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Swamp", + "Position": { "x": 326, "y": -118.5, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Village", + "Position": { "x": 418.4, "y": 118, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Cabins", + "Position": { "x": 288, "y": 144, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Cottages", + "Position": { "x": 128, "y": 93, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Tank Bridge", + "Position": { "x": -355, "y": 188, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Pier", + "Position": { "x": -338.6, "y": 525, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Scav Island", + "Position": { "x": 216, "y": 424, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Bus Stop", + "Position": { "x": -96, "y": -6, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Construction", + "Position": { "x": 52, "y": 134, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Bunker", + "Position": { "x": -153, "y": -290, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Crane", + "Position": { "x": -625, "y": 484, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Scav Farm", + "Position": { "x": -622, "y": -202, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "West Wing", + "Position": { "x": -171, "y": -83, "z": -3 }, + "FontSize": 16, + }, + { + "Text": "East Wing", + "Position": { "x": -329, "y": -83, "z": -3 }, + "FontSize": 16, + }, + { + "Text": "Admin", + "Position": { "x": -252, "y": -146, "z": -3 }, + "FontSize": 16, + }, + ], + "StaticMarkers": [ + { + "Text": "Ruined Road (Lighthouse, Southern Road)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 368.559326, "y": 334.897644, "z": -61.12998 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Old Bunker (Peacekeeper)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -388.99, "y": -383.73, "z": -2.66 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Smuggler's Path (Customs/Reserve*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -730.79, "y": -255.47, "z": -26.0 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "North Fence SUV (Customs, Dorms SUV)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -542.9488, "y": -381.020721, "z": -16.9900017 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Road to Customs (Customs, Sniper Roadblock*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -861.65, "y": -0.36, "z": -41.7699776 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Railway Bridge (Ref/Customs)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -1026.47, "y": 299.85, "z": -60.79 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Tunnel (Lighthouse, Side Tunnel)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 376.36, "y": 319.25, "z": -55.9399757 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Path to Lighthouse", + "ImagePath": "Markers/exit.png", + "Position": { "x": 448.9, "y": -254.6, "z": -44.7 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Pier Boat (Lighthouse*/Customs/Woods*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -336.8407, "y": 568.4276, "z": -66.11997 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 1.0, "a": 1.0 }, + }, + { + "Text": "Climber's Trail (Reserve, Cliff Descent)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -204.5, "y": -359.71, "z": -10.74 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "HEP Station Storage Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -220.38063, "y": 185.880585, "z": -33.858 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d8e15b686f774445103b190", + }, + { + "Text": "HEP Station Storage Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -220.703171, "y": 193.687332, "z": -33.8470345 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5d8e15b686f774445103b190", + }, + { + "Text": "SMW Car", + "ImagePath": "Markers/car_door.png", + "Position": { "x": 157.352051, "y": 133.891, "z": -47.3859329 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0eb38b86f774153b320eb0", + }, + { + "Text": "Cottage Back Door", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 102.532318, "y": 102.731339, "z": -47.2590027 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0eb6ac86f7743124037a28", + }, + { + "Text": "West Wing Room 203", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -229.608261, "y": -92.90662, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a144dfd86f77445cb5a0982", + }, + { + "Text": "West Wing Room 216", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -179.379257, "y": -80.91263, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ee30786f774023b6ee08f", + }, + { + "Text": "West Wing Room 306", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -216.905258, "y": -92.90662, "z": 3.03088379 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a13f46386f7741dd7384b04", + }, + { + "Text": "West Wing Room 220", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -166.686264, "y": -80.91263, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ee34586f774023b6ee092", + }, + { + "Text": "East Wing Room 206", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -285.857239, "y": -92.88861, "z": 0.134880066 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ee4b586f7743698200d22", + }, + { + "Text": "East Wing Room 205", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -281.692261, "y": -92.88861, "z": 0.134880066 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a144bdb86f7741d374bbde0", + }, + { + "Text": "East Wing Room 313", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -313.835754, "y": -84.47537, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0eecf686f7740350630097", + }, + { + "Text": "Utility Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -142.583267, "y": -79.9176, "z": 3.05788422 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ea79b86f7741d4a35298e", + }, + { + "Text": "West Wing Room 218", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -173.983749, "y": -84.50137, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a13eebd86f7746fd639aa93", + }, + { + "Text": "East Wing Room 328", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -357.303284, "y": -79.9165955, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0eee1486f77402aa773226", + }, + { + "Text": "East Wing Room 226", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -351.9118, "y": -84.47537, "z": 0.134880066 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a13f35286f77413ef1436b0", + }, + { + "Text": "East Wing Office 107", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -333.767029, "y": -79.95798, "z": -2.70200348 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ea64786f7741707720468", + }, + { + "Text": "West Wing Room 205", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -221.073288, "y": -92.90662, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ec6d286f7742c0b518fb5", + }, + { + "Text": "East Wing Room 222", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -343.3838, "y": -84.47537, "z": 0.134880066 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a13f24186f77410e57c5626", + }, + { + "Text": "West Wing Room 112", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -189.173019, "y": -85.4490051, "z": -2.69580078 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0dc95c86f77452440fc675", + }, + { + "Text": "West Wing Room 104", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -157.433029, "y": -85.4490051, "z": -2.69580078 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0dc45586f7742f6b0b73e3", + }, + { + "Text": "West Wing Room 219", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -170.853256, "y": -80.91263, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a13ef0686f7746e5a411744", + }, + { + "Text": "East Wing Room 308", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -294.3863, "y": -92.88861, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a145d7b86f7744cbb6f4a13", + }, + { + "Text": "East Wing Room 310", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -303.411255, "y": -81.46161, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0eec9686f77402ac5c39f2", + }, + { + "Text": "West Wing Room 301", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -229.202621, "y": -100.151733, "z": 3.03088379 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a13ef7e86f7741290491063", + }, + { + "Text": "West Wing Room 222", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -161.293747, "y": -84.50137, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a1452ee86f7746f33111763", + }, + { + "Text": "Utility Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -142.583267, "y": -79.9176, "z": 0.164085388 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ea79b86f7741d4a35298e", + }, + { + "Text": "East Wing Room 306", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -285.857239, "y": -92.88861, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a145d4786f7744cbb6f4a12", + }, + { + "Text": "Utility Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -360.193237, "y": -79.8936157, "z": 3.04288483 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ea79b86f7741d4a35298e", + }, + { + "Text": "East Wing Room 316", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -323.389282, "y": -80.8936157, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a145ebb86f77458f1796f05", + }, + { + "Text": "East Wing Room 314", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -317.992737, "y": -84.47537, "z": 3.02988434 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0eed4386f77405112912aa", + }, + { + "Text": "East Wing Sanitar's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -323.547, "y": -79.961, "z": -2.70200348 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5eff09cd30a7dc22fd1ddfed", + }, + { + "Text": "West Wing Room 223", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -165.451767, "y": -84.50137, "z": 0.137084961 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "5a0ee37f86f774023657a86f", + }, + // { + // "Text": "safe 1", + // "ImagePath": "Markers/locked_safe.png", + // "Position": { "x": -266.10675, "y": -147.65097, "z": -0.3202896 }, + // "Category": "Locked", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5a0f08bc86f77478f33b84c2" + // }, + // { + // "Text": "West Wing Room 321 Safe", + // "ImagePath": "Markers/locked_safe.png", + // "Position": { "x": -165.664047, "y": -89.05765, "z": 2.53099823 }, + // "Category": "Locked", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5a0eff2986f7741fd654e684" + // }, + // { + // "Text": "Cottage Safe", + // "ImagePath": "Markers/locked_safe.png", + // "Position": { "x": 93.71925, "y": 111.979019, "z": -45.01355 }, + // "Category": "Locked", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5a0f068686f7745b0d4ea242" + // }, + // { + // "Text": "safe 4", + // "ImagePath": "Markers/locked_safe.png", + // "Position": { "x": -242.451981, "y": -153.367249, "z": -0.3202896 }, + // "Category": "Locked", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5a0f0f5886f7741c4e32a472" + // } + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc new file mode 100644 index 00000000..a4ecd897 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc @@ -0,0 +1,1092 @@ +{ + "DisplayName": "Streets of Tarkov (TarkovData)", + "Author": "Shebuka", + "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", + "MapInternalNames": ["TarkovStreets"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "DefaultLevel": 0, + "Layers": { + "Underground": { + "Level": -1, + "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_-1.png", + "ImageBounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "GameBounds": [ + { + // Concordia underground + "Min": { "x": 147, "y": 338, "z": -4 }, + "Max": { "x": 277, "y": 416, "z": 0 }, + }, + { + // Subway underground + "Min": { "x": -15, "y": -25, "z": -5 }, + "Max": { "x": 39, "y": 33, "z": -2 }, + }, + ], + }, + "Ground Floor": { + "Level": 0, + "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_0.png", + "ImageBounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "GameBounds": [ + { + "Min": { "x": -279, "y": -299, "z": -100 }, + "Max": { "x": 324, "y": 533, "z": 100 }, + }, + ], + }, + "2nd Floor": { + "Level": 1, + "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_1.png", + "ImageBounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "GameBounds": [ + { + // concordia 2nd floor + "Min": { "x": 128, "y": 339, "z": 6 }, + "Max": { "x": 287, "y": 416, "z": 9 }, + }, + { + // building south of concordia 2nd floor + "Min": { "x": 128, "y": 335, "z": 6 }, + "Max": { "x": 152, "y": 460, "z": 9 }, + }, + { + // real estate agency office 2nd floor + "Min": { "x": -68, "y": 449, "z": 6 }, + "Max": { "x": -34, "y": 475, "z": 10 }, + }, + { + // cinema 2nd floor + "Min": { "x": -197, "y": 370, "z": 6 }, + "Max": { "x": -120, "y": 432, "z": 12 }, + }, + { + // courtyard building 2nd floor + "Min": { "x": -175, "y": 477, "z": 6 }, + "Max": { "x": -160, "y": 491, "z": 10 }, + }, + { + // north of courtyard building 2nd floor + "Min": { "x": -189, "y": 451, "z": 6 }, + "Max": { "x": -171, "y": 473, "z": 10 }, + }, + { + // construction 2nd floor + "Min": { "x": 188, "y": 284, "z": 6 }, + "Max": { "x": 218, "y": 314, "z": 10 }, + }, + { + // Sparja grocery 2nd floor + "Min": { "x": 107, "y": 283, "z": 6 }, + "Max": { "x": 132, "y": 294, "z": 10 }, + }, + { + // Lexos 2nd floor + "Min": { "x": 46, "y": 257, "z": 5.5 }, + "Max": { "x": 106, "y": 352, "z": 10 }, + }, + { + // abandoned factory 2nd floor + "Min": { "x": -156, "y": 265, "z": 3 }, + "Max": { "x": -77, "y": 305, "z": 6 }, + }, + { + // hotels 2nd floor + "Min": { "x": -214, "y": 235, "z": 6 }, + "Max": { "x": -163, "y": 307, "z": 10 }, + }, + { + // financial office 2nd floor + "Min": { "x": -190, "y": 217, "z": 5.5 }, + "Max": { "x": -157, "y": 235, "z": 8 }, + }, + { + // family market 2nd floor + "Min": { "x": -234, "y": 271, "z": 4.5 }, + "Max": { "x": -209, "y": 290, "z": 7 }, + }, + { + // tarbank 2nd floor + "Min": { "x": 31, "y": 198, "z": 6 }, + "Max": { "x": 88, "y": 240, "z": 9 }, + }, + { + // chekannaya apartments 2nd floor + "Min": { "x": 91, "y": 205, "z": 6 }, + "Max": { "x": 161, "y": 240, "z": 9 }, + }, + { + // pharmacy 1 2nd floor + "Min": { "x": 32, "y": 144, "z": 5 }, + "Max": { "x": 57, "y": 173, "z": 8 }, + }, + { + // post office 2nd floor + "Min": { "x": 31, "y": 60, "z": 3 }, + "Max": { "x": 59, "y": 140, "z": 6 }, + }, + { + // archive building 2nd floor + "Min": { "x": 74, "y": 122, "z": 3.5 }, + "Max": { "x": 90, "y": 146, "z": 7 }, + }, + { + // zmeisky apartment 2nd floor + "Min": { "x": 99, "y": 118, "z": 3.5 }, + "Max": { "x": 140, "y": 159, "z": 7 }, + }, + { + // vet clinic 2nd floor + "Min": { "x": 209, "y": 166, "z": 3 }, + "Max": { "x": 235, "y": 183, "z": 6 }, + }, + { + // x-ray building 2nd floor + "Min": { "x": 180, "y": 91, "z": 1 }, + "Max": { "x": 197, "y": 127, "z": 4 }, + }, + { + // school 2nd floor + "Min": { "x": 199, "y": 96, "z": 3 }, + "Max": { "x": 224, "y": 160, "z": 6 }, + }, + { + // rusted key door building 2nd floor + "Min": { "x": 173, "y": 48, "z": -2 }, + "Max": { "x": 199, "y": 85, "z": 1 }, + }, + { + // CCCP building 2nd floor + "Min": { "x": 241, "y": 45, "z": -2 }, + "Max": { "x": 253, "y": 62, "z": 1 }, + }, + { + // pinewood hotel complex 2nd floor + "Min": { "x": -125, "y": 45, "z": 4 }, + "Max": { "x": -13, "y": 173, "z": 6.5 }, + }, + { + // kilov shopping mall + beluga 2nd floor + "Min": { "x": -171, "y": -89, "z": 4 }, + "Max": { "x": -14, "y": -7, "z": 6.5 }, + }, + { + // cardinal bank building 2nd floor + "Min": { "x": -97, "y": -73, "z": 2 }, + "Max": { "x": 149, "y": -14, "z": 6 }, + }, + { + // cardinal apartments northeast 2nd floor + "Min": { "x": 39, "y": -160, "z": 8.5 }, + "Max": { "x": 77, "y": -114, "z": 12 }, + }, + { + // across primorsky ave from cardinal 2nd floor + "Min": { "x": -73, "y": -160, "z": 5 }, + "Max": { "x": -44, "y": -141, "z": 8 }, + }, + ], + }, + "3rd Floor": { + "Level": 2, + "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_2.png", + "ImageBounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "GameBounds": [ + { + // concordia 3rd floor + "Min": { "x": 128, "y": 339, "z": 9 }, + "Max": { "x": 287, "y": 416, "z": 12 }, + }, + { + // cinema 3rd floor + "Min": { "x": -179, "y": 377, "z": 12 }, + "Max": { "x": -155, "y": 423, "z": 18 }, + }, + { + // abandoned factory 3rd floor + "Min": { "x": -156, "y": 265, "z": 6 }, + "Max": { "x": -77, "y": 305, "z": 11 }, + }, + { + // family market 3rd floor + "Min": { "x": -234, "y": 271, "z": 7 }, + "Max": { "x": -209, "y": 290, "z": 10 }, + }, + { + // tarbank 3rd floor + "Min": { "x": 31, "y": 198, "z": 9 }, + "Max": { "x": 88, "y": 240, "z": 12 }, + }, + { + // chekannaya apartments 3rd floor + "Min": { "x": 91, "y": 205, "z": 9 }, + "Max": { "x": 161, "y": 240, "z": 12 }, + }, + { + // post office 3rd floor + "Min": { "x": 31, "y": 60, "z": 6 }, + "Max": { "x": 59, "y": 140, "z": 9 }, + }, + { + // zmeisky apartment 3rd floor + "Min": { "x": 99, "y": 118, "z": 7 }, + "Max": { "x": 140, "y": 159, "z": 9 }, + }, + { + // rusted key door building 3rd floor + "Min": { "x": 173, "y": 48, "z": 1 }, + "Max": { "x": 199, "y": 85, "z": 4 }, + }, + { + // pinewood hotel complex 3rd floor + "Min": { "x": -125, "y": 45, "z": 6.5 }, + "Max": { "x": -13, "y": 173, "z": 12 }, + }, + { + // kilov shopping mall + beluga 3rd floor + "Min": { "x": -171, "y": -79, "z": 6.5 }, + "Max": { "x": -14, "y": -5, "z": 12 }, + }, + { + // cardinal apartments northeast 3rd floor + "Min": { "x": 39, "y": -160, "z": 12 }, + "Max": { "x": 77, "y": -114, "z": 15 }, + }, + { + // across primorsky ave from cardinal 3rd floor + "Min": { "x": -73, "y": -160, "z": 8 }, + "Max": { "x": -44, "y": -141, "z": 12 }, + }, + ], + }, + "4th Floor": { + "Level": 3, + "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_3.png", + "ImageBounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "GameBounds": [ + { + // abandoned factory 4th floor + "Min": { "x": -140, "y": 263, "z": 11 }, + "Max": { "x": -123, "y": 278, "z": 15 }, + }, + { + // family market 4th floor + "Min": { "x": -234, "y": 271, "z": 10 }, + "Max": { "x": -209, "y": 290, "z": 14 }, + }, + { + // tarbank 4th floor + "Min": { "x": 31, "y": 198, "z": 12 }, + "Max": { "x": 88, "y": 240, "z": 15 }, + }, + { + // post office 4th floor + apartments + "Min": { "x": 31, "y": 60, "z": 9 }, + "Max": { "x": 59, "y": 164, "z": 14 }, + }, + { + // zmeisky apartment 4th floor + "Min": { "x": 99, "y": 118, "z": 9 }, + "Max": { "x": 140, "y": 159, "z": 12 }, + }, + { + // rusted key door building 4th floor + "Min": { "x": 173, "y": 48, "z": 4 }, + "Max": { "x": 199, "y": 85, "z": 8 }, + }, + ], + }, + "5th Floor": { + "Level": 4, + "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_4.png", + "ImageBounds": { + "Min": { "x": -279, "y": -299 }, + "Max": { "x": 324, "y": 533 }, + }, + "GameBounds": [ + { + // zmeisky apartment 5th floor + "Min": { "x": 99, "y": 118, "z": 12 }, + "Max": { "x": 140, "y": 159, "z": 15 }, + }, + { + // rusted key door building 5th floor + "Min": { "x": 170, "y": 81, "z": 8 }, + "Max": { "x": 181, "y": 89, "z": 12 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "Primorsky Ave.", + "Position": { "x": 9, "y": 308, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -90, + }, + { + "Text": "Primorsky Ave.", + "Position": { "x": 9, "y": 104, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -90, + }, + { + "Text": "Primorsky Ave.", + "Position": { "x": 9, "y": -80, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -90, + }, + { + "Text": "Kilmov St.", + "Position": { "x": 125, "y": 10, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Kilmov St.", + "Position": { "x": -104, "y": 28, "z": 0 }, + "FontSize": 14, + "DegreesRotation": 10, + }, + { + "Text": "Nikitskaya St.", + "Position": { "x": -125, "y": 210, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Verhnyaya St.", + "Position": { "x": -112, "y": 361, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Malevecha St.", + "Position": { "x": -200, "y": 290, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -64, + }, + { + "Text": "Chekannaya St.", + "Position": { "x": 111, "y": 251, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Nizhnyaya St.", + "Position": { "x": -101, "y": 441, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Razvedchikov St.", + "Position": { "x": 174, "y": 430, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -30, + }, + { + "Text": "Zmejskij Alley", + "Position": { "x": 140, "y": 150, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -68, + }, + { + "Text": "Kamchatskaya St.", + "Position": { "x": 232, "y": 100, "z": 0 }, + "FontSize": 14, + "DegreesRotation": -90, + }, + { + "Text": "Kilmov Shopping Mall", + "Position": { "x": -128, "y": -35, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Beluga", + "Position": { "x": -45, "y": -52, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Cardinal Apartments", + "Position": { "x": 99, "y": -71, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Construction", + "Position": { "x": 230, "y": 295, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Lexos", + "Position": { "x": 66, "y": 305, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Sparja Grocery", + "Position": { "x": 140, "y": 300, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Cinema", + "Position": { "x": -175, "y": 400, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Shestyorochka", + "Position": { "x": -218, "y": 135, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Pinewood Hotel", + "Position": { "x": -35, "y": 64, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Teppakot / Koener", + "Position": { "x": 65, "y": 398, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Concordia", + "Position": { "x": 207, "y": 363, "z": 0 }, + "FontSize": 18, + }, + { + "Text": "Cardinal Bank", + "Position": { "x": 89, "y": -20, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "LERM Expo", + "Position": { "x": 239, "y": -60, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Sparja Express", + "Position": { "x": -64, "y": 166, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Burger Spot", + "Position": { "x": -30, "y": 138, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Post Office", + "Position": { "x": 42, "y": 97, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Pharmacy 1", + "Position": { "x": 42, "y": 160, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Office", + "Position": { "x": -173, "y": 226, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Corner Restaurant", + "Position": { "x": -197, "y": 340, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Pharmacy 2", + "Position": { "x": -43, "y": 335, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Pharmacy 3", + "Position": { "x": 90, "y": -227, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Tarbank", + "Position": { "x": 67, "y": 230, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "School", + "Position": { "x": 211, "y": 129, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Vet Clinic", + "Position": { "x": 222, "y": 173, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Hive", + "Position": { "x": -212, "y": 300, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Family Market", + "Position": { "x": -223, "y": 279, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Marked Hotel", + "Position": { "x": -200, "y": 248, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "South Hotel", + "Position": { "x": -175, "y": 297, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Abandoned Factory", + "Position": { "x": -119, "y": 287, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Diner", + "Position": { "x": -80, "y": 235, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Primorskij 49", + "Position": { "x": -13, "y": 244, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Prestigio Cage", + "Position": { "x": 39, "y": 230, "z": 0 }, + "FontSize": 10, + }, + { + "Text": "Bilbo Coffee", + "Position": { "x": -70, "y": 343, "z": 0 }, + "FontSize": 10, + }, + ], + "StaticMarkers": [ + { + "Text": "Basement Descent (Coyote/Labs/Ground Zero)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 74.769, "y": 49.22, "z": -0.701999664 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Entrance to Catacombs (Labs, Hangar Gate)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -249.008026, "y": 243.797, "z": 2.566 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Ventilation Shaft (Lab, Vents)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -124.127106, "y": 425.738983, "z": 3.114 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Sewer Manhole (Sally/Reserve)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 276.113, "y": 345.389984, "z": 5.356 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Primorsky Ave Taxi (Woods/Interchange/GZ)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -2.191315, "y": 461.232971, "z": 3.2 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Sylovate Elevator (Labs, Main Elevator)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -44.7435, "y": -72.6544, "z": 11.04 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Crash Site (Painter/Customs/Interchange)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 312.74, "y": 405.96, "z": 6.8 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Sewer River (Labs, Sewage Conduit)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -264.267, "y": 223.92, "z": -1.535 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Klimov Street (Ground Zero, Mira Ave)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -263.41, "y": 43.19, "z": 2.9 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Expo Checkpoint (Ground Zero, Scav Camp)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 213.12, "y": -104.96, "z": 0.09 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "Ruined House (Hephaestus)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -248.971, "y": 344.275, "z": 7.195 }, + "Category": "Extract", + "ShowInRaid": false, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + }, + { + "Text": "MVD Academy Entrance Hall Guard Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -250.476974, "y": 131.546, "z": 3.98400116 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "6582dc4b6ba9e979af6b79f4", + }, + { + "Text": "Pinewood Hotel Room 215", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -67.00622, "y": 59.3249474, "z": 6.024556 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39f08cd6db0635c197600", + }, + { + "Text": "Relaxation Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -208.164185, "y": 295.5338, "z": 4.28889942 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "6582dbf0b8d7830efc45016f", + }, + { + "Text": "Abandoned Factory Marked Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -133.4689, "y": 272.9284, "z": 9.712829 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a3a93f8a56922e82001f5d", + }, + { + "Text": "Financial Institution Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -168.1108, "y": 230.025009, "z": 7.11500072 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39667c9b3aa4b61683e98", + }, + { + "Text": "Financial Institution Small Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -186.393311, "y": 229.271469, "z": 3.72240162 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a71ed21031ac76fe773c7f", + }, + { + "Text": "Backup Hideout", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -130.730026, "y": 391.625732, "z": 3.37588024 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "6398fd8ad3de3849057f5128", + }, + { + "Text": "Real Estate Agency Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -62.37935, "y": 460.344177, "z": 7.906067 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "6582dc5740562727a654ebb1", + }, + { + "Text": "Iron Gate", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 131.168167, "y": 227.64386, "z": 10.5814857 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39f6e64283b5e9c56b289", + }, + { + "Text": "Iron Gate", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 126.369164, "y": 227.644852, "z": 10.5938711 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39f6e64283b5e9c56b289", + }, + { + "Text": "Iron Gate", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 132.49292, "y": 225.1011, "z": 10.5825262 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39f6e64283b5e9c56b289", + }, + { + "Text": "Stair Landing", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 108.3958, "y": 224.57489, "z": 7.45609 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39fd1c9b3aa4b61683efb", + }, + { + "Text": "Chekannaya Apartment 15", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 107.048935, "y": 227.6278, "z": 7.51593971 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39fc0af870e651d58e6ae", + }, + { + "Text": "Primorsky 46-48 Skybridge", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 49.5526543, "y": 147.7725, "z": 12.7623 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39e1d234195315d4020bd", + }, + { + "Text": "Primorsky 48 Apartment", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 45.3423576, "y": 151.024933, "z": 6.742015 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a71eb5b7f4570d3a29316b", + }, + // { // tarbank cash register + // "Text": "door 17", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 66.95923, "y": 231.536, "z": 3.841999 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "64ccc2111779ad6ba200a139" + // }, + // { // tarbank cash register + // "Text": "door 18", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 68.86824, "y": 231.536, "z": 3.841999 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "64ccc2111779ad6ba200a139" + // }, + { + "Text": "Zmeisky 3 Apartment 8", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 104.26915, "y": 129.2099, "z": 4.99642372 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39dfe3901f439517cafba", + }, + { + "Text": "Archive Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 80.078, "y": 138.528, "z": 4.941001 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39e49cd6db0635c1975fc", + }, + { + "Text": "Zmeisky 5 Apartment 20", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 124.2521, "y": 143.391266, "z": 14.5957794 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39df18a56922e82001f25", + }, + { + "Text": "Mysterious Marked Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 186.18, "y": 227.438, "z": 0.849899948 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc25f95763a1ae376e447", + }, + { + "Text": "Rusted Key Door", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 177.724213, "y": 78.84773, "z": 6.821482 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64d4b23dc1b37504b41ac2b6", + }, + { + "Text": "PE Teacher's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 207.952087, "y": 140.7129, "z": 1.39300013 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc268c41e91416064ebc7", + }, + { + "Text": "X-Ray Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 184.997482, "y": 100.691429, "z": 2.82870531 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc246ff54fb38131acf29", + }, + { + "Text": "\"Negotiation\" Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 165.190918, "y": 165.05, "z": 1.79457092 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "6582dbe43a2e5248357dbe9a", + }, + // { // usec cottage safe key bugged + // "Text": "door 27", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 174.013977, "y": 163.48201, "z": 1.14044952 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "61aa5ba8018e9821b7368da9" + // }, + { + "Text": "Construction Site Bunkhouse", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 181.878983, "y": 312.128, "z": 6.85800028 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39cb1c9b3aa4b61683ee2", + }, + { + "Text": "Car Dealership Closed Section", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 63.478, "y": 301.057, "z": 7.8760004 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a397d3af870e651d58e65b", + }, + { + "Text": "Car Dealership Director's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 66.86121, "y": 310.662476, "z": 7.935705 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a399193901f439517cafb6", + }, + { + "Text": "Cargo Container Mesh Door", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 83.1959839, "y": 296.521, "z": 3.72701359 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39fdf1e21260da44a0256", + }, + { + "Text": "Aspect Company Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 55.03196, "y": 332.649078, "z": 3.91900015 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ce572331dd890873175115", + }, + { + "Text": "Supply Department Director's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 57.615963, "y": 334.707031, "z": 6.847 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39ce4cd6db0635c1975fa", + }, + { + "Text": "Concordia Apartment 8 Home Cinema", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 217.9483, "y": 400.558655, "z": 10.3969755 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc1ec1779ad6ba200a137", + }, + { + "Text": "Concordia Apartment 34", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 227.979279, "y": 406.048645, "z": 10.3969755 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc1d4a0f13c24561edf27", + }, + { + "Text": "Concordia Apartment 8", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 224.331543, "y": 400.559357, "z": 10.4224167 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a71e781031ac76fe773c7d", + }, + { + "Text": "Concordia Apartment 64 Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 274.591, "y": 383.685974, "z": 7.404751 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a71e86b7f4570d3a293169", + }, + { + "Text": "Concordia Apartment 63", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 268.47, "y": 387.507, "z": 7.4047513 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc1f4ff54fb38131acf27", + }, + { + "Text": "Concordia Apartment 64", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 272.6917, "y": 378.880249, "z": 7.46978951 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a71e922b25f7513905ca20", + }, + { + "Text": "Concordia Security", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 211.010483, "y": 406.7196, "z": -0.205203056 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39c7964283b5e9c56b280", + }, + { + "Text": "Store Manager's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 119.953995, "y": 290.827026, "z": 7.776001 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "63a39c69af870e651d58e6aa", + }, + { + "Text": "TerraGroup Security Armory", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 60.7049751, "y": -79.95239, "z": 1.29402184 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc24de61ea448b507d34d", + }, + { + "Text": "TerraGroup Meeting Room", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 46.6899338, "y": -59.4043961, "z": 1.31902039 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc206793ca11c8f450a38", + }, + { + "Text": "Beluga Restaurant Director's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -19.6295967, "y": -64.19723, "z": 10.6449995 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc1fe088064307e14a6f7", + }, + { + "Text": "Beluga Restaurant Director's Office", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": -27.806633, "y": -60.68901, "z": 10.6449995 }, + "Category": "LockedDoor", + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "AssociatedItemId": "64ccc1fe088064307e14a6f7", + }, + // { // goshan cash register + // "Text": "door 55", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": -208.95, "y": 179.655991, "z": 4.057 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5ad7247386f7747487619dc3" + // }, + // { // goshan cash register + // "Text": "door 56", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": -208.95, "y": 182.011, "z": 4.059 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5ad7247386f7747487619dc3" + // }, + // { // bugged pinewood safe + // "Text": "door 57", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": -77.5323944, "y": 53.20392, "z": 5.3959837 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "61aa5ba8018e9821b7368da9" + // }, + // { // bugged pinewood safe + // "Text": "door 58", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": -67.94231, "y": 53.4928131, "z": 5.31730938 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "61aa5ba8018e9821b7368da9" + // }, + // { // bugged pinewood safe + // "Text": "door 59", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": -49.45166, "y": 64.02192, "z": 5.273139 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "61aa5ba8018e9821b7368da9" + // }, + // { // goshan cash register + // "Text": "door 60", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": -30.653595, "y": 468.8241, "z": 3.66407585 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "5ad7247386f7747487619dc3" + // }, + // { // unknown + // "Text": "door 61", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 78.59352, "y": 124.437378, "z": 1.328997 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "63a39e6acd6db0635c1975fe" + // }, + // { // unknown + // "Text": "door 62", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 76.57499, "y": 132.901367, "z": 4.36699724 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "63a39e5b234195315d4020bf" + // }, + // { // unknown + // "Text": "door 63", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 58.10759, "y": 337.684021, "z": 6.26939726 }, + // "Category": "LockedDoor", + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "AssociatedItemId": "63a39ddda3a2b32b5f6e007a" + // } + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc new file mode 100644 index 00000000..5932da25 --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc @@ -0,0 +1,216 @@ +{ + "DisplayName": "Woods (TarkovData)", + "Author": "Shebuka", + "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", + "MapInternalNames": ["Woods"], + "CoordinateRotation": 180, + "Bounds": { + "Min": { "x": -692, "y": -915 }, + "Max": { "x": 647, "y": 443 }, + }, + "DefaultLevel": 0, + "Layers": { + "Ground Level": { + "Level": 0, + "ImagePath": "Maps/Woods_TarkovData/Layers/woods_layer_0.png", + "ImageBounds": { + "Min": { "x": -692, "y": -915 }, + "Max": { "x": 647, "y": 443 }, + }, + "GameBounds": [ + { + "Min": { "x": -692, "y": -915, "z": -100 }, + "Max": { "x": 647, "y": 443, "z": 100 }, + }, + ], + }, + }, + "Labels": [ + { + "Text": "Sawmill", + "Position": { "x": 10, "y": -3, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Scav Town", + "Position": { "x": -485, "y": -390, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Old Sawmill", + "Position": { "x": -517, "y": -210, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Cultist Village", + "Position": { "x": -80, "y": -705, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "USEC Camp", + "Position": { "x": 290, "y": -475, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Military Camp", + "Position": { "x": -188, "y": 235, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Ponds", + "Position": { "x": -5, "y": -515, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Crash Site", + "Position": { "x": -252, "y": -37, "z": 0 }, + "FontSize": 16, + }, + { + "Text": "Checkpoint", + "Position": { "x": 239, "y": -65, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Shack", + "Position": { "x": 244, "y": 125, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Lumber", + "Position": { "x": -16, "y": -122, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Cabins", + "Position": { "x": -3, "y": -74, "z": 0 }, + "FontSize": 14, + }, + { + "Text": "Bus Stop", + "Position": { "x": -234, "y": 368, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Jaeger's Camp", + "Position": { "x": -327, "y": 19, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Sniper Rock", + "Position": { "x": 85, "y": -147, "z": 0 }, + "FontSize": 12, + }, + { + "Text": "Convoy", + "Position": { "x": 200, "y": -606, "z": 0 }, + "FontSize": 12, + }, + ], + "StaticMarkers": [ + { + "Text": "Factory Gate (Customs, Old Gas Gate)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -363.8, "y": 365.53, "z": 1.43 }, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "Scav Bunker (Prapor)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 220.426651, "y": -705.7956, "z": 20.538269 }, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "Mountain Stash (Jaeger)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -206.59436, "y": -215.9796, "z": 31.47127 }, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "RUAF Gate (Customs, Factory Corner)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -134.26001, "y": 419.8, "z": -2.37 }, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "ZB-016 (Hideout/Factory)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -389.159973, "y": 11.0449905, "z": 4.147001 }, + "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "ZB-014 (Scorpion)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 447.659973, "y": 57.46, "z": -13.46346 }, + "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "UN Roadblock (Customs/Interchange)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -527.8743, "y": 288.2304, "z": 1.68126917 }, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "Bridge SUV (Streets/Interchange/GZ)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -484.5639, "y": -506.413239, "z": 15.5812693 }, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "Outskirts (Customs/Lighthouse)", + "ImagePath": "Markers/exit.png", + "Position": { "x": 347.315643, "y": 347.0304, "z": -9.148731 }, + "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "North UN Roadblock (Customs, RUAF Roadblock*)", + "ImagePath": "Markers/exit.png", + "Position": { "x": -561.1143, "y": -58.7096, "z": 9.321269 }, + "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, + "Category": "Extract", + "ShowInRaid": false, + }, + { + "Text": "Yotota Car", + "ImagePath": "Markers/car_door.png", + "Position": { "x": -0.1508789, "y": -61.946167, "z": -0.680201769 }, + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "Category": "LockedDoor", + "AssociatedItemId": "591ae8f986f77406f854be45", + }, + { + "Text": "ZB-014", + "ImagePath": "Markers/door_with_lock.png", + "Position": { "x": 448.623047, "y": 65.5839844, "z": -13.269 }, + "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + "Category": "LockedDoor", + "AssociatedItemId": "591afe0186f77431bd616a11", + }, + // { + // "Text": "Shtrman's Stash", + // "ImagePath": "Markers/door_with_lock.png", + // "Position": { "x": 25.1087952, "y": -29.55574, "z": -1.47199988 }, + // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, + // "Category": "LockedDoor", + // "AssociatedItemId": "5d08d21286f774736e7c94c3" + // } + ], +} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt new file mode 100644 index 00000000..8a217e3b --- /dev/null +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt @@ -0,0 +1,5 @@ +YOU MUST HAVE DYNAMIC MAPS ALREADY DOWNLOADED + +Copy the "DynamicMaps" folder above and paste it into the BepInEx/plugins folder, replacing the files when prompted. + +If you want to revert, just redownload dynamic maps. \ No newline at end of file diff --git a/configs/OriginalNarcoticsConfig/TarkovMapV2.jpg b/configs/OriginalNarcoticsConfig/TarkovMapV2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..18cd9992b1c378a01032b5a50c527e5257ac10a3 GIT binary patch literal 1214077 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

dbbv-}zXYX72p#T_G5X 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

_uH_q2|zT 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 z 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 IU8pSMKRKSooRF*Y5_bqICS4?0rK9Fa1-$STn^6 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�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 z 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

4lA**a(uk&K6)=Gdg3w1_^cio8xVc+Z#a)Q51+ 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%0Dl)N6+im)uE`@)YPhh?r;y9- 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�}$sRcv-$RC2NIdx%>R0)2Srpm3lClDey3PIsecMO|sD^|X)k>`s<= z6+v$dd9C&uiI@I>b7hw-ozJC2aHf92RIR?}jZUv-%=enAPL(7q% zGaGfSVFq{mA$bmJ%(P$mzTIPCI*p?ao@9HH(M`_=2-izlUD7;?a`dUMaM`=g6<)72 zr+YO#d}sgT%aMCM!QftV1$h-YN7(OG!Nuty!k5X<=s^u-0y!=q@#|?v@KtO1|8{)1}9~XI-3x#2?r*F!bU+)zxH9NV$FZAuW+D~~~BF8v9$mSJsqN@4ldB07QYm~JLNbY~ z(JVd{#&?TLCzmoVh_y0qiUU%bXPc+QcJiKz;JX%%c-fxy#b-xerh=i~uAq=otx`@& z$<0+U&d;`PqN4KEWP&Uh^i(wPCmVSyA+Ws94l+~YUw5= zC=;5GLRVVSSx?hL9kZz>PGeqYGja%9bTQxibUx*Rjz1AJz;id2u2@r=?*(QOqB)Z7= zMDs0V#mo=gV|5h0;B3@npKE>lN6cnEyF~RcmnctyK=aYi7xfV`X$pxd>b@{V@hh35 z-CfdZl@-|{Q%KFL@9iW$X7Mi;^Cb6eney#VdBTkUIxr@|R0Krf6@cKq29xSkWN)>2 zbEZ2<>~fnaka5Y4;i7+VhqAXBy+P#*<|sz^e_%>dC@Y@S;6f+YVWwRJ&-SVg?59L{ zV^~yqA>&S{J&=Gv5Mby;kz|4U_6;IE5zKa_a%T4& zPswK~&p~)-{V~|<-47yjenn;HfM$YY8B0=8LF`&DzboW6hc`7FDC0V_Txm7Ij+|&( ze^Q=xZ;HsQJa#~;)1$qVeLv2%(B@`i|51r)TQ(H`J#H{%(SFV4wtv<-)gkQ8WxL%i zn$FgD_+QMmcV{bxSykOF!KGbsnAiPcre7~~D5l#h3nRL%s8;G+40uT=_*q}jINN3E z#?tIP&bFhZ_$@`{TN0FqUd}gVwlCNSCqWZ=<-0i#X$JjXVa%~3$uc*PjyxuWyg`jjot8x zKj-SIai*tG8VgetVGzTn-cm=UEOM^m#wPy54tu-1vbuWfTVdpC=jLOW@m#~4iClIs zxNGX@H?U0A*I8R2!24Oa0h&)rt5v3g{JPM)SUiMb`(ksF7$vznjggG6YC5mE=8L)h z6U;_K@Au$5LDK2DRzFzq*j(`FNf*0+N2Oq06Y|-0Hp2*;-KrEJ&X^<8^Two9A8{P+Oc-rO0b}x`y$J- z+6E=pW9xa@TCZ3mR1BQuqOaR@u8fi)3W`Mk36`S$%5R zd-+)t8gh;=PVKkbm$T?CnWqK&BC=-!WoQmsY8t;36UY8mlrQ~kuifUvp|Of0Hb2{} zfSQbEF|D%5#Zi*m0C^MxZ(T=t`rZ2abH2;jxF>|Z<+hw&OV94JqN@h7YvdphJ4W`3$)Tq+S?z^FFJfs}zB`n3cG>H7Zc{*iJr4~(hhX48zd4~m-jpGZ=j){_=wjVAL2C60c%Pf3uY@0F>pCXn4OuNiBFH<0~X`I!ClZN zaB7;>&qe}r1CHI)-;ZP}8j0KlDHW_xSYbos3iE!r`7O>=nf< z##M|we7W=Ar;^7aHTAfCKN7vnP5{&hi9BB5Sxw~MaM~_+bg1TvsZc7Z=br^<)a98D z#OXm=M_%3t*~nf@@;8ZI4ez=>Xm!&3!2@sDRUzYzb6<{=mMYT;Yp@aC60Pd z9rE#ag>8;WR|`RHwY*u&_&n;w$UW8>HNt6ijC7Hjc!4c+EK@ z^=OEhHbE@e8r1|~h8WL40t-;+UHU`~>h#+x^Qs~fjT^s8J^Kre%9MR2;S&RzaMa^rL_j2KV@$6M|&a+o;k@vJzv2J;Vvi*JmVBxbd&i*p;}_Rb;UE-Jj%*bc;*oM&OjWm`dve_p$#jCQbeDJUl1;ozW+yd(|Zr` zPA?XP-_uC%L@*yB-1+$?UPh$}$RCH)19KWe^MJb6E$EQ6|5dLQyVC=eTg}Sdj{u~6_+o*4d_PDoM0r9?0I1Qn`0ya#y z@VT@xH-s7S*74FUgaz*@pZQ!0q6i>7ykQDPBrTC+L{&Rp@%<`uAK@Dva5GFYqJIMF zFp;Qvr_xq@cEwm2(NGQ;ZAg5SZ7ac@6PdX?lB|yMD$z8b)aYr@exTJLK9w+`You-E z;zxmx9lLsk0J#RSAgwz8;3{4nwZXY-0V6RHMizN{dshQ z@+d6$t8?3P_|cRO=6-(%+G2KC-U*l@3;n%TiOp5~(EN+g-08l6s*SHeq<0>vMwgb< zXnmBx+`*J-TgZ1K>fZ(cF|RF{VH@(Sxf@2fn6W*1Y(8Is>UGCS zfF6}$t4m6y>PF2ap&RUBf+mp^X=ffo>Umw(l zH2&qRS@n87tu@zUKA}CJ_lcj?%IRq# zteBo?HZ(^$zq6NCXA#Z?J2BmFk5A z%Kt~ESsmN=HZGw2?ufg|#YVK0(eMyM2LnRc6H7T0XctCOglulo8y4@>!aN^7>2z61oAUWr!z>@9QwYC81zt-(e3ou5{*^4Y9>R{C_L zQ09jk6pLIZN;xmtPYWOw!`h`f2c{5thq;L%5tqJ?RK=_5y-OlhX(BcfM*8js#C~g8 z+*I|SuLPrO5CN@8znn|%d${*Y^g>>}1DXA;DmmEe30epK)BddP8&dP$c3?E$Y*IV} z_L?T8C1AC5)Rn7t7&Z#ixhI-(*%q2^&2d{}$g2>LNJf;vskHxuk48Xm*0w6GNVev| z%2QWzK&wg=8eqyr^Y=eHcQKFE2j|17MjJo$XMVhSN4yZ2zFAv*GJozff+^#sYVSgo zo9`ZLXIoRjCU-3RR^q+_9tbD`AQDqox@ClF1^rcWARw_&<-UsTWBfa79tVKeXFVOe z41vLAm-bcH@AcV~1PZL27Wfk;wUa1NH{l{+{npHEhh6F=_p@)yG2vvw0414!h5MF= z7ZV#nmPXB(kj|}$9VT4&_<%Dq5fzbC2&I$n|GI1J#-aE^=>fqEg3XGV~ z3$}r_^ts^4U8ebv5_R$fW{ zB`34;zD8b3^#blgSPT3@%#kg2#eUyp_~o?(zX_ZsMGRkZ7}>LZB(vf7F#DC`enMv@ zeH{v6D895JSnkNTzW|>rx=@DVnWLXTl|ummwcRSU~onzZ4$wZ6I?c2Bt+!rm2)aa1MevddSQ+x`-!8Ov6xoPtAR*`z1! zku72{C!Q6YtiyLB^$fk(wS8UDAtq7kA1vbCr71k)+Ul$y0<^OXCB|XM;EVsr(l&!M zG_mcjy~JP(LCDb2mKsT#PF_!a?9z~M=jzVJe`I^ca>WF2i`puBM@Y2ty5MaD4Me2J zX=h@WNh!(&euvFAft2#KKmE)#4iENJp+97x@b`E8hJK;OJv2cS@2%}fyU@( z-5I`n+et;k`)J>KTJ$h3AE@4HHE zAi0TdYKrmg;452j5&Vzr{WOODO`LLsk;G-IR`A!c;pSVw+qIy1D*GI!Pp!!GS^Loq zqs)&~nZIO`H*cj5( z>PRm1t|>#m#lg&CLgr?eEN0+rvH%C>`pVt?oz9Zihmy_ z!t2bcW+r>2CxiI-ZsUJs_5OQJtubXGKC=r;w3CiY)mB%M^j}iD+R^`!9mU>feJw;B z#{=qIyFLCd&i(vw85usZ5yN-`(tkev%6?mVM}0P=3hs^Z%AKfCr6| z${KC!B0U1&)ph{Z1FaVwi{V`#yatkyL=^=3 z8`s+k6r;IP+4TX`RD7YkT*+@1yWZT1ym*559cNa;`ct7JXgRYD+wKjE&7Ed z0QI@Kl_OmM4+_)l=be9H#n6G%Vi%7Gp>8d=y-sa?G|5J-%vKY2)uYa1Tq&v%}``}Ar%lN;qgJ*@R4 zReaSD&%a{w{HjQ4+9uj9j+wU4B;Na{1^Qk~jtu?U1UaXJ-z|~!#S#Z}mO`;XLYzcw z%_Q7r7nL)`91Y0~0%>{|YArtKP1@5=+zhS4w)a}isRF{;o(67jJ+A$jAQE|`o+0Cs z=~dAf0t%tpU3^LKt8#jD9yglVFkp?bdN4n$k-MPKIw)~C9%gZ5M=$jPA4UjbM! zxHkxsLoCE-w1p7ik7SP*0(H5^lzAt3F`vCg0j7rv&y6gWfccceh?E`mG3zOxJ2}&a*RP{G67aVVxN4snt=S6Z;4|(S?N9nz9aXGKo zA@2fzQZm&dnz`)W%~f<+m@DKhDOju}>-l`udXny0N=I4RkS#2Okey+ysJNxmd!pV) zSt6fSJ3i!e~ ziMiUF%_V=q-j+`Q7m#!>zfTKqVv|oQx~Olryk6b&!$VusF9I}-mB&qiO?Bg8N?$5K zyoIf*fpZFSJO&OV;Rh}iX{>{d$!~Ez?xd{5Nl0~!6|i>Pakq5E>gy$%V&S+=%n)Z@ zp~7w7r5hU!*<%Cjm?&305le1s{cOF|G-=B0Nv8For6(=!-qw(ml=B$Ps|kmEf0ugL zJR$uE)x{xt>Mz#wnPkD>&*sH~cJR+i-t^d!%A*_6b79eRoqcDidXO^0h?rITQ7lmT zUg|{V$E5Z0B@5uFUzA8`M6b4>aiq_?KRYhSH(x*V8)$exJI~Z91^lok>IIBuagK?5_k7{#^uF~(Wf$H!h#7)-A!>8{V+dZvmUe8|W%413g z@N&Qf^b4x4i41|^MfOHINxltKuc9xD*I9mZrWt0^3)^@h54{c`GpSJdWuc^H-v1w2 zP~V2Jmx8(<<%N=vn1y;UgsIqF-tr0jQl4Y94O$w6X)Ne*X=AOvG(`K?R|ie+nHc3# z)-K3K?rbA?rm|#;JLYnc63|EH=8l!SbXeDnp&Qt#2e@@hZbF2sU={ZYyk-PcN&v0S ziA$T{RIO^}vr3`^98fLoYd&eLaWO7zbMdhCXT|zfqb#qxaH1`sAFTr*`U^BX(O6K+}?RE5-r)4~CQyEo>;wKUFX1@pTT0aiBbq$U9iLc%k z3O6NhJws)=HLNySF)W((74+B8j!4r6%lVx)YgJt}-}aA-!f6P>(?qwNvu`thed9!H zFBiP?;wbOYiYHQjGk+4?hIBtZwbXJnKNn`pYUlm)vd5ntRwl(tRbra)yK1<{q~UBdLcj;;%-j z1;2YSI=c|=D@zlaq0t;^82t2O^i=-?-(Fcxl-6MyWin9Ll z`gT8HFXXC4kP^)5%=`@_&i|4#5KtdQoJF|yr98WlRjP#2cX=7^df#lx;(>v3q~6ir zfdYPO1F*Hqzuc7=0ozEKn``MiPemVH$rHV;G~u?HXmsz0f#=tWav9!DDI+5m4?chs zy`TYZAIz`tp~EoAif``JT5^6pXji?%I%T(&hwJ-~E6=xIlY?zWopT?zuGlJmwCF>n zOc-SgOz;$+xky|8E0hm3u!+9VxlzwZ_QKmxWND5;IDq4WSF3!Pc zzE3PwI0c}1Ez*4!6RUYwk zfZP^jjRY%%Mr#297hT;-H^i+T(#^wYE;EhO30-)_rba=O`A|JE9S-UF+*A$D_hd>l z^b_(nKR?uo$hWs1ZO`{K#wVBz_P+Ap2F*!~e#w4zG;=69UHIrfvQaL9^fh_w<)OnD z8O-0&1M|Oo++{tYYU4Y1MjlKUiL}Uw&YOy|f$V$k_Zq`K5pOHosB)~PQ51|ea%ZvBuFBb@>Uq|HGM<+=~; z8DcnUg`Acn1koYVJB6CFmezWGVQ%eS|-WbF%x-Sn3L#qBRB_;j|2O{E&&&*j~j;oGzj?vB0V z7I^ZCx}lLc5W(+tn7*pb+UM*=8l9BmaL7rIpx5GkepejeAJ@3kYq{l#j?YajN-k3j z8t%e_h2}apdziK(k)*!-l`vhPbL7k%oF1&E1FovLfRl*cB&-~wXjiN5>4wf3iJFAf zSZ&Vb*kry7B*UiPk{e9yd3>G#g#r{&ZLkmhQlZHNBpvE&Ek62@qlP#9)zYPw6jgBK7IbX*dyjg zJ0Fy4f5mkQvnqRZxm=~u07n`Cq3w^6Ix~N=8Gm#ue!P*iZr?7SBg0)dmzB)ZM0?OA zHs8Mdr=98#Hm(a)cRcfE{7^qm8?@0r3+kRB(Ur=*X8*;4%<69|gwvi;^oDC0;-+^-OQr=)Kv3eE&M#=82{_f+`qjz}!a4TbH4!L(A3% z4i)wT=d7sg8S5U?DwM37a^k8^>iYui{c__Ct4K?;M0{>2;>a-X_h=&b{)O=pl<`Uc zB-AxDAYXLVP3luUg7#g~H6E#qp+Y_@lZ z68v!YigD*wCS*Yqvi|eIad2-IY33|ce zP31d*;poUpXxp7>7xnW18!Ax3b&9+~&~gaNuBpZ8ul}*FuT8^gHfmN% z8f&rfABv`;ZQc-13S9#NU5D4~LVjrAWu~PsUnqiI>*KfEYj3whS0ogp8?W{T<&}AY zETud88+4NQml!a?lgk6l0Iz6dgn4}i%<AwE1%p~#5V zhc^jyZ3@?6-V)V>H zoN@RJJWQdq$8h4%r53%O241%}|A<+IJG3_;;jXm{{DH9|bqxwxR&H?)WR- zBu>$rg3;hf+_%X;O1}Jl<*E3d>l6V}_x6Em+VhJtlEv+KgWetJEsd&{46sd zS+Jdsi}@*z9%%VOZz?`l#!9U$lnw83qJ7@CYx6ZuC2YW0@eVn>6Xx)hwqXJvKIA$F zw=~z>>*1s?-luh<`R+b>E!&pF8L%@h#?-i5I>F4WXla-XGpcMpilMlCzTHkIFCcD2 zH-_5vkcqdWq<=Aw98}~caA2A7`VHYaPHmHvRZ83I)kSRZX|8v)C6MZ?k>cK1p~a{T z=w{F*_Rg+c$ZcopR)c~2FNYpz^R2kf!NH_z8>h>D99gyl^f)wfrHzw_R20CjkKd0f zsE_4*loS!Uwaa&Zd9lhr5F4)5_*e?Xoyb))Q`fb;rJ0$Oy}i@5>_GamxP7e`>J;M> zM+(!^@3_6TibRyL{Hp^`MJFm(u-(W#Gz3$Tq$i zgBFSudZ3R;Ir>WKzHoU5ajCh6O1pDT zzAw~%zP*RvQvO!mJLe z-Xnup2LEPlmB?*xCUYn{?Z#!0EDb{6(nGqTROV*RO;(4Ltf|zqNaiA9fA+IR0xU2O zjq2y0Mh~X4JmkX&g-O;avc-eJmBSKi7Pn&_Vz{00!6C? zt%BR^RdF=e8-sw;J>X9l1vw8VO8%cgaSVS_qA2R$>)f)f9y*?ifzMSd9`0#7r~t7= zgDxRMkz{)4#EqSF14H!nbkDOpGC@t0O9bm>9wHZ^Zb?1jTWvR0;;xgX24A%u7p>1H z@Qr({*IFVvNfxuTr@-zC!V90)Wgrc(IH(!{!;Hx=pG%yyV3`Bctd&F}BB4cPJ4QcL zNczQi1!c*R@1wlMOXEK<8Y*Wi+vzp_U=t;ur8ppxHXU~Ikw<2kO27Ph!h%}blU~GF zeB==8_b@&hc?qq&^vjE@dd1Wqeo;?;Z83b_x_71dBpM0jYX%N#?wm_H`BiuA%NBnW zu7RxWEnQvCfVzYAF|#uZDOsg{|B>m`)PzwZILdS@0sd&Rzyxh++OaF0>kN65qc8@5 z9^5H6OZm@_==o~e&{iWejW{*|pdhRpeqx@TrRn$HJj>K_ z;sMJ%YBb?Ox+GRZBEPJ*sw4S!d$V$8Dcg1NxY>}zXhM}tM!_(odu9so0HWc*F9lq= zHo;6Ctj=F`p<3%X>y@ND-g(}Rb9*7<~l<3-XY1~Z(1 zj)#BkbGLdy0t$7Lw9?-eJ^4Gndk!wW!tX7^8n;(-bQ{XUC0J~E>lsdEVq)68Im;)4 zmNwoFNz`U=8pWiBQOVFc4{1zEsL#Rp%LS8FO>(vV8EZ^?lxEtvE*@$*Nmi{DGWIB{ zqZWS4gIS_FZh7$Ngao#W-(X4^k%Mk%8}j;G#GZ;`fM>vsw<_6yjH5qy)*jF=ap%ct zdTmMX=pOJ8agKhjuUfE{d38P_wPz39;i`_U@Q*0XeZJuXt=;C4WO>L zhR0rci-l<&!g%@6Z?fkC(IWb$uCo7ieBLeVK;(ke4MnmYr5m-kYbMXcqra$Qrm}IH zHdVh2=GhPC);Ae;oio0(qU8WjcEG84Mcx@rI@4I4mwABr0DBV@8V9cgFVU#egIhr)$Zv8aFpYihMspDJUDjV^yOM z84oQ-FE#xBSId2M0(AcfUP@O zbIC)~&+Z55z5SuOpViQ#e6-ZbqyP;k-`O@<{H^g>4oQylG5R-N$EWuM0SdN$@_ICqJ1(Y6WW!JC)BI@Nb9@%@4)Pq)wSP}p&I{)1D?s<}{dKCS`=q#^4IRuQ#9;%r3}@tZSN22?C1%Q>$GILA{a|;!3J?v> zLl#5m2wH$H=sgu?p$ogtgXB>?(0ev^(Ok^hbZwhfDUo6tOHZ>Z9YT+jx5CQsXfCwE zUK&_=q^oJ=IrSEXzvD zY|?6uXTH-jM#XKssxu;Y+bVFP6!_CW+R7X{<$kNLSsFnm5{E5W0xvx`yoB4zh=L<$koj9oX(gOG82J9>9hU# z@}Mh_caSe9uV&^lQ*s-7+1LQv%w+@Zs8c{??Tl9U7x2O)t$IyG_4MK2s*mHfu@t78 za4iSD$UV;k!x482d{z;9{)3vxKjUR1if)BBi*nu{@F_0KI$y?*Bx|^Teu+G#xn)*n6mz^rYV^!lyKl7wDbEn~c+&WVv`@&KP`pF%(P9RsUMk!onpSc9|9Ef1H42&9{UO?iBXJjL)VjYP{IydCf0H)^Ma_)?=`1y~>8rCqqKbfchDmWUd6J`ZB_;l4XGDvasJo~j0L0T4zRbNwNFBIcS4Uw7b zO{*t9yqydgt#!ZozjFMP1^Y*7Yr{ z5Hcy1)a57ul{#c?_brr%9Io|E_k9;ief_YmsQ71Sz4Fvr-M-f-iA~U66W4j!e$&jt z`67?BApui9=oL#uKxA@8V6dKM21HQdQ7pm>`c0#EVO-<+wYxcsMsEY; zt4{Z)6&~JcYn7L14MQKT1sHAl1(ZIlSHdjYOfkFc1R4Q-XgverD)O^rmD(pg6Gy+^ z!PH(h2yK+UVSl(>u07T`ZwA%Ijb5=5NLN%!<5jM>pNd`Af4m3>56#XOwf`fNTvYdL z2HCLL2Y5!i&lK+^iZ}IiRmf$eZ$aKtjn~as{BvNea5m%`MNG5k7Yhd4H8IolsAGcf z?^)h$nQTM5`WAPTIw9GDy9&&Ce{VeZ$=c(z1|Haq+Q8(w-A|Lbr3)SCQR#kPF7cvr}$p6LV)E?>0w z@j?J}^y=NORV%=9O@KD9V3w(ewuYverhF;JWTCdsG(}>E{hge9gP3ZwMj8COm@TAq zrt-kM;JZM3I;Y)bpG2-rG5=23$g+$Cfz6shjaFCBH)bJjF-LchXDE;_)zDoq(04QQ z@ECd!%Ton*%(%tc73uMH!^PDS*Q>jDrNE}P-;QN;AM6TwxiA)z!>we9@Gp;&LW}>j zC7yz=O669e9ftsjGO2#Vne8!F4KJ9O-^JOK1;xi88d_sMEwG=v7aPxqx-gTS${Q@+ zO9Czr(Xl`U{IB>lIP2vcgbh*EfeA>KVmXr6lQOHw|V(vtw zP(w(@swrR+5;Gnm%W5QHNIU~*UOyZDU^{T$w!@Y*LJoPU8NhPt z23>{|-f>!EWPEP|%E=bcB&Ax+B>LpKU{7Twb#9z>6mPeh~gqmg4 z^FbP&V>fAA;G`KYGLJ@}vFg%pKdO1tUZR6Im(HK=u)p$Yf`^oHi+ot9(1vg)((Xf# zD!8KzPn3mHr%o)SqS|d=Us^##Lc5gy*9QO(%V*2M$5oR07tl|u_R*Vaakw;+6Ce}Y zm0``hdXy}DN-v&QYbscbt5z~S68h=JNYA>_Sm&faHF?mrnc$25a)SsPB@vU5q7sqP#a_F>~HwWE&sDHj%iCA^0?ZK~`Dz30NAa?q&svpiC0Ni9*C z5H(eG^thw8{Rf>#uH@!Nnhh)E;1OS;7m?t!W@H%TY0~SXH*;v__KWHL|Hx`s(dK^N zmMHR_fdAhUa6#T1nAp=4;=M@viOE-Y;#~867KJSq`6f@UH_8F{%&5o8SJI|9_mD1V zi9(sfQAt4Vzbl)SjhV7DULw|C5ogosb8NcfoL~!P$-zY~=q?Y?IGg?x3@cwKA+5-z=>s-ac3RC%rkSy&?jy}$ z*By8abPh9(JqrWf4z~1l)AB}r2B4ZmOIGRxrT5-8M_kVUj*n`jR*Y4ft zoa;L8i=W8@*N3=^-z9LMN#Di{s-S%c zVoGabU^B$ECd%|8s&;V3{`FSbgBzcCT3{VXFEdN?xRWi#!MRXJHyeVuJY0 z@3vR7xyOo}>2myQ!8~um2)lBl-b>>R}44NGuwfX{&(~^^*{=I5R_qq z53-Ul&G}RzX?1-D6wy1@c@7~CQ-~Wmv0+83D?1@`HD2D;%2sj%rD20H@{X19id4!8 zgxzgFzYs0K_js9+jsM8hCwMo@T^y2e19`9K!hWL<*lb_zjyMZk`ibgBM9gx=|JBji z3qmjhI z?jiqnL-5ekmBr8O@;fsxNP^1MD#X z7#D5Yw=HZn1cT8N*mGw6-H_LzHDR38ow&x4Mf0J*#b*U74ja-FNb=~W+%(VVh)}4W zzEkjsR6ntNkGbu1Xef70xlNr!=zSv5wxRJYJH-!qv{+Ow*c z757--%z|pk8-R8Ue20^w%##UaqFK5pjo@sYNbh_IPYRJsNpKmI?txgp!%pQav)(f1 z6<^dMN-snZdqt0?H0qZfiK)0c3*o#MMb>;G`W`HW9lN^>RuRVTa}~~~vW<*g|B`fv zJY~Flwmq&yodGr8K<9sa{7G@_>0ExV5lso-d*^%aU{*zR|+<`Irk1q zm&1BE?$fF9bSVmmNEM%v=ZY}zWlr14A`0=YktzWX1j%T z2lU8{DMS750&7KHBK2h6W>!eytMc?e3&dB;5qebW=1TjV9-hVI*(B#ZU?VM{31tyh zH}vRzf?Ct@`dtUPjbUhQ2Yx!mZC-lbNS&m6b0a6Gzr0btxn(tG(r}=I zESZj2Rv5Q!4(iPQe(C)!&)WBqcD;*4)D+G4fOlynaNCFJ(n88 zL7c$HBiA;iCjP}zzuqbdIo5mo;P7NFZ zSZWyPEsd4zD%!tTR25(REWPiphpMVKvg)YH3fw_`7hW~xu}Prnfhg*atzAzFy@bvZ zcUl_r&2Ld5Bm52Q@1Vlvd<5UQ^mADP?@A$5#}%Y@WNy8LXO7pZul@slcaYIfiz)e; zD=yCFA_MxpfH$wnl#v?WsFUKpq#(pFcXou)wOAVq>(?7xRuA-mvTH+Gv`T4x?43a;=Sk|Ba7ytLV`gi|3xsN|M6%X~gn76$!1~JQLWh-E3Xv3MVpHjId7ocxmERW?zwD6`+1O<{S8eq;|>XvTX`&H&hx zm?kd>8e{26&FqnuI31DB&&Dk_jq%=hcaD+?_+fAs#eK~UnsU*@le&ZEtCTr<1%sYL zU~;vvqU|mYwonP{sPQ1>pQ|;0F*%;wa^~!47Ral(Dw2~8FS&Qn$vl8<&H%1PDPLG^tSB62P5tWVLN>ZViB#kAt$vvS@ZZ93iKc@c~Xr(Q>M zK0bWH1?CXM8>w+b32HNp{w12*Tozz5>Tjmjc(tOUShUjmOR@T>bqJpw5qzYU-d~d) zktJ;8c5G&Ri*s*!>EU;xM3_UXf1t<{PS-;C@L28r z1S<*jkaLch!-KC?uxG)k7bII>aNlrH9P#VoC^XX1ByK@;1vztAg9zI1%P%etY`c5=OE0AKCW#Qd50! zT{!X~TB2CMktMvJ<*G~m>P77rXEj{%AFqy#T)$D+hEK`z&~wYm$b*>A5w|$>@VRRm zk_S$fa?~@q{yo#A%v!*4+3LzK?_57qsV$*& zBI@7MiV`0`k(&8y+_8=U&|15;^27$J^#OMN@H&xT3KSMEc9ipetGMzG6$5)TIPDFt zuL?gXUX}WN`$m(p;+$}>w++n#Sl3YSOas|$L673lPO84Cei)IUK1u?aS+GLbE9XqF zFg^>a`PRM;rM)BpYsfkMvxBh<&8kIUfHT8Mj?9l&NbT9#Opl|peU{3|YCl;|g}0=| z^yHv1zpKsfmPh;WiJ#k%Nj99lM!}?s{P(ni;#J>QUeN`WVWhBZ=diNic5MYVM+FWn zAi67(b*_SU@XZyZKiGOHVtR=xh~EUB@%&SZCn|w5gHIlEG_OLTFzlLRTfTQ~w?{HJ z)XDbyPk{qt=Mc9aV@28<(Z+XwwP<`O+y*E5^&qSXfa_V*@xZ;9VQg)}4Bg~qC_xaP z1Q>d@GZB&;o1~~o{Eq}``kE2I5HD|~{b6kWDtBsaNC3L_WTSq&U-RL{Y^it_{o~@! zbO!DZb~9-YYvUZXYVEVDpT0_`$C(>47Ch}LoqyOZJVrFE*Px2zeFWy~X=J3CDD zz*0y2{wF!8d{wzsc=+BliZT1JbX>s*#hRdK zUXn}`k|jn;rF-29y>m_gYK8+Rp4BG{P!&646F+#B@ON~b@_GlgGF?xbY=$@SEoa~I zQ3M`whKvE}d_d~W6KB4H-b>nCgXNkJm5QH9fVf3HlR6)LL*s~i-(pzuO+3)9UXFw_ zAXaD5P)aJ2mj9?w8sTd$8<0k1xtJ%h!(j~sQ0JuK_2ZlMOVs^WDOd~^w0@$iHr1*m zM;~~!7T|uB*F;OxPTJBm#`~|BI?5FMOzxMH{4j3{R^gZ}06qBVE)cZtRZ=ivX6@-( zNqlew+ova}1`Ww{FNJ!<(hRK@dlJ}#2Hr%M!I75v{J?wqw=Ue?A=bs8-ddxL5ygf7 z&6Xg(L!J=1+~lh*D4iRfYBW-V_GfQho`7>W1SdTd=frV__-cRe<<@(63ql(X=a-z| zpF4{zy#bheJr$qX^^O_LZ^U?;hT9_n!`Z1A-b();ne$ka5N2VSyMfvK)x^zh6a z2(0z-)K)SaU1^SEFmO_4%WtZR``yoTeQ}E{074Mlg%$)DPk3EzKey$;v<%~QSFW@$ z$VE8B8mFJ2GUn`=`t4Zk;%8gq8fB=W#Qaa{8||A?ce9UhIY;go;Yf}Y4&+hF^`lw2 zH?{!^*LRN&DhtGo21nQ@7^A%*kKF`6c3~SC5|dnvLPBufVNNw7)By%~_zD$odjms) zbq*eEJnnS(G&GsWZMY%fYcp~fFz75Bemjf?5gVJEZy@0#ophVOf4~~ktgIVFg|2sg zjnKlYDI^Gow_vU5{HKL{kLDJ}4<&Yx1$b#EO9MJ}df;mkW#Iwml!HG&z&CYG`i~e9 zh{||83AgoAEiJL%EmW_laYXyHApp}vRgY-7q>IezhzXVtzP^GN7Clu&*vcVl+tFID zK{SK6JZ1f*v!y7i#d=DSaMbi( zS+}m*d1>uYPux|c-FkLvs9#L)AcN->gOK~%y6S`nDYR8=gz2Gdnls~8J6NRqHY01^ z*x{e9w^yUPU>)^tW)R!iknd7234O`%zpXHtz2C}3uj|8fekqzvMZayHbsCPKr)#pS zmL;&RwM0LUPRfh(=A-|y>OBtgz#%7=V|ErlDsxdIPoDoEsNoUI8rQv3WzHgkmQu#6 zQ7H1o26IVV8Oe|tQ@LR-lqcyhFU&VUBh?58dC+xE#8ggtt1)81ILXlfZMe4YAN5+t zu53O~!~mY;Eiv=4#soI66aFL1L$_FSdm=v7V9UdO#HlN-2(67TN~eOjs|jzNQ2%Nd zS9XKphPvxcv(}Zgv0Q!}gIPN1b~HoB{NEnW6oRbiTMVxtcY3>UGOgh_!I}H3 zhE=Tm?Z6e0Za5E;2Q(#UZP>>B_a)!;6MWLLkKlqc68?Pa<;Bl;ER8NRB{eC62BS-% zJ%)ekpVcS|+kVwDO^z@St;%?)%160g8$%D-IgDv}fCpms4YjuH;+&bRo#QJqRpqgdcm0U#? zfhQM%B@+ifydLHNkZyT<`r|Ax_0BX)m~=4j6A-eS;Jf7_d1?5gtmy2xw6C|v)6qiU ztxtWFok{+3jau`-LmwP!D$+r}x5nCSI(A#Jb}7WOxtKtZa8?XZ!Zc*xBpM!Fqg=&% z%N;iT1By4PCO0*sRvYB%bu+xxT-h4UWBmrOhTr8>tWgL3yAfkwam-v|+>v6On7a{o zwReeTQ?_=}E8v^G`RY|#C+dX}+rTBX#v?3gsl_I)a)KlAMjR&artB8#_C@7XMHx|+ zP1txm&OEpEsA6|_TOVo4LshS4QFEi)r*UO5WR>+!`1|pdbeA62C{Q>)8^?8YwU~Qs zT7~ZDBIfvk{`qyenJE4hLq?6;u*V|&<}&?$;*Im=R5XLhD_7i}7Y!b8g?f|o4S><*d8;TE)&-n7>{6hk z0@QpkQ~Hw;gK0|9tEw9pPFviN40|gj&9u>~3om2v`R3;9RvJv{Zl>4+oLvXqX^SE;X@pgK_}xKo76;P(8)NFDI!WV8lzlNjq~E z5@uKu{2-=9DwBet!s+fpO`|pLO5IE^+lTxnc9jY$yyZ&_wkJR#^<=W>spb*f1AL%2 zCN|P_hqhw`dh^)-CY4V?NDdGIc{z*DlO0C8H8o~J@Q$_R_C)OHU)lE58C*pl%9)oc z7eoI2f?7+z=sW~XTytOjY{|2dm`zt2R8Beq({OTJtJ!-W5jpnf9OTszRC+qubcI>ZPV|?ZvwObX_O_k|Bck>!0{*1zaOH|A4+StUa~0evdb1V2(xFyImSF(09x z=MNU_X#u~x@g;&(qJ-+LOwSMHzaEkl>NQ#VUi`kUklu!Sb4#9IKW!%Id96YaewD!J z7Ua*GSN|&D&xwo4}QD~ zpr3=BEt)gP{tBoE4MvAipq|xH`QzRnWwn+A)}}NzBzY-B&Fjp1V5`3D^K+r7yJ zg&XW8@|_r|4IB9&y>7@>%k9Y~jc4%asPQ{egg>Bdi#URikD@Z&{`d+^wC*ppK;F@G z2bczLcP;Nhu=$Uy)(Vvj<*bVNVW*2~e6)fH16T0=kh9D~PENoa2UREKuwbR2VQ>X$ zWtz%X-ehNYq^VEAlvhb$%ZSTVcfF&ebgRi#-Q~nhVXK^C=Cayw%XhMxW%5z<>3#M; zu!bD>S=R_|a<&KV+e*n+Mx1c6nn>dA_hr!lV@&IwPYXEpN$qw)CYo57R>+gs#-xm25$KD1p#pLJo*KJ|C}LbeeV22{)dT=r;f}gsiR$YoafcS}o*z93#f<&O#yS+xxi_cX9FqhQ+flKyNs&*}nIiyvD0Wei z+^1?uE1na7@l-j`ainW0nxU17$dCFUHWcVlxL12|k+FKnslqgXFZIc31hd zr0!d@*MqZSY<8am{bG`Ewn>26#=Oozh@iJ2iZ(n#eR$nd{vIIuXkZ07hgQqqA{iA< zlPfOb)f}8oWOA3qe}2x)E{Ef;)E;-_s50^fMVdgzKk z-7u}D++S@C?s{uTYe4hZ^;EalK6*(1dXOLp{c-}jOArkJVhdxgpW;JaW7R^D`y%>B zS4GVeaN$?|Ioa>N)Y2z=*ig~Y3Vss*tmxBpEWXeAD2Q`s@g}M&{$RS_+@#x+^_@&> zI_1I4e`I{J?lng)f%WuTlQ}Z5WVJP9#mS$GPca(LY#t|cHm*B|!+nE0DG?EK=do!! zyKPy**_~ptf_@n?@}08}%MD^P9@*V`=)3$?7Sv#B5Ak%96efSLcKX;bk00vpN$(`L z4H%kOF`3P2ym$jwzj05oqv0Nr`;8zPC?8k?!>hct6Y2^avTFh(F{{R%1D6>frf@1+%+MdV^ zxoj~JK<hcq?=?zM#?$lYJQm_-DqmKWT&ze%0?!j*B(R@f4Ob3 z!mO*Ks%G*Us+OY~p!m=T_ikaAJwURAyU`%ser;MAv;Wq<#bT+USs=9$|Hakyk!q9k zp@tdt>YJNX3R33*15+jVVa(z%)!39;=g7mJ<9@awLg)DN25p#1qzMYmE2sZuqqw*r zFYuXZ5{$3*C1;2F-MdFmt^r8Pm44wnm?lm~l73-lN`O5is^g>W8iR2bB@v%5Z;5hF zQQ+)9Mq6I!Q*3r%xGb`3Vx}Pn(4g=!Z14k6pEz%_RS1InGTMM3uW;&C2&jw019`$&mD}3}6-NJKw8=riQXZS&+EU!vb`c`>o_uWX|s*&s&heLq)aM^A~E22r3tH@m$R zIoY5s2f_~J4nIDNu4Nb&|C{8}dPw6;l-hf{N@K00VGtis+}ccxyOa!WM^UXJQ%o-6#46Oa{7bWc~*10>HYe=IBVV z@|76BsZ=j&DHDnaZ~xj$R3l*+Ojmb+V#MBd+Q@$~8d5`grZrz}zi}J?S_N8<&}czG z1b8I!SG-0=a;%nw&zOmjz1`a~l5I63;HogcMg%Vpr1R)De40N zXRAE2Z2?;`H*%PQt|3xgdC4OVM9$1Lm)hS4Hqdf=p}pw8uX3%MCG`0A(i1jsuWak} zUkIp30?v1`S~6)m&$!EOTAd5vBCanCj{1^a0i96Nxa)xIraSM6=Z!xMSSL(u^UI4!ClLQ+&xd$ z6J|Vgcg8e{FT>B##2Z#a=Uz9?%1gm`-PPcT#T%2qk6_V`f#*$g|r9uiPcxDL7^>&;$R63eFEouzpk_ zP%Bun?Du}~4fp_4br1l7u(vLb6!3FW`_#(&`96EyY4>i7+)wGx9a!6?KBMw5$_6}~ zwcGsC-|MWP4koy7_Wo|lZkp4aaM{Rnuj+$4C=ogTwJq!)D#D<9#26MDzc^dFCY$I7 zqNI-X$0IKPN9g0!AJn1xAEn=`r`qJ8fsG7wZngSsviLg}6tnuwUZL!!{E4 zZHSIWl%gyC%b-Y7Tl_X%vDz?+lmW-Bc&Y7fF{VLFe@NV+VY%*CJep~x&O2JdofEl& zEhiG*6VzscW;dV_`m?CPSk7JX3>+!_^`d~fR^YxK%^QmkCPIt`i+xviZ7omQJ_UFu zZ_MTc?Ua(V{@?s!(wv)-g~+v&g-1p!uYf)aIi0^+I*M`_)b|TalYxCH^E7=fx}dbn zat>Iu=b%ueY2n&7xfOraAWx}`8vnM>nf&}%*Ln%X>+H43EHy0VH?6x$X}@wr+>7I{ zmHA>}D=twS0%zm;+Mo-Z>KDb-fvGaAM1A2hh-3ptK*4S*36Wv2q!;RY<8;}5-$IY@ zu|M|PH2DN#<%HsN#!i=G%CbII^MnRXLmMEFy;D!@4piVY?jqJk`9gR$EbyX^oXbgd zlv(1Zm}X9#-c)F7>{C=w**qvZKoDD3g*SyjX|QB8>lR4_VXY0K9@6%p2USQ6PWAYY zY>~0}3>CSlhuN3p#ZO0If*t-NOH-egFU`RxaH(J^)hNdYV*#5>wV>~7qlhOqE3Rp0 zuHeqpeQU)~y-5zQ!H?0dI#0tFnCVkiVjn4Eq$FZn^5RT#a3UN{pb^ejbdm=o;>XRV zfnL@nBbaC;wTr-5`nruRr_YHQuxnp{QFJiErK9ADTbwa+=>VhMgCahXOXDF$gNS7o z76Gc4sc815vOM~lqKF+04C7DgU@xEfFY6B8y}vqSx-Y3MhLeIZ>`?t{**irfC@%lL49igrvH6kb9i^#w z1FS@RS)aDDU{u?^39w$J>15^nzWA`ICQWKiH7ZH!Fk+krKvD7zO{1$+lD-x6p~=zm z!hUx1#eR)72eKZ^*)|>^hlOvX3a=k${0u^dg}Z0DEZh$K^eL@DVNC1;==Cc3`dO|q z^J6mqaVu!mL!jAMN%;YA^L=X zaW}5ggysB6LRp7iks3<7Ch&Wdf~{*G*IXssST7_a%9TD(liE#E(Pm`E5qnnTN%P3$ zk=@S$)^kL)NA#WXPMq$n5xVz*C{-!aagM)}WAc4To;`b*sJ4S<9r`>Fvf;|~W70eB zSSm_?S1au!eHt+R;IvTdyb}G2SR9KTc{~^|k(DWKwkiFjjWw|3Wj+ZB?%tY6@Qc#Z z`nbQDFh2H~?co#jyJYzo`R%LoU^-k5P1>L-l1%uq+NnZK*XnH``$c{N$qC|d#K$1? z0~sU!`rharTOmBl8F032$nz7bD99s3%)o{5+YX`#Uwc3+sPPUe5ro6f`Sp zMc^e9JXnPwN6|Q88AD1DT6*MDs~+@z@zY^PtY*$?EF-&xY;biWb3XG=@_&Wj-HnB&ZzQ?oe@S|1^c~APRVZLZ*VqwN&6U7rTKI5;G*keU+K5<#g%jH zN_xRTXiE!SDh7$MopcgUelOJbt=y-;7hk32fbJU_gmfmIKrsQF@=E)+MZpyJpiSVn zWtu|@;Weo98wdLq?Xuv&a95qQm9vYMUMsmq^_Z!k&#Q~^xMkIWg6&Rs58vBlf(>71 z-!?d>waNybKmH>UZh5@I;d$EhX#PV}1>OR^H-%4spI*FMn^w}of^s;BP4#_w!B|d3 zb{}>(3>v*a(&u=j4HOE}q4&L^!1oGUVc!KMdav?}CAn>-wxQ7ME-}{9HETI zq?7R<9aH~D7ELC!e)6ugU^^1|rYoNMx~57lh#f@`Djf3UeX!78U}1p>UomBUx@nweq#J{VBxrR#m5m*~dI<5?jKnJeJK`}5;l1pCIQC7>+nf3jIsmIWuy?xlI$AEj0 zqfmnyNnlRh-tLx|V+K5zZ1{4#zq$_k{fbUzaR})!g!_$#CLHAC96rZVVZK+xtnaVh zEh^}$!dE%}kJo=`_ZTHs3-`vc-l$zvV9{C1WEcGK4?TAMZ0Dr~4?HUBpGqgo&J#Rt z>O5|?%*vKc7L>W9Qyc1WCGY*NmwH(*KSGhhQriRUE=-TnZ7>?PC|3u+cf;N(BBc>@l$6Fw+KzwC&X(X2(@Vp)8Qd zKOgg?pEY^+`gx`2W6! z-G=)$05f&8$$r<*^Kt9VQrG8nxtgyobjFpB8o^uGeh8r(JGG~bL2Vvzp^mCxF+X!M_ckZ@$dh7Lx=UTubHkzz8LoBQ>H%jESaN5!b)c0P3guB z4 zmj5B-HH=$N*f@A=202J?A}vW_ML4$PlLhB^jfTSWV2V*BRw%2IWAxW-gB>z3oWaU6 ztPsfC8SrYld1H2cy=MIbkY3Lhx&i+r2J9g3so!5$)}*f4&VEOx#ZeWF#x^YFL$}tIR)7OBspWoC?^?k<$j}`$ zeUHSyS3{Ad>gxu(7Zc+>h9U`GuDeG2Wo0vSGn;Hv^UmG0;nHmXbnj%@4zqe&)aMr3 zx2Ve24L!bbK~lMHd8JJ%@cVQ?qTy>ZVQ+RI2U{PZUe>-oUM7VLdW$U&Nu7X{L-II@ ztKmM3w*J~Ddh2S3(3gxA>Non2%+vb*?l|Czw&OptW0BZW;z%~;@Pc_{O!24o2EJtN z87VPDxNt&0CFMC@INS2LEkm3dUvwb+XL7@oUET}b<8ruvmV3PJv0Tf*6mPpS<8EtZ zK*~GGTDSHb_c)uM>8$(xJ8i2YvS7QZnpn0P;d)FIfUTjgahI^BgM*nCYY=;8N z9P8ZYl;G=-A_AbB^OEWQFG=An3KRFBO&Ti`1cQ-7#3w?Dzb;iaRgoj~#O_65#l8;e zvq{bblI!5R|Ab-X5XN}!c<(~O^=eYi_9w-&gszmEkb>hq%Qe2kw<&Z!xvmgrxyBbh zq{Ax7`s8lImle#T%)~wVik~;o$!uR*5lhe4dN+q&)=virPs2|GZJeOibRz%jWxDna zHRN8Gls$IZ*T$RYy~$A){PK3}#lXwWv}43v$m)7_hdJGsv&Y2tttcCi9o&Hx&(brPULoTY{idW2Ra!#{) z{=9UHRx7?tCvf;gml3ts`ky|xj)8n7{U-Ca5*%185Zw2Fl?%?u-k6E_ca`nwG^ExzOR*m$oqO7V~ie#czrEEK~0D=PfZulHa)SAqb&w4K2~RUD)cYQoYPvlvyyf zfzcX{jO8C5OOP5lf^|MWKIyt9_o}PXRvMe5Jcnc|-R0(vd-~m(D&(u{ziC5rp0I*R zCVQz(qrY+PW%ER|f-)Ywy7b+|n>1I2To(KRgYZ$p&!(Lf2FM70Kz{8PbB~<-|ENeu z@iDcvanobzN4n(Ix)#Y3fK%mAkHheWZze~#EI+-4jahGdw z$NRI3_w@Xo;V+-!m>jon*q%PEm%MXJL~pS&*~YZ5e`9iSO8PvdCrcs~de&^+IRtZk zHd3UJy%H^{T{p>N_<+L~z8s@*&oVnTMn|I`a2Ovnt{~Ywz8MB}Fj_PLM9=5`U9fHW zkt<4{_Bwt2;yzhDH`~KE%!oUq*Q31Oad$rco_67$eS)JO0?`}#)w)gg7!)1M{IxYr6oDUIiI;2GOT0MwAI@379Dj%Md3=c7h)* zM_@lNKQ77g{Y~9#Z&Y~^VU+P{l9Otu5L|m=9i5IMhdUI+2FtEEZ8*Dkj8|{TN>=L5 ze7~F&@_V2579G1l|1X<-*V}Q?FvTZOl(`TcK!IgwF4SP1)n-*!jJ{VI&DWeD{K^*h z?nuZRh?*w$!JftV7_B~#nZAnw&!%_ywOg}Cc^!+cC%0t9;zY2o#;Y}4ArKC~{ps}kjsKz7<)V8*KXA^NbNaSDfml6m_R95mXpSm zbm~_;O8EF)*vGq?|48T3pA?2#Heufu^Xz54dwQ)W9%{#*Czn~$OJ0>Q*D?dF`*T^eRw_VC{d&Pi-P<-gA2jn= z(C4E#VR#5^*)}iqfbi-vOq^BiKD9>wM5&Y#Ur~#JuT;Uhg2AW5zw_`snTk5UBuBT2 zVy04gQ}8opMN6jrwW#@BZ#{8qfpw&p0?F$1HNZah=DY?3FqZInFN!{PIzLdF6sDr6dlC5{iJ+h!(&wZca4oB7j>3Bmx|nVsZD$Lv;1m9>j!yC z&+7}`H3qo9OG1lHC_A_x)GBKMlgvqQ+dN;fUU=e&Xu52eq^Or z+8l+@60D|1Ey4$QeZMgu+0g$V*}c%R*&APySGY)I!7sEXew%wBnlDg>WxV0=3*)ck zY}kRXZ=SIKSA&KXWn&|kRShXs9K*u~7U+TJWq9^lN{ zaeTp}d}u`Z;+AXto!jmWg&nb!!;1#Panym+q`9yKHa}>>cDi3{Ujh(Kum633OG0)n zUL3E#D1t9uKKzdRY3fK@^GLldbzQ|!=?2+-@yt58keHCMLS9S^!1&Kg;~o&xzx3di zLSw0R?uGTczE1E!z^Iu~6pAm4eX*ytVe^k zNAvK50lvYio)#oS!t5dA*5ven`{ot6bBQ*H-4Vi(U1siR2pPTK1F1ZU-FGF?nsbp@ ziA0=ZHeW*W!X?NX@qG{ZYleO29=C17kXBooVzkE#m4!q>Zi}2dkOTP|8*JXdWtUC9 zdK{h$(-ON{$Dk!pG@FhGGL^B{fMunfLg2 zD%*U~J=Wy!s~4=9NH>44%tY(s0-=PO5Jhi=L^|Vt@HsWA^ZN3|zlIUh;}PBePKUm; zLIOoi>lZi&U&>fdef@_nwRE@Ph9XhI)c(^wOEraifD)gSZn_;mHraSv!JQ^I$ljF7 z@wJJ{j|hKHuBqCb@0on=Z?`)!ysBpZ6qK)0S}ozq9a&uAhEuKHYZW%pVUXQlk47vaEVpczpE{LLxd)4guA-Z z;Ow>FMy2%M_^r79Cvw8l-6|6CbemoW^RBu}KA}!X5uv2oP1aKFKgLkv$RPz8ZfSO; zecB|ujg!`q1sHZpHtfrYGGR#u@%; zJm9700NM!SRm&)9a^E)QX0L+j%a3LE!SA9#;zuZqkid( zCFeHEs3`0Lv!08l1-N*N?}JN}&H6=a-71m!$W8H)kGT32_e9pDCy+t5gQIexjx!(S#T8pGOBBAMp-~-rKjg6X=O44g=I-5vt?0=u+#QNV=V)(LiEMxmV zZ+BWsB>Z&N)3Zta)p><4ce4F`ijuzGb>|yi6!e*@Og7;e;(OK+yG^FpJ0o43_lcZ2 z%Isr{_F`Z_X9FS`<4c=hc`M;_p)`56$?69>=6c!csd`7Z1veZxxsYAQTpFZujs|ym zsAO;iQ$Pg7;Uh>Ycsup8Yy1v}(WhOI;^XmA}5Ab#E1yV?sD1VwBsh@&Py zp&K{1hXO=GjX7)*ji_K7R6A9&sWP#b+8Uwm$SQWJF2=hHqFsE{@rbD zSo+cSyY}PGAd6FU>CFEAWWm!waqw^EpN^L$+Y(T&hZJjpkO87{Sw9^7s!CKKP%=sbu=J}heKi7aD z5|{e^t7b9ios*u1J26#`qmE+0=b8E0H84~(C;woMQ7KBgtw$gp|K><*CHzMagU=CO zwjH%dGbJZdm}x~>kNg44)<1cq)?WX?Hz+}c`^^ZSO-wCnQ3}r8TZF|A}*?oKQ!4E!jCzQ7ZEPyGjcj zEG2LT__W|fu#%XR@2`B}X#Jzu4#Y!9ZJbVHt|Y@~x1ec{D#-7%s_GjAJ@#&UEDe$D z3MmI6ymgow9XV=!b2Qo74ZQOQ3yV1Tk4*oj7~4^uUU~G|IEs( zoZ&1fF#s4v@1F%kR1b<1|J6vT8vxLEWk% zdIvOfOPWY5nE3b{SBItV9xi;a$c{HI+^r28yM!3T>)QP;qWeB`-@2>p9W0TX?@1E< z?tf&Dkt2Am7UlqfCPi6`0EMx_k>XG8V6FgpY+)A(vw~6Ug0VTy!NLT~6$E`gEVa)y zX~AUFs4{eoRjXb<_*0heWW`-Av!1=qd?V;r?F54NC?)i?v2ULXOlhCoKvn<6*t^~N zo)Y@kdY@d}mpy?LF@&b>dgR3Fkm%!l4x`5E@gQdWqdf(RtF!<$jK~j}&99`8%~GIH zXnxt4axrdVr zZI{+f{;1x|rk6aie>HQg)!}|k>|J{kp`}nFXPL?hGSSG)QR1ZkmBlBxz$d}K(I=8h z-#$_|ZNOXiwF3F3xu(ia6(9E^z~#lR9Qlv-Bevh%e0!WpK`eBhPZH=6OzuK0ZGb7Ar}H12XN1J9Hx ztmds|-EH!lIxee#?p?n@A+fi{Iy=3Sa(0~2MC}JtY1H8>jsB*tQ1*hP$3K{F%%Wt~ z54mH!e;UtZ+-4)Y?e4cf@pG3dv(urB-?+cVO+VfZ%C7dKi9r}n>RgJokOw*ZsN}hhawilmHD2Vb0e0v#>Q0rd~Jaf87^&bX-R-wm51Mm@{Z} zU-u|jAWKD7AYm^z)+*@1I8PyaPkW2Xlh})@<`ZCqW-^75QM~$2^5hjz>DlAovQLGLug)$5vQbo< zG72PeOe4O`pPo}1$*T9!f^C&R0o|ARjEvmHVoDA;+oO4O#Qq+-NkL00nV}V2VG9e= zlr=W{%^>(en8cj+-E1RUVxOl{>d|Jq{hAO1`HhlY(o*OlA29Yp&0y&7_Um<)4iqFv z0CefQP<9LZx6SD0=hCb)&-J^W)KVVB0ZJ2OSuf^Uo87ZtzrL#4n#U0~0<@*dDY_*( z5ydfadAoYrG{0%Z3x-py0Zu-nmGk+!oX31}7 z``s$tP(;Vc**3DXN)0Uq6{;2V7(5AL(bQxA*c7kZ$wl!p2*pTfL8l6Qhg}9thyPWb zJ%~}7CG+FS#A>4HKo4)(LEwhyid}^k2eWSqqZh!Pg)1U0EvFxar26?a8vCcm<~hun z*4rED5Vk$zpH>el7Yg>%mRn|pEF%(br+T=B!4QA!Ur8ndfnq1I^JY51FAc0iif zhEdIZpDSp12#RE}UGAb{KJ>w+RKgR0wI#xSb>Q%pIJ8%9ZB%L*=jmmckGJ!WlgN4K zcs@M+o3?3J&aNqEX0OA=5xQWhK0a%>g3ktwBMNV-glP$wlZpAJg=dkENS&^i%vGX$ zJ(>r$Uo_Lbkb|*CyBPj%vSJ$CV;l}}Y;GNE_F;2uJiV>(|9+JO=d~ZshUG|(ZQ+-u zGIDKw=cJH+v)OONdi<2mu0;F6slsYm7dmu%l%4Nff0Z(bvN`4Fn5J^e`+h+cGPu3f zI+YtIi%}%&$57Ur{DPG4SVqt<&nZ2s>_s1^Cw@75>~SM7t{{?Im0WyNgS*Z@c)ANN zM8Gfx7DwxYk~J#%zf-+v7G6C$+nH-Gk_o!WxpQ9+Jb*Y0yp1>^AbLy`-w#!R^kY{! ztz+|zng&&|36hAmV?TtVwpy=r1ItK=*WJ{;3*cN+y{-O8tD-_VT|+g*DL8$z^0yCZ&XUs^mY1!07q@ zZ!HT~z~1aSKc&w%X(_HxvG;g4fFJJko723I#8U4EVG;d$N6L)`E&-%l)fM{x@Z_dZ+?DCiE&U~ZQN7e? zA#NO`ljcX@9lo}P9=@vZV_=UXZX!tYG8X**5e-Hj*si0JLKd>028W(IPtLYS^!)JH zxsCI(SR4-*k&JUvrKu?wW&Pz-m4`nU1;9kQeU66xKl=w%oV_?B_B!W;9nRC0*1Dy0 zh;Q1r2h!PfGX*6T4t<7NpRW*m2PLV#jLisHTULqsZrpF2M;_EnDY5aQvnyK=`yNbs7_&`*`?YuMx zu-hdcPtZ62klm0|VtZ~O#kbg#8+D~eIDX{(YF5@1!s-KYY!I*_WaP>g-cIYX5&k~R z^;Z>OwJ4IHJ_aj^AAh6GL9{+Tw?FEbR0tv`!51|U0&yU%ZxZlbXNq_`iH$k)qz} zm2e_>_3UQA=+jFxBvjM8y36L1fD(?G+oGNSDiEpET48ma;_R|F3fVc~Rd+1mM);t! zyzHq8qH9!{)rciWw^6sI1ULTp`?IRNkpSetvR_l~oyzHF$5Z#sy?Pny=dEoQkGGCX z37h^ zsX58G>g>j{NOrgG0qdGcY4NxbIiMzU+|A2w`prOz3vzxE!BXbIi>j`9bK?iq*+D07 zKVO=i-`-@-NhkLpL&b73jEE1ufHTUP2l#cL4e3MIyl1Z6(Q$m2q|2VrQ74yq13swoxyGk<^mY&)0(7^|O9lR51i0G0`X2TjKT-Un-A zt-?&z*;by=Z|6{j+JfjIDia67NeE5JFwYpVN1z?h>yZA?>eyTMDXwXScZq{s&Tn|+ zeXE9MhP=^>XYw9QyN2kq77Hr-bKp(Hc%+SmPEYE8MBDZh)iSH)`#Gfke(FcsSsa-K z^Zj5K&gp~P+)Uxl8il`tFT1YRzv^7vS+L;9Z6>(|25^Cbil zKu%6?#T()XJxOL?%%9-~N4rrc2h)r_B-p)pla+;!n2sJ-(^H~|BePDvF~AO z2GcwI2cON)9A=~&o0(qjLis05Yw?Y_yyH2|_r=a>O1dWMUn%I4D2~Th<~Gk2h}$Dz zmG*e=yRYW`e9tO^LW$=)ea$zTMqLX8+?eKPJl@|+(n{Dv6of8`D0(Emd-N_hXRP_~ zJ12D!wyl-fw)eMCWA%1$S?Q!#Qmhu=|=Z9emK_&-t$6)7xJZ=>DlEW!w@r% zjNx}zz-zr7iMn~>qr--Dv`CE`23@^@PdZ8h&kb(e~3#++OlclITHSy{fKq1 zQv`@_wMV`nfJV#Gblblwy-;lxX_i?bp8ZO3 z2WuAUU>@q=L>UQ8QO4-AO9i-b!KVSj%pA%f1>Qr4Ge8Fj5t)H66 zCjO;YXuXR^OJ0Zd_iuSrkyn(De|@5GX3;UGyYcK$+g^u!KHz0Z(v{vIdnr#6Ct3fx zG9L5B4X!4y6Zo18=P6QW&M9}S)7-j!2kBew?>Y+=&K!aNT<6;xRdaLOly@?Xv4=YZ z8KxpFO{EAnHcRW+NtfK@9&MB#bNHCBkq&Fgol<-0sH%`@?@f88K)yqLb$MJ;=rd}9 zYoW7WS<5b`*N;Q1@z~jli8og!&nyA9rt=q+=%4iZ6?t%px<`W+0!8y5(Xje`ITM5K zf0dOvhr$J`zkDUq7!w`zD&wLrQAxp@Z0K0E)fn^P|538;4AK$Jq;it0Y{{O$9ySNY zPB?X@2LYhrO zO~FGn7zTqGu>Xe0pFjH&pW&$R`q|uk$nF>bt`;)Y!1x-7m)2rCO?thQ8k7LIT``r>vD_Sm#g?|i;gh^R8__$xX5el*zK&svdR zusGZWveOJ`^LQ*Y3a2&#Z83l;!lYoK!ncODVR|@F({usa=8|&I_wm zg-KG>GnW3b>gkn{gO2#-vM~wLgUwY=eYrMTN2+QPfH8GdY`qi!vH0}fAdZwuHFQpR z(z{~$$5+7BYqze`<5@N4?+997aP^fM)#mXCpXS3Tq`HOpfOD0mE9I_#`7mQT=kT#z zwYQ^9u<9zads#nyUE#M-Ib1EDfIN-aOmIr3P`kvLdtoE1mqvfk+NBZun*+_DIz3hi z`>OkQMZ^VGTZ~*lIuW`F!^yZNdPiMBg)f9ewQ^Xw1VPO6nE7`v!=-oz^EDU)Im}z^+D4z6K?afc6CK*~^Wyh~*17ObwnTn@XQY-3l}Ff~K!NP9_x3Eq9@xg2 zDSXs5d~5#YW^G4BNw>PxY6`1zpECz=^o|guniG91sM{yARzsqU0R?IS=F{*19abxC z_6TO^SHMa_qPY{{?lxg>AL6RH`$nD&k4C%gpIIn%LI#&_tf}0=SI@)#BU%S>0xxp_ zz01eqIR&9l8~oa5kjt}Io`=~wDeLSiTmqcmF;@YoNgu_|Qj4{tthNcl;njHdWb*#s z2`lNexaLi5y@xxXSCD^uVEgOAe49|*e?#$8T3n>}``ncd}Ave}&D^v94Oz%Vxji!(1+|A^Y!k`GGvomkDR zx1|1*a%Lt)I++E9*76c4NegFh6?al^?IWuwr)Q3x(fBg|@j{}9to|9HbxWMWV;n}* z$|?(o=$OL#29R(cC%n7uMWR_Rqmm(@sXC_I`<_8jle8EmKnt`8rCK}N{M=|hP(iT2 zmBRw%E9KOmA1w&j+vE2J+wfGgMdl;T>Sh9>n+pR3U|(+_=eOHO-T4kYx0em(HHU+W z0=;9kBf=)?hQ0D$@&c}bvaUc7t2B#%i-~r>z8j_gYpeN~n6S&tHZZ~QfaB-MDbXsK zGp`-G3ZlOxeKmbvUm1vE^z_0vo+Ma-0FY0(>J>mVDljb!CJ^Ib2m6v`pVBwF7Hf}e zCoPRWZ@ffX`)0bWhlG78mC+zW=^6jKJ|y)Uy$AxD9C`I3`~}eTVN;#~9`K=>#B0r^ zYPeTncfNn~`55wT#uD=bHG>o@jLCMyok9NLN%r!EB!jr@k*g*ZZK)vfGqcrLWOGrb zb-BqvMUsnE-RTbKJp^16f!5j2uX;oGzPwmwKEBu`#D=g2q^KmeygNDiXHlz}{;Bms z;HP%&P$mCCw%B;Ym~q)~K8$->;ctB&kHnm|N}by@Hp^4I2()W0 zKR3Mj%8T?i3syG!dc1jMeOo~5o8Vy-ov+^R$a_p-$MG!$p^vIjiaw%_S;I(L{ zHva8>9gQpEo(sSnLDwSC5s>lOHg2o!)a9iXLmk7yuQAb^a2mXj@@hNTe1E8fl$1v< zSrU5zSvzkGTx2Emv16@LVVM(4YBHPeIU~9M$hkT*H!aVYo?-ImMq&k^kQ^1uuu9Rb znvkHvpNdmcMM!+@YI_vi3j16S%TvmHWe0 zMBJH4;F2jN+R?I*Ne)_Me(kUN{G;9dWgWkdsnU#os^l|BM=N6=6S4}Er}6HT0qhqT zgPbS)GycxCMK8AlpT6`)phH8(ah0LE<#LU*~qJ@mOf>j{ZF{QL_A+FCFZkp-+$6 zdvoY^k?zU?WtQsf@vCmE?|X$Vq}Kl0lc%n)F)JWb%hxQdP1;h?yH~rro2$daf;F}9 z*Z{8NLEb5(ktm%hEOY+2`X|fP;<{6Wc%D^(UY1*$)e-axKleU|a77IbnvM2>`7~x%TQwa5VJ7|1xV^6Z+i6^BF)jolx-Aem zex6rt2I0v63?N8nU_^ zNNY`P7_P4`-KtH7))sdf-TZ0ek^1HXRbJim-*=THk9&g_7j##luv6o5wR}mX?SHrN z;^=1-USItv%rCUdgrn)^`?Jo@w9y&Pn=Yl`MX3`+b?C?CIewk!z{5Bp!Tp2#Q=wE4 zJ%JI@;YLRT45!6RB{dU72jL2^dq*H+u9YkQM?_Be54xVOdZ)Iz3in6D+iNt-X+;U= zK=sMXCmsUDPJ4gSN|l!<77n^?o!oCWv-p!pgE2(AZ;-Nt2o} zzjI8WFl}WANY3Ee`x_=h5bboB{Pebg<(mAZye$GT`fp_4`ARV4YiY^8d^T8 zc(l$II%02FnQBJqb}aY&rvZ{M>A@@$JA}|o+>*^)zr~_rUEt4GZ;Ty(h+nT0E z%r$msQ*P!&$vzNpG$ik!B)DY!NAN``!Aw8};h(U>!HVZPDW{}wIVP)$PM#%kc{K}V z+c<|szqINWpvWe4@8heyvF)zV8Q@AeL;#l4I|uEKkw2uw<#Y$yeAUwE1GZ)FE}iUO zE*)vnHHzK&ygd|XG(IbS&W}ZXg_C17`mS`MGN6$PA|>133~)h&6dT|3tFYx9ienWY zA2Fd0!v>L!<_cjfe6;1GzSGV|T|QPIV`6B#H)v=}+zJnYs9>pTOSYRsyR$y+0TG`9 zpctY3jik+9niPwTIKvwL+85lPiT;w7Kt*uVcq53>1l-oEXg8|LAD~|?a2_XhzKE%M zvhWAx?Mf_cloGD?^vgE*AR+2jW;%rKc44{BJ{lq);8TE$Mx6)zZBNiOn}HtWH9FMM zY-JYeCcl?a3VgB9A%~Ia-#CoBeX`g77_Q?{flDx*hO1Oq3W62S3j?^Pr-mY{a~-+3 ze+fF2+)?2FEJFl*>+Wq`7Bxvh`JkmFfB$gS4UKHV+OMQcHK+a&-(~VvkGlN1_RWI# zGoxt(!d2+3d=UCF)aQA&2T1yMjL@HiryaR<=sR98OlpcVJb`M1cc{acWa@DVs}63M z|A;p7Y||79{TrM0zZYO^W>0Xt;>EH`W-7IlZL}f(Shl({*UjV)<$9!c1Pfdy266Uh zY^c`Ga>5PTWF~Lc7c6x({qR8&Npkha@7N@@KOOrX;~Rb$W~_)AE)>fqS=cS;@nc?{ zV0FaHgrLaL;1-|8W;|8?!~2{eBZ;8L+5Vy5d#19zzI^Ai&XVn-pECH#meQ2btncXX zy9&{)#dEl4S$R`vP!OOCHf5X4N#|@i4E1G-jL4$j9Z zNDe@KIaIC+47BJ)Qx_h4K8jr>ZP~p8IgSWY=1yqFiur#;ir!mk9xg8sJq8)yop|Xf zRM6{%S`G_MMw>}B7=}Wov4GT-)7}kz&q8iL_JGnou;$RATIfVu@P9fih*L%+*%RyXPiWqnD|m8s8Tj|`U|LTtfkjF5@diL&{# zP;X!}VM*1QL*d9GwUAigrs&DO_{GD0u<3*rf8uNgD%#O7e*8qzWmwC8eAonN3OF>? zl{TIVeMUdu=a9;i0%$Sc5*=1{*;sPv*FLMY&F$YfaNUwEk1FPGNUwWr%!I9Te?cF) z3aUL~$l)9*%sei7pb_8FRQwqsa^W$i=)jaHmJ3Le5O*=B(mBq1d-7^+*OA6o^P=%I z_db`%h|(Dq?oNbpQEI%@WhV1Q31VwB#|b0wis4bXxy!ZV-IA^O%BP{f%Dw+s8#4pE zy>rPfniYUE3r$vIjt!}C_lss`vht%dbbe75Ke;GnrR7;de-_(cdY5RDc0Ul0{B97C zOW)rbq}CNmQrts5tJX8;J+~Q=t419qxM7xM>KDBXu>VDWpJr@x<#b)d^1dS>k}eBb ze6+T5_-!BZI&V+R$+WNh9uWChU9#ehTHUx{*|NyUJ7Q$BQq@90nj5lTqg%Z{-S@`X zUk@anH6L91ZbWlz?mRS#vu0n31qXtHk@ZTV2(xbBOBLR8%#Vf`gJ=_qPaoXx7*p2$ zDY}_0 zdi)(LuiH6sRtkd1TTtA8L<2`ZV^bGfGBSAhePKa#0Ma&&WgM`FrNHtDR!(JQ@7JFx zViT1t%~AWec$r0fdzRdQHr*C8tGXLr)XYC0?V4hrx8&3y$5Fa^h*LLY^~uzI#~27F ziwO&eP5f#8k$o5kEg#PfHVp;<(l-5PEJoCz01cP1m2N`x$0;3WZED=gIE_D}>6ABt z%5kM#TUnJ7Py}YE?)R>xjAIox6#SvIFJ(vri;!5Raaf}Li>2<}h6seBU3hg7b(lA1 z!*=1b&OBd)*Hpg{-A|FOpz`n{%k=8L?s6O2Ht z$DYM_oDu={MJnW<=50;|9MGMX-H5`}5gmZ$Eff{SiI!wEEWE&mSbl z`RPa|CZtwhn~>`Rw-g}qvsB>M(NnrVFFnDN3i7M1u1Fv#)8+D#<@8(ls8ROlY$r|gi zLfiY=V)S$Vb1vhm*cAAgq_<5)nvoZ&E}|0l@?JHcVpQp=+5O3brz+2#V7?(VIMx#X zW=Em_h#KIW){wN(Vr56Kink4n1_JwC{0EnsY$VPCKKJ6Ca-!PkotCJNdgGx!>k`t8 z7c4f3Z+i=Co4hXNt=!oq zqY6!d^cU0?p4uuIk6VMBLnb-N3BRDfNrMo^C%wfBU>5CSEBo_b9d2A=8e?VqcP!t0 zoBYE8JE?-=`FEGtkNOI$O!l(rk@^4LhtBp@W%ESSgtvtlxc#r0dYNS^Z*uF?>+D5QHez)^&MVs;cXvbdHbi-!w*ZI3fxOhMlBE!dxKq+Y|OXRo2GH+Zp$m4rpQZ z^#Yo^_xM|_!$(!>Ry(J5YB&J>C<){!b@3ivYIWiC;nQWOYrr_7VsQ+Ky>68^m{ugo z)LFEPi--hv*H83=S<3pP%HlhGt0FXT-`E!fwq5`a%^wi9IHl#AiUq`|f8EFy4~f@c zb>coXH8`vSq~AwxJelH&et#LexO;d0(zPff>=&kpG#4k(lQZ`yK&8!U&lmy*%zCG@ zI&3x`KFFWnz0>E5(nD(!u*ab4D#(aW=`JbXswT7+9691y7-2e#1rk>4>U_A9*s`v( z1u`x|hP>hq|_`H!ObIR?AX4Z08-RBmM`jnx*^!dr^ z67F|r4yIB&lhHq3`YdypJ;<_#R5MjE=U^`0_w#yGg4k!bIp~^g;3$bq*2=bzUpJ3s z*7?1@!6Ic=PB7+UVOa9+`l|}(x!Y(u4zFMaz$t%PWFb3S+ERj31m))RPFbBhjGNgh z<9i0U+0i7&IAkJ+@!Ixi{Jd-;v%9&fm{qO7p)8eL9M+25Vfm$ai3~qEb0kScE4DdQYAi`0wdp*(S56ZvT|k2@eRACdlXkyYad`;h)dQ) zZJL$uDVo?M$@1#=ysu=?;X5vLXK{A(TAHk^!FDc(5)D*^O9r!_bvvG3zMi9xv>E~f>QIp) zaQ8U^_x?yQP_Zw}vAElHVrJ*O_6=67Cwlf?K>Vy7SM}hy#>##O&$7SHDk>5#eb2Y% z11^8RXlLD6tp7ZKBI<8AkxjNIHM=M>tuE};;wr!q_q%N_BajT^&e^Tt?bLOXiY3QXi-;U4DX+~`R(H{)cW#}_MB8!+-+f+Syh|W% z=t^Pb*GNw?QI%2*W*b$ZK0{03}uZ(2V`_h7I9Y zqX{frY}-5&3>jpo=a9b1QxGcJ)$R9iJK;tBQ z4@;F#n7@e7+$uaxIdS9H;2gczXVK#o>w8Ay z8&voDt+0E%eO&R+714<-$A)31zL2vN%;@lNo{ldZrYNXJzS(HbRm~JF{3yP%#iz#9 z5`Sxl$?3qze>f6uKOZM2v>5>f+dAcQJbo5j`2S%bNZd2Z^SDEPlZ#4ysL;?=N{Bh(6v`ugKCoADEU5o37#_ z=sIE6)7L6RN-3pInr_l_BF`Oqf)WmWpC48JG+G!wAz=e%L*C+cg3&P+cM-etDj@2e z;UcqN^k4i_)wzZ@;?2bV4s>*|`S6~m8y35H9b4Q`(-xWBk5fi;U374;zy{R{@ou}y=Nm0(#04(v(cwk_B6yc zPSlHQo6oDAeW4kB+Nr`V!v&ef`pMcz)Z3d-sK|mpBk^x{Aa!@owWO){?pVRL)v7*~ zevSk;OG@c(Q*g?D!K5}YX1j2w**L;w^@e|0r#eaqBZ&TB6&I))O+Mps zMrQoo)+W7Br9Q&KG|AAKbo15%U=ZItf{@zWk|e)boDVrAIoaM*C4=#0BSw4WQz zLI4Bd4XXW4NbTb6Yp}kZR-y-6@K2k)|MfEI6EJ>6O%}5QLe$v~EhamSyQwB@<~tP~Xpn%_+JHZ*%&Mt+WR;2h`&Rzb{Sae_g=Nn zW3l>P;^IoZ?16Xv?w2}&4xs9|s7@!`@C8*Tv!dmveJoZYhi z(Pm}-LN{l!WDho529H5B9>!+#|BrV*zH+17GY9$CR|7J4I2nH!{U~r~g68}9MPn7J zTZF5byG84{x;W9n*nIlTu{v+l88mVbXIw-c<;6zOnDu)4Vgnd^8MTEhEgPDTr3w93 z;qs{haW_lh#s0OI)C+D4VAkg(VXi~hiG~^ssIxtLb%)0F=;@x z(Q{Hx)7bKNzH7dYWh4bLTp#?`nbp`Il>Sq&PG8E z^>YEEynlqdJ8cgWcZ@51NMc;4yY1PX>Kyvs-=-J2*`~#RTT0}0aj6V=$$$1qR&oQ> za9!?&7uh+y)Hzu3-{3;mK-V~#Uhy{cYp@0_!Ke0ct$ydL{q1tRS^i_b5v^Z}#0>x3Av4>?+Nn{HJbTYhPeT+d|GA zCvL^gcp|W<(!KUahc*q^+hityz|d#ZW4x&)47M-BDJ+NbTiY|r=?gUbN-kKUBOW=(*7Kp%bCY19di=W5Q|X~Bv`5} z)^ZnTkK|WqrGE5%_#}J3>w$o^4)XcbbgTkFAvn2F?p9N7ju>-;dmtN5NABy6w@~h#`X}KvXLJ*?v zvcAi(h2E$>gPw%L^{H_iW8c>HRN zu?IK{2 z)W$Q+z2Jel{4n{KeSo#w^_IoZ=y>Kfy+jbog1#5rF7d6n(l3YVmICD8Wt-tJw>0xZ z8yg$l?7g9HUak7GWUQd+V{9lfj$yA4h3#f@uC`Bw7Qo3@Swl&-hu!X$VUs+TvQ_~P zOmF}l!UYX0QW~8MX;oQO-dW^E@I_ z=bSN1l!S$yd`*+*!GB0~15xponj4`#4LZy}e#^&C-`wd8C=gAzkPI3k8^1bLVvYJs z+r3tVIT$unLSvotZ$}Y*AC3syYQz?c8It zAw($3F%@7LT&qI8>^Yxsh({AS^GQb?XiZNXJOA0H4usUIqfNr#yhGLBkJXgl2iRfX z=aKsmd~d6n)xCmA!GHR4iV_x~w2DMZ{}Jgs(tEdx`W9c;{RpY6(a2{1ZfcSswyVt? zQ7N{04xrAPnT2Krh%8x+@$E;g20;c1-jNpKBuXNNKI(^Nb>jpNUr2U&hNgUIb@h}a zb%xyr-K0w;P%{cfsq!VODPH`RZqLE&1J4!y!WVm7rY-)8B6=8ax3WwK+nVnm;w!GJ z@vjQbzmS6{Dl!=u&w&`VeqTyG;%L3os}wN*;m3!W&-K`&1Gx}yqT%$7=^4j!;^78^ z2#+1@#tcOs$;s0VO7Wv(GGQpgfN)N+@J?og#~5F)^-*g>YGbBuaw#F~G2$&2r?KoD z+SdNd=X6vV?9j|Fd3F+zmULVe#NsX5pWA&tTu-~Ge(_lL`DC;ZhQ)c;^b1+>&)Dpo zFd{V`$#W$B^At3unBLReW;B1ZW@s_}6_Qul`Ia*U**!=J-T3DiaGI@$^l%|!*TN^%F z_=KE_asDdt2)5yBD(&yPIm{OP;4t_Bw=rl7I+*JvI3+R z&9|8ImL~UecTJNaqaz;4H!to838nH9k~jUNyx8nv&&&qV;CgtQn=pZ%U5tqN5D$HB zxg?$D!pUE-Ci4e!$Y9~3L-6oj>@?~=30`{fTaAGnx_%2!=XR$ z8ECsk@Xr0Pub8lq>u=YN&F67E#rbV1g$Jp|n-=i(=u0K3?y@Guw^t@NBNsBEH2g9% zL#%bE6>FSk@23;J%+RI8DEjHko*%(#8Y>Dyf6N^%pFA?>i+5fF`$%p}Ghp1r1gkIY z*@!`3cK%%r@&?t4_ptP2*h14;j%9o8=Ww%br#D0GZ3c0$%FqJgKiTd|uu;v`9YIN3 zm*SyuJw!UMLH?q8FzF$qgHVaga+njw0Z3if1w%ByW}NhlYT0NWmLM(_~vBRYe8r*4=UvJ?_V~Ec#VoSS~uhtzg-3HA%8r4ZZ+ew zn4LYHR^~X5+SoCTZF~=vP>^NS*ov>aGp2GU5_)u%U~0%3kNERS@dc`4vp&V-oxqHd z80H0QJb^A@-t_gY)&zE6ep;Z#h~c{4hBsr|dj=U~J3eZ3*7_t<)dAbWeD}-Dy34R~ zN!gb=`@%prasI9^v+i_$P=0t*WB3_-M1T)npu`KezHJCws|3E_sAQOpP=K1-MW28{ zk!ik(n1#wODgqR^i`$3ygCrw*MHrQxauj2kpgP+Ld4NE? zIJ!8dzG%m`<}Sb*6rkqXEWvYp*|4BK^aqo18?hRC$=E-AYd?#lKlJ%?wJ0d?;VtVhHA4GtIeQJzHIW@~ z#ptyw-%rK{{1XdlEl_$J(4B8ZZ8b=zwi`dc({|!V5>=IVw4mwc)aJ9kAj-Ca2q0e_ zP@3={90E<`3wB@MOj{lGxcGQQ9rEDI0y>LK=Kdza6xD0Ttd-{xS@#57<4Se~#Rz=T zokXs-XPFovsJS-br$L_zF*_S2nl-h#O^IN~%k!0(wNLK#inIdp_dWiq=FZonjt)?0 z{Ex`XmhoPW25%eQhG1^ntCz$d$p3qa61%B&%`A?qCRpEMCnT``uJilGAb3mKVS`6@ zUF||uY`L`+emGsmjt!mU|Lh13kUk_p>!=FszMM(Gd2?fwTLgr#PpEEi(=wm4Qv}uebs-4bDccrEc*T}ym24u{^8W3^uTyE zm^APr!TpqaHo|=Blrx3}JaakE+~(fY4cy<__ko5wyhR=dAJ&rELdSJx{4|d$$HPM= zDXTE1kE9v4GVnp?FOjC8XqK-HWXP~rr%(=`pVc15#|r$v!UUaZjq4-8YwY%&&(YMg z2MUtbKBX;$q+^F$>qA5X#C~m=3i4zEiC*fOTRKCntFZ4j#KT4HS6nRjdeVX@64(2v zA*iui0c>oWEV4@2^>NmzGt~3A*0NwQK@O~Z8U|(&~EN|iFU!n+x|me`ZW#DWOxFJ5jSsue3nxr7y0w5 zwfX0Tz^OA^vxf}atSQ>}y})Q=GhO&WS?XL*oYzSMNr8F4KoHhmcM`@Lndp1z{JOKu zkCOow6n<%!^fH*z9@jO=@g%*O^iv2d?ShF&Nv{)HmLHL~QjnKWogbb{_^g-Lx#PcV zIIRG3p&VUDynarkn@t(40$#ZhvQD_60%VbB3#@bA9e9d$DZewedcC(FC%3AaNRcEp z{=+jQ<#L%_7E!4)E0wI{0(gF^P2IJ+q3vXd-oGk%1K}>p%Q<~Fw(OKj$$@ynBJba? zl*KQf^Vku&yX139-v4IW;Ff{po3l=O`D}5u2Z$U`FiVN!$LnFiqV* zv;^R-O#_ygCkyl@;=ygLxb{^r!T$JTBPO(li+-cM4%Exe+S|q)zSOtLxA<_?Omg4- zmXn69D@9ukd~Tol84V-axQG3<1Vqin`6x|MR<7&g&RZ30`OVqyK;`$nd+U1SCX0%^JATM59GBe&I zTX$)<$)Uh~nj8(E_G3%T4#+2s4P$DlRPR`O`bL;AMj6IG_J4EfBLHiycl$fa`gBPy z*}NU2enhs{aVyA}>Mn1(EXrS|WCX2{6u2Q@)oQ=;Mj{1T_$%I|R(@N{A%dtKji{b{ zK#WvZ>6!Gc0@-Y)fkr~i1)|gR_7-ZY5VKXc+2=hR+!IPO6Ey-wx{r~tTegrM(+dLf z^l9^n5ORS-E$}Kz=_yWHBk_MTREeAD`8O4Lt@fSuzCa~Tyu~*)E(6tGE^TFZN1c~d zsmO<${@=5v+tfDv5)?!|jt+ahcJ@bV%xZaFcRv4fy~oe!uWp<8^QAy%Kj~Ki_)U>@ zlTOT4^g3%4*&KW6O;3+A@CePFnqxJyGx3y{g=>7o+N?$P!>lztDsM<^XD%nT?h;yb&7u# z6{E)+Ugk4nAe+mSvG;x=)sUg>jZjDE<9>8IeQ+5=V#-e&u{HXwK+8g@m=a|#*ZoS? zyALD}K=lV%9O-DE56&aR3BQEtP+wDZrT!yIRHZLgCwW+^YmtC}&YYmx+Y@eC=SM2q zonu{uvQ-84pm@ag1rEv~YBVQC_|DmOKxh9tU|$jcw(|(uW34mA zJ#X!GOlln#o4wio2F{JH=Bu5qYbo@;ZyWD0rd9$SP|!a*h@kx#93fo`)jF9dtMlF! zkT`&CxNviCqu|MUDVx)t=HLwTsp5h)gkBKTX!2mTHjj|y$JfS*i`KMrlViO5u7IC9tC-GO9{>0p1FoJLwczW%tv<#{X(FGpXt4>HO*$0R8v!c(YX+ zb)vAZ&;(UKyB^OIfBHMr4{8acs<2D_SHVmB*yKMVs%y(^>7%ghKZMPr4_|Z?J2vYP z6xCasy`c3$cxvp)r$U4`bolcf<==I=@wln!)E-QQOs*EgF0k)~O_uv4j{>y~i; zd=GZp#=%``b|(j#ssjc@fX6GFJngoZPv(Dea*Yh0iW#@IDA`n>9hGrGvk3(4LwXi1# zv+Zn+1|#XSH2%ovMAr+&t$C4g-bwpOcXxX}XtlJ6wNMm$3i5N-C+6K2-gJp~d&i!f z#T}ixI-TO+q;j{PZsFjgs?{_7KJKA!>&i~PNpXH~9hHP5qO9(LQeNgA`1(f(2V9*a zI&|C1$;HC<70tEPdqMK_SSB0o%M3CQXs#v2o>p{VK|aF$Hqu6*&xtm&omlDS#@47! z)5RV6wMMU|DHcX^VcO4eh+3Tr5M<+mI}-TPKHAIcw6+#m{hCZnj0U26+v(AMu+yL7^l8fB(Yw$Ue??w17z4P+w7~wKuZ){`wvULCK zHv8_8jCaexus=R8nn|@YyoOM)ta3*Ku7#tO)Tqh~5XWSDGO>IPyY8mU{x|JnOJBl4-bya=-&`}k^=CMf% zEB0tTOd-y`&BJw})*(wB_Fd~Tg{vnod#T}I=%hA-nmxWXQBr>P0c+n;ltjzTYkkyA zE3r5Wxs1~k6o+$~{g6!f1B`-4!ppBnFEEoa*!j|WjR7uQbA=2a+&=+*R_6HY>DMws zOAOZ^-aK?LxpFDg_vk8Q6u-VeI6*tOlU4OaV@pMO&8}s~2l1LpVgSr$%YL zWk`39_m8WL;c)r0o%aS~|CI7C1Oa-5*Uf>gXh=EaHA)w=#EQBnrjPTzQ_?j^$>{bq zgpCOQqp&%6{ZabYK-UvOa+;IudfB@-Swf8G?xuiIS5CIN2Q-j4>y1pwQ9M- z^(RDmnriYwf_C;WvbRcZ`0ynTV3^+DV2IiQ(t*{@B*wFmulDZwP@#%Vz5D9h2_>fI~aTUX427s(t;|% zbm{Ta=T`XYDuEzeT^JWM_&|}2G0$=fv?qgThj6MmIJ04WTF+3otk?kaTuUm5ahLxW zrOU7aAY<3P!yk1~QmOk4` zHJ_!0gv>dO>*w(q&nY+=XVd-#9II%*jK$yYpUMU@Z68Y)2s`JJuOP>YOTLl8S*ZLxud zle1jY%9n-0{LMDVv;0?qp3C%6l`1ZvChKDzR8#y-t|cNS~P zkamN6hKaVMYRTqv2h}kbKo5UInXB!f?PRA&$5{$@em5$3829fa_M@d0hqEbhm+mk;mOKHc$S`c+3pT*pcQn{jPIVcf6A)4Ymyt&Ho#$ zIitO6N%QqKpWwT+8!OkZt(b^{D~bo=+d$GTzdwQ+Y|Mp>eT_r+n1uV?M%sF{`1C9? zStAo9(gnua?TIJ&dQi-ja>Id2^t^kGCQp_N)v9RTa{?t_UPLKEK^&8^Og`RP^VkoL zM4EHTwC?tyR6op~QXF_M6#OP$JE*y0GX9K--T4a%VVTzGU*YNE){nS?RBlM+N4MX~eNtDNxg@%Z0 z3YG0KDZ5D4MU53t*5ztg#2ah!VUM@1d)S{A-+Y~{E&O8?km!_IBKfQb#P!W6&AcWc zb#1m-pbi`0sjEceYKE{{vClaaoEoj&uLqv=3VW&@NcaB0W#j{jJ`c|0r2jt8U6!`6z5dk49Ale|}<10&jqzEu?%gW-*jjt;A?QwNvLZ+TfgLFNcHv)eWqXr}VT?aA6H z`y+|EmcP_iOP;jh&ND$7fWU;CE~Xn#)dauA)%YmEw2VCLte;zdk1;&_gS}jE8>FG< z2!y)n7bPKw*oIsJtp#Fr4Lw@Ig*u*HYgq07n@}ZiYIujj@z~m`HhSL+oO_T^&expV z?R?RFXExuo!No!AF(^AhH^`=2{L3hb`)B)9`q;9bMc7Nd9EX(mrUc6qIl1HV@;6e8 zTcDR|3k4giY_G+oQ2GO2PuJn*`k#3Hkb;V8R<&tZ9pkSZ+#OD!yHH*H1M`0rpX&y8 zh13&-9|!~WU!uIHl_3J&qH#{`4#d+7WozhDVzhU$tG`0sR6cEHTf$Z-;&D8qA2Lnv zfxruTC6(5j!PK9WIRa6H5xhw7X^c4k7)kOjfJd(PuSxT-=#!)xa!^Yz_1^^+DRr9< z+&tsE_RY=7O3WdF57M(-y&3c*2PCPc#LQY&ilOwW`p>x|W9mj^! z+rcD@r4`7&wbjLK7n6B*qIeKpp<{r(q+9jR7##DLm@~b&rT72C#;lPQVQ0SMl&r|_ zeLPdwlS32NJd2pzAgyY{LZiv4R<35HeuNn~-Rm9JS#rZK*jWANAC@#k^qYEnH0N<8 ztp`&K=ZW-|=m?4-C*ocHKKr=}fj+x`qE(G9d`gw_N)2^2WFtS*ZM_6Wt2lwaU;;Yx zS=?C6Yg71hhmyWP8waYsD%^Xj)ZlBAMeIw#`C8MV-gd*=dV@P2t`x9;DlqV&iz&<1KF9 zzkB?3$+|B>U;)CzsHD#{^ql3tsi)eGe&?wiH0-)Bme*Rjkqsf{a{)RO?$s|Bj^?R= z%M-o{akm~etU((SX@7nLssku@efBJ-GJ34jv|5_Ljyua?MojLWLwp#Y^CuU|d~kDV z*dfkyPqchk(0lW#{HQ zE8=TW#qQ>`wp=s;9+mI&R%d#gL8}kr`{%4aSziA4Z{95YK2{OO;fjG|eDa$cb5lS} zHEN#OvdI~qxA-4(pIqLykSU}ApdVGZN@cljrD&BpWj8mwN>8!|dM;hb#x`cqcQx8T zCNesdCInIDDV|_;L9B(WLoP<t!KHt&o_tV46(e5~%>W+;Ukl;!nGiBjrFQ z-{!fZ%};cODE0FVu9>Aj_5B)RL_gED^uUIyoeeYntQQlB+TSnY+)I1^XXHoRlXK^` zfPrTzQQM^LSM7-+N|m@m`I-K?E2k?y@9RBlfN3I))hl(IkG{o`5P6SsU)gYonzA!e z(!_i9^_13gTNihcNwex-_S?p6#!}0aaqDAIc@NK)KbR^DqkHNKMdas(0sy(}vEH1L zfO!v*AOh0zGW&{K1FkC55C~rt{#4J_Yw9y}yrH6^eTG_^iz-}BWVM*Kh;|hS(`3Wi zyd@rW%c$JE;v^5;_Kf8|>6Jf}@t(Ly={rZShw%W<>wu3dAx3@fwapDN`Q7Ys zDKcg&@{bFu8o(KZp|B+L!knf|)|g?qhKzQW28K={yv{6ZK7*h9PZDTi!qjL=uG{Y& zSK2UJqOOzXbHS3#3F5}eFN3Vt58?FDSx^joycby~kx3UE(>IA6vyWsdSW-kj+kE?> zwLW9@aoaFww-8$zJF=)liS89d844_1@y~#-32ioeQWla;JX1;Z1VCr(XM4L{nm0dw z?hS&j1}8g*o^9N_3szaM(mMUT&eU*8j=MAYMN{+g&|+N#CmG4#(r|%dy5!ej*fA{X zNGskRU-dm(?xEw#^NsptTkr&x!KCh)r7cTNhUXv|xNdUIwZ64IQ?5fn|cs#RkH9*IS>ubE zCO`kpv~q7t`SE2A#3t8iLh8+I>dkt3Un^i0tkN%OW`O-1rRBdDO3U&|Z6X?M3vz3q zesBLDu=gxDYwe1i62^G9GU#C^S~(5 z#D#SP?sygj${@wew`F?R>>W@Ea|bdri?rAADgA-Ys@Sw(a#oAvs9gy#h8b#0x+0@8 zKc9g{CQr8;&OtX-Fw1bS{Q5Xiz)qbT=#qvo{g2|8Me~V6t;v@LntBQI2AgWdFmyhR z$`Y&cL+<}0gNpzE$ROU7r=64COKy5Ukb;ksN5lLzwz;X+r)g3W4rj5F==J~9#HRMhlu;fKaTbANZ3UbH}zD##z~6*nNNni$d*wY}Tb zg;7Fe5)#D+j!56ql`eez_pmt*%W{3&x^?e0Vm9MAc?v|wv`9&Kph-+|%rO327TrOv zc{0ezZw2EY3`1h?(!cLz@=Sxlo~r@Vcw} zri1X7fzJXf!qt~KGl|{XHm8Zf%?c*g#ros-GBS^yyV=-)kfJn2Um=HJbaoilG2K*t z*%PFFoc}qFI-xcWIkZ+Bl)u|0kRja?USmBhNi0pZ`3gx2xnXb_8GZdI`u$P;%6NMuTbM{Q`IbZf zUzdvDTH`@zXb{u335Ji>0iQ-d%1@Exl{5W^R%J6LIQ@(7Nm?Y;(s4u>kR7iWmVRU4 zq}OWu2J+V_NG*Y@E~uf?NOzr!&(&f3wy&}RcNU#In_F>Z z?QrfYw@#TZaks%c=kW(Zv+mqK3Nnml_`G4vmeZmQ_yfq3~j?QG)_(na|L{)3^=NMQoI0WZkf44B4ngs`It&FuA1-GC0Nlbcb-al5nX z5|(KW6I}5==ia%2y&)V659+FZ1bXiLB)c?{yr}B}b9=^!9*?7L9wGN6kH~=%Da$gk zz9GeDQ?bo2St*&8;n#^yGI`sl8Su{XE!wcrr5;WxpLsWrBhUH69q1{$VI_XH#yG~D zwx%wzOJ?ox=oFpeQxU?bTT?4y@n#|+;Y2o4f-Fk7*YKI|!e~@trq_q1 z1bi&H+*@>?_~U4oMWv-GdM}~dzc{xDuhftIeUW{uIcYYaIEW9gHj?Cd0b>mmn7HGI zrrPYyFD*YrM|=Nw^QvHdcigWI1M5yu9IM4|_%GO3TcHiShO|Ngm?Q2_&x9TB*|c`$ z7#Oj1-ShBVuZ@6$5{l zPj4%Y4eP2D@8DK>kSNH8zAGrw)u+NesAfn%qthSD8;=k#x#E$x9Ca`1``+z|Oe<>4 zNHb>Z3Gq{*CkKdto;g^}J$I`LT51z8beM%bR=9>~H!h7~HBwYhaXBsgRd*J;6|??v zX7kDcUcP09Y5f5h%R&moijg)ueC_EU2FIMz-y;e9M88#=HZq~U{*yfAQWN;8NpA9$ zPdLMaO>GzsD`HPG68|iBds!>z{j5zCZwvxzdDYji_thju@xK4Bbbem66HOh#8{N;tT5FiXXQ9pVN(y>G!w&O6(^gE}FQdZ!6##-`@p==@?nnK5F* z`Ysw?Jtdi@I{v_-8`Dy^y1%z;PY&53i*eS-e4k}_)6Y+rvUiT@{!8P->#nEAu1u?< zx$sj(Z5>x*`o){DRTQBAkWNy6#2-_%3>xp9Hi`B=KYHERl&JN*baT6XiJYtx^!;XI zu3wAe&#E&7-%|dz2}uHmI+zNV=m-r`5zU*-|8y`Y2Wam|CHtGA zZXQSt2~Z%HokUj+F1|v3aDd|Btny>H-$DPO1{*FL+h&22lGQI1mW=pdeF7sIiyHi5 zJ_X%l(T-R{@u5YWOT6Qb+~qMdFSEgPF12rA_e#4b~r;AHv;a+ z_cii<*$CHm{}iRY)Yp0))NiKs@v;(x*YZ!FuHg}nD7r5NL$ghs-39VTgimW=pU#FW^<2 z@9Ut{dqsXFML*1xLDnwU{>alV6w4b$T<$3eR>nmmJEWF`Iy`dzQmU@(^76!2n$?_w zwE4MTg*1e5*BL<^9<`3l{WyMHTl(79|D)%qWu}&>g@{IzhIt+J?X=6$OJod zyIfdyE=E}=FP;oC#{;d}nH%cg33+Mm+qfnl43^i$54QDtPmKf|0xPZG7PTb+%p|?s zV!e4SFiWDiJ(ZZ!dz@lqxd4O==8y2rmGkuc=VePhZKVCb?ZD^#_v1Z$W@8;=FOZl!PAw0huG2i8eXwaicEf$-i8Qe?~8 z|GYFR^9A6s_ibMv6WED1j9B@Kxan&W#?gwWYaVqT(wnV5W-5faG25{+ie2!X(NW|MRJyeG zhfLN|ui;6LUJYJmR}JCt+P4!&UYedH71Cdw#OM;f#P-@blN7>(#=7oo1e<0VcP1rm z8*HKnf?Uvajqw^c66%sOYz~q-a=jM#LYeEuMm4u30Ef(I2(FJRQqIoy-z54 z%;WB$cg4-P?@8*~YDBf!{2H1f$(GD$*4OV;56^*$nTBVl$x%-3f(gd&PI{PZwwaAj zehcL zUy`db+#AI9AWFm-j#I2Bhb+$J04uoTb-cZWkBf<^R4+5j z09uC&wkG8j|%Mh(kuMSN}*w%bs5u6 zj>!2K36)Ff;l7nXm|{-WfhfM`ME5AO5H)Z%ObeAV&1x%Ma{PKNRMreCq8%Gz5aB{%|BlmlD+Z!Hc1Br#U*KAQlGNm&fX1^1?+=@n$|$Oa6!IbkY|*|o z)7pl+vr&kWbHW`@!Pux?%B8e5MtWvyf4SI0`O6p|{wtWA4Pck(uX}hhT9Y{iiJIK& zj^~~ayk7p(l^+mDZ)??ReZS$AhfT3AAR2CWMf0H#5t%s}vl{bvE5Y*x!)lDb20f!L zP4P$Qn|+z>s%zhcWDtjfoBjeM$(2|q%f%&<7vt7vy3Y}JE@v%<=s zCf?HqbTyw%FAYuA`KbhjLL~N6rgFJIlv(A^*K|yrAolJ`xaC6vAS?P{VabMmrN+vR zT3*1%EE`@n{7q-_)Oq-JJJ+AZz7=8FsXX9aDawF!7ChplBLItJJt^}*`_Yoht|nk( zD8*q|TctN_shkgFvuU8Q1bDhDVghj&*h}PGFDqEMFE&0T@Xa{%)oPX<;LUm@=~lgo ztCa8mWU3}6?u#=>1n}3`JH-AHOOyx%L?d#j(R37H)z%PI>7L?-N)TT0&e3Pm?{%%O zRUW_l>)VdI98SQwroG=6ZE!$_P(xOxH*7l=P4o zTdS(0J%eXb%%aYnCjp`K=QL*e7Vr=Z5!2$ex@9L(M){x?+Q6o6bva`h2QVV zkHeJq>_YaXZ|B;+JM-G>FGCp5AL1sDIL96U_*De*P@oE%KwjjW=n`-f^(JAqh zXTLom(lty`uJ)pbr1+REpvu8TZ`PywNvTW8Hxh#ZYR@8~N#I1LNF%>g`1De*t&vTF zu@!yUKMIfine{8iQ0EK#7p7U8_Jc`-J)r8=iRr^#ChQ0bu2 z%Zav?=E4=dc%EHs6ZS*QmQ+VX*uzP`jyhFa!B{pGL8L!X=i>2n7lQVM#b;#Y_?m96 z@b*5<%%*~K#O}_n$nHwAA?CmTw9#WLa^_|UJcjac$8dv@VY%3?FADl=dtq)Qej--| z$r%3CjYremI8krFecAHRgC0e{0-uOa@D&oO#g2TA%CWW@CV&~XNv)A zt$iMqZhDOqe%Raov9$|F{ZU+*D=^AkW>3b9N3M?x%xpIe5N`{3eGkT=V;DRs*jXtm zs((R!As9BHVB8YwS#CNjl5X-{BY^d{Q2Y1bh(DW~IgHj-7cTp-#~g}g_u+iP zKMILt9+|IAK!%)E^&sG)$S6{>C7Q^wiaVuW` zLN2L+NjLmI3KMK1zs3-?@I|#1=IwIOn`|Dos%%lE@ts=Qxtitb zI?l|9{2>6FdAv50l~BxBY>idc>_Nvgy893_Gw&iB{{_xgU#=vNYa7k!_D3q$9a)jw z5Aq3V_rqb)hDmyK@6lsAUe(>mhD&GZO*@vh!REA>M6yF;OD>rxFEmLz6-_(TKO(Tt zrB3BGJc-R&KPVFas_dE7H2jv@je<(4OlX>y*m8$ofM^`$V->g#{CjhsenY2nHt3lq z)&g!oPQnTVa_3`=1CqNWl?UPP0v~18Ni=iwXNqIgo#20%YrKwTE9tW@Bl9PJ%vXa>V1ym>d1Ym&FX)lY zTn4f&RJ9OvW-^;N6kaP~b40KqGXA4@22YDij}{fy<%RffO#+J=21wSmk=Vga{keJ3 z7D*W;ux_n}NYTn!G3*Hurj=+so+VFb$`C^k|A+w!bWZ)9(;V&MpgPl-N4Xuqb*#Z3 zf5|XulE53D@8`u1`ia(56VhNsGhW+6%|&ty)BR`7O$n+7cV7UEig{&mdp~fbrX6T zpRZl3Z}+`~dDPAT<))hb;qK*JD9_Z31YsP}Qy9@0aoakbVZ8WtN+jX5c{89exG=a} zCdb|(Eg_Rc3xn!hrq+gpir?2=S-x2{UjY>$hQmoTL<1Z+*CE?4<#j5L$H-7Z9djD~ zIqA^_a6@lX;gbqRuUED!=jRH9X_K8EB`VvUcia8-g(qe?;&f_<$@~rVfArMS=h0l= z-1aGs2R$o9L3?3&buoqv(I2N7U81#Cq9JXJ8eg7S|`sW1@}jqx|~xazVLP1!Y%dqH!|Tvb-|5mMlN8qGZC z1S!GVpUN&pkMg-QVcY;>{C9zFB|EehSt>RKR{G-oh}$M}+lpN#r+xSKXrH#RPJJZk z7BNGexPDpqeanXSScSTiVNP1u@w%GOZAyHP&jM}xW1`7Y;?6$`?@F6M6&*ZtxhF(K zi;zl2Fe_fmS9CD>?FLCHerh6qSQ__yC}J0Vm-q4(QZm2S-1IWLqektd#k%s)Nohf1 zdnnjY@cD0b-Jw7WY1CVFN-!9)g@GqN?aJADU=SSp(T>12$y+6Ua?qz`im6r zOID#lDmH9tiwSAvS|XU&S!&y`%ib?dcaM9Z*diI?%6X1;0&X63yxp^=$B79KmBX0d+I&qqvJ}@3>cSN54#W#EbaQb z9UK;c<9c!ClmN!vx%U)A)ie^v96X_XGs&|R@_j4zXClvFq!X!(AoY(Tje3$?8wy<{ z-fhG~R%|nd{V{>>PGIfqc%@ZBA*VYpWQB36sj&%|pBey9yoo)_TG83+tb(g&ML^4X z>)De_FfmH6u|AzmPA9k@F&MHHwL|-7l85!(fz-%u8s`64-)qjHxPq29r{FsGsy^ua z{KX}lGT|9E1N|O4H*508PVjZH;CQK+@wgVj-R0E6v-w0>JucNvP|Hf7A)I&16C=Jf z6!qcYzEML6>_bWS$7hI+*0cBXvwjrhdBf&Z`@69#t}XMnxB!{I>GAEGL&5vK@(vk` z%E_(OD9*Q()5fKptg3<6yVER>@`RVF-!;fDRU)U?rqOXQ!TM7E{t4^R21yKh6MP82 zuVVOnHPb&lKD9t+x>q70DFEHRAf9%fNAK(YI0HfmiNp#KVE)N05aX?2fOZYu^VC}D zEe!oQk$zfw9K{=oxrme2coXNQT(Q31M7W+u&jFMc{c)alY!iFMRYS~XiNFxl@i!v4 zHNIYG?6uC@aD=S`88@d2E(@>ZF(kl&L!8CngaF5*IBv5xrS^8R={TC?gWkP*aD`E@ zZjqP3YPi!5{JgOWEhU%b8**i>Y>P7;?l#<8?1%!0G$Pwp$X)GXL&ZtkjiI2s1S8v)cD4^IWq&YKLA|d7rMK^6 zS#zYa+oRip>ywsRxER&z$18WqzN?ye+bBLxo)5n&0UUuZ=PIO|FNYhMwpRmHDr}dZ zHwd(Nwk(`qdW5mzoY~18d#KvyVb{@kb{{vX&0dL^NI8CXZ)nA^w&3IQw#sC!dCIGi z_L@8H%dQ$wUn{xV&o4Tf%#U7Ou zmt{_;FW2Hz>HJSB>J@t0)+IDc^WLAp=yo^)%)dU$JCrNB*?3aP<=lIKv650W{txVI zR+C_H`)>Wbq_tImFTvfY$at=*TJTs%#{IG1*etwj&Ee_(MIjehMgQQiWi?P#k642; z;TDnEUahoS;G&X@sVmyPekr3U{!KBfKdxkHNZ*X0;633o4jYKhmkQajx7-x>JPjh0 z-N$HRefC82`it+M4o zo>eBR!_S1v>y2!iK+?RNu%n#5@v6%Gd%uMR{)E}AzrrWROCh7rZ(vHQf@tG&DA$u! zPZQr3!X$R6w2;>i7IqDAiE-q6h5Pq|;h2SkSkvT&Jg;k6lBlfx(OX+(@^ZX+vvQUF zk+*wO=T-$A(veehiKBrko%0WIuc(A&evQXHZFJE#5;jaO)s=&l2@Yt;yQCTqA)FuV z*+D}tOPH}1?kt@l$U5CMmOSaB`vRMF)cE?4W9~}?iTNPCtuWASOXdDtXk8uEv+SUb z;8CjK#X%psz3snYkDE0~jD^#IEqYV#$3*)H@qE9UYkf*|WE#Gd3uM0Or$p!OYW7B^ z^R&l4YGC`)7UylyGN~@CS#*JbpIs>cK;2io4iAVP8F#%BtjjvBhauaO`guIXrbWAK z{BC|r!exhMeIA8F(xM$vjD2h0?9c4<-?vd9mhGajEt|Wh%2WqUWB2+5`gePkgny*- z5AWdT+tkAzV?B1Fme2zji==U;6llxW-J~za(gl2@I)X-ya|vL2)20ylTLvwg|2^3A z$eLZs7_=Rx*IqvfMC{yqs82)=f{z zRne0jhXyUBciTM0gserS7(1%3e<#u7jiRG~EcB6eFUNO&v^L*fABxmLCw;7F-(Md7 z+y0&6>3_p2DCCU2#wgU@703Uxs^x;FU@4 zcChfNc20Q@t(K*hvHQ!3jsN$6B;7};K8nTU*Vh)&V|fp9R0}s0=&CBV(80>zjAgQd z%yCPo0B1Y1Y$RXq_a$`-bJ7b-z_+)774<+F@f_R{g0E=s7=^QTC}t zte#5XP<5+}TBp2+vg!6RJ}F4+!50j^ zWfOLF?k#-jyA40IJVu0aI9GloI$ow<-M1jg9n_u^zB74vFovxIw)A{-1EY7Z;q$^{ zloh`9?nqtuOZ;$-i_bm?UxOar;`Qc?A5Zr@~3v{HU|fxnACXdQ#cJIHMZwWLQQ+ zZ9bKh_FCp>+f-q%oKvu_EqIJ_n87taJ&|`)*J*xi-cvX(b!L08mQ~ZRj}&0DJOtNHIGBbps1k;ulQfIx=^`qY zCiI1yeLqaqf}q$O`lQ=%xbeR6Bv9tjq-_EkWL2$pcyHtbN*)z_m04(|O0#zA)vy50 zAK?s7HX5viF(_&FJpBeyPQ~`6 z>9~8Qa!VNTH(@$PbNNS zH7*o&>S*wqwn3>n@vyJ&>#1}cC_mnO+xi2P(co*f-Yfnwk71nLn42M+k6jMj6sD>a z;vdb-%NJxh-Mwx6=C;v)jzT`SZrlSO<=;DkQUR{fAh~t{=#rnCZ&nHUt-3NzwOXRs zQI2t~KEZe19SrS!zwsH%^k0A=PjQUY48Mhv&};v?T2&Xvk%Jb`ui+hL%Qf`hQqGK& z?y4ug_zT~$?}S&{%I(M0=S$LrE|{MWW(#($2HuhPU@*^R?Pb_^DM|_RKzqU_GHd4} z3J2pOP$#85k+U+FTXFS6J>EHn^&PEg8mG;uedhz^;&)0uE9Ja zkb{uh_}5BmfgJf?)OUFHp0T+NMuzcbT7QqW1f!*KBhd;r@$NJM>3yvUZ0ffV-=^MJ z)-jRJbHVqDn!v(mCo+CE+|z+Elh#u>d8VlUM2%^#yggIhPned>7k17n17%hbKt<^2 z`+#>&qWYT)TtMALd1$WZtL7|L;ouLg6pe>ZW=@1sxmhy74lB9aS&)J)+SKTLC`crwoVj-JBsxqGz z)wim6tWQXsNm}^t=Wk8J9bvSvhJYB+j^p&hw*0msyW@MI}v1G{^nv+F8dalR-z+ep}#&WQpw>o>amKS;+ah6gIjzZ`NP z>1#7Nm$`S09+V1e8yg3cg@mLOC!5IKaNHg?w{=LIXaK+Qq|AU||QQdea zp>zSoUON}XPKcY9lF@jI>&y(S6s_kzC=;{zkHRIFOWHG%J@p~;*Y_rgufeSk3+x;5 zn6hnlOY^I2sr%ynf4ZnUn2H=-9|uZgh@=2B2rtm&OsI!MxxagZe`jmowH*l0wqKtP zO~fe`Qcw%XBh$m3;I>yR(4Z-xWSMN*jsCID_+Blb$;85~Qb%HgGds+^j|8qspZ;`F zJG^IMXRt?31;a_E;OR96!UqhI;+HKcMfY0kKMKNdofhJ| zlThHMb%{99;6%yt|G=n>Y*1*7@`-g#V&6@R^y6b#vZ<42#@er4OhGz;2efUY=nrlC zGe4pEd$RuMPwAt#Alz^ofuVDS|1M(#RvpoNhuqkVm-aAIvk z`ff&Fd=ZM(`UFkX=nQV%smyX8Ki;UFu$V6EX-lek@+?nzS1rJu>#~rqzkLSLpheWF zbYn<7mM>ViTrEeCzbOAG?z=VUtj<{o^W#N@6fw@&)@6|33;y^Hjcmmnts&ODVyFnSI#i z%bK~#j?mk=u9f+Dv*)tHy=RMzf{HKtod10>s|@3T4X4Y6_G0#0Wxh z`@N;av<*;jR||2d5-hRmK~^P?UHvTpe4t%34TLf%r)PH?8#`v{d>-ctVjAAI;q+5t zGjnX5OQ5<5T?)s6FHSFa#(pY!^;Yz+y~GTnl=>=#oW?G0t(E7D?C?%QH7@jJ*p-y$ z7^zXW1@ZO5|< z>+rn4oQu|ZL*)VEF9uE1J?D3e+-Y?c&^HJBakbN{6LOC7LgsA=EM(_X0->gZceE(j ztjKlERNM(;#Nzv*K??}-L!0QXx{{rCp=vCe^N*WN-`dm0Y2T`rkX>E>lS1J-z8{i0qn^bepU+7il3ueH-)@G;vbcgn!| z@;BK(k>0Co7LSYmqo_%%yL;5^w0iGIx1rXG+<$R#6KytT(;RVo^r22b7ClsbW7QC! zMFA=Pl(oBTV{`xKqki!Qw`gi}{m< zt@JF7h}wNIQ^Rw*wGLU_uuLF3lKPWLzRC3YPGVG8jn1}d^Z;P+aQ{;}egqa291)r) zy%Al2H0ORg=BGBp`Q_KHwIp8F+DyNsM)f}Ol?mJ8$UQ5YtxCS6X=lzXQZ$osyO;-p z$Gu@K)Cs@=x(#rAAv|%e>>0=IAi&X~O%7&}J}c{UXJ_7^4ca#*zqP-8wIs45n*7^( zSe|3&01pXf&uD)-AuW%EbZ7gX`i{Z!85Xd#eZCJ>%n^mIBXGVCmcHn}#;q{>AxMR+ z|H8cc<^n^V;@fLkTFNE$B3F{uFJh`+AO^OA(d_!sa}VZbQWD$9M!|?Vj&YRTql3QO z4dSYA?Ot6RJyIJ<-Fs2+Z10Qz`cz{plzbqtcxr2WF{>iID4kZVf(=Q4g1Cp47C2^z zF$-&svvY=%Hq20gaj4zqV`Hw?r4V$=%$#m%T;a3DlOaEL=Wgr;pV3?kmoQX}mnkB@ zw$so%40NtxKlqgREd==PK|JVw*vJBA-dqjB)5S(kqfw9!I_+^+I9j@_^$!E3xOHXN zxE-^G$>_2SJjBfG&sT>%B-SsWf@#ug$ia>3(#M8@SYSl$mQ_$u(6`EbfgFyaCbJ%> zY&cQp_s{W^cb^=KDYN!WmPC|qj~6vIWy{|8aj-wS(@%7SfDg8)4snC=^HtW!1Yd2=-?WNV#N1HSgb?wP8JY22eRbm$;f6!HabG zTipuI{&0cUY(5>e^2l>*xO6#IgEwiZyO}exM098dnoLT9m<}`R6`5jTyWWyM&Jzwk zUFzJ!sfOO`)j)k@7Y>{a#=tZ#RvJBj-!Veaa@x0v{8 zbavbyiKb8sJ6^|y!m~t{T(YnPvXi^uQI?c}f9Rv++FJQOkEKLVRGhc1VLsb}=Vxmu zj;+=dJwW}H)|XqbDilI6Wvky?E-TqYiw3sT?+Uc}Dge4~t$jj4Mo!>x-kzz9)9X)6 z)=J+>A(|pTl15?*iZPbvs=^YA*?g4d_houqS>M_h`(Qe{sdYxk`w4?HD6Y+3vDX7$ zSYywPlp*Pspx=$Xd1Eim~>1o(x-eFFJ%K zZ^;9C%(FfThcTFa@XKG^UP+>7wnweO0w}=t6?*Bh~yi-!?YpQe0uEG+8~5QamPhRkt5A zmq$f^r^>@>S^V^B~LxRDOMCW_^{I8$QTm(lX zQ2TKWv#r3i5XX3Q!V_-wwJR$Ng0#Qv9tYR zGvXDC%|5_p?e6UFs`y=@w+V*6vC9mkssYMq(v5KCe%73JF7KBp;MV*alMXBKR38Uw~J-a*yC(nZ3yu zKj0@U1*^pO5EsptFIMYsxduw4&(*&5E0=XhXuX@g+gH=P`8TX6(R_-u8UAZ>D->}xan4HC- z8XH8hayQEYYstH$Q3}NANM_XH-{{4Q12f~@Rt_^l9*g*}Vz4;4&)5g_|kr zU5Kz0Hranv=BU?NK8dP*BR+WyL4aQd_nS0VHD#uQ5OzwcHlz{$V13?;KmXEM$D#nC zb{k}JbMp^eZKW?4R&ae4tD}KGZ2#CR-C7k@&Mt3-tQMTF2;n~$)o>gMG$)!^novHy zo;$k(&vyn5(d2NwQ?en7(bB(&Zry*P9*h}P&62-JY~(h{PTts;O+uLKDEQ6R=&H7< zj?Y+zUTpk!vBT${>plbQ;v_7h{9>0UdQfYNIo$7^bp@V3X@1*@0ee{--i#E=^tU*) z0zMRtc?9R2B{;6Nm-WkvCIfw$2U6@eLXQW2Pq2kfJ zv988Gi67CX+Pl4Vb$j7H1JN3mwT!Tl{iemX%`6OscKoZFNoeTaW+quj?>W@1U0^vv zx>6MqlYbm)jcg~dt0Ybw)OAW6#rs8^Pp}T_AUFZH@k^1A1PwPdmS4uVwB3MC;75WsEqb=DCHIuhJ+{ksZ;YFg1-=i7= z&M03V&*Wqii6bK;IpPXUSvI#%p2}X2)$raV(1!E6+T^H_6``zggoI5|BIjDYO-OuqOVSf>U!#&Sm5ac-BK>2{B z4wXyuj|sn}w7pv+pI^&qUQ0ANYy8$Ou)Z}sOaF7E*)}P}x8<55WJKLRVRs5p=KBGf zu?DG88sdoCl^JmXz(8Y(b?G_-1ptiq3dogy`xQfcdf+gTr-@J zmhwws)5mdqNFv-et0@x^+?sAv0GSj=nbku%?;(8BV-{LG$gRZTR+8|4*RWm=8QE92 zlG0rYRuo%V6xyGF5{kcjo2ezCwsPUWp+?S7S11WxX=8m>Cn?~0R`wsg9l z=Pbd$ZKz?_g`xTruBoR<>97n1m+2wOOigW(nr7ZLIKS!H2N?QYrrvY(d`8^YT8erU;lO(UN|-OT3*e4pHem1mfq+zNI70*u)S>{CH#x#ABXo_HoOe zTiSxc=UdPI69B4GU(rX?qd15em03lGs|%dgOd&4z6kxBj(nL#SMPKyKIi<0x;lQz) zV!aZH#q!gII3-W39{OI*Q3QX!fVSj(lsV~J&r$ZG$J~?0fD0p>sYGgLmbNm<1d${u z5j&VJIQBK8DHk?9m|FPbMk&Us|!id zrOA1`92oAAfCf5=vidJaKU2EDyUrt095l7(5C$>hwz!bC+&f`z7Ly~haB}=8N8S2P zTU`F-sjlU}cw)70@pzh3zU$sePLcP-Hx0PSlktk9e1evF+uweMOCK8EVh$mf@fK8l zAU1AFRy|q}$s%y8Lx*J_NbvSt^dPaJQ$Y;Wlp=#|w;eODP2E?m`6I_?#_cTABHV;Z z*}adyQ(;nmPmVpWw72?F?~Fh~9L`mQA%;!KDr}wmx~MF5Pqzc+?ZyV@a|gRP}D&AUyQvBIxF~m)o(Sa zem&_!#cmkKSP(U167>oS`Uwf+J-!TG0cOz5i20rQyqA$EEn`z^Q2Y)&7HfuzVwaA! z;Zs=ondTtTn({{hCfVX@WHnbiS-HMWKuu(Fr_OZ_-TZU4U;mjdI0w?9t>aY&@L$@x zj8FF=$JSj|0DCnHoV-)um}-&eW>i2f#Nb@wF%k7~ez#jPZ+ciI*WYk9r{0b-ZK4R1 zDs1O>60Y5bdZq}=<8x_8N}bF5SCpSB+m`8;@=Da0*p<#J7aVd*OC6jdxF){uG%1Zz z&yk>AbS{@TALU3^j~DLAty!}DIWi;9nI%ZB2P9$#2i5ol0|yVe-0<0b&8^?$IT*^5 zHZzy};TNyo2#?N)c8h;L7vMH`EPyfWY|p;8=0oyzYPpuC{dVQtA}1y59L{^SF;nEj z?U;-!DqQjzmrK=q-=v4GeMNdT)=l`;D;WK0t{{K)w~YvIDlgVZE>GxF>kF4n4z8oW zK29h1jIwnJk&e66@9)VjMPdhbUW1wWRtkpGT9xAow-; zln6%a#WWQ!*b$mN;_k;aS2vqv8S$%Z8V95an%|q{Lzm>nrj_*SC^cDV z#9l*VE6NaIr53o-9!&lPb5hcKKKC+qw7DS1xGq)R@{`&- z;}&W2;g|I9w1!$vRRZLQD*SL0xN2^p8X*C5`7y`G(}RqIRzlgvc&7A~%@vW|9G=+$Hn>+Ai5Nz*n6V%(G8BQi`y{)a zi?Ki>BcT46Thz6CA$)4(0o7T7Z*`ba1^bt>pfeT8z$J34g32`5?FI+d#C;O6uC%4mNS8M=xBM|?X zuAp!m+AjyS>ZdBJsHT*J-R{u1;b5v%ok%CtJJJu!-D6qubRhpoH(D29Eph&kno2x` zn-{7YF$!1f21??TT&gjN4B5AKw5rW+EW~~Bnw{)y(LQ^)=vv)@UlL5b#bBnyIf91T zSiBGwULKa%ZTT?Z_hzcE0Lz%Nq_sD!>G+PTMY4O@7BUS$H;d6gwHAuX_adPR^U|q# zjH~TVS2r%ZDX(TO;ay0|C#R8I;^_B4Tq+o;I`ZD~#f5kIL5tOjZ&37LM=HRZ7LDpNnr0)(`O?77WPglDkQ2f+Ydm)fVB7sJ!q-kAxy zX!r*TpM!m=qD)aebv)w_kQx7&9N)O~(^sNHPm({;Jx|dwo-Q@{N%sa$3t%tun}#|N zQw5_d&_{eS@ zr9br(Ec|HIBpuA-=F?G!QT$U*wYzr*9*-AvgylYaW??TZ-o6dT4Mt7*(`8JAtMe0$ z@(-+LVcNbK8!oj+1ZEt^xv(z7+VS;|`oWhyI-#ilkc1bw)&9ine@weEE-qPkk;E?a zH8U?EAw^bzvez@%-;(@lWYP^yA1l?L-k~%FWRhFTTD`>PWXJ&d7b(2ugYsac-G4f_ zHgZoqTqwz9c2Rf7<;Dl>Dz!;ibp+gs>>ucH!Mp#9z)DnQJL7_?AJn)wqskZu3Nz_F zHX4H#Cf?=cGZM;M1Edk#sLTj} zP~hKv$4BUPFez8%=~Etd1P`4oeRFzo90)^=wG*x(jb`l9_sUg;YgIpHE<>W415dI0 z?K89yiPOBnEp3gzfnkwLld%=}*9jjv>N)XP{S?$UW)tYtg8LqRSlgT24n6sX{?vBW zcFr+*%;0APFn(r(<6d+0NyJom24C>2LgnC+^~fQ4TdDd^lim%V3Ahg%`lB)u<*cYE zzpgxQ=Vd-^f3dUTRj~3CTU$!VpriAUV9WDYHMx5_Ns!tR@*rY)@$yb3@PX;yp`LfxRe%zEXv(OVS4V&CJfy9Xr zPil{zmOjTTFXI~gm;q0!SS(uVYpQ9S4E4&1wB*S%e^cwOX=m=PW#Z)B7is3fk{W5F zb$M%f$&*+UT~B|Pn)R*`-Y|~G&GGh=>~OJ3G_1O{JN+jA0};6qZvwy#$4u;njw=n0 z-CupUVHMo|v2t_NftH||u;%Bx!pPFNFT#3THPrlEbuEfVy`s&!!s0*4^X~Wo)ds(W zZ}zF*)qSKP+B%KkN-QlCu-~F2t4b>>h9ER`t~fj2DTm*s2S0v9j6Q^I%_aZu7XvOQC3;(;31N{^rH6n*nAo^kRHJHWCjriTBfY zZOqVeSk;FV-cnA+AiSyNQxlsu*D3x)F@MP{uy32qjUs`|kE1yuLC%7ssMUB&M%XLM z{O+qO5BUov;_tpO^VN6u@1XIYW*(escGrMl8tp006Il14*dm2TXn>)Js;rq)Y0RP) zb4pUrODVA{t&)LG>du=gi<4yi9f2DiQR*2}$Q06@;JZ@SO4VN66yu}hdwwl+AA45n zwrg}`h$Z=`&TQqgA0THnmyvPG@YRW0J6DK&ANdtNJ;B%GbGdw4lz6YHxGGz78xx10-WOYAiV_;V4 zn_gN#UFBjbu|*ecm+AV!PKGbNG|RF~eYC5wQ7`xFS45Mak`M7tQD#dyIB!2 zVKW+?%hvj7$dpj6lQluVc}8!iSJRG9S6E&EkMbBQ%A>&^qV4Cd?LKm7Rh9wj$nkDH z5b&X=O~D+ER8_)nPRsDFttnfdyVw-}E6MxHVB@g7?m`@rUh#bGUAU>83;_OBYDcif z#-lz><(O{W8-@UmsTj0GONIQpV3-Pt=e_fGReg+;gc{!Uo$LUQEeZ-RbHog_eobha z`ibDI2AG8BeBEj?g>vIFGXF8LKtS!Kv~!2;mxuzI z@k7fn|15?7{#br>?Gvx!^!nMa7A&nMKAV`OXq?$Mo1@5JWKodoja)GbJL5RxfmIzLxfx-0fsB-IO=#6RXzJSw<7sRNuOv_ED|B zmdbe##Y#+?X_~czkMVqb9-Yyab zxOla=dYON9h2-GEp{=mVz)?|@oeKB8Zw7WEzOFftrmlul{g={94SDb3x-S*M+*W_x zm2X;>-JLg;Ps=QNsea4kxO)Ocf@^NJ%~CKm()J42oM zro^izZs$(z%##goKpzqgnSYABQ%9ESxG!GpBCanNHKA~qR&)3)x&v3C5DT4*R|{eF zor|^6mFY~?egyKDE6;aO*2iD7dU@r)vNx*#w^j+BaJkCdwR^#SLj|$_w2b#$nK}CS z1lWVGvP1H%{94|ApH?0?cD**~6f$!JpIp>*RT3nM9$VmGmHX;t-1ySOf!FKageUH(~G$)AukK-c-q*6(X#0x&6>&~wk?xpNN--6Gb{Y8^l#zeL&Skcf%8?~ou z^Y#@`bzd_gruHk~e;pR&CrTb8XpszEhgt>jicc zIbmIJ;}*7+nepr$oIkUCoEI3}0lzn>5k2m3=E7Q`U{d7Qbszr-a%EHO^6XKxw0>`W z&!wkdfeMa0BY_VUxa=^R{>@vazgYe5{4NZXEZ;*@w^LRvAIg0OQlJ6eWi;c7tg5-c zbqZUof<4r0=bxW9+l>JFkUWfi^t5D$Tn6e>BKrfUeVD+ddzI2%(vdhx8P11LH9MoE z=r!g$D1blQ8{1Yi6`(6BBk;UNfiTyyPun_yoU@D8&jf{`SA8J-BFF2Ws>AUO15(|3 zMe1+*Tjm6^YNJTclD??=n?yPBc2i;yGDs|c$UL9G4JaxvU@0XlbvnWlb%~3A%4zY< zQoemMX4O$hlaKB{EM);xDf$W5+dgF=E4)&MW&yA&oV3p6jYYo+kv;$QFa$l|U1Q0c#zII}sQxMalXOx2%l1(MzV zC@r$k)JZ^SFg0v_j6e{pgGxTr7`o0jwrs}M`tG}6f9gUDbC*U`M0C-J;5Qho9&_C( zIv0Ce;J)9>*=rBZSa~p=d3yn@8q?$URli5s{jcGGbk;qoz({DZt$k6rjIXDd`)&}` zGo+`Od9E!x6&iX`=?uyiY<;I!5xr1y%ppxmJwQ%8)$6%vs!j498>=m2FSy3q7&xS< zKek}k1kRZDvX8*_9D!XIZ*pE6ygnty?~g79HmN(cOR@odZ|%FTB=omH-O{w$RmLCc zIoEq-hg8R+jXGYSNJ;F6<6)UxRE@s;JVEKt?GuWPz};sisOzBLOA>2C52H)$DDN&p zaSQ5r^zC?i#NFp+Bwu)LRGTA2m6_9l!v}i9{xplGgF7{T{Y*ATM7Z_rp4KLtG5H}W z>qCFvGUTSWZ|ftaSlx*A*d5n~2_SWHL02b>52@GVBcQ8WFmA?aBZZ+JYP;27+7zM` zkNuP=hhizsea&wwL&@={-)UwfxutZ^+@1IASvNJls)D4>?Q0Z$s@Gobqe*YATj$*G zFK+GiB>8O@a1g?Ytu3;--Ol`B$~?#++y?INFN0N+yihb|a5xmgVP+~Ymhsg2dWlfd zjjtJ5W<%4b#vQ(*1A9=lfk4Nh@*pp3i?0ZYS4hN&ob;WU}F z$tZF305!gp2s3!*ae%nn?lZ!gxi1dgQ(U~tcZmF?!(8k4!QS-!_qj{K5~E7Lm5!RJ zY9Hr$QY{B(Gye}XI#mATN*wRv>&eenqL}L6x?5QRcwzKKaw2gp!EkF*EO14wS@3<& zdiJ0-fBy}*h2dspvC4RjA-uE()A-w#js>%|t`9ZaNKk$#k5eMaF~r_BNMKmi&PMZU zrC-k?JK%O>fe*v6^c&Z*)tz5MPb|MkRm)w3$=~Kg{cQVtygR4;7ecUp;qimAu21UC z3KoFYUrH-iTh$kDD?iOV+|v2TmzfTKw6XTI;G^I}^kZ4 z(`?2BoN;(huRlL^;zLH1J__Ia{P{=I#v=uP^N3Q4;Djr0!`*&@&VQ$ODWB;sDF<)# zX{e`>n0z|+N-vI4ThxVZ^t(vMI`dKBco}Uid)+^N2s>l3f#)m0KPUC?f^-s`O-P=* zh^mZKvn$f$2tCWBA5E|l5e}(eU%73ffW;I)%So}G)(S*>54zk3n;-k1^{Dfab`A^GE}Nq8KJ z8t7;`Bv^5;pviv>d774GVj>swo#12ky@Jtj=-dGbEu8Khn7f7Gj}|c=<34(Z?JjJ% z(`G!W1Ja6orZ*#^pYM%V-erstfcq+PWHc;_P780BE*CE8qXD5s8PyJJtHJF>d zgQh_GP}TLB=>tD*IyPdJfX=!i&8%g0P*F_jL56)`bbd8-Az7Pa968sLYK#Pb86q@U zA=M@VUccRjqop&$64K^tpe0fjbV+%D-qEPH{Jf#!@9!%sn1`jkxfSw*4mxsozHve8 zGpF;ub+vn^>sRpwiK+U-q`78b)QrP~D_;W_8uBkpqapAT z@)@fG<&8JpRl0RzthN5wFK<(eUBy+BtWvSR|1q_&*hRQKEg0eU*DsD%ZuSKUkmhM`H16O)R(o`a_Cuzz>39&PFzztjM!jGxHeS%%sD!M3O zYM~Xsm2)t2$IbeR2CfC~FzNpJ*ZfpX=P=5)z2c#q%y7jx$A`{|#Q$spcgP^py^#t> zKPw-bH3Q7<*?CaWpJ3x?qu-bKLl!P0mD8|Zv#WDv&o!skV^G}0)p4=0TF|Zk*qr=7 zh!nj}kuCO~1S%VU? zJs(I-0_KAk>R%ayF0Zeh2e#C92w}RiPGC25x*fJYBkDbVUaUIQvO`H884RMg%-=B` zH>Hjh*ZtY?JvOk53sc*2mfv4#6aMsLvcPjc6Zx#E1!MxyUa$@T4Q#vRJ((CSNva&5 z0~VtpZ1lu+)%n?>r*D^NhLx!8)gnh#Vv2ot8qV-)=J29X4brrF(?SUnY#YmICz2LS zZ9k0&IX4aQK(fkK5%+C!ated9SoDi68XKL?@bz|ImMwb88Ua>rC7Q2QQy!Ox3o9kx zVittM(g%qBiunr*{iYWK9wISOs%s|*8}i!t4nSMN+%&;qZ|f+<*b^WjoOhe5SD>Q? zAc&_;ohg;}=3WmP>c72~IW_3Daa!TWhl{d*xw6;LlONW`n=YUEcfo zoqimhl{)tSDkPmtsgD$G8lIBy1YE&9B-&s#eK_%qKvsvJrQ>3+CrrzSSDysj2VRGJ zC}-uIEC}t2mkg`gR#Br9_3P7Z+jxj*veRG^m>lSIbJ#*I%I3mavHz8SOcKcA@c6VK zsR&i!Wjo9XTy*P--MuhTn^(>vX?lB;Z7==pPo753)yUc&erJ8AJ>f(njls&QI5b;N zCEY*OWZZ0!?|P2`ti9zKy5-z@H!&z)^UXqSN~0x)R7ha;^L5G_u;vvde`mh_n?`~f z5}etnc3|ujq^7l8zZC6P=AFL&`f0!!A(R=zD~Sr)jgQdn%`1AErSaiyL6G{4%ek<8 z$0kz#M_GpX!B7IWTz?&X3s@HO-#+zFMJuUYHdyN<59~22B*2Jtwt*N^WZ$yo*-Jju z>OI})+f*I;EcgcHZy8(bSO>TTV6yi%8osX=&BFgNZl#YcM)D{JvPf(P7}YP zl6E12vl?sRyji2gH{--B=Wmx^13cqPcVqc)?@|HY?W50`oNy$poe^!v_6sKq38t8| zKq$HPrMF-PoCgYAp@7q9`18s@@J1OjqJ`CSs49yn) zq;fZFZG>}pldkHd19S*+$p~|`+jRHxJb4wNTQ~jW1yrM^BEoz%)3tVf_SB_UMc^74D^`F#fqhU9 z^nHwG&0cdqwq4HtWVMC%bzO-=PUT)|l7XUU#tb)~@()5k!O#I)0y-TJm?KW_lox z|1r*Siv%e0ecYeE>y*{ms{ATrZMNybn==P+K4?Z!Vo=;1{3)2kTJ@EU{vuzdaylQeg6~DN-lnowRpYaS z_3<96a%QgI!apX){)lmdu4L<*O|pS2^#^3no)HFF9v4?1h-^~68n=232>o6?6u$1X z1-|Q|p;ZNcF89JI?4eB4Pxs_HauJ`EqEimv{R*j$kG=<3Y5e}Z@f#^{LX|=@jk{p; z1@Yi7Ix|=Lq3@W(rInWuYzb?_Ye)N8-Nx)4_a4V2GFFEL8LH`3S20E6Zum_2O>lYK z$%FN-Ao9fTSlb+bwJYXTEB~{gktv#*K)$CzwFKrn{$tXJn+^U}@p2{(e*{-NUS~~i_&rAh^^@fTY=RfiCukzY#qmOz}LG`aR>$p3(xF+x9QA$c0@no&9;&2ET5M z@D0~YMfoxtVYcm7uDHf%Zlez`k2EMRxkd?ep@oTK-bZ9Wu+pqoVN3lyKXY>PiRH_W zIR@_in2~Qq5nrYK-Dj;sU1Oa65QPq#x_18Wv8@_7wma2w8kxB>Nw-6O*z!!3gK zRT1Ez-LUOJanOi5O^Roy@QGs-ddtkAfw2r^m)+?Z;>BvBjz9Jx4PtYiJIBX3gG%L9 zN54j){z?W`aroEA)H!i;cx1&QjJF142#3NM_OG`)}+@e@XUs4 z7Bm%g)H6K7W-rrPzw1{-C199aqZni0^N`8nac!xv#^){y#)-EIPjjh5u4e4rzOo#7 z;S#qa6X;=@c1@69JZ);&pSJbFzn1Q5*nM!Z@Xg7Gfzl0lH77&-l$*A*sl_t$`ZaK{DSfxS z6#qZ$M_i|BnnM9+%8OPj<-rqMZl^G~pLO1i2WPWs!k%{R(Gazz;Eo@?f4r(x3d&Tr zKB+$e;4*nIhA9LLI(Q%;A=1(Z7i~Vo*kJdu?0pOyDP|HwRdS*{-0ghCxn zsG?c>#C0^Eb9QsF2>VjdwwFXR_4;YN8Dnt}M5`6h+F8-7UDU0aHj)4XHJT#k$A=Er zy;0fPxHRDL88iVfF95)}ty_|#rk^o&r5SLpYV%BRcc_AXIteRmKK|U=6R8@H$^qCd zy9SH883!@9f;DlD{@}5%*wcv+@at37_pb37QjDnlDt>WPNQL-z)h@^W?N7vrFYFM~ ztMZTO)ntkLF;KbFTlkvI*qZKav)^NvuV^cf1)$nrm1ZLKu&CcI&i_B;-R3(EacFh# z2@JqayY*Xld4!Fb9)HA1E~?-Hf!QkEWI`l(8#LW=O*VL5+h?)h?MEvdAG?+RuCCrZ z|M=AvF)y2E1 zcy%f3N@VlTeYOM{M?B`*sxIF^x!jOXsw1@I#+uDOHK?Zc%c)=9! zIOtK@jd885Hd2148bZ`dX4=Qsf5Y}9^c}t`Jt$vg0rV$RlVc!o9QGo1wS6g4V%wgs zhg4FK>X!JFedeGNh-3WOqCCQRo!aHq5oT}giKDbY-@;WOzmCSPwitM%sWcG~es8L( z+WvR>(}rWvP{x);i%mTsXCGJ?hVVPiSD-W-HJ~zzWAg@lP1&Aj=FksbFUCgufQUD` zGz8QpQ6M`pXWq+e=$RL9hp+kNKJj28;*vUHh; z*D6Sz*>JIm60P5(GkJGdf7&zSDJL&zP&`S5xL$>}n5`-zb5H(d-WyM+sRq3y?>!RNV(cSt#x*)B+GX&ZI<9U-^(m0y{Ii07T*bB zQOY#_d4yCaY1b>+e@Wdd*I_)Q!jcVMh?xGU(O;##a88aIE_MVo{vedAicGq}&fSPA zRKE~`Q6x#=VEIJ6UgoZOj=8zvIY91zq{ZGmmsq+$+6iGo<&v&M88V?wgBCf_b{`}o zntaC|&e$PL9`HB{z%^S__%Fm{goYAR>3`aJE47s=o5p0v$5;38Oo!%wFc%ZroE1~d z4LC+n;M$+jppDxXF72URwRA>{T0GPa;SoXUVF^?G)~E9=BJ8Kh;L-Qp&V>c0+A9{dO^SOOpKHTsCtJR^E6^b4Mp`w_oFJf7L?a7ls>=k-oE)cX8IZJO3t%^&>ve)l=Z-ULJpZYq&sD>*PvtNkeK5G+g=O!W&2; zOfsrndX9`7kj8mWWog-|j7;Be&`=8tFi$Wz6rLF;XH99dg>_Eau^p)dC6v9rl-M8_!bW*CW?>p1;C0c zHf-swYPuk%yLtI<7vPlum{-8P{U*ub_K@P!jLAMJBc2KX-aa=emyxXO&Ny}pj+FEo za{J-C-=&@@%#q}e*40qHkyJaQ4X-h)t5bKFHB=%z0vR`8`SU_OOFs4T+6r9N{|Nx1 zh3i~85c~FdFcZH)IO|Qd5u5t3!85P|uRA$L^B>Kw0dp6oZFdxrT zvm1ByZRclDzMcmm(W86d7^*o#T4+3qmtJ#uQpi8R4$6HhFi6$lQI|M)QLPd%@(4U2ao4+ot#N?2Yx4i6LS1WvgSa^FF65`3#QSseSvDdXqAX?`7ooFB;m4Z=f_-!$l$8$S6&8U_A6i0M}+|6 z4Gl!X%G*%ZsaEN3;kwdK+{@=xfX>`)u}{A5ia;|;gcQuv%pHPMN~O{)zohvtLdsgH zLbhRJ3$xE$xbJxn7WQMQZK&N`@r={PGJUW0aIgnUhw5|uSc@6iiSjLwq%A#_*=wwL z={z%CiVS+8oO)d}nctPyrUTg<*2b_pcoVz&9u=DC&M5Ob=z9chAEHn?zDtaL2RDlV zC-R{R?Zr|Mv9%&lrprL!15;^KKp^FfbQ0-9ptlh76oLQ@o*)N^@@hFkr6J~%NR*g$ z!?zV4^LI4=|L{}QQHGj-+ip(!Wjq9F0<-UG8F20aB;F6bY2XVAjOa(bI!v>1x>sxL zy9;bQXn@)jjaAp^sAVm?^z!o`6G+!<18&5qz6?WvPTO#lNJ; zC?TOMlSnQTMlCIO+!E=|g%6!m?+o2Pc6RyCJ$}@EzxN^Yx#Ea_OflNL^+|1fPGN^DP(~;9)3?JOU(yKQUdr$SO;<(Oe(A4doz=zJi>F!9rHmuQC z&Pu|@IMQ{6;W}*>`2N8s?KXog6V$Qa)aHs3J^g;j7U4F&!|A@ax45B(->=L=3!_Z) zmUOtBJ&(r^3*48r=Zoi*$e{w~vggV(1@LMD@9qCFF}M4f2zP-+8*)vgmg}EbF|E~i z^&@Kydwcw3Yg6Z84=bueFR&preC2? z*oS1{4OY1neuteu=Uk!@5GNGyuG!c<+W9);l)u-se`SCwMj!jwNXOE0H zx{g=a2raIX0aUp#q=y?fPwQ&;-qS@fPkz!#g>?RSlXKs=wzR+`V{jaWF%K=a+JQK$M^q;P^XKF)t-Me;BDxy#pS*{|L@rr6i?sxA_)C z}0@7JD#lQVLR%!AXDqk;?$ld8$%NdsP&Z>?dk_LMSGFJMo zo(Xc=u?~g#{9-kbAdaU$&Jw2ZKzdUsukx`5&mq2!(cmdaZ)@SQ9AW&FQNpNFSTz51 zM#$k+Qo<$&p{DdqW324@#m%Wa6i**>;txoWkD%;lv}{qo_r1z(1yO`y&Xpiwqx+GQlO^S(-NS5xAeB znTH6^rH}DFqRna_y~Zr8pvosZ9u<53?AuAJw$B&L9V<2Cyldf8xf_^WN95?PiR5ue zO6wAC+jS=4Tt4UsD>0(|Q5f!oDH(c2^#6h{&M&;E2A*4yS6~iN)n~ze5hsdhm-^7S zV2)UOx1=`)WBMJ(Bg(T0J{D2s+a!OeQQ|7lW28P;qE{)M0U|=_kbg|hHI-44qyXUD znBLGoCZ{cU`)OG%rosJPultBu_QYkXvHqKBzMw_NLnLRU%c_h2K5eo+HM;japGVKu z&Gmjis?R?r44nKX%2BF9W;u9-c7U*?>elpptcAzDK7eOJYK1?tT&N-*t|Xz~aTg1> z(5-}9BRe22id7_?B)Y0ylr{=_q+bP68x5%f7ox%?k|3TCVM;X5yq(>nq5o|2?@9l4 zLs5E2yB(S2kPu6+kj?UD*wrvv`Qls1QchD#ZtkYDsB5(Ux9&4B$3QpxNF(#czc!`i zUkjr-V2nSg7HORz7$h;Jtn~=3?|TU-a)2zPbAv~m1t})paM1O6Cpm{4?xQ3yYP$)z zO(^pWG4}HSt#t8p{&b#Hqi`dB=Xkn6^*K9$vu3*dvgkZJAS^*f7R_Tyw_eZ% zpNSkuX<)dKVW#*e4c4iU5HyQ!XT26POT?_&hV0?S=uxj6|i`fCM;C=vPPfUSRgDNEuH>{F6KgUUwItf0M18Ybn~!m^E~2_8!xE??U2?kCze2GH9ul6aC+IwqwxUwmElgb zr3K@KdG(iDg?-xNcJHts$*Ws`33{Oz!gTQPC}u>9S#r5OUiUBTXNcboIWlGd>anizM+^q(s^80@xAJ{}bhPDASnb@thJ~f+H$929&NP_iNKTgQM$2%Qq}2d+m;E|r zRF{1|gKX*JWd;qod%DLX)hWv^FZy;&LgeFm&D7U(w-z5%jS>{)ZPJBM{Vs#mPW2f_ zf#|W;3T>eb7VivB&q5NrI4%kEF_15(F4)-`J`oy_-n?h{`bV9)p=hn4h-H_vVxC?` zsG?H%-$EDc81;&&_NP_I?g6nH1F~kJt&Wu z(2)2jQz-|DT2vHRnTTOd20RYFUhyU~Np3+Tq4O6>sNh~dTq&t>2h>2ikX%{dJ4jI% z1f_BjH^#YA*3d7kuWBaW(aST_`%K^G49u6_1)lT4+r6BaQnmo9^@MQO2WaQ>-=S@v z0a!eD$^~@wUOqgiG)6ni_(+Y?UtgN2xvKb9JEQ6+1&Zm^=FfXJC0kHagL2w8k?j0V zFa32cEex4=(4JzCVH`drgS?homGippyGbarA%5i_4$ct(Q9m`3PJ!{9+2#dm<9SC# z+i8<0v(-8e8H6sIVw*^ZtKw6En{TEK)FcMYZNBA;?!dZ?FqBaPVaN zwZf`8F9c1ew2u5zd-Fhckx+kIpK%OvR`~!ECqrnFUWRMQ4s+I3Re#jwWB)JWBz*$5 zk_(O}uA32K5nZ#`u5a{Wn_}<^FS1F-A z95*FNoL9v4)0XLFna^<i6&kyJ}*^m=0{H zN?%>6PiEF;l0dk540{!$R#Gn+q76Nb2V6Yyje%6o%h96lL(fKDaZ6!XRQlSzMm~1+ z3g0XV%M0RyG_k@IO4{NvcHlGMkwCqqcCUAw&mdTl&pOT^JpVx4q_Sis4-I3%%Yk>v zCYrj$px34s5YK`rv~>nr!SwnTt%p)gQ`*g zm;{Hr7{78*FI16-rPZJkPPOOysIq*FQD2(B=JWc@Z1bRShD%D<)ZSUZ&Z**9yUAv_ z_@Jk3Td;2}NiA6=b+J{y6f0AqY29WmVD0-e(;Zpn5esZ*6O= z_4>}7**WRJZRt-_+wwt+(iaZC=Y-1pRjP=G&?ecx$$LGk`Wpbw@ZKD3B9waaiMV)s zv4d@H0rj}j%WRaU2tOpmcvK?lJBQ4uelAr|p3V+0R)ZDxQhxnSZ{bgLDeEaeneFl5 zag{zE#&C{_y**a5>zB8^U`77)n+k;QS+m>N2fIl((#KJ*VF^2eQd66TIj<(<>|l>H zxz2Bw{B)9O6e(>mi@4{9j+M(7T z`0(4jgOGdp(a$+2lba!RA=L{mj%o>)?l_G|SN&%##CV3UI!+nvZFM0l5FNoHlur!Ni*JHi@hLLbeHF1tDf8{^-=mWR`jL#M-^N0mo!JD0MPtJ!M%zW*QsQ_o+mlx3-vxe zAp-Bm+P>O|)QsWlbmZ_hPhP9~tSjLf?xCTYmabRwe)6ok$XL0CL`+z|{;=cDFzs=x zzU!UOX{*@ofZg8}01MzxU_&qnB+LI7VS3 zW==DGh;Mm$&^fEOMu6V=(TEjH`ahKPt9QORND}{GVrO(s7`P7z}IL0^~~z zywRM(#M3YI;m8IEAAkC&qkF67(&F}!f9Tmc?*Y`qc$o^l|fv5_@{!F9YnQVW__n} zCU>>PpK9pY#tk!&Sv4;Eviz=ozMOvc^!owwW1tF*5{G+O>(+!RG+f?jGq7KW>)F~{ zkl&z&Rq?yqt;7-B6Cq<(Ct-`6gyNnbF|xaeC_G-v1IKWj54+T22UI@+WYO~cWvm%y z#S!%c&L!5xxHgsgsqZKji#4Gttr>)YEDgx1 zp)6)?qS{suI0=gwt0>oPJ#2schjCV)%y*aOCfMy=KKAoG`{Z(n%KBjE`&_agR@mh| zF1}k`XdxJ6`(XC{RAV#8CHv_IV}eD8LvL`U+%~2X`AKORUTR0`IyJS===(`Q70o5{ ziXK(J5xdvTu6kHg+wIq#s{b)${6hjk=Zt{yiZl&MBbpv-+ZgSH`a3l`51A z#Pi+dp4Ir*mw2Ulhww2(GfGK=93o?NHvO8X%9$edZ?+t@iKP)J~+XnBTgEk<%V}P6bMg6%bcu5rMGdTa)mq zM@fhg#Q!7fJ;T}l->`pezpbjO+M5=oHLA7}v|77p?VYNk#NJy~QM)KAMyj@mSP?rl zW2+ewdvA#uE4}l(@Bg#^a~y}`_`LJU`?}8a^>S}S$E=R-o6G6(^cCET>pG7`b6=}a z(;UR{^yQ}-G&HMxJVU;-ar&DusM}fdN(C&3_yicPFU|)4CDwi4A_;tRym$km7*Yh~ zLLBunOTDRoBi~f*&G`4OOAm@DOMjYd?IoLef;*-c1tV99V8314?Xao3!J~f^H)aDm zQ*fZKS1rt%2nAoS8o#r$1NKQoc>vAyqZ5@2TL0>Gk}>DuJsT zXL0T4;*(;0#soOOCf`Msj~HWrJn0Zr#hZ;%Moo3;BK@k~)AK{fk%f z+j_Wv6g)aj5c4XxPmTJm`K22#qiW5C_nmnj|akz%^*oa}?e2bzoz-Qlnnda5=e`#rKjryu z2CG|k{*A7qMf)4JvwAWpU$AQyH_m%;)_+L&gBy)?mn%3l%X!Y${eY=WdX7lFxC{SU zyD+vppPhXy-BLn4)ET{A#)=fPz6DzJ8m4;~UAD1cJA|>09$RhZ+kH}2-*5md)(1wl zGLxBnuR5qX2i^?i6$n=CTL%&N^x1P!yiixuK^K4c(w5%GzqqT)50e z@MU75Q+@0~=OnRUFGNj&PECq0GOt!$v+j{-lhQ;|iLO1zJCm7-?a4W{F&w$E$>i1K zHfZRNmRy<*o&RG_Gg<1>V2f1gNGvevLD7dTP_9lwG}DotHY#JT_CTVB3tz3Jr_Gyj2xr(r9yb$)#BGTqx-P9>sI0m- zrMl7tYkRPNH#K;*euGB~eIb)1D?WUc@hU5m!3q5JygTpF>Nt!)Rov6`XiyF9wBpqi z>zwbI_K$-1ORIiK#quakq0IT6#FIyvY$mx1<0iB2+g+iO#11_>o$V%mTRueSXY#j& zr%ED&%fLuKbDhq}tk=|x@3T{A0-hIAqp=myaoINeOh(>HMXyc28LeO-!7u(kWq9Y9 z!NIz+)$ z`x21iKV8(fj!>FkERR~Op7AaI#g2sB-?7J4rVm@j{*Bf~V#?EX%5c$zUStv?O)S&n znb>V_YMz~4CAohTjrCGFpNlCYMEPb9g6Ed1#e%7%a|rddw%`5PmKt@`O|7J>FGX$V zf?s^Wu6jgS+9$kdDF9khR1W>LTaE=XI1SnqY9st41C5O`IPQ@m%`ajt6)52dCFzvkU=H>KT8|k=`PyfcO#l^hk$_h!UkFC?8bU|TG#^@Px6!($>H*M zd0^ip`1PT5nK_nLXMcX~cYSiOav@8Cd)f1{TyBD8U=x$Fut5g1O=a>)fHAkY)e4#2 z2>+R%Zdh_wCF%Bee9YN))VnTG`FQ9Vu;ryou{tP|<1`-qD9OC~;2XnQ8<$h|`D|lO z`4(*vsAIrCOS~IBJqc-={*;Ji3%R39Fh5Hd6Ztjq8^^oH+I_o%1+Byy{l-mZ#JnfZ|_VhR#*jC7VV|x4=^D10pFE997aXx$)^6)%Of- zr2#Q(JbMe{;cKLac*b*WNp!<+!HBs^WUT@1kHm?cM5xC>a;~y``$RJ}D6}ih_q)@N z&nr^CgX0b}?@b(n?vBnvpPb1g3TKnLlXNDSEIt=cHktZbT0qrs^*3U_1J=K1xF5-getvNMLMJIDY+-Zp=`Jfy^i8&y?+(%09thyhZP z&o>u%k|%cV8F-neq3Z7EQ|Z${73>bgsqt#IJj{pI1NgUDjQlA>JVyWb}oN-QiHq~*O^x?_q@Ja8@ zgwLJYr!yvhc_ifbt`L+~VmkVja2i1vOEo(0kJJU-nw9c=u(#q_L47m3kZ5AA?2Lx{ zkixsFU}v?vG74(CoYE^wa)NL9`^&Px4=q{N2qYdAKB?edRiZ0C zAA7mp={%YyLf_U07%fGnHJ(F&?Q-%da1l$Z{F`t{@-m9`@+~<}{pudIIB$KwShR#w zSZih-)T^y*4nSb^4Q!gzAyshJe8lkJkta|D5#z5z&8Wrvw7e*Gk z*(dL5Q>tf7KhDj-?^~Kl_bYrG=D?g`T1kJE>7_$>I%JeTWbTftQdG-OEwx$`0o>bG z$Vjh44LP!NhzF|{RcR@HL-QhK{Z3ZU1OE7Ew|d}~WR zMYmkfd{J6lvcW#Nz<7myju>Yv9&RVp2en*<5x(ADIr~9MoBmwvr1g8EhMW^|5-Rs` zbFUp|Z#VjAyC=LcKh-@s->D=3J}{jC_rCh9jtJiLu&Pl{VIqS&ldz2s>k_h^1hg~Q-X*T;AeU2!N-kpX`6M$l&bV42Q5ww5^dz3ff zy8AxDrQMQicROOxq1(4?xsq)#7$!doB~LMCVZli}Qf+8jV7jD1qwe-_anDMtlqq@i zPkdcgYH!@jL^d+g6oKv!R8@V#$?>+vPUKlY&6Kw9atrq!e@f@lb>>YZAHp|EveRSU zJFL!aBL$o0>miG7OdZgv?(*0gcR9v=4jRD@5>Lap4+WH_G2I?5(14Rnz5`; z9U50~JXlykR{VjA9!dgtsU)GL{ zQnON;?Nf`$L%*{2SQma7fp&_QRM;C@bJf*RwCM~Wr=()N$9eM^wl~M(dGooxMjjq4 zuc0?}t|4uaT1G-FM3j)m${*qFx$?grMy`}a!udom0>?YN;5S&&mnG9B6SlYRw<`kl zeq;qAWPf77nX1zEZ+;h)5058BDM?ikBNlR`4fG>F`WWz1-O}SESo!9QtAJg>1=l)L zu1%tz1oIIjP4NPGTtk^5QW8%nZ^n?xi+uP9(jDm%3o8rr?fbPkOsk69Grj(?tybDo zx&Zvy)rhSaPTEO2NRTe5R~w6PRZgP$&}0^kK9b6Pm8X!W5Zv zry_L*?}npYp2f5SX*K^7LL0W~XYzd;KjNEfy*KI81i$ZOU~S#YfB2@eM!Xl^Kwk6f z(fg|#;NztGUwM?>HwMTG1(~!3I3tT)12JpUbIkx?^>^(dv*pYpx!^lD<{_^qFDoQnTHKyg#t}oup!9OYMNWUCgcX zy;#@h218GHIn=^>;aEOFuB7krt1SLC#YC2ir(`ixP4Uj6oj?-dNi)Ne7_)y-f2YTc zwW*~wY%o28kJSZBhCO&=UN>D=+kd3~fb)}M*foF-p5>&AII*mEYu0S5m5pE$F3m&l zZ%w@-X_VN7he(*0xK{SP7zu@iP)WWeL{!i#jG)bjURFo2Mr&l5c*NX68E1sn|_(Sm&g6FulOdYq6RRLbu!NZ&11lqk}^T z#a;8%d(6tzL};fqw?#)>+L-hc*nd-;u5^{NWE9qR81pvs3AV7&2^{ZxJ~_X8JAJh? zFbYF2mMs}0{@|Xh!`*A!gMN$nBd9@wrYi8G>AV7q0p5gtpv4;5j~*S>%lk!xXIb|8 z!s>Wwnl|o%vIr~*(n)OnuGpc{lC2brhp{Zp4FOpGr=v{zoeL~}A1Db5+y&!-elf?Q z99rX2I7O8MoZdvbRBK(VuLj&$_THD*l=qnayl3USe|xR&(kb5wUpuL2O zLfHbtTbc0IYrHsxyCLm2#6)>Es%*rNpv%2n=SzX zKA>W#s@;DzQpsld3L5?FsbBBz45);se+UGhleghz-zCR zb$!M{DZY(PuFcvb(jVRq6VgcP=eLV8V`Z|P1^K59vaRFaLzyE=*m_h_v$}g%^>Pp}ehLLHi8X zm6sfMN5QAL0&$RC6~7>pb>LQu+ZhSPu#3X%AkUQfHb(I4?c4t-p6$xwRyZeUUM={A zAJ@%$lvu_Q2tQ`R-t57Z@Lsj+8*X~Jz|=KR=>c0& zKxF5VojJSU-vgXjlsPSKccc~v1gj4BD1tWkW9P433Kj?RkJv}6jOnXi4Dhl6On#v8 z=Ni%$Ap_5<;fL_N*5^15V5GcA!2XqR6I0CBjsE0ZB}pdTLaHE{VDcNeeV zT;Ja))arOIz&K}7l%Bp!3a2x@UEP=|ZRIF-q5_GI zykxegNwqwxDVH`YQ8RJg>%`}Rq6@Z-q8kx`xq}tND3=?HcG>9?(xpPpd1$9YDPq;K zj;$GZSi8Z|oYPg}`MymLY8_8PS8)wty~$1G<6q@1>(^ATjFgkS0A zsO)9Hv)f9D4s#t_+vnQ@utW1)AE8wEkMYRk;zxpOxsWV%pP&ylFZ$3ze=uO;@}JZ$ zP8j`JGD=zNXrr6Y_RK!U=#7QxjV5eUA=Bgfmdu3_sE`kn#$L`a(}>v9-JRwbq!85m zh-oYIPHUpoLq={xFGFegjgA1X7T@9$SQ4%OyK?VM@GQ4#jBHO|!|jF}f@3L^%Vy}5 zghyHb~Qe{a`8-O*YyqgM`2+}-0x)X2l6@@pGVwA53ONu3s zBtaw@0%c4wka8Pu!CyC`aw=b*L2tS4j-@mG`Ld_IM8w^l@l1J_3ZMUm=m_1AmA|=q zd=kBsb8p_F`oc+Q2AAKQT&wSLrY+ogS#gcESV$rkbvz~X_J`5@F)T^hZYtE(qNG^W zv*RkK7#Vo()lT})4eLP8FJJf3PQZw7${r9EtkV)-GpCokeULk1c2llU^3ur)puUKM)ATRRssQZeDr###u|H4*Z0xe|9F6-ZdYk%A?Bhs0tKLqPFlaGu z&$sE!iie}auc}|X$EM2?fgh?WRR;w)7CA9kSXoia2_()=3uGU~nBJ9&zQ~6-o$^dy zoVb$L+D;r$qZG{2YjAfH|GppmRiW^w#*khKCi-W0hYBKRaH%(k`@_L4cwOd*MfEm> zTQk|xLW`ewwJxk?O2yB5|(jEe8-q_R6Y&OPwP0yP*y_8~jn5dDXdAGdy z`=2kj0bhj4APGm>1mCdRQYTe4AL}u$KhDG*cxM9x5|zL2h16JO?7m#GGH7d6AdpH6 zrZh|D&9^Y|$?%8Dp=X}*-&-^|vqLn9n0D~#H-I{U4gmt`?e2PH&ydb}6lkxmnrSoQ z9m3I^cg~*j4i-nIwEsl`8nGu9jiBr@(cXy;q4+Z_jNHG= zWt&Jjzfe&PlmDb)ucEXQSGyp2UC9Kk5(4_$OofNPB04O7^B!cLaM@kt$Q+i?ot?!I zf0A-;QCzQEZ$ZZL@b4ORPu%!S`Kxp!Kgd~(+B$)gM$Yi$Ky%zt@af5AtNQBnKZx26I@XQ7ou!MqHnZ*?86ms_f$QX6kw*Rn$X%TluT()YLX8%D}G zpBAri+h?Ea7D8WFwfh!VkvAqMZbX1sD8K29m81l=GCN{Scu1Mkh>M%f#Yxr#K^nl` z7Fd33LxSJQ=koeTu?7FR{HC8Oyr;@E-j{Fd=#10K+C)iR*;8UQvAVV(Cw<))Xq+SR zMrgt$-rU7ca~Bg*_na07?WUp0g%orN(q#O&u^n#`O;m52$KEd=%=s0&69x*glXm;& z*}9A4Vd^FZp;6Odzm(oXU+BUdM`6bqH;X{tQ#&;(FN=&!RG>am*HLEY*kq#4*Wv6( z)mfyaW$PHOdZSfiZ%0HGRyVODS7B>5wom?0`871BqudcHonh2W=c4FwR8h*{?cfEBr$9mvv6BT-WX%6z_m*b1{K5zT$~L{IVrIrn(Jo>6gn9$ z>nhYay>rz*P`w`w=Hrw!Xf5pxz|kfK@jy;TWuVFR0=oHTWD%@=oXC0h_4o)z_T3#A z#h#R0J_@+Xich3B8z)s)q;^lNeY47lW4JgWG=0+8Lk|#-(MJmBerd|FUN^v}$ETl{_wxrKU){%jQLkS|1s?7* zSz6A|i(uF+bFUr2r~D6@H&-PRz`pM=t-Gg45G2N5J*CWtkl6&&MNV!HmD}lBj+{7+ ze08%6P#e^)8Ow_f2^1;+n0D%3z+2L5zeBlf+$?EBfS!bo`|Q&Y%d{25Zu^(9fG6d^ zY;n(TKf-RuFxBm<(RS0`Xz@YSKt6{pIt2TS?ydkOb@3!=5Na>|)wj1-A3JR8)u6yy zOlJ@2!KGO%U2kK*x?3ggzQ0SsSpu|!+p7@}`H z5xRF0zt@1!#Rr;_KF2qFm_W*D7CH=X>LRlG!;FWN(%Adi6p-%zMVZ&KoGz!yl(Kl; z{+A8+&jLCaEQV!n{S|L&ahLbm#>s#2J?!$uy7bNB#0C%V{a~VRFFJBXWWtDLT$FwD zm+D;d#!$ZN^_#g9!^GkaXldQaF7`{T{At`T6mq~B2hB`1)C9w}1GWAbs-Jo!724|1 zrXHM1^^T;lru#nM9ybbT&--)M&?V1ufaano$~a_EaGH#y5u~XPWg7LDe8XZw#ka>= z;UiPbw^o5}gRb$Crx0&G@3@TrE{lkKH&>8uXOP?9E7fKE30=7*%x8f~@0R%%FX>LB z!P@$ikjz5Tfj(Q$_Jb>5A)c-^UZvO`#xeY(pyDcJ`$tj1BE2z5V*dg>%8s%fbOZ5J zkCHITclhzYw;}kX5Xk>OhnIb_Im{W5&Rii#_5X5s!i8tkJf;4EkoTU}&&e>dq0pg7 zp)!NC?DCZVPjRUHSz5M%=zyQ=wY9g$x8~lWyizC(d5O1JSZz&k;JR7~D*A3`6iwdw zeF>|PMtyc^R<;X}J&7fHX(PwzSGraM)))=vYebO>Uh&z1;G=zZVjZr{{MC$xp+r)0 z2x!AIn>t@jqN02$1qtHMTw9+v>0I}p>Ar{0`MLPl97``QuJZ|&cPL7N`CK8Sc6J61?oTT|uSor4p4OE? zE^3IHHMcJ(b+;HSW$f4nW0$QQ#Tu~=^O0=b0TmGo!#gnL=wrG4V|#8(N;#X@LsFp$ z)_h*FHxUTLV&^4)U6t}B{-ao^$Pt|cj6|^=cLnd__m|e7_`WlTn&eE$R1TgW7+5Gq zNja%g81!o@^ngR=o|zscwpnPc!z*OINsr6o6cd3fHA@IPi5m;7C~h$eopExx0dzds zl@V|Efs@;epiKeda+B%EuFa?qM_495lEaKtgheeRN~;N3X%$M zJO|SNhdR#Bj$Te?o)+vMkQrEg19l0nVVVNc+7`WNt%2zi-WdGSU6-E z`&pFu0c%iFj+0fV>Sxa|9=D(H$%WO*Fb0`u;tz(NADIkMy?=R9-T-6oFm~|o>xQ){ zZeE+*a1!;N>Nr+P3;o2rcGtnLs(hCDgzE(js^jluWzGxX?jXZ!5T3|goBG4oP8OTS zu1CjBNNk7G$@Sv6l@C+PXJb?4?@=3{Zrs`1^?p$WpA+PqMAUW%8HtcZyq4+-2tUKt&3@-uf?Z8qrePKGh9lbXgsY|oM3LYchacW0$d6>zb zMB4HM1Z-N3rgy94h}(yCc-c~m%ol;sGJo*?GV zm^nsHs2O^7dFHYbSf&xL)@aibB@OEypQBEIGdA^DR8!9&@Tz1-*57*0BVEAKkmowt zd8Noc5w`K5=?584d7(0enD5XowdKH0Nue9}%7yjQ2>JhW=W-8|m( zIRw>}E6mbv-oGsqH0_&=Q8u3h+r^3!S3&E;S#ps3SLF6#3XA7M{TFN%K!X})%p(Rb z2becFv0-iNfV5uYrBOv>2vqYK;eT;tCyw}E+o?-FO1#X5@D z^{P8U?OuWi4USxHVt7E_-CHx63k+7O(cOi1)E=xr%R7fzrOeZ^+=#bZ+9D#j1}@>} z@8Xf_E}R{7n&$L>kEfMHP5XYSp*@b70z0~~A)Sv3?2J#~)Kx7YTrPRTLdjGvNjYo3 zxovi3_rlB#{D3P=5v9pJzvralzTlQiGgHRVrfWO-cVY-_OD4hs| z1d#LC1D7{%Le3Se5#37Lst4e+;uFZ#FXvGCEyAq%RL8aW)E0xg^X3PRjAigXRNB2M zzC=)U;;pnNUg}6AP{~j>%9|ec^tcvp4=9kcBW4Ui$1|HA4UgiGCUkR-r_*27ld?i#-kov?p z!RXJ9V=l*dYA5^6oF!R?*X15ts@4wEGE4sOE>6TOp0Oqd6VadWjg%9uNCV4H`=Hhq5};S1c-pykgfem-^) zvn;sRBOi-FCL8X~4tkyIMWCu5_$82>4ZM5cf+*4hXxnM&jlhE;;hKJ)LJ{9mSIYEf z`7pyt>93=^5gNjLdW2LE%ZJ;1N^76xUxO9N2Vm}~l>Ql4;#R5KdwsoUmqjoNZ3g1f zXU6`6#d@Bh6v6kt;fZp2g?i2CPmGc=8g>s(w_n^1wRMK?i(49X=lf&#ZrB(#+Be0# zr1axXi!Spw);wmcPxx{;%;oq?il*I(dG1Zbexj-g0uO`bbZ_)O8GdQMUOD3<^@CH` zeJ4F*8DE^COmj`%a1tNB&4QzZeUS-SN5Zg|B~ zK95h-r)w9!b;lR^5vGCYL|83oSR@;1U{Z1H!+gjaukq`%BBN=a!+L71(T-b zz0qYoH^vzeyzJhvAhyv(OozN@e+QI1E}y^cxNVa!W;AmPWId~-msO~J&Ev!tviSS+ zV(aPb@6XE0VGD_1pVmBrZP%!!($wxw1RbOW=&v!j6o*LUnVITpQVsTI+#gs_=Zp!Uji3KUpewb!^{sh$zHq$L%_0Bdb{$yPK*g_ z`T?-9xJ2sZr;oFxPU@}iXn0lHXVWb7$Fm|=`HnB2RI1CyK4st9j5mH4GBN!2N$(B+ zsIc1E|Ix9G^gLc?=qxED)nJo^x}UPOc)a=TBL1}5pj_SU1G|E$uB;dv+=viQZ%(AP z+ot39xUAnt2d;#&5PzdzOiWJLn7nZRSOH)1Mc!(7Z&T}2FY?StZx)UYR_ih;HD?X8 z+Y=4gB?9wKXN1*$JR5@#2Pi%dgAFI5J`EcEB6>hISo5DM*&M@^r-s|WT*Dm`ljS>n zQD+d_0bA_;w$*+j>6Yqp*u7atB;BsXZwZevN@>&r9*C5JD)vf5|8mp z(?XWepxiHMB?qE=HpKk}NOUN_L~EhV-4ro}*y~;vt!(&XNMtRdswT$fi}*oV#Z4U; z=sqz>3w*Hg?HBUD8g@dC*Gb)2u+8GEBS4wAx5UvM5YM=>=w!p5YHUHrI$lyB z+*9K=f>7s|Knc%6Zt8RTj^eTIeYR{%^Z#5uD zxv+FTi9KAMVMyw3s+v3DR!ZPTIGRfdDJ6v7Jy&Vp9;^x<_SrSM)Q^#k^0`Sm;=d2- zCtJ}=YEk#h(GL7C25)0$CSCI`jHb7GCPys(QJ~TNIdh1!1kQ+OK8$IyAX4$Zv{yM} z<=!!K)#b=v|C<>)<2x32m~QjHTuGQv+Im7`z~8cD#)l2(CS<*!W(vqSX?12R>>cpU z_KCUMw^lZD#A>H6Jot;4bQ1wsFmf^!pT^-Otf<$1P%@I{s8-|jWM1zN@zst_o~j@i z)oc(RZnpTbF?Ch#L&(jL50L89sC|t?1T=sJ!v!*VNn}~jyKD8k*9YX;xo~LR1$aH~ zCJnEM{^+5ffHObOC;xYLJYQwmhrca0f(0~eIr{0)oS3{zmqsK(FO~w`fBTO3SnN?4 z_plp&zQdQWQTJOx;m6HFtwS_M>g_AdI!%uBwbr2L1Ff(NB#WS^RRTUhq>Avv%Cu{4 zKNB~KzPZFhiQC3Hr|*<0J`?UGqZz&i7Nse;sHOl`Y{4f`i=xKXW;;tYyQ}%pxGSeI zZMXSec8~cM?*&5Ilfr&X-rT~I7j;vnVG!rIs>X$h5N*@MZZQbkIfg&Wb%$&Pn@#*4x>B;C z>SdD4Id(Le^|s}^i1?QQ)A&0Bm|!2iEd?880pTR#V1=cB^rCf@Q+XR!EQ8A_pQHAt zifqc8vzn8-E9fd2F{Ko@*g(^ob%QZQRl)3MnAX|({J@0U$VYp}NAIbWj-2WeK;^R{ znKOwm2fcx}0W5+E09#jxCzfRZp2&FTyv%S>E9ZAenvmg!!Ktr;SUjrQwHRO1#_kp) z+HdLTN7i6vS2wU-LVHyXPg~8;;U}?V)WQgURE%m$Xhyp6c4qiycMwFYw99_0P)K07(CNG&m>VfPh;@%HBq*0s<%fwt~O3A0jg+De@|EXo^mIHgG=Zc;IRbQU9 zTtPfj@H${6$Rt1b##JuDEm6Ls{C+P}IjEsf7|nD9>>$^`_A>4jHoXNaBqXH#>;~PL z>hqp0IDWppT&nMzI!*>heDNUSIx+GIL*$qKsH4mXn@x%l09hC)yPHGsy=a@e+4!^P zukP}xjjp)$@PgPi$9Y3SEk{v4Z(Y!U3tshxy~BT+Xkgf%?zEWeSsW+`OG5 zKT1Z^@)R-KE5R@)IcH-D=`uAeB$rH2iIWy%&>aI>4*JxuxVcP~&!>HRhnYhHUg2?; z_#XnGU3m+O5F8UOuiSup`LboZRa83fBzYCtRLTFoD|}p^rk`1HbA46q_cM0s2f=ek zeH?68^Mep4)-o3t-2bj>GyMFZ5E@bdTTOkkVBrgi))UoR`Uq{wIBiL+QoktGiL6P)Qo%OI#BfT&swVq8;5aPQX*Q|B!!mVf6~Lf*R{Oq z-b;8<1;SBDku+fYHYO86B^qC07PYU$Ec{S;|E4G9g*H$gYihCe{c1vIAoQG54g zvu2rp;M|_{=rS_pM1$%6Gun#>E8(Lk9)dx1>C(nR4czT6pi(;D1gn=>NL?s* zQQD+6(ul|@KT;$yq2+zb7P2{)t?zL{&yaCvPX7DR%|Jf^=!(YlSs!?>^Hqr11*y&<6bFNK9LzE3xQo z{Q7zLalF?kvKUBfER-K-f(gq!Jgy|V!TM?c!>xfrW{2uS(bmErI(FHu8UIlXJGoya z2Ahe5Z6D=kho0Ap){4<Z3*5L11Lxjey!|ICR;%$=URa^ zS4GV)Yu1~;UocphhwTE(EzqQ@pQjb&4)<)Tq?xq7r(qm9R-f02iROzaaf4S=n_7$O z%t(XhmxQZ)pKmmOS)l4CZkU;{@-g(pc8A>++^0YxxK~+zhr|?Yk5S?yzg`NgA{0ST zI<+X~j9Mu3@8)6NTmum!kV=+kdQ;9nic3kqZ!F1=5*1fU$eS2@IDNm{x0Nwcl-8$a z!nHU*9RFG1q)hShAV|CA8De=4E=voxn<(tn-8~1}5`F9LWz==*J1Lb!=}l92c{))^ zY8QPqyTLPe)a5tNM7jmymcS=M?CeC7bH^_)R+j1+mRsz7*9cWf=23c_Aon7rnM?4I ztpzRP((mI#fT?kZ+EXDhpu}G0g`hvV+RN`q?yJsL+QvLzYO1RO|1JM$m+TIT!_R;7 z8Pt{WY4NIEg3r$QhcCWI`rC8)VutJ?Q^#eGKX9fdIn1wwplS3Z+y44UoQrlB=FBzu zPHj9=vuDLYwAL?u@Evc7ac*2Kaj(m1FKgxC0K)8Pe6Xa|T zXsJ;aw7aQB_I>?Ga{^#C_r(rmhUD@k-P0LZw0dFAWDzXnLdCxfy{OlbpsX^^Pw#Xm zRwI7zUF-ocYM!H3jF$LiYl~2PuyTWyY_AJ`NvJ4X76lEAyRt9lFEC6QGmi;h&D^;V zF*Z?WQEm6r(n4pXYuZ3N*ffKB9lbW!$*~XKJ~Q)u_^IPMd0(0J*{q`OA4L=Jsg1E^ z=+EK+tx#8SpfV|MK^Y7TIG*2*l036L<#|hsMYbJ~=@1KwiCDKw>5Q*N?!$h>N5M_J zi)iu&*!yRX5Gtrbm1j$U@~rSQ`g}2-WO{`jwSII}8Z2DuA9#WlXgm~%OujX=Vv}CPmN8dL%pzpkU4qiwZS0p!~WqWWhPT@u)p>$hG`4+M%^UsFF%>l(!X$G~A2ukp( zgG-(GuC?zGD@}15P00{$;LIiT@Z(WAE)KMRbGvf;wM3V{mqcP3ju=D^MxIFhnnPa< zO~Z1$RFRXl-H2op+q?JVO}K@?a2R*|V7K;K$m@R3#tUOnt)EY-tVgMgm#5Grr1&V3o zzb;>(`yVyhqV1TTjO%{!`ih7%-z3@C!mRxxIyr284<;IKbPI3lMFLrBA-DY>dS9$I zg4eJTGu_35{qAwY&g*MOO6|?Sb`o=h3UY=~Dy~hs(!z6(wC{8_C%ur3jCB|9KU8wn z=+*ITQh*-Uj1-L>@4xT$YSuOS<{vNG0QQ&ws;_P(W~kzqFAWG}qGtxTX``bct>?40 zz-8+0fDO4nm%>%VLmw#iQfDmK$fvM_23ArP&a6#nji{+Gj`f>`X(7s2;X}{BEvjEt%_2*h{y9y}aW)3zuxN_1*k4+u6Ay)E<``HA} z3?v6{j*FwZ>}4~5-dsmX&G)3wCi>J7cA-Wi*%fFvk@&T81A8youfP%OfIXGc_F^nM zXzo(-6O(*?X2?l#{TN0gi4MIqE5)m)g*g<(;`}`j?B0On{!sHP_{SVk7 z(uad-WFPm|>ZLaS`|?P&7nTxuPfs$?yT1qUHeF1@ObHYY``W4G!0lgZkP_?ZVwAA7 zlj?e6G9t6XV+uJwC4D^S=@R9$#9PPZ6Pr3t8w+wdH6KN zS5HT;p`{0lnp}#A9T!^IK^K?&)(b-!kfdDXjXhIjo$11R*XM$4Qu_@49H#gnrg5pW z1Uoy9L+8Gu<8myAB z^r&^FThtw>pr1NnW_xoe<_?~ai^DfZ!{W@olS!wUnsM?HN> z$Ohel_2RHY)EX%G<`wKAk!JzOPBbca*{`@%z32QfeYxL7Xz^F>?ApuPJ^QGo*ITr@ zj&rnEH7F#?K@_wY*_zCAk~*tV<>VqWEeiXXGH13sB69$LRO_s}IP(D|NfHhA9S4{Y zbX_d;>Vv$IVKblomzsd&B*DqIRur+VXlBc6v1+vnKq=S~IB!tO?uU9ceV$-C+H$Up z&O6t}U!3%h0q%wJSUJtnG*2LgqX--p*TLJ^DNP>ma0{$cC#JH~jW$Y7q?}RIBb4^) zH)@d?KOAv1IdZwYsLYIv4Ic4B?wT<#_jGsET&d6ZlM_izXuy6e$bR%QA zQzl?nE(-}=oiO6=F&GevCI1jixraciQu;@ck#WX5&?*jO4%V1Js735-mjiYDKg^^0 z4*4B$O*iCb;};ybZU#{9vR#PH_-kGITYv~po?&q4E2|W$JfMnZ@?Mmv{ z0Y{M?u)eV4t8wyW6ZEP}a?i!+&DVrMat1f_@QtJ9GDni0*7pA)>8zug{@?$NqF{jN zTj`jRO4sO6k(QDeJ&|U>=ne}IBm|^mDjj3=Xe38B3Mb_V3Ef7^U3Ut^>FVZaUBeNp1VpgtV51O20|aX;{cuPfv1SVLhq^BQOU3ZSWfC*pOOt;sDfPJ4{w0X}o`n;`> zM`~4-fu)Lyhb6pvq9w6Poe*MNRmCQsvevcO&M3d`{ubzPUL$F&c0$CkqhdspZeU(d zYxuArHZ{lO_wk#JHz8yOfo@xB-Ze>k6q^N>y^%wQB{2A8u`0zi`mcOPc8l4j4}{ZSu@M7$}ll zW3M>(pFflgd8zp0hdE!rl9rvoAa_2NS;u8VwzH_BaFDCF<$6{dzW zV*4f6;SD^EBu+?1&EZqL^f#RAK5xtjD={6131s8!j`--%zZTJdUNQPaV!+h0?H&A& ze^zK7yXlqGO2hhvHLFm3TkoUq5J!RF(Jg`YjHqBDkZ{l`_uv!WRvn-G&vVfRtQW88 zwr>}=@U6Z&sXEe9*5uyJEx0)Q6BO0vf&~-zIU@KPer0eMeG-0umLF9_2%B@~iBsBX zrcLC#q7v1ccx6ow-%TGfcn}4=Laewurf*(|k4l*K7gnk_JL^LLCx3Q`*GUxZ7}`j{~U`_n!-|B zHq^H14-rORLq1IEBtRD}S;`ReT}70f;;E=x`VtkBr|F2iF3l>G>vZ%lMvp!0d8@#H z-Atjl@QmBy^gnCr=EjD}=?eNL4;>|a@heq(_6D)I`5w>9As#kw>lB3ZppW!>_X;kn z@p|o?+C+H?-rFZa8}}RpC}DZImK6r zrh)kSIrDAjdULVXWM|zgwC0}x2O*)@tgv$fRa9e@1CvF?nq^TpfKOS1-gAs_KbH+DBh!$CKqL<=pzl)T|Cs$)-DIBQei`^4q%7Bs1RzVDJWsM=7~ z7TaLoLBG?4-s@bdLwBSd!p^p?xQNh|Rx*T%gg&Q7yAN-p!>zDQAO`0zWig#bzh7Cu zGtpKJ1%d3selNELe(G;nBQuy@92w-9h-a5${~-NhyuzZTf)RVK%K&?Uhns2_euS{G zHT3z1hS3C)9BCG9J`FgRT3>gJIccXPP+U=7!z7`!*UiM21gKVgw^g9E9!8<|ezU{o ze74Vm=Pp=uH)uU`5$QMi;--U)t@Ya0?~i$rxk&~wkYR4vY9Q&UgHM%N8-E)MC_<}_ zhtUDSNcPXwfb<-a_YIrzxVW5=er6fV3&+7tVC-9tTVR0F&=kgKEpIQX6Nb^@f9Rj=o9_?-u6?n zjQy=@VC!gC@tegD(!<%S_2oj0dPw8&6*iNJ9%H14MAi6d=|W4(NO!`2mIIS-&DPz$ z)Vz)MPf`NIjKNvCDG;KGi0h@%c$0>-9Y}Vx@k{8h8q_gGZba~m@n#06dc7*sDLbSp z)#`9!HMvDEU7{|l7)Ef4=iCepZBVp@o+=zuznz!uK`RSOvnYbE^W!e{u^U=vx} z`WURgun_1d_CqQ=^B9_7O-t^uZgqkH!rOTlQ}HciMH9c-+}`lvX`ua}PzKyF2sx9e z$9!R@@5TReXZ`XLokbeukPU^Xhe~a?Pn7rH*3+lfI*D6h1uUKwkS!8bz-Rq@kG=nr zEYI64qnt;X%PtXJW#60UxFe9l`&$JzP7IH+OAaDGOGfEu18glCwYzTpT~pL?80tIO z4O9@a-$-%rlC22tR(hUES{t;-bju-i(T6RU!&!4c@Aw%t|B}C2bbK+kP ze0e3j!B`VqgrTAeD62Pr!7UxKM*o|GtoekWmU+Cfjk9RiqW+*%gvTJ^XYqPY)FUSM24y8Mc64|mo*WmKU{)((ksO!v-**>WE+NgD9N{9 zS)nEpSwr{VTz8R|mG0wX;50diBYfCgWu@E|M_U)?u)2rnFX}q`s+4c?^Uns)V=ev7 z%xD?>T7dQ{)%V|JAx+TzC7Ai89;g=lh#>6rI#RnVv_bJmV6D|0TL)#;hHK0wIjaCh z+K>dBvWl7&c}>Pm421#_RF^hw`14P2qno{~F7;s3%;#Lz8DTeiV}<$-3M1x)-;C5; znfvWdbaZ4|a=?ssT#L1s%Su0}ckxe)`Ph0^^a{GD-=M1s=D#v;#v@ea4{+J6!~M5E zbKu*sjPLQY^F9`Kde04RKG%~iABt_I!e|F`KbX%>$l@z-rtVg`&L#c)yd)?W{BD77 zUyJDdk_{Q#qLG@0FYV8!d6Wq+*x}uvup}K97@%7OJUz=L`pU;sSDO&D{~lq?g_oJr zeiu^K-lwW}5V}%VFyeTDr=Cq4Kn`kkvH8Kh0cmVmL1(3M?w_hR3X?a_$l0E_6&SUq zw=xDHZWjL%SWw~IoW}_qU=j=`_UEZ_lb| zqV=kVj-Jlx+;QAq#C#`|$tZD(As+Bo!&rJP3NH6(2Nx1`rlI51tmXzi&YqzdT00leSm4 zb|1hP!a2EFlVrvqdGBqG*X^KNiGh_>)(`0Dj}NXMmvvJb5>(i3gilv(wncvEzQ$az zy$N)Y3^CzVsIzMs6~n(ln@g3?+x?)k)g1>Cwi*n)kKGTf^b%_6aQ6+lA;%($0we2j zzvMMA1D-L-l+&w|xOu(d7AKVlGUct}qa&^MNgPq}{81lUK2)haOUJFnqQUG_?n}Z8 z%0W3FBQk}AX(yzndsxB{&=To=3%^M-lK3RgR5{s&BC5x}%e8V{u#gY_fdN z_PP;^8-9^Bq?Z*jB2$bIv8}qD|DM`Ve{NUmGTANq(>>=Kp`7Qe&JiXrWUN{oIe#`4 zZ=;UN0rZ46Ax^H!$grFseX97Pd=y-`zn#V;U;-Dy<1*=UUg57pNbpF4iTOK}67qT^ zTs*&$C^4l&v=Bt}qIX1`+O#4hXtd{HeY!BWyPT&rIJ=TH%)QRum-$bv*#3p)c4o*g zD4__oiMwhBpF*b2f$$X=L+_cqCFzjH7on_naZx7sc9?zj#{-F6S_aCg+WyU45wVXL ztn9YQRAj>8RcXZ+rE4X{!Se`nK}LVW`d@br>@Bo;m9g|2L1({tNJU)CtnQw%Xy5Xk zw?aH%!IDdKuCAvqZ=mb+oBL9S(YBc3CfIt{t#Ao<0kde&$oVhBFJx(CPv~E|2l#hG z3bE8=`v}Bw?Y@->m9bm3E#`4z7ROwkUGKmA>_n|c}7=;SdU^htNp zHyucAZ}_>jSYA)NaeXTDr%{J_-~K+a{-SwY_iu76|;g|)^uP{`6qAy*-e>v zY=X^g^ zW~V$Xq<%|)!8w&B123)x{?TQgu-iCcqR9Xqc_H-A1oUBHFKds#>gc|!%|E%DFNS#W zcFp)c+{j+Oj?eC29$!b z3x7^~olI8`ryTZo&yh)F#TJWOUGv-U+B#m;IhW)eLAMm+Iw8%-#j4+h7UO5foaU-ULah~me}Ei@2uj?7J{mp?4quq-I7*&f{m4RcjB)QN2Q*eEM7n>R zM2LJDXtK^sS6$VlI9ST`?Lp-->P?~sCo~zNg>4V_K8#ESrg>d&vDav*K=&WNjC0-l zl)A6W+_YL-%dQddcp$ihC2-T`=ZI(KXsr6mw~!eQ-@P2_kSP!I>qOnWlKSoRoNvKo z?AGBSoLcu!lS8e`NcPW_JjLCvnHjmw6xxX{hHXY3&tcOk1!bEe=QPIuR9VV3Eb$X9 z;eXrY+s3z&_E*&`bc-XK8c9Mbt4nl?7EP}4Ms`BEz3sP0WFCwD{_fG)GeY~17$|Y- zii{Bj7V~|pwL>bgT<0r8u!gIMUdU3^C3{_qpJ!U!I_2$3Iszz$G{EvDKw>SjnZ2hS zL;pLVK&R1!d9w{puqW~cfZksJ+V>r7H3ujiy&iir*xx5xP8VmA`}jJWq+l`s>Q8BZ zxm@o#Yy5*XH2tu7a_3aQ3)K<}!`7LCcWFxO*5XzQ2?_);{Laqq*;kl)q~zpD!v;Us zt18cZf!&0MmKP*IlE$2smM>MC%JuK$uJGHZ@>s1Ipqq*br)f5u>w$F|k?+cyTuIKK z1qS0>{;4fF`GBCW#y|}GX_CgKLQ)D>Rvb?JmF7+fRqY>iR7S^ucPus+^1~uqYPvb7 zLzPj|=*PD)6IBKTbP=h${t#8932gZ;D9x``d0@K404Ec!)3{hw{_`YEc0(e+)2KC= zDh*xOuBw)M29z$Rqc^=V)q-bT-VD?F^9{hsE6WJ==&X3AY&73Z+|P9%1rYKzD8H5N zR~K>0_Fphn93#e6@SIK;f>rQ@@YWmxH1G7h6=x9Iw$@w5D!PYAzaLIW6|){Lmm`NB zr7X#>gU=VfSW|IGXRj<>jb?SdJ}!B1el?nM<%s9JoH)e^xo^%hWA<1Y*YS(ReAu(W zNP9(TV^g2`IBSwKqhR@x7@R(Sv}^n#$t@SEr*&2`S#;-lfnV^+zloyTw<<>Sl^p?? zrvb?-I&|IRWv@LFYv{7*>+rTKZpcV?ll{@n+J=q0h_n!{Ro3tSqhK_v(J&ERb7FI2 zMpU*vU+VoI1GU$o4v^VNo`pB0%&b5?9jJJ6J(aVyg!MOyJ2IDH@pL@JFhL+qzkj=@XLw(S z7ciA=FosLT3easbp~6xQr8@ZOkI1>QhwBLcT9Wukr*#QAOAO?mkjzLcPaVuWRA&6= z(NA@S$XIOiel$`xn&CV-c6hAiV=KAcYE9DXTbWBwQP@Z@&w7aM9oK3X{8;ALs&Qs2 zueV}sF6Hc5JLMjjrX+Sr27<>PR(zXzx%@=*6>}8wbpPLp7h>BNwpF>|SYPfYb_~ByCoo0M1 z_W{lT)z{642oLC@dVbhsdu2ZCf#mM!Lo;k(D(;!>rm|AqG3TT6wmkYvH+)&w)*9lk zRlT6;Fk^1|z6N4=^aRW#)Qos zfs_Q?ac-lnQ+AA$Nn`#?pDQ7H<~A9*X}UK!ht$oz9t!^qqw^tK;92gG2ip+lIJM*0 z$ClyU?X#m@%JdBv%%s|eZ)siXgW86ugg~0X96K37N z3?+mwx}@S=j^Jn3TNn*m3%f~Ln$Ynr+HRT>oVcEIH*3RRf{Z+TdFY(!f1~v% z&3&%(O(G5mFO-r4or}y1;N&rH+xusU!D!SoGh57G9Q*Dm>*`iS?LmU_oeDV4T)rst zrrWG9h%4rzeRXLs+HE;}ZmO?dzOK(eyMH13*gBG$k*UKl^}K4wo-q45vql+7%qgqEn{<_!{vEG6M%SsPQeZz9o`9jKASJK5Hx9`6iV&AtLJB$ z65g6H@=-24Dx9$n8g-vLC?xC6AaYaT-sSn(`$MVPOO{>p9()5CK6XCN-?m|_fF6KR zDN!$6S+}|&HahcU5%o&+|3sDn_vW|5Jb!k6x^W4L%g_bT`0oVB)@eC=sju$%F*XgQ z-ffcGCC9Yrp0p+6(K@M`QYyuQsa~Hw+kq!rI${Op?yLd+sy;bu`I@rLx;X%At=W5BS zZ3{PSVL!+bSCtnSgo_<7J!n%M>DWFxKIjc+S-BFjxy~qf9@apec}9m}>|itpN7e3@ z?KT4M{>~am1-)jrxb-OsrR+m8-dNs8okKPi1bg4_9#%YHV$YMF8AcrKEDyhKm3bjNVrD`WwwyMWoR-2t9!DdpB~ET}67_!Ma@%bfI3REDg5 z0{;TYsrWSlM7GV4slCuvi^m#O54%70sGoVD{AuK3C`PMlB4=(L=f`QC@gn3)zV694 ztkDkyr2Un~>=$s4FG-5!eveN{{1XsQ{A<2CyF)hXYIkY{IW#!N`fRx*x=7cJdc_;u zJ87&ueNvdR;M+df2r*=2NnMyV{?i zfC~Y(^?QEM6~z~QT4F+{!><$vFtiimrNNoMJ=b)khBblqkcaZ-o zoF8bCcYzy~V<+xI?^SFW9B(lfOos_>pLMylAFQM931m#yvKy`n6%6-~dH7Cw!rww6 zL%pkca$W`Mi^*1U0QKYz-{-5(VtPpXk07B-f8-Nx-fll+Pxh?)v08O%0j?%|*WqfN zm{hvI^OnROY@#d#8#HOrCt025tRng$qKR#vn-0Cs(gW(|PpSs3(<(>U9IJE42Z96d z(7c?GlLrNEgx5`cS`PNUQgS1Qp&}D2O~=CqhCfmTR@^`POqg_BOL(AS%cf*m#=Ea) zeqou$-_r%q_4-onxNlZy6PfzJGjRma@BP=YpcTkgin)p|@&aIiHld zUAus92EDI+*%ME-C7w833ydl_5ks^V9jMa``*Ptpt**2=r+4267FxaT3Z)ie|fEt?-Nlts&P?pv5m2}omC>xHlm z8K46JHaeHf3wZ%pbf@q;11sIUl}^Om=Km z;DlyyhJ*2%#bdd|xtdGEC=bI<`>D!PY3-s##(GcdY#o-$JyVbfUi}pk)>$K{|EJ2Z zkAAvd`CCX`1fDvMN~hf)sx?Z zv)EFfoX0*0GEz-*?zkv@DUDF>dikGI@!+bW3{t)Vl+fFT8OO~ia?&M+E%(ZMf*=3W zY3~m52OJ%?kB~o_cTa|rmPa?hS%gom0NB4!^zB_-nEKtd)qeQ%ts<9E2PJE=erwBaFlsF_yh7QiRkx$-{=M$#o03Xc2WUrXDOa|><`>#37~Z^suy5k3b*C3 zKq3sAMNy$HE+H{enoe3-uYHPUvBNec9iB9~mX(!>ti*Cz>O&ygmvgWPXJe~{e#0a- z-)+$pXKqx)lIXLUtf!V+Qq%;g+RDZL37hoKwBuEDnPJ@xvB`h6(Wl-(grBT7THv6s z2+eqhktKCgpB$xSeyyQ0IvGI}^L#TwP40&xq_2*=Nl@B3R(ib>yV-KSM%~TaM)no$ z8rc$88(uXxB1S!w=-21M#4F^Ved$D(+K$7Z9--%oA2@M4Ta`H({9X z9oCB1RY1fy0EgrxIiYv*n6BDl_IsJUSvI$mxwO}!r6-l~d}GHQbuQp^;tFAjGoG^| zbPqpOV(3-GFXoAO=Unz`k^ltxC#(h=iDQ1+N7b|d-oUG@h-4sEcnA@BMcB7whE zN8-$11Z(;J+8%*PRBvvc`vwVU=GL*<%ay=0v5ItU?T)=u3aW?4+HK8d3~CgQo_4(l zLD%ZQdy!_;!96hqIEbSPTXsjDb=a zN5DU8Qkhj7F}T~K%qDxUDqtOhXZ^>*n<%&m`1S(x5gF+`J?^tzZa25FmYE?Tkze~+ zLe>erVY6V|ll+m3dcg7r!wPs9SlU(u)SyM0ne_OP)6bd*#-E-kxz}EQ_&2|eI}RC8 z=3kGBZ)ue3?=#$ecbi-YyCKlS@1%o3q9L+A6Ja>i?em&8OC-FMrV z;d+uWh%)J+CdA{`7ea5i7}$}3c}2H3$z&OVait_@p$x&SSV>IEc~&iMQQ`tUoBLw& z3N}}WQJnvpYB1cl-6ZNsaA*gv4IzbkH#5Xht5z?%9v12HKM0%f1Z}uU{$9$!`c$2m zF}POx;Ge+#O&%zvO%b~7r2%INdT^Hjc>^NtWed!IraB)iyd8B|2H4VlT+Ln@W(Y0> z$OSb8L}KB{yH7kPfjnP78#IX529CT!a6uZG^+uLN%y(LD!29eTZe;KWzTCHenltdi zRw*cCUPGyNN>ERiRyL$6n`HddAi1ml&)Sd^+MDf=e^tD<`Q93PRKeTkH;x>q))t9S z#`M9?_|RP~5AV#+J3TMVtm0B9P!P%4kN4R6)sf`R!YP#oXzVVQP7bA8TU>WOe2 ztlm11p{yPw^7Dt%se2bu(wsD&OEn{OaQZ#&-pC9aYr26YwJcvyw*BkaA9obuA^&xb zf8corO_AZ7X@>i+CPZC{5oH&hf`pNUyoy*j}P8Ws6VOeWKe_g5Snzl?>+eQHBb!Pp6Ng$x>;AY3K5Xl;3 zj5DwO*XK#E>T-;1yu>~Kve~T_cp+20)PuSf;ss{-YE0oF=>f*9AdVE6^9rk%Sq{}2 zSd*RZ^*c9gZYbpUpjScF#q`&)!Wy;Y{fG*b{?ZVH<|Dx9sV|4M}t0~2GM zT4y!?;bv^x_b)#_TR`EK7TS zTCrk1qTKb9?=bE+PfNb_V^DB|W(jq_W{Zt|{*!7!eW=ZtZ$4F6&8m~ntBoqz9ezc= zp0lRmzi|Q3p!E=Y|1)CbGo+gg{dYI7nVP#?Jf_B`bcT)NHjUw8pV8T2i#CR5YKb6% z@2=i8BhWXO4KF#-`CZgu^kx(I5ou_UXcZ#T^ndf_g8!R0w~^<~y;!pIX9?}^p0c%> zuGNsu^H%Zylt0Fceb*`-A;-6qJ$ubE9Sqm=w94&e&6-u+aZlE-|8qTQ|Ku;^Or#1? z*xG^j!{J=jJec3xU) zVNK@$51Iu62D{xezi@lecW}j=vNKQoR*O@0WKvZ&N(zr&A$*A|h#ke7w#aW5y(`dE zoh$1#bd#3{`dsD{Gpt1#iE0h=vSf&x58wfmEz)X9q_INj^&~B7Q!ucMMXiW8ONJjs z&)1WiShibc7mm4{u?>i}3(v^%*b8DAAWbpuutyCk?zF(S*vPo4Y0bDc2h>dCxYt6N^!*9AsZQO!tpk0{0;#gb&Kju=+12X0P?eGNuRS7+;OYpYgM~BLJ#!U%;Q%Zj zKe={yqAhsK()~A{ z%E+zC?$S7peI3m@)C4UIePQ~bx_4VRs{h=1QmYKWext{r>JcU(@e}m~Ld=k9;PgP_ zUhwq7TB~WyBrI(b=2GSfiCXybyKH71<=zs~`;p_*o4_9azG^_&RC8CZi$LBP#KH3@ z+w&zw1M8XlMRSZNrrIOSWhJd!`r)oBHp?9XGQ#gMq|V)M(t}fIt{yN*#T}`fC&0a& zS2NrZ(;Kc*9xfHl2&pRXO&MjaKYPCeiPL_RwY3dNWcl$%%C`>sy}t>!t|Z>Fr=_Wr zrJ}C|`bpID!f<#GO?Gd)7+*dA7Ahg;KbIi%EY8AJpLayD%p8&`4CV^5US}g|RQe7E zIvgRX-UqW>-aq?*muVU|@5wrkKDNcQ=^WDjOiTN$jza@+OSeNz7wPfY@@=?|M;t*W z>2kRv)uFT=z}6gl-XIX}#R?2Zd&m0r;9pVN09n<}GmI<(-U7{6Uj>ubS)`$F;UQ&k zXOa9JBm?eBFti!1=Bza>i#Dv0&Koq$@qHnC1L?keQlLqnoIEw@=lO+TnD=FKYaa>R z$d!51?C*GZ`7Y|6)YW3n3mR8tx*%6+iu%Rte>adO0$$C*LBvTRA)P;NLW%Q0yIAF; zKPE?G`19f$dFL_4p@HXxsYg%t-!oR|sEKgC9I^wa6<6@}wn;c={3b)Ee?L9_^&m|j zpOOm`NomcKkVXXzf%(b!vlHqk1X~V(WLDng>D>|(ut%+I$0ShnN1HKjiE>$ zwyfVj1sMyR@tW-B^84x_PD;s66QLT0tJ@TzHq zdqy)&tYO3Bf0v!uSL?{dQ=k{C2Hao6_?6;rPVI!l=L5emeecX|E`W12CfGOs&eoNl zC)EFOH-byUnRI(RylTyvd(hqWBgD$*z9H{1(}LV|T=WB}gtRfkn}}~vE6FV<;=QBm zcbnSHh2k97yORp)ewEJ9UThZ=LUf98xQW{zXfS&lDL{`J9%ekIb{p)yEv{jwaxCyb zZjzcB9q;^+@(6!kWAbb=b5&vzX!f}@uGK|5xc5^p(->vN$%@;}gO$uCtsLRkD z$H}BUQF~U?AQ0smErb01q=1XKAeK~0z9Ov+V2%V4Y<@JS0X8rGG#CKUumTyGnprUK z#_Vnp%pjbxlAr4&hi}r}V@Na(Gss4Z!LKwk-1Fmko*Avl=7oM-sy@`o&A4IJW(zp* zHn0p(#=Y}MEIs>M@c{r>JfQKX-xnyHXfg0C?S*etTK{zU7^Oe%Fz$9mIG0YFdT=_t z8^)J(sjpBCU*c?Kw#ua+4Z8!(2wx_Kz7Cgo&)PI`N;xb{z8P(fu9yhgV&kragFrT= z1Wr*{12}7OY(D+pVk9c}w2p;I<IQHf7L@i&1fEZxuxkuUDT{Pb4%uvhHOKsi8P34Aw8bubzFpVdimlI?{{3(k zV^`6?D75*RAloC}yQt%(HU*?XK>!P}=VbF0?+g$5mz;+J_@i0{Ylc_*dzHQI>DFKV zO60<>X2CAbE59H1ZK< z6bNALV4ySHi*W`eWVsR{4asD#zZ%+F1qxVv8p)qRH`Kb7AG_ zx>GrwH$5>m?e-#HgCb!okR`f+42Qaj+CwyF0Ldu4Hy^Lw;bw7$t**jDBYq|I_*{ua zN{p0|qkLhoJilThgJ30~8X#!puH6=E@0i@p~xO8sYuzUmXUB2k4UOKK#ibLecA z$;5IUvSzX(b#;aw^Hr3O;}n265|Fz|=W+y{wFOW5AlU12Q`;RQr90jx zCyca$&M*_^lil@AfACwk^{4bK1*|eg4Hr9_eH=#stU|FI&mz(Y9Y7S5oj@a(-|16N z>p91jT>!HRTbgHi(i>65-B|_cLvWXzUPmBb(0%#z(0E|!<9#{hTs-hSYiIm) z_N~whEsr?U9<`axpjL&70OXe|9^Nd@MeDE?+l$D3+E6;OYf~hOBo)9#deodXTD8OQ zG%JwDqjdNb!AkfNkl9<~68F?f$(4cYSB3v-N^aUps}{D_B4;FBek}2ebq|e^l@syJ zMPaj3nuFK-%Ex7QSGTzLa8LsEgg^OiLuxMC9%dVb1T!oMy!LmeU*k}|P6zHnN`zfq zg}JQ@{8&yzBEZbRe^)Oc>pOJyk`(KXz`9icX3OBvj%zf-A(>d9E@@DrMQ`a`2(v}~ zHvcIgGpVCA4+GLga6GeUt^Q~JrxcccL4AVICOlhV2kGM@QelqyiR2?bVXQ!RVmmtGmB=qo_09E7&)83{{KZPC0kJG?lvp6R~onEH+*hm)} zMVhyMI!)qOa>7AbhV#3ess^q-{zqYcv1LrC6RzTR;nE+*fk6-!ix3+Ebtnh?SkfOL zP`UNV`f*+e&%_?}!Edu1&5jDWQ_*4m(0|>M$y1DsXyZ=P#<#mygFnOE*pxdq{a=F}Fb(6o0%-ji(IQvoOrpee{|Io^; zhLY>n!rHb~6mEM(!|lKgC_dX{WLmXEf86|^NtXo;C_s0qO9s+SE!<=qN-O{}$C-nIC?)F&H zGXk3+lbLD7W*5*Z_=mB zYB*whLk0GrbAzZevM!~KY5P2NkoSKSf`Jib$2ug|9Sq+bRHVE@xn}mWRkSSq2@ew2 z3OP($A!X$g!u4*q{Hg9kjG;{g?hosVMwajPyuT>veR3K)TBh_oY;2K{piDk&u9gmJ zTw=Xl{u|)Oq_Ob&$i_7h)H3CqYpjSB2Hy)isdLnQEEFLUWL}N_c4ZN|IzOpY;K|dCD$|%Rt(B0xt&1yf`LdYw zzG8t6uD+3~3=CqZ|8_E=X$DXa>xR{055BfIL;vig37+}Ka(-(LodKRAagW%PxCx=Y z5J-t>`7z&swKZ*+jrl^qjW^9H=W6(t&rE_?D8PO<3k_Yj-Y+A_LtA zsI=(8&;sLk54ziA2*wow>Lv}4EZGXiK&TYGVEQFm95v)2R$J0f)w+9TPnZr|jSC@! zgEOFl`$lS?e)=kal!+!+isNB`fU^EcJF9bMTPA=v23hnisbsIP?ntUAn*7E^C^)Zg z4*8>%qDWkTydmzGP$0>cnAbxnD3lzzsa-MY`n1-C>-Y81u78YB18ph5YJnvcWMTs-hcpUi6C^(v)#QuKLQY<7K3CiwFNaC% zYwH{v|(ofzqaVi)38sC9R=OVUJ-5nhRed;#9%LovjOa>%;w-Si3Ox`|9FNU5$$ zQX@S|w6ughDUA1H1-WE{>?_Q}owg_VPwoF!JlI|7nMj%s-fVwwqGW_9BTVe-X9ZOm z{G;^``>$C#^R;BGS*7y5Wgy_bC1&2;j5W7PHA?AmRFB-7 z=ohBzu?*@XqUx=_EcCeQ!TNu+apMUtt0dt7h-tEcacxH4q{DK<_HZE6kPjDMR5okd zqT{r^EW69kwS+ul9!CE~siR$Q7{Pf>AXG`S9LT(K>^j1rvmm`@xVyxRAzjV>+u=^n zW(aRKdPd-~Y5vbDFv(Zx^cU>bOwXHoQ108@W^c>H_zxwee$`e`c!I94Oqgl(2iYuW zo{rk}wcM<4QCE%yn8Upw;2(Ts7WTijDmj*vox25}B+X|dfc>+P^ zj8M~m!LzRB#D6N#bA;4u=G@DP;=k=E5_zSwT12(8qa7S5J0JhKlrXpwk?_^$jf1jN zLsPhj=cyzJZZW4hRx|)7kB>P;WfVAjUfGrrHNhIaxR9j_mL*C-ZVrxIhmraAETy_B zuvxj^gn;k{CP1?7)@0=OWukm&yLbhybtm_q(6-v@HH7R z58|`)B|SQHNcLZWFhW@U+}g$L*wEj?W`gJ|5>|^%W|&rPiC~!!ze64)Ne_vDb4Z7> zs~zh5(~}Fx7QvxTJ=+Wk>AP-MD!QG5<*8Q43M#&bje7FwydBZXMZrBH!~UW|q2}nS zG!TJK7^aSOmj$O?PUL&(c~t$`8d3-`{9*SbBVezcvNr7dl+7o`+99-p+gv(MwsgpW5ygOt_LZoPj$(qx zqI$8Q!*(=^&7sXaUH}kn7|EN)ZxNX3$xBVkrVv)9pKG-`|NJVMo`d$!L0q-1#UT=gBDc`rSMRf z79a6@f#`C|aMWo(wq# zOuK*;P2wpZGZkN(IYaCIM?ujVzG|g3GNG2HUlUiKsy`906FBl4PicZ@FYDcPnJL$x z$?5S2Gb-C(v!Wi(hC3jWxy5dUBF?jp^Hi@h9S#@2vzMQ9Sctrhulr{cpey6ts2mP) zuG-kjHcS7oT%w;)W951fe4?a{Kib37G;Sw}net>x?q0B5YWIMv_At3M+)GePF&U=v z;Dp)Efc6=1=_L(lX?)@?hcDn0U*q!b^Te0TmzRcxn1NP-h2PilcGMeFH)KdSnXulY zgywJJauL#t&cTeH;X8NSK}RSPysdUE7}&R<_+Pf95E?#2Ne5n3ngt7l>%>?;i? zgHMOVxJ=@U%2nR~*2F&jccWP0RdF2eaF((dy8xgQ197Rz+D*uKH4uY4R*-Nz$X(KN z&WhyX0%qj*`YwrO*H0_8LX@rX21(~+hvD1hd;d;&A{Tr7uJS8%D73Gm-G4-2en%C6 z8gjL7mawE6UV`r9`OeA?+q)FaToEE%(zljlPv8mEApwV@@oryJFTcvVdS7p>u37K zd)Zs`7YL%R%Q0D)c*^ULAvF;2Kuw^CI^t}iW^Cv0@^wq5`;5|$>tbc+-SDXYgb-2t zLQwAH139T>a(Zh>`5{Rf0(%5E7ka&_9;NK{~w+?_BMiO;f8Yd5g z=0l_zj%wd^FP08|rfUG69_&#Pg9F0P%wjB<_G~kE&Bb`;2LU2TnXWI1g8%~@n9Uv> zvDJt$y3P$zUV*U>VU)_pXBRc*A~%{jrkC*mx{bzOszPeX{L**DNlE+3O|9i8L2#d- zykusr$3+K=i|Tvyi0-AR_QxkBKX&UVg zr?Fmi7AGemk1jOQZWX7m@!g_~wewxe{nLV227Tov_#gJ7b#sZhO}5IP@u&h1Yq9HE z>dw(`VsqO;DbqP?8jo5^?v;6uN2zh3INMn}1H8ZY9Wup=P_Gu;)$Hj6W|vNW{_Y?9 zc!u8@qqi6?2|u##eU}`ksOO*6O?sS<85-HQ6$uRCr1D|3?2L*#{k@16A5X+Zbtg!un^ z(teqd=1F1y;MI=OF5nkJb~0`=URuFRt(vBU>qgYugl^Eh$JP^jSrV=7QOp2b3g_$V zkmM#g;haC|oWJ+?qz}51wU6Z3%#qBp@Nz>4k(Qdwj;bFSngujn-fa&Qv*#-aUijsA zIZ=mgq*Ru+MCW3iy=Zmv?A$FX1jbH?)9n*z0y3UI4i~@u^;6gZb3r9rMcD@*BDu@9 z>0Vf!_p^-u7(LURbu9*bF4`V^0pcolM%agM;0|W8UoKAe3Z_h}QAvYl(0fhod%F%s zWj6|6KcIWfMM;08^Hu!5y(P|s{PY5a$c()kJqtB5V}aJ2XGQk)&Y+%#3LIO@bzwLbvqKgHs9W8wgT#CCIUaojTT zoh=h|p0bGYT2Y_&h#Xp}-eBDb}RXyodrWUCHBNQ6xY>DcTgzPyj91K2sgd z5mmB2DllTBOlZ;7V*?3^e8;u%U#a2!qs#Z7HPtpvWloGZW%+n@+$-1W3odgNO6G@{*n>q-`X`$nYi~iU*jr)-;q%M)|K$HDk8&LMkvnP+A=@-bHrP7jopj$**i}O#uj%!X`hXOs5_D=avU(|H^&4 z;XDy?tw)#ZB>c;YwMUa*gWv?@*FS%4vGwW^$%PpfYeq6zJNZp206Hpric01@2ECbm zVks^EcKPn3DykNcDLY>sesI|2-t>EW!){b_A!!v@2Z%y<0;`3Ha%wex^QD0+@#x>i z1o+Ts6AGTjkgDAne5` zZN{~`?FRRiz^(>8ww1^yG6Pq`mCc5qW)r#6jAsJM+E#tB%;a@WkS4D=SnVNmq`cC@ zVvkXHDmfQ0#&4n9!)1a`S3l8$5uK*0P$Lh&SDEPQdn&*j1|2EZ$@{%Kxx!bMnWkZ; zkfzo6asf z45!BY537l5N`hy=ippGEjegWwzWf(dshL&>DSSZ|Hp_A%q|_7)7o6;lK}*yq|H$zi z6uJ)xX}Ps+E>LN-8o#I!qp39;+uku-2meZB$0lJ)=H~~+PNW7{!4ZTMJkSt5CbKV` zntROzO0gpfFu$8RGpTVCwcNKq`UG!B>|DQlISy}QzaVK2+xF#9#V|>;*@C&1I)_#B zN4V^$5tZBp^_wJ7FQxEq1A;wEUwMw+&&~_9>=ZyN;@H@A=L@qT;@@5qsqjx5hwSD4 za(Kgi13* z=IQ_*@oNvHL_of77`KTtGLl`oFz8!kfC0dqx9}T8ZiAE0)uk1Qh-DOKeBF7-h{C%`?88w*&izD;0~1Mg$$OH(xa=rlIInybk+ z8DnQT-cZ)@C{87)JZrlAGj*xcw(KVhojFN~&Qy?UkTkG~%DdTF36{K>Eh!W)JksHfP}_7|mwv&&&!GU0sckuOdMLK&*GNnIQ>*&-#YbI@ zTC;C%;yW7DsjyE6Q#k?pGQ!Y0CzHr}uQLCXR<*n0C-Y814@UExo2L!~>J7j!&=-(I<9g6dKZa|4-#|cNzFfJ3KGLEUK zvTiE}?%1%a;j_5Mij^y;=n1ro2^?APQCx4xp6*!o!5u`TtEXuRvlpypJ6tHOFo!UA zXWdJ<%l2OPUpPm=|E%9W?dQ3htqXs$?9O8n{5|Kj9hm>jw6hsW6`d73L#(Rfa;!1j zwloR?L3q8EoB(Kl*kScw1ZB?5nli8Gq$I zn-cN71(g(+YU%ZlY?62Pc|*cltg3>GKrSxun|1O*K&Q1O$aqiU>gl4U*=TpkqFTjg znQY41^(4Q_Cb3%y4NNntpV^)cPTL?9C*8$*g$t-{RXEmQZJ4+#-y7(MFwgk;xAp*%Dm4p8wTc>D}jhgvG)3{Xc~mZYTuU zk$E0PT=9LAVmdj{ci}zqU|#W{QcoS$K|&MEZ0{pBL^nYx3#=}(bu*vrNo=e5ct=9r7}^Co`~Xv zWy*A}J&-8Li$xyTCJz&gq3Vp^6e8i~DekK7gLg9nJH+j~toXf5tVq~Ff3BLCS~g!KE6lZrY(mdI%+&o4T|9~lth=G%{I$H!gIr>rhM ze(y6JBe%TU8GO8+(yM2=3C!eH$&mh}{`3cmYC)lh0;oOOo%@7A{MIgc**WwU*!?MT zUSOE1$uuue`gsFs$wesIJiWC1kIc}%^!P@1GuDTD{3qmNpKRn(9&YV#X5E`L6{vm; zqEjFYQniL&s1<~9^|0^xOi&gUJ@U67SL)!R?HP-cI8TKcV!Z!U^cdiuXLK29n|K>n z<~XE5+UrJ2X0|k!T&uP|eV3NkIR7L#=I^VW;^KH@o(qA{PPQK0H}dx%C$$=X-oIVC zkn(~mv?4!S4L-OlHx**Ic;HeBnXONpjjU-DV8Qj=;Aij6(cz~}Vh`tsnRXvM=9PAz{l)gKCJ&k1 zaFCYw_XtF7zvErZKL@QW-thEO%w#Hay%p}mv3>LDVp=)-3q-ewGYH%7DdF7VqjG3sx9#S^&53pkqF_IE*p824D4uy zm1E1<=^>?=oaTAn<^gfDVS=_%IK2QdFeevDpF)Z>*HfkYOD{Mpf!;u;w+i9yr>(Z( zXXvpL1y>Ej72ICoY{hW8?~A@dQ=3d@Mi_h4p0~-J2u0}=_Tq?9! zRE7tsxbU)2@I*NgzXRPZm=~N<8F%{QT*bE1?9L6sT^I4c!O7W9=>^crSdtRpfdGU* zy%b72N5<2LpK;dQj@{q6d>~o*htqmBL(a2HrV9`%bk+ym*}C-Xw)?h%>l6|U9&And zwNERxfZlyMA^C7oBI7sb1dV5Nso!iE+&xm(A2q?HiHjE!+bo z7Q8*vC^fA>?f@Y5nr>z7+FsHM6QTOVv|L6LnJ8Y52ig{$%(LdE>!O^i zYwKl1<7Lq+MD3sJtTA>xxbpae`RrV)b76LhJ8s*HAmN@rKGoQR@PiY9+B$U2k89K>?2 zkTbLN5hfTf17#RsY$z{1f-C!04&$b07e6IBE(}+1!=fSsAjf;>7r+S$r8Cl{@u8R`F-x=-$6A zqDr%k585DV3DF(}5gw*4a=0Is7|X(TNaNrBgzB+bu0EI z#IU8yxl1-T#ReIs4MuCSa|Oqlhh8fDy#Pf#7ZWQpi19PIO%C**-vq%!!oDrW@ z2&TW-dM*b`!XjnM(BABs*OtS^r|{V`C1mh&S0^&z9A+tMF3@MJAhlpxRx0fp7kLR) zkojaRr0Mv-7lFFV`&;Hu;+|O2*i1W>oHzY|WFRVStw%RWBA=G-Lwl{7woc)Gn!alrHk0=?{T(*TIdl|Z#U#N9 zy>`TsMD@+Q_B0m?AVgi)UW31kbzd$K2Q2y07hBZUT7zusS= zMvdr)he+B>INvj_aqKHwaVZ zjERI?mcbD>tUU4@>S22lwK!i@B`@Ds0GKIpjoQ#h=a*M<3zxc}P+1O((dB}i3yb}B zR<@UIT2D)T)!UJMcF|i}O1F1dC>=Q` zS?aGyW(&40feL#aK6Q!CIEHCAO@U>G=iM9px=BFuq>K5Ly{8L1ZEW#X@T~c^;d;bC zy1^*%8QyJKL1$7}Vsl+?B*QiBVy>#%V-EDDDnrR*4)7+sO@sr{aqzuP_S;J;&uP==;MDmGU!Ie;F;fiMbGH*O;B!<5vuI!|)m<9~?3z*!~i zEc68-w`i*l-&cq4{XUR+`xG%Dr0#hd;Zk>4GB0nX{5MDsWzbL3fNa=Hv*~x(&LS!> z9~dSMrpfspFa8iXBHoK99Aln!bVURBKhw?yEnqEtdtR0;Qi!>K-4M zYhC&hymfH@k#*Lm9ikzq)ee3H%bDb9Yg^}J6BBNESfgofHuy2;wy3$rrJcRO0#|a! zyT;M3#o6EUr%gu>6-w=`YI8!u><0(3cB(dqquXtTeG~E(Q>qp3YTmJ!JIRBF|63~s z^(-(1l8z@Z<(EO0`Qt$w;TytKgL6}=^JV~>%*l}n?x02QsUMGmw_CInvPZJ1e+xNC@-txP01od zjBDNX2?MbBIH5lVz2^27jUZ<_YDnT?Yq}av8MLdP+}Ip0mFEoa0#(zMQ(bhc8=cbS zCB0e-T+};U_?`aQ=(fDeJAdij9V#Nv6gmqKkNrIGtj$SN7Fs%Yv@J8}gXr3HzGjEM zpYV{YQ8a5Bh-IXMGes~V#5NZ?JfFFW?!awk zUHH9hHd=n+162`@Gfion_jPLVkKan!@}{K1;T+mN(v6YQ93{rw>KrXsC?mW>hY=J(2u|WBp9#> zC2uL7nX+}X5E5LDoT4qP$Q6NlXl38Q}n6*(@) zrviU7-L{z_nlbV>*q^2Qpt6-pv5t`>!=BWN@C_C< z(Q>^{i4C8&U3T&oxGgmDdw{#2G-Etb*9uNjm-zt_P=Bn{=T_^`=1MJR4j&E0lRSS| z_LalA$O-EHe`K%56r-*{9f2bsv{IgpvGtiYwCPgouqpkIuZ>d2QL2hgVvyr?Oj^w3R= z--f@byUIP;6si;Iw+=9z$i|Js9+L--u`ec=ySe2)^UGFq$WU$1O5HL8>K9I9FUo~` z^66(kfmG&ClS%xi7$x^hRi7XnZu{j>F{mlJFC&Tn$M19VY`nt^Aa8|76hZLuZlYrZP+t|iB zeBkAfh6|_`6s^*M2x3dlVfU2{8+ptzY^j-Hn)f@h@Q$W~Krt?RkGZI~2&&U)|J>dy zq4#Cmpu4daDMEMa%y?l=Wf#$E7VH9 zE0S{zXrspr>)c5dApd5S*o@CM z)&crPPC@??o4axgsM*m`GB&U% zXQa}6XDZ1sXC5u#8_eRoy!Yz1*3Z&EFpfb7o^a2Y2Q0PRRZXGHG*uywVV+tY=t?7> zu*nL_P3<?S!|42;2g-E;7gv8j~-&$kZFzc_|=gitS$Epq4WeABK^WHUw{g z*!#H2ij?KstMzZ?%tov$Pb$Et*@U&F)<F}_;lRD#K&?;xtXkVfeja8Y*t`n zc95}zj?wv@m=U+68=p8AUpuHltvewiPfM36IXRbX*EY3aM6DchgOYq};&{0k*uKcz z^in#gTmr;kC$(p3eJ|AP;B}UZgtGi5EXxE(4Di2Bi*ZX{p(RDBCzar(d>I^wA9araW zt3ZCJsTOlkxtVmoz>ui@>{u~VzjtGE67tV5N9CCQZ~_rln_gz;vM}80JWxC1lhE$H zz%W5uk?S;dv^U52!;S9MD-J*Hy($U~BE zK~B#Dc@;tfUgC_Vc9s;%eCI5KJh;KhF%IDCj0mjC#7ZSsZThYs=1CIxxn=P}mLsO0*Dx<#uT`ZU!SW;|6!T=pHS zE^4hNC*P~l_ovNXQ}wrq)*3>6eOveMyktGA=o{{SC>sz&M&ysZe&3h8h;oBTc`8e2OtV}4c9Yt=nvk@2Oz^#(z~X~roJ zgc`X&h4Kitzbm7+WZ7)>PkayC7N38pPFSKS zcPswwmvK+FdMFwWFF31VaDWJjfIIu;EAyvC%!J&uc?^;=iWb4;Ce0BC4cjMEO6B5YIp`{t_x z6iPO_VtjR}SzbtycAMz1=b-Rw%FB0)7u_G~wEPb1@Y8tx263lXfqvTKRBatyRs~Ik;o{au6C=qZ?53L|J@YTRY@I zVsT-iAO__+rU7#G@5@4&PWwvLu>&OaCM1eHS=9cO^v%=0&UaYRZMgsEYDqyr?Nn;q zc1F6dOcCUF#X1q0BH$NdH<8HkHZ%DkXJdgEM?LM7Jnt=HstdbiQY7j698w}bkHc>~?r37=(UHchcEPi2-SOvZTUn%F(<>R;hK*=F z^@x27_M9Nql$NeR_pBHAjAZ)N_IjsO%4PVp%A zMos}>X)~1gj#xE)laJ(}TC>{EGwRD?$hsd(87F7hJGNv^xAf{AD_aL#^D6rn`HckS zq`a#jU?x)BkFBQvkA?3^L5MXp_Le_ScTBy_`_#(wyTKnC>@)Va4D{bwIUW~T*6F8k zeOvg-UfP4w@-$av+StMRI(s@=t_}O`N|vj=7hXYXR>_!N+^r@x2}cFeSakeb^zqXd z?|Q?ayLw_9@TjiYf&Tuj{X*w-{yBmodq1}s%1D<6odTON2A-PWG#}iGt`@NM#;rU;3)_Yk zN3{*bkYf7wC1~>lr2`_z&Dv}v5BIMJw#gFN z3`m>U+q;(V97Iymi}HFb60iYsAT^%kwUPx|p#YSFrI~&jltXs64rW4;83ihyoaXD8 zT0@bAmzXR9BF2;YdD!8HVoW{B?{mtfod1ZEGe*x|`M!p;O}rLfe(^!&PblcVrKq9m z(O9N&Rdg9z!dhy1k2|f=ekKpCn|h}{j&goc1P1;?u*Z#GKcJlrE9hSQfLx1$=C>q) zuz?+Qc$+*YC+7Z2BGJ@ffzh`wE0t2O78|x|a3uLKujR!@ZCY%ee z^F*~g9WLV?lVE`jTi$8&G%K5Lcv|1TV{|O{XIyHFUM|LuQ8u7390JqR9o7MdqnQ~S(u86Heb-6;y+0eqM}1L&=SfL7gpiV*hFKj`E7 zP9?RyxM*PLf@A&VE)n)Ynf$wO<4;eH+E-C>g3fI*Akj9s7bys==s z`nB1F2@M+tGNv0=RZo^pS=Tg@*ZtY1b;%OJRb;OOymUN~^K3wV`a$n-0K0FmKl?m} zDdxAJK8~#N*RBA#sC&oVr@ou7XSrc#@d1VLFXTBuZ=1X%*|HHpRTiCnW#2?dfGnBCVKtEKsd?r zO5Faq9I%zeaVh4LU%Nea98pDr&ez<(8=fQ#glAp^OQTeAwmzURe^whLfC-Lq_q z_3&lE|9{{AZi9U#-gIV{}Is6m+juFA@LS4?^NYO1@IyLxTMW2KzX;-KPD?7*y zCutR)>M+Ey;zAvcDC?1)tk`s1rUhspGa{Cd3Z^?+7_J(K5MZRE#sHeuX@Dsa-VAc` zaWjEG@^PCzIc)KG6?ei!8d_wf+(bK3i;%*1o$c4Q0oI2yZ2SiWFp89!@_>?g}WxEq2`_baXsC zQhE9T^(Ny{Fep3gDcY&&oy|zoK;%MLGvbtoP%RQ(3*2Sz5A$LFo(k8O++3S%;OV=_ zDlqu2yY1GT+I*>LhbIE@JQ#W8p~xLCei`GV0O`&t*)|qT!VXA}=t}@IcLv@xHGxn< z8mLYX@ZD>6GeV$l{7WR4au3C9^}vhkq5P?VjDFhPk|Uwi$-ge*-;i~3A1j6%jC1N@ z-!u8`ag==eA$zqlL}FWv>Rks~FO54r)sst78Pt5mAeZhiVY4iHSQgn+eEN&3klhDE zB2eg{YnjLQn$|X(-3=1lRd%uzlQNf451Yog4G%l%63JCM6eXifQ*)e?Kb#d3HL`aB z^dy5r%pV5R!f<&JPr9P&%0n)A@)t1IX~xF!EO$_OBV}o!&sqD6 zL9n~C@1yUEKIvXEi0(zEA|)P+;D3m*VZ!r`kOK+8SKORw6P)f>Bra@Mpm)%|LhmEq zJ(90Wcc&5q&U%=xmK5zUkh*8MD&cseRKS}BVJ;Q-XSP2J4AjQu=T${Kcu~GB(6O%Q zu?}VO57;QFfvjD`nb{yJI(~JBS)QTjPBhQVqFz_eR)$$uh#0ms;T5JxV1_?3+FQy? zUL!useLhHmy&mJCWbh^vu3>6M{QF*&*e;#EZAS89BG0voqPJ8go}pCKw={0^b%T z4Rl-oOb8kBmmteuNWlQxDbjTdCKhr2Y1=FMi?x+?_3&`xNMlWWH4!l`IbT-NvDUVn zh`b?*A{7$P@16V>L#5}G%!Uq#@=JsW*hXf}$A3ntEIeW(t*PCxDpSFni;XXx62;ek zdhGJ6ySzEtdUZeJx8KFM5o`9EjB%WSd%!kJ39)eN70v5;l;4Ds*1IM##HSwP)bCzks9zoB#t=uR zlTtgEpVVzv{2WTU$nnQlE4MI1w6|#v=n1lmZ~Ddd9k1+4R(ehm9?SzoyOL@OEP}vI z8!`*;%6_Oq4NaW3 zelNV#>)Cf)zWjyHR*RMMmDh4XN{9DXh9`X*nMh%fj^KWHy3+SQvjOzuO}DZv{>FPs zm+36S16Slsf``5X67!NUJyMdNXrE#LmlIAcsNi}e7YVIKg#Wta$UYEWy&RB*8ad6Jh>!ZuMspE1YnmR>o?_s-_=%OoF;0Y&%a!k zaGJO+l*{%O5?Cy?m7b_{&G?!fEI1o_u)nvmc8_$ukTL)U4RV@jF)?g-tFRfjh7TBG z^koZZ_{;h0BSk!)yx#M55|$qn_D=G^#5jGI%`XW_YB@F*d6u9Lm^tMxCsF$8jxVDU z#~^6UaTl8(FnrI>D;m^~HrQGq*is`}6J_4u0IF;|Pr)9Gt+Pyyiku`a;w7snO zew!%b_)zM|xnSEr*qr1ZBcyk>-f7_sgxKk5T>Tky|3e(D5KqI)L{YPy2fT0I%iSHe zebT9!ES1eQKXa;3c$#^YNPL1F{@Qq)?DtmcjQSq$^+y&&&z_G$L8UKv{ryOfI5{T_ z)Yq)kosE?4a%SJEvY#!C6fs};P*(Y3TcE$DpBi!Bp`GPS!%g+ z06HXA9E=oo2sS5yX96t|Gw4nb3+(Y$V_lkjrkqxTkxgb5GuctFxxq4s#zB!`f^F)0 z;k_ZJn+$PhFMHbmGz!-m+(JVCwaYykwMVwNt4e%@4&}KCjK_%BKcjlac;@{3KQeJR z)AuA<;e43}#RyN^G2^un@q*MsWZLG9UfvBE&e~ZbD=u(a7`n;I(Yls%aA0nN72(*D z9ZE;OsyD$DE8@+6H%Be$hx-09nlm+f*cthrb{akJ$|;s97!;_NX3t%_-8w+*=jqV& zZGu%(W@3=G*UAQ67)jKm0pFSFqm_l`MQo=lA*$^mIJ5sDFv$l1Khd9%^ky}u=aSq8 zRWnChCTKu}^+9653@h}?jQqKE-$m}e%SrA@uW&TJb#{5^Eq<~Ig0j2GyBB%1NH;S` zdsvm((sHt&U5gG++cB+cH0+(FmqCb(A9o>V2j@JF%kXiv_MGOjv|qSQGuf8!{lZO7 z5aq{L#+%fC&+)Hit-Y2EwFf`y!{kjf|2iqBr`Sm_Cm>a-!-V>fTJaZo@ zZmV5~k60Zq{VuU=p-cZ#|36WQ&iSG(F-;)y>iWXk41X6AGmjJSt0} za1gOH8*rocFtlV(X;yKH2leTZT!micgCZnHwM{hhhNsK2=%=y+u3)C9;_u#ZJfR-# z>hJ%C4w_FLQ=55VtVT<39Ym%+H+g?rAsYM6b`ea9DnBE&bfC*DpJ$GSSS{~IyW+Ie zFLef=UuC+`Ivd&h!BTj`wZ6p}l!~2{-1o_LT_x7^!N&S_<3xShza%@ zBT1|?i>32^oL!~RH?>nO%oPb@t+T%^Dp8;BF8ymK&Sg#Z&l76%^sFIGx-NvSGwYuj zu6jDTSyeJ6`kowXo1X8f5%Q8Z7!7zzy(^TpmLMtl9%s^fAlTaj{G+!4JoKh zO!SuM7|Ap_^q5FD`vU1R1Y_`%(6Dt9R14o z{v2W(>mz}0p?6P2W~xt9CSdmoRZR7b$zWDP!Efm@Og&J29AhhO6WBL@h<@KJh+&Sx zv^6naMAL7T?Lt*qlFPPQ@%P72L!;f{;y}m6U}W|^4}!dB-hgwNbp*8QQ+?0el|Va; z0cz1i(DUa$P4|A;)9i1%D~=~gJ#q&(w+|`D*T4N#eX^A$N_uqY&YoH6;AF;g{~k7s z77&%YaW#uAd`5{o@!Hz-JzoE{z*g0`wFx0Tl-7Dx{zrBvb8@J>NV!gkl|PoaG21eL z)650q#oMS|pPo;lBSssRTV+YJ##gslf-czDanJXr$Pr|h3{efV21dG?T@TY-=#_4# zB}dr}ImXpV>{5E&c)hwZf~K>)t*ki9A$|Cw{Od)Rp%S%|z3Mx&qC89$3c`&*L7t)P z0g5mTpelNi4goM7dtxtf8QxJ6oydK1VK96V9_}Q8VXTi!@_r;1dWW%iX;*K7gqRlN(0y)- zAPtAD*2=T**466iq@@c@u#1hwSnHdME{TS8U~<;;_{aqREIo@nb1*ZfMrav2<)&?a zg!c=gz&`!7?WvpAO&?d!L7mYA-TIDqj8R7-SiL|iKv32rLV)+P!O6+y?t&GElls#b^_a_pYFLvfM@;OxQ2@Vl#iHWnt#wt&XtAYw!$stp-+u z4ANX}%)aULV>No8S%XcE6h-Kh(Iu1K0>Dn<+ErcC;}#Y|sjGzOzqo-{{dA;mdQyDj zO*xRV@^yGC(iwg2Z$9a68r8)mKPP2E(FFzX3*#mJ= zU~d6uu?&-5E(@<%vO%b!0lP7&HkwZYwds@-mz&H(!}7?IDU6G*R4FclP$mKHh*#MS z4^@1kfkSmB%T88Pf^8QJWF8b_6EB&#VUoN5kpZC0q;l<9^)_SBcMrLr+>3Mw6;uo^6vMzO`BdV+HVV>|R~Ar{{))erW{D)v}zyNH&eU1B`|cIknS&smn?U z{(^a1I!D@fmY<`SO^yCa;92(>B5;QpqB8HE*|`;(XQt~~ZS3c*9w%VZOytxQHR&JW zj<-LH-o<4HR{cko8kka;8@5b2vSPO$lbZ}op=~QU6({XX*H%5w5QQQV&g9oq7q9E9 z8!zc%snBkIAq^b6)9%KCaue+?6#HL&F(e^#LmCVc}x|a!$Os@!r|gi(GBjv z(zA$_%}lnf|461{ej`6=KXs=2G)+@2S525XUbRJkzouGaK|0)(5%P)dD(_i!Eb_4K zOkQi5qX2Rs6k$jrLep#+`beUuFEt*Vc+V>`!VJ(;OQ` z<--bCoB#s?z1@u0?B;s{AU)KF^Vc9Z;$WnzwO+ST!1)$P8~XYx7RsCy)rP}d*rrR3pH*YZ(dB} zeDBEb4ZnT`RV1l^Y9|LwP!EEA2?*1Zw>2WR$G>WF`|Cz9e3=*^P)g#5KdcV?*Xm5z z`Vknza`2$qffdHUuENzhkz_5+%bi&4HrT~iSRHTL-@J$%}qZ{6XzW`uUTpOTyCzCq!&>jWH#BR1f1ihDrGvm}CP_7bpZt zCFbL=GgTu^lvaLj5bl$abvUB z-DkVoTB=koJ{IRBJUH-sHr!6nDFZ{232v__9%+Ej#(nVZ5rQ z4EC+VXh_O%Eu{E+sG-`ZYc;gD9I`dJ2VPWK0!9UrlThU;-3;~yUJPa`{TQ=1sgc`? z0}AvdS+9wAdU5cuS~-XxP+S9bct*1(gJ^6KA!>~r@4exWwXE!55FKU@bXvNvkSTJ0P5@B!t6#&eZL@b4@2)m~OJl!- zTmiZ@o#_zVp~5Uu*`7aKJ3Wt?5PRWZ;R8b9XY#<=Vy!)`ym{I&AFsv5^>V&T8M%_| zZ`!A>-g<$QJ|u7QeU0M&I(51HjYb14s=w(T@b%jINaJ+cp6 zrza;mfC#3IBxut4jW*P=k8F>( zO0m+pmbFE1>zI+yBDVQajn%_P>BjAie3MBHy6KIZ#- z7dX^p)>?*GW> zJkEj--Un2hDc9z4@aQB@!bR)mE|yC|o+_C-Ljf1&a@F0|H>l2o;dGbxob6!9o!HM;v08bQ()Cn{N&!(}12WNW_h48rpYW{T&XpIxu1=S3E8hIS-6QF9 z&(-OFa=s8(=?(yE;sKE!V1=jl!Zm?Zn^OybYSa%1_#^}+u^M>Wo>cib<8>u4(WJ^! zMfiqen*zp9De$P*zhYk#Qx6b$56f@7;?-SV9m8DTUQrX)QMYy;IC3WSOJoTXeDf9a z%k2^{_PF6w`+Xh5jo1ZEMO7L{3_Vv^k2WY{5vQ#cvxrL~Q~>E`doN=oev)WB4wtRh zcgZiIMBr6=(`$TG`vT|G3E&<9(|r*$l;p}_copCC=07rxMS-U1-Er9@e$+?0@~ogH z)M*(G{udDZAK3$#5L6rwYsMwZaR8JXs>kHvbUWoM>H#)#R{p+gEth;juLW0xv+P5- z>rKhc>*#Of0PTitDN>4bPvOMj0oS`Vux-AEFF@4E0qFN)rS$GzE}`NGd+_y|%MM6> zY(oE?leK=r@wl+EwE>@1N-;C1PWc-dmsdH9Vm#90&SK*Ib-RISRn%dD{VD|eEh9k=@7{fFK#@>dAMQ+Qm*^}(7c z+7sLQl?@#MBO^pDOSo@sk)}kN?K(e&Sye9Tl&mdlpE_Qhe6Nlt+<&?kR->;XaA534 zJ84#|)@lcE?l6NWk7rt*EpE?-Ra>rP(i=@h%@}XfIwVU$z!2HL_wT3XeW?~#3wPBc zy8!HZU&;}mT>XYV!FT*^0pJ<;a6KfDT5fCTinqTU{2sSgTG>>imAfhbPpfRZP^+I5 z8J=ExpXmo~9(Ef~#Y`Voo zyDWBO(7@2?=*+Ciz@XdO8;NSf`)7~Cp;Ia0iZs{5B+UvYMzkS>VmVa)mSbBf2_kBf zpMyv@dx`{;F|YNOe~5Id`#rbN4`z%$V1(R%HLg;Bdm@yKcoEzzT>Di?`5zt6j!=Vi(6z>~$VKZeA4GxXJ^Oyw1KA#tO z%l6JL^4B>@0gugQKL&igzC+-`g6N2n1n>OqEJ1>G&bDl8q=Bm5*T$zf~8Jk(ZNx$IR8u4#q z@29`2iD46e+@X=-5Xc*a0>QsbAVDn4C$sf~e&Kt!7oD`ow{@gbUCVq#R8X1l1=~xR zS3Pqjd_?fD8t>;2Z$whr|8aHR-)#8r|JJH%DLRazq^(uEHnrNST@OPiz_=|M^DW|4 z40{8OhW4Lb6tLr8%Ax8$Ju&zRCQR2#@g%Q>rvC^ye;W|~b^)nf>-GJDY1XuoOa;hjpml0!MC39tlu9kG zUs;FzMzMZQDR^1GXTfv+16}hJ*$1e%85%C55v=;Av3B9BslwB$Bb&%QmNpy%_w=qF zKhC9Z$uAxx+-1XovzRXP-&i|;y=H0>r+Jf9~2XpU{HphD$8URe zvb~kmGNGRyz>~9a-)*f50HNb#Vzo7gBj@aEQ+oMsHh6GpNCrHhaOG;Ln|gT>#} zCy;?G!R@aT@HXN;Wq^j5K$C+))u1!8>X5;P$6TIRu7MBcy3HH)&&hBV9+H=l6?;^t zhZs*%tTPgWUeklpvMcOsmZ!L*Sf=~AbB%$ysw}s-xE$mt1<#_SS>n#3`**paT&0Ov zzsdl>70gRBA$>(`oA`0eM{fYD0Z-7-qk*awE4Lr}3z(Z6td7Z-Rvup|58USpRV@P~ zTR?2*c(+|<>CIj-DT*^(yEJqTWt%aQu?}(N11469*=Xzri-LD&yjh*?IfUZM;8J?W z-t)+{BN=YWAYlt^^GoX8zn}bD$x(UfWST~eF~bL^dZ#{%J$^`ZHpxJuxh7jO)=8kM zfj0B3LOi0ee{PN zm13Bk)fvpaMXJ=^koD zNJ{GamvKw&z4qgX#H?BmhB;ISl*O-}=MlNen@La7Sr_jnZ5^b&*9n_3GvHVs?{KK` zUYH1~-u!TuxMIK%==yT#;DORdoX4G5{C@ou7Iy!92s6-M^gF;Bvmt!02l-NQ*i#o* zUw+HOMv=Jg6Juic=zKv1z6D@;WXo!+Q{!zMeq5>hiWHD(jU8Hd+xQZFLA{`>c5LO~ zWK`~ozARUvA-S9%+tlv4PA7+Usx$Poe$p2MxQ}=;uSwNiWN<0tB^P~@4Qj$o>Q8l= zE`;rmD@e$d7Rt5YB{B9{p(o_?lBL%4d%0V8EHdJK3G%r10LMtsgX8)eNH-HtiYCb5 z7T$4$I=(bJQ1{ZM~%lmMC zNtUoA?KZPd>(Dy1Xq9hCijzz|^v)1Imjy)d;RJz)4OssDz$eaW$%1Xw~QtGs7fO2{*>B@pI&d19hBO8|KD!1Xp#kiQL z?sU;%++?7s2%uH%z!z`TsN|#c+NyMMG1x#;z8|zU#qx|GJ9Rj{_`1Brd2Es3mL$M~ zw-D&^%WVJtFs^k_E9A)g#uhL8Y5kE5sGFO&{@Ke8N3!0^11(xX!}#(in5S{`b?x>A zJYAhtGCFX7d;Rf-1IynBOm`sat-{QbwTe=9esVg*1kw{-sgPk))dk9qCTWQ>=2w=Z zF`~wA%%=~GlD1?zFq#2M4(CFlUA7P!CGpEP3YvB@>!Sr{f(OSC0_%H30%iT9Vo#ff zLnEO|o|C9Olc)DOg>}HvFzAN;;VwO?iVxMQj`A8*qxfmI1oi6Hz#ML4M#-oABQGx_ z>u|*s|BXF7@!#z zQFK{};mfk5Z|B)2hgf7O%E>OZ#kwgAhmXD_33qxf$Xx`@d$B94Q=D=1MrmwJ8qKxg z@}*)!yqObv=Kyi6qn(;GHrv-eGF|2wy!@?Ety%1rj`nQf)WrV)xKHgY6gxh_o;Vzh zuo8^Od~x#gg#ECB@`wN9(T1Zu2Nlky+FX$5ns3gH_IPB?&!X#8-i|DTgi;?YjEuOv z^-3LP!n&3EaQ~`at#B&xVm&4VdX~V_`+UI6Zg-q3`P0#hhvmu&+R(~?zWP$hL;LKKU zYnLwih`vQa__~jc2j1pqxp;gC!@NJLUd!4<^A}7I#IF7ymFcr5cy`T!|EN6n*a!eO zCB8jM%8EBs#Ql>}=d*Wa4gWZPgEEz2`}+-AyvF#<^-veUH>UCn$;k)#j&-rEp}?NY zG$mWgXD-)ePFQtca<+RX6c9^SdOn%b^6^>jC5>3Q+SpH5#RRLp+{tx!5x1?W2Ro>T zBRY`mr0XhHXu)m=(voS*=!LM4zx_QupQ~%PZ|%sWE~~P**zgi}bIM+VcQ~&JS~s#x zN!1^1o|;(e&kZIBqXOv~`+?KavFYNX2nUE8M)njzctgtB)6^w_Rtj6&@4l{SeDT0G zRG@vlB1KY+$t9EN+GdD!j{T$v&GFcN#0WDEHRSL5R>41AwkP3R$m4|WD4L_64iRqA zOAs@Em8w#vJEF~HmvPCwiNh}F&h{?`@85P^#mrSLSRGcW$8-X@qve)t%3rtdkGKOT zX6kn*24@YE{ov^t>&ctOwzgGiNv~(mtM~Ps%`Z5nWHO{=7i0mgz>T%O<4O#kVg)JU zUy##|aj*MwAP^fRX z$QLcbl4#rW=07TT5^!f^&>=9q_r*FQbhO=Gl=JnZn0QsDZj=S;hd!h#UxrI@;GHL= zqG`FmiwQZM`fTEBoedWHy;M)WXJ&uo3Q4X5!M}HF`spU@0Y;bR{a&m@)h}-@jU~N_ zf(Xg-yPrSP9pJ^8%r_g7=I7=rr1U+vRliR!CJUr>%APiD=BAXr^<>c*Hh{GbCtFTV z&&s*kcqIhjjuJ?ja;OFmLEB1g@Q#SjSnr1eX#EdOb+! z&b?aM&EIco!sgK#S8vy`AyfmckP{_&oFz)Z^cB% zCYg$|IW?}>!00Yt*Bx6Oq5~V-z(`Jtm96kR7`0RHnvg{seGqJH+%hH;ahl^#7CP+f zCEFexmOVp<6MU+hU(x(W)uw&-9VrmYlwE%7(z3C#?B4Nrw3~_>D014{(wbwL*U5{? zEw!KmpZu?#@kn^h(L!`ZB!%GjYrLiUz>H9I?pU9$JQAU#^jhj=j~FkP8sm-Y2<6G6 z^R^J*%&jfw*?2AAA?G0N$<=A{Ll?By-61c};n^MS3Y!``4cdUS3Yi<@Ukz1|^pW9D z`0iM!rP8i#0Dx}?RH4ibv^%&7=GglhUL$tav~MQCVX08*SKgxWbv)GuSw+`=qE!y5 z08Q~6CZT?0 zbbg^J&f|Qxhd1WH@vCgk;v^Lzb|SZRbTfjUg#Bz`Ogt`Sa^ROgDS5D8@-O(KqHd~tXX#e*im5!=(W`+w<%)eL zHw}W6k89x)H)u%04X2t6R4#|f_g78ZhS}V4kIbX5vt}-f5_xxH4%E@UoNHUVkQWxj z!`=2NhVQbk*W8m9c=j2PjYarL^aN^qiYD%#77Jqxk`y16m3>az#aobhrWoUj>dK0$ zH-UG;X;QKe-q>_J7_IZPD^QNAlHMQo>dfpU{npU^j-HF&6g@1rv`w`)IeA>RS1p<6@#QAE<)T4!6*+K_rceTZS{k;Fs z@yET6n;*Ys6PQm;9Mss$`h8#EP3eV^Eq>Bei5MiEM64MTc8S?~b}7}cPOujQom@+T zyae|7`E^u?8g$B;{YQmo)K`!(yc$g1TfJZo{^6F?)XqGJMu!SD05N}vF`GJr*Ky|0 z2KPH41LhF~!pnx|k~@#ywXp|(d~Pm25Zt59H=*ybxipZ!SS`3 z$MR{FHOtSPgh@1gpg@*D#^?sz4HDXW;B1QL6kGdu-TA4Uk}rR})~p|RLeF8;skh#3+Cc_)qnHCOg|#+O%r9kznGZ{^PNYIkJQ`0*mUD_jvxMVQ{;fP=tHk7_ z`)ay8S8q`|8Dga78hinLM}y*sDqy3nqD6e9mNVT09Dl&?uPLJWaJF|<>RIefF$$F! z>@;VTsR9opY%(*_n0S=JdY9!($mYYTS4=9zZ8Kop#i#t>w$sXWWarZCxuxIGbSa4y z={l~x7LI|GbMx=L_Dym%<*da-&M-K`?^n1ECMCi(1!Qbr@5#g$%9j7eo%c2gqcY$i z1-3y&19xC|!-N=hp17}<<`eE5zMR&=zLo&))G(<2yGebsauZu7PQ0_d1-)d071~_7 z#QIy-%Z7j-{PAk58(jEkQaV&`c_iB%%j|rKT-h_ zn8ic0k|h#H??qg-(0Q~_(`S+*`6f-7Z1SE#59+R4QsBcX=>blv@3XKNH@2`{IoMQC$Xzi(?$ErCwW?j%#vl5*~k)U9zvc zT$|4ejx>Dn*veWgifzW#Y=}a=c?=7dMXh|7(+a}RMxxoF-S3HUqkZT{6S^baH<#jYFu)iHUmqj{UaHg*oss&p`bk=!1~mM#gh z^uAOMYH^?-d!+)+)?zdhbw>V>)|{U-4l4t35k>z|(H$(4tCh=HCo@GNZCi_5)5$kCu!?PzYH&n;nFg8;y>r)0 z^=Zhw8N=)M@%-|jAnleju0x_2L>pUG2sAxXR_$nxC|%jTy@Y~k3=Ven@p@S6=da9M z=oZXdfjEKeKPo;h985%`CJy6taNSZ{!0y*QH*`+^OU1^#4F zO!8p9v##yv$y_mV9ZAq7E*f09&_g7n_F-;?gKGD&O`+jt+-3=N^+pA3f_WjJLoe*f z-(XtYJcENw_NP<(tJ_Q&Dyb_f*Z-sX8h~6GiI%8Y>i2VS#j3w={lJ}iN>+@hmgruL zZnZpbGZ^zE3w5GyqO38_mgv!AgS#OppaDUExcMI55HD&ZFX#W0n)ep^FSiUy6yE+ko+O@3+WsoUXjpPV#%ND8_mThlfnY?fy=6$>HAyS08nwg4$ zZ`-4420s7Teuj?e@veph1-%tKc&W|jfG!>DJPp5T$2X!VJvVizD%AeL0F&!Ji|;Ak z_f6Wzs3pM;-Xs1J1umHL-jG&sTHdORKv=7l4Dx3V8$!6RRhfdDCQZxa-CK}c(B=+r zij|}C>`Ica%sbY)OpwW&oxtY8OI?W7^?|<8wC>oAFkA5iZ_5;cJxyp{{?7Yq=2SLQ z))t@&h5ei180m@IyHm;E_@%Dim9XI}ToTq3kREwq?;x7!V{UEpI`np>BNM=?zw+m; zz+_(%1WUNoDrDy4rhm*Ff zD)(J-sTv*37ho?=tr(|Jlq-e!1yAT*=`2chh{lTA#-AaN3F!7#rOy<%s?v(d%K+Zv z?T;bjm;&8Bxi<{s3g)-a_X_{{HLuKpKr+2MeN9z`L0-g2waE(ufhZqEN=-L%@P;N+ zCXAMHNM#~vu#&q+2?*O1`Q^NTEm)+En+YE{#Bu6R3`W5uHI?i{y&U?5W2&d7ea11y zPauF>xC~G`Tt6naD~dxpV&m+OzoEsk?)(~Xn?{?d-Yozp90hl@HhSM#OL^5=FD*Nf zQQW)4XWH$KIU&w+!8Jo>_gAMB+8y*P5_aLDs@yH*{UJi+u|*Lg_^Tes-@|wOsddKr zuL;U|GbWd3vaV#OQbxOAQF6fYJ~Zf=*;*(>!7gciEz}=>hdeOypnL=L%rm|nFEmab zfo z7HIch^yl(07+}NOEOtDDt`bdi=iK0U4c8Ae+1@4Zh>=}6kA~+ud>ShI)yz<;j3Km; zq^=%6Ho3)zt&>v)AMPluNRe3tJ|h?)$z6ck;+gAb&M>zd`#8}b@PC>@J<{_}RGX4T zx@bA)QqD4he2Ba1;6F3-+K*2j-Z8N~{yqkFlf`V7u7!R1iDWsbB8ZpI2eA=-a`W%j z)f#vwK4TmR$V5()Mbv*`Hc#jxw5lSFo&}&~h3VtE5Wu=qn{yUTE~5(Of0$vs0S`f( z9)j%rkBZrN+f(frgaimb5JCfRyR<{gFzbBxOjcDM#v`2Vbp$_#lu2-_JCzI0Ic}oe z`BPOK6e=CUPqKz?F+^m%-F4ZB<@>Hrr*cM^95*s??w>SG@o74x9L{K-klZgLaeXp< zov@0rZ#>23=)uH9KwC)ug&j$_m^?adxOvj}HoR+>r&xH+Hcpjj5NE8przjA~UX`EN z?0wVLBCKEP#;AS~e|&7q_oqQ+vFnwH-PTjII$Eq%F2JqA@#!EcHY_Y!hQagPqS<*z zjNhNL(i}aBV5NK`x`_6EgO$6C&u&SIqi*QUQznz88EPA17XhB6TkMLHN#kKKje!5c ztxsHxXykf)DHVR{vXOfsNID8$26KbiQ=RG&*QM4O=DZdWGnes7G`~r@9eXwwTdW7x zE^0x4ko-D%ML`m{gwG+5Ng-dVL}r6;tha?8zu7B7cIMC>m`<)I@-%e34MNAoLfI$Q zi%%}JkjCFOy^I2nxBP7337vO{lmd#XxVlT(>2tNoNrlMn27Zr z329BrmN;aj5+_c2g3LABUl`}rAK1k^IQP6CLw~P<^QV1r$k$592APfqgv$zq-KFfP zB5>+0rvf6#b#_`M&l?YKYd(x7GDVa5Cw%hQV8>x}K#fB1e(zISoztL(aC=>V$SZ6U zuz9DbwwB3H^Wb&0uA~-fX=mspBoXfK*ZUt;?Bdfs7IH%V()YTo^(K() zSDBCB)SmqMp{3x3}8eCdK)h5KAp1 z!vH_~Jm8$@3j1=oP>L`rRp4U-WT7}M6I`%ce5^oDBEpRv|VnY zEt?gy7Su0)A;^2EY3Jw@CuJmMP73=N8)@2fS7R{v=@;ZWXeV?Qg*#5hF+~6aT<(ds z9esN*oWcLeWGO!HCmwH`bBvIgX6O>})ANu)a#k9;-Ors7yPwe6W{b>RUAm#d_U{{ynQ zCA>#LV=QHJ@^^vH@D92TtZ~uCIe#7n&$)+8r{{|(h0a&Gi}|>c;nU8hx=>7+xZNpw zqrD@Kj%0=;-%dKWoUZf+m89fUho|bR&OQW8BXTb@y+NwCE|{n5=2UNME6I&es35&N zk=u(O?5K3aWLZ~N5kj)>$Ae~Y@PJpL_gr!G zag5%6;@w=RsDxL|F0D~)s{WWq#_13IhM6^Z%xm-o1&!e@@as#w;r72#clAicubnja?Z zbv&_QlU~g&|4~J%!r|-5pi&o%!FTUAqmgyFbd5E)-!BUSSwCsry3*hO&l9u;Gd`vx zYDS76#!5iBkInxMn`%*>%FdYt@@>ey4i!2gf6+>tz}wc=>Zx3fJc8GwAE$}mXRen0 z3i{<+mD%ecQyZ&9Y(g+*Zw|{Qr51VTNgGdX4*xzGD?HH@zrDu&V69QcGSVwnFJQ}K zZ1mV;&27TD{&J0T)+az}6d@Se@k#_f$LqM48}?}|g6>hOiWN@j;V~f9|2$+WGl4Qf z4r%*ry1T+Grk%T5t_kI5mGpQ1fQ$g4pmWBcXK^N32F)2BQ&p=Q`;SX?iB;+(4=0bp zO<9mT)LK!gT6%2YMKX8hC+kGtQ|NhS}WveGVc#1WAaKIf(+N8(Oax8Gd}JUKy?!Zuji zaFTLTy?(zGxT2J!lBB*k2Y?_x66+3;OgGaaLXh~gi2mB4vc{etj z#gawi;`2c6pijEmbQ-b>4+Z;ne^8y7!6KpA&FS4b59$ML1D%_95m3tIJV*c{!~LKr zfs*oVsSiXX%g+me^m5?U$XfdFsQxjHTYT<@l;WJ&?cLIgGu5=7W~wc`Xl zHOeRD=W)Fubv9Ezi`&u)TcpL;1jc`BZQJ($QDH%Ui0z$!N`atpH{P9n>7EgT#dhJzrR@Ixh=%NpoK{Y#AkM1kI%bgY%5qfK{7C5ZM$Fw-M)e)n$UkkkLUgOg!+OS zyW{GvE1a79;Z5syXAe4j6GIL<$y}7EG93CU^cc7}uEhSE_>i!wlnI5m8o z<%zaN!5g03S9o(}#7=`d-US+P^mr;41*_YfmoJbfHrF$#Jw#Q%E%)kadJDU$nW!3U zAs&T%btZ*czHABMMo~gBZxb%@Jjhi&KWL`8AxO|Xw+wI6+WVo2RU zn{@S$k_ngYvgVgxBG8VrD>#ztSm+N}9s`N?#i){mPvPd7UQt?Bi8~uBv3N2)VA~Zp z^&AlH6kd?6QG_36l>OgFcx+~U#3(eVBn11a8%g|$F*(Kg85IetC6Ujxg%3P0l*OC+ zEJJ2(Z>@sciHSmK25JKV^MHe$Y52oue~-U{EVkJAbRJ+eA&4@YkO1 z#hDq8-}!?exi-bDE{{_DzKxXt`U{^s$#^+EGKgszY}|EbT{zurQ@wuqTSBpgyf49d zdr%wj1fVm)c;KUGb_}*43}q`r`2`@y7r`rqS88a z_w3Eu%j!6*6;i_{FzWGmznXj`dg?Y5fR0d+nQ;a%n09p~YI5fbvoyDAv#JXK{I$rB znW!$8LT;X#9*}Pmma__)mDRdUq37iu_r%G{?5Z$do2!@E+hmRlesqv{(N=n(Pqo6i zNvCitgNQKereUP*OgG1hvl$ZO(-j2gKrK+(bAHzGzJI0jWVqmXiZ!M-?$r*VGH%z&K9iJ4 zOt&D}2Cr_V?ID?yBwtAORWw`)sEOS{@|19aetwwceijNm1jO0i^AV4E);Z!~@9fTy z^=$6`j+3DAY3jFW9K`de99cH%)!2C4 z2b4jL#Q8a#V9O`!(qAQ+t`cc~=d8s)hp_449#3fD-JJmeu_U|Dz{{&Ar^R<8pnY-&nT-j#D(4rw7Mfs{% zv!6&%O@j(q@DU2d{u6bD@k;u&eAdc;op4KS_L+f3p@{lYo*XBr` zf*k2}VdGNgiDGr!iFxx03N7O@pt;D#v`+jjKh`IZic>Yq+>nU2lMWk6#2!;NCM}sI z=WDNaKg$8KNBsL4xFN3U?vM#=3i0NdnHUdaK8t+IJg(agccZk|tlj7RMpg=P0XA}j zJgV}TWL#k5j8R_8mi3zu?IzBfTP~Dq{R+3+;Cc61s}Bj>KMi>j5nO&7k5(3nC@7aL zTuUV%dG-v5{lgijSYv$wcT}V))nz`R4Ip4@Z;=;=h+)Qka5(KN_4{uPFQ=$Xmcm2p z+@r`W1|^}Ls=+jwTVoY+UqQlwMH$RV%u$Jd*%ff?yQ8MN+Y3awSEQU@);3#1LA>Fs z4JLQXko?BGRh%{7HgY9tZPYzfZ(p#1mI2?{GW80qwVmDTc#~^tb?CwxS?(j1{BXIR zwB2hVj~srIA9jB_=0f3_*`zBg8niKHQ|0Anr;33;D-t*({!R=zqWLsGOrSR~$DtFN zPS~pG%!VEX@cLA7bq4HhVW{H-VSAFgzc2i@oIaGlQFSi)csz3XKdQf>*D7;ldh!y2 zq@*c>`~9(%kE{;4)CW!?Nzw(*6r}QK)in193c6YQ8nyqDKJQo6@W`A!b_m_Q8za>v zi*qV!GQSS#s2Y39yk-hpYcNh1g$lug3C+3gd*WDbN-sC|dNnpK;NKF+=3!fwAtLWR za(zT9gZEw8)k=$~&d=9BQL$_S(FDStZnq6}@{1{%IJURib+x}`q5dl{NgPm?Usad_ zPGQ8|+>ZU7oX+OMmmhf8JX;F(%^OY^+48>--ef9MURv3>V6Mffc5yLv$p(nWh=8*? zWhr2UJ3sL_!>a^n@l~si&1kNU06uuSZ!!2mf<_DbC*)Sh+|peYDhR6qBPq~)!cy(r z(na<-pg79DTobw=87{}VZi&QZprqK>GbR-6d`+gJo`Q27ATh>)7_xO z>^HPL9*vmeK$rGU2yys&VXR z&6M2h>l-R5QumE7o=|Tk%uS;Y<^qUo@#zf7^XC26 zjp()VUs`mt^WMFRP7Ct8tXJU+8C$$lI~rtBIcM$6n%<7#pGIldP9*IRp=oYADnrbU z*x)8^*Os|;S3pMXYR}A-rR>QsCsilGdQ^c*97 zZJC^*z?SL{Gt=WPDw>!DI-;MB_Kt@YW6K^CNJ_=J)9PZ|j4V;1bmqX1tfE|nI>$h7 z#vUHJFW18TnrMdChv~hMJbxbe*i9!6g!cij;PcM~$}S*dp&#+}djgRUo8ZJjiLT;* z(?T~kx4>X*OMe?A0sF}o3Fk>{>{Xb?`y=JeBXWZk#7xg z2{(EX{}w$O9#*{pt$Cza3AG$ek}iDMjVmVbC6-kJ%E9LoKR+<79Q7DZR=Pd%5z0zd z$}Dr=k%010IOsWWL0^{d8VJtj-U{qZx?v7*~^Z-iM^^K^uOU>)*F?T?@gEf@mY*7LBDt+>KG6C|u=$OPi6|FZlq}$# zVx4u^!d_-85V;*x)2Z99xj?%!Wi2+35%Ih0*4Wg@`zrBbcK7TZ+RP6d%+y(WT&^r6 zo9;0uy>Sw&Y!bh5!6=+vKUpcm_AesG22UbgWO z1hX>UI~0`VpekV_g*V4a%mk=*mlSNFPkClhe-tjw-=3|R3p~N73^OgH=C$n(SWWx- zx{UOH{HST?REm*lKQ3xb{I%vv|*!MxQGwwZHKN z4Yxp;PSo|ltF5GNDTS5%9?|0v%LLw8x9&griOwVcSxeWQL+&0P$o(bOJL$`q3g0t= z*2N{)@u0jZiq7{*X$|_*z>mnq`G03L8>w8dbKOUq*9d9jq{%DV4&=)4hA8qQ3V#2>C6qu3D5SL-h@WL5qCRymu|z{#j|#G%5ER>$nvknzH~TD^~C6xzEo9^d>E^JjxJ`PlGm;ZQL89tcf*fcJlk{1w^JK=>*wNIY9v+VsG z%;SCQxfxpj9?BtYv?;hN&UXVU2C`7JDkuq(K#aQ=wYrlsh2jQyIITRA_meN81jd`) zzX5ZmtA8)5D|x=)RZQu{!+)IJnL*2yUc5@SXlp>!CE<19;dF98w?ans8D%|N-z^_0 z5P*wU_b5>99!Ep^1C`g}fXpy%H!PD{U$3&hC#WF)4N=gSzZ8vcU-T#6 zUY`%tWDB#>jD$WhF)~g{3fJ+~AO2+a?KIQ$*cX)H#pn1QB)cZ#KXtGVf7_h;?t8^0 zy}7ej(>E!*ATo!mZ!SN@Oq8GyK5g>jP;{}$G!Z&E zz4pQ3r>q|}5Tg=V3P~c%PVy&#v)x>FF8GL*l*5Ec9Pq_?%}v_2kS|7M`D(eaI^YbU zATn3#L8%?5n}Np3=^1Tgn#Ke+(|TRQYOQ5@sJ*KtlpRw$#B<%|6NA;>bUyUsZB2K& zsvV8_FXN51d+p>qQgSl{^5meragTou%$DWrMwgg{xAGQ5iQh6iP^4FSHI&DIcdf=yrCS;Mrs}X0_ zy`n8V_8mWfwtb7*$yb=BvsHG{uksSlwFZo)k+$O~yCt)=rSmMl+K0TX6 zh+n3f9k-HR2t=sXQz|O}5?i;IVydcxt9E!}8XOPt?Ug$V!moWf>cwfFNf+!6JQIdp z+C-uuQn?PNYygMZVil+ucih`GMQx0%%W<@4;C8Z;?fI>440M};NK&!9yz8LkeRchv z>I?IwJ8(Onvfy~B^A;QVU7HNz#tP&zJ=Bo_&d3B1(`-s>rQ`2ppmWnYBtO&6<3cx~cbW2(ga_2d z)S7)O(=qgQmhqmb)vheP9%8%s#&#a*)>7ybFY_P?!Xg-iY&^r(UKkXIg8n7H)Ldjq zab3tbT{QypzsI+;dbiz|wrgGQz222MG}`(JA>w>3RM6%#I(h3&aDs6rzm3WFeuDl4 zTsMvbJiRX|*AQ@GV`eamQ9MzJwosST9}759Ha4qua=n=0>Z?FMmO*)i_1JHQ@J$zf z`8fyg{DV_2O@d^;c#QOMUrkNN4D9bl?{$|k<) z`n59=GRoBFKlHNUj@65`)Q##&eQQ?_&p9N4F#AA9BykYJjf2Cx~Q$3Yn8{$l6hgUl}nE3MM^dht=Gi@Y zmp{*vZNx0|#=GCE!0ylLmhX<9$C_P5cPu-7FPC0&Xjt^jyBq4F4Cr7zxaN?wrMf%} zY9#6I-P0wtt;_|&RIsuwPj3C#Iqf(zL!B*cXJJQTY{Wn)MN^RT*NgM=&Cprlu4VqPvgCKzj1=1^3>(df4t=KCB*#xr@REXM`ya^dH_#E z4y~w7OjAEecbRXxAPZ)g);r}tCq6K&T$b0J$88xTKM~&k4NSc#Oye(LjoOXI?Gnn*c@0=Rl~vjKNW@6;yug=1+?ezlPsaJuuIHoEqxc@&V_pUjJoK?&Qke} zj;qa$4xq*~ZT6oHqK)eX@xAi*P$ni^*9Fggdm45qLcmUAPd_K6!qpvQzKPz>cIBsgJ@%mK@|=D<$+=vg`y7i?I{6{D#i6Kf0S1W&%uL z00xh(p`N$%U8CowX#?o2 z0by#K-OaHcmNh%4)e|xs94Wcp+ke58EmmWd9G9z(;0j3Dne8|7BB3e7W=iL;DUq?7 zuQ(sD%XkHsdA4*MN=lK5k*RJBdR?&AkGJK~UD=dY?Cgq%RH9cB;wtOFM#AClnRhwE z&@5vS-Or5IEq$K-fuw8vPS=M{be$4pNH?%8PWov$Pu>&>~CMxEEI%F+a|N3iRwU^2EG%}wOb145 z^r{EL4Or0BKji}7GTAenob{m-ra!9+BUDJ-cuFR!%tX$-T}kzVdEOMZWKS_l|zi+%i&W&yjZ1K;rdp zT)}u+$`8p{N21V6%v8|bT5-eaMDp9t6X^Xv2-MkFi)X^hgV8H%w1y*taMJ}-QP0`D z@I^_3Nt16vQlCTM24=DI&l~U0ycnW7GF8=Abvz#t?qI!6`H9oyl8QbmOh+a7=}T%? zWwtM8BNSqKRT)f&ov$SWlPC8jY_+zeL|9?%;YfjTghuNF7x`MO2lKp;d@Y;VUZJli z!HC}R&j)nn5x(Go=zj7LP=y6PwQG^KQROl-R!1Mo)I?{J6Ypj5FIK}jgvr5Rv9BjV zAaf30&1y(vTcrJv?pK12UhF+z!V>U@pv!dNiipYy5P4TNsP?3`L%Fx!%Fozb&=)kyW~uhcsi(&C$`ef@c4pR}uf@w`=Ys2Afvf9>4d#bRn}_|P zzYo|EwmLEEB9K!9c38q)bD5NIix{Ef5^4FgQ*ODHfb|kOkIkBA*KN#TADuJl^gba# z=U)sLY=XZ8HO_ffg#ybOC zz;KU}nQjTG)y87mhP{zRmio7DQ8okY)JSRvrz+#WH@PdVopDkt>`4QHcp+_Ev&62C zFWf9hVQ^W9u$jpi97Lt|%2%2KSm5wJi<{h2{7qQM(S4=V)5fy;Urt-x%0F0j9cB=X z6;j^l8n(oE%f)(;pvP!WaR--%k|5P!m4$3BRO}an=TEoca-RtV{H8VK`~Gg=^X-;) zy5;41d#|&QiSTBNeCNu42d$l-7jS zSJ}&m8a#h$nE*6P1dj}NFy~5{h{0O|AsK!`$rINb-EX5xZC?BK^Qh$t&M>LhXIR|S zU{Lo`p`GMy2y-Rm!I-a5X6=hR2#^N_!kw`3Se=P@9+-JPd}FEm9()M7Q-PycA~PwV z?v10uuCgHWJ&={`456YcFW?+u7RqcDoV#=)E8)Wvi*3&*+5TT=C94JBo(VFQX~)&> zd}#E}tApU8v@QeVYKR~6Ilj30Me$~7z0AtIM<#Dhkm^T~?RI~EfyEHqG=;#;cdJa- zh;rRdAN>FNNJ`&OAASEhezS#9>-QbDaM9L&&f!V^e@yn;POkMjnE3pI*BgTDzuwPv zH@nE@m&k5f{v4eE|4KIhxnvu%v*7NIIgIR&8kX`m6h<_ zR=>(^m)v7UOEx#}n#{eztm}7KB{Z{%uU}N*`n!x&c61o~M;;7lZ{Ei<=FDUyBUMR+Um?-JN%rC@=hv{Z_h39GJH?ukdahTMa^ z$DVDeJEwYyM3$ku+Tr4a81e3#{Nsmys!s3y1{rT2v8*{}z(rUTht3z+yru>`GiSES zq|q%?hnka%S4p@PgE-ltevo7spkiK>lEwK_uTn5t74b)s&Mu}g%O+m(1)N?Z&&o=3@XlQ~9Bca9-2 zyVQEx9|ZPFwywp8jiGlsWZHLJ!TR$5)C1&t#Hltz>ufvEBSgQ2y6U;Z|V8sk^O5@xX%ixaiiuZ65d49C=*rcqBi8dVue=30+?q> zt{P|Gvg~u}kw{}>cAXQ;>;a?oRzH zZz>l&V#X9}f`I~+Mw;i(*p3_X-V*a7yw7zl12bT--*i2+*P{2uBZ0%E73_S?v6`TU zRa2{{GP_Gx+d)e-C@E*M867Uc67D!$$4GJ zyFTR#`@$ccSLYK|CTiecmO27BP3Y%m6QidWS}UR5PR5wRpum2Ym`mh&K~JCZRAr0o zb-y`v6Cj^5Cf>dl_h{o^#6;}m%F-hR`+r21-#w%%j;z|ys4dyQE_5mth`dmup^+L->v`Qx0H?pT1+vCT9M8i=A=0MTihKaCLRn3BT+$SBMGteko7n8o#FUaUW{B zg^jLH{uQv)-9(BBeWe;m+7<$6uM~BjwOP0<_Nk?V5jrz+#zj8nohgnjJk6+>WMZd^ z$pgzmBT{P_+46#P5Raus<+WruzkFs$o)+hD1VbCIz{0P29I8M@LY)cQr(3!|CCKTH zOfGcyQnAjXedEq(Wnf*|&gSGRg7<^BQHcw1_7Ll|J5p$ulH=`}OX#U9emI!ObQ>KI zn@^Jl<@-gR^f(dSGK#w{W-r8%fAW=7IlYH+(m8qvIudCIJ|wYcOeK2srpm1|w9~oM zrHn+q5=Zps6e<{ce69uMrcf!@rpcJS!x@)Vx}zsnTNpYA?Mni1fG&2ZqQom8ZizRV}>NgMlnKg>IHX z)j9Q0G{&A;kzdvpZb{T61c2~59hw%9IjvL*!a8Uvj@9PLX8)k)Ml0v0fYl7QQLlJI z6wdtgFAmX}<^KN9jWQbQ!wtX<_576$9@TcHFNZ>E>}WzTSZ6ScBO&N>E6q$$M(uJHV2=r{;nf&UU`}F5v$MDCjNtLraq6Y+6#m>-InHT zOUdxD{DYQI$veChBb(KuMdocV#VM21N@ z4!p?Us5OGuFgE&Mb7;JPbCfkqIi@VKW)waTQzXKym_^C`TNiFNhet~gI2 zd+nAV0mxOT^XS9@=aSMt2op>?uYz~DYbYBk%Qxs8h!5H&pe#uz{VoL3)tN1+|LWq$KG z3i<Jb1I_&D=0Nmw0!u3i_<>waM#R~^%s|<6sFOf zlmpw5%FacA74|#;`jrL;Np+ci=vhse8LP2y_7#fDX|?1Cy5^}vHcfiE2T&|3)+oP{ zR#4qWD$G1zGQqF;Rgq*Yi39O$jhleusYC$00Os_-iQ-9w(ugwolck3at+VO=A4F^&+1WqFBS&pJnp!8ct&vfi65H?E4B-sBU)FixH6 z%BiO>v8ev-=;;v-RA3Q$`p44*m3#3fKgG=1=A7bvS*HtA#?AtA{jythRPm=MOEkdl z+UWaZcWiO!n(2c7XNz8@?SsW;of+1sU}U|~e#>p5?B{AGLMYp3|3Te>;GzdZ%D3c<|3D*Yz!jNhuVGfuHy7jiTxJA>(P%)xLThOWx<}O zr7ST@Oi63EBla#`3x+=mt*Fh;XJ#>q4nv)5UJ)5R6dU#fvE)wY}LanxGf97WRPa(o@RFF;9 zE?)HSII1E3f)Bi*RxnpnMsIt|v`3XNHY@T;W8_h5?SNe$JTM}H=sId^Q(^=L;gW4T-= zIwpc^;z#5twzKPZ)gPAp*=)8P#PhzZf=J}tTezMnMVm*8FL;R@8~<9z9##Ng0!k1# z=Mk?f5)lS((64dx!qB=)>~Z49$Nk zw;w8jR8`N$_Qs-}vr_{o8fZEcZuTsTJoL%XYQh7qlM8oW*?XCP{qQCIeF7gB)$@Oh zHzmG&gUYO510do^f;Gn9KoFca;n8faftoDiPEimBKlhjqQoQ|bHK*3DcWZ_@-g$zSh1@&5%&GQ8m!k6yVfjUBF8XoC+VN!h!$NJb@^VS+tBEOCOY#+xXnx*{VE`s^&NRbw{D; z^^I;d*Yw`7(|~EB;wlS*2EBC_Q#u2d)Z71~Q1#<-kW+&0iR;m;Tk*rsn{RakUxsO4 zWr=6J3b30_^nqzL*H@!{QGNdtY_$7!!QH-mv>81)zxLSUH!xFbGk~7$4uvh2}TxLslgBhB3-` z(iFsref3g9N^zV=zdx4t25p*Hh4R1iGpF8L(&gS5k+uNPidp?tTABUPjOjT@G4}?z(3VC zxUqR4VK;Mq{T0^HFsUk*u&l54+Yp(QVJr<$@z_AFm~RZLR-oIrdmi^9!yqG%l+GTw zN9*V|tV1c#1UmX)Qt|xQp~~Sbv4_;Bf2g1K)B#`DFNfL9q}{&j%PxK!CuxgR{1Z5~ zcpHz3lanmmTD+a8(wJdd87s~5$)7Y=H1ag0_1U;B@rJehM%x`1P9||W#HX8f|Lc_ z!*28<+@E{aRwTv4Hr}w4wIK?d6mcAXT?nL%N)?9o;?|WrBQ}%jF@tL`ho)rlbLK(Cnv&$8?D{LdQZr zrk;E!MMB5lUBC!2C&q6-56SPSUfttjpMgg}n2LR%22Q~1A&_xVELTjJzRFG5T3OGgSRlo|@VvAWpNp?mseu02KS((s7ZIow8*Deo{=Aa-kd6AFlkZ zuQB3wL&D$XN5f_UYpzV8_G%Fobre!&jsPFc^b++t4dyQOz2D;wlGAC8c4@WjnY$|5 zaYPz1wbPKRoMTwfHFHx%Q>;=$!?!k$#96Gr|;8+O=$~~Q9&Hyo3TnB z=D5^)6TY89Z0M<;Q5U$N`?!poCV&(k!H#KZ|u~;|^&!L{qM^AqgYLH2B zr9pu5p7#836lR+!eM{Nm!_)fWn$;d#=5wYV0ge2kV085fM;}wP3!`>)@|a=SJJs9a zb)Cl_BF-{cm%YxOa=3G@H25Yv`=M(5gbO#D0$>(Z>5n?UmMCRX9KsscyO!S2wut~lsvX`D-a96=mlK-G&5PwFi0oDYJAM!q`b8tz`vp6?quEc*j$6BUeO1nTYi-|H@>D`>8WbAe zC994%)G|lj-e!&^D+53BX=l5ytYjn4KNNDIh0L^^Wz^C&)s^Y3;tN9%dT%Z<-VOepSX5~%aC$;urji$@FjC-ZU{ z3+9}Axl5gzY1Q;*^Eml>l_;=VsjePye(1v;mzlYz37D1kr@TzSjb_g7B^nR&kZjt@ zbd_{dR~u#R^4E#C!7TnSm^RB@k4vtB1f6`M98Re0aOp$C!7qv=%ZNB8UACZ;h4T|K z*IIP)S#*m>v^DQAi23KV3Gp3+CaYt%_wV;yd>WO{1p)j=1e z8iz6>B(A{NxBY}G3$xyKAG$I%q{+20Qycy$o`1nhli=rSu50IK7eQAWa-qLXVD)f) z<)-CoKU*vy3k&lJUbzZ<+&$i*$?%R&qs(_jJ48{NHUzD{huKfBHZHW;v#WM~hl**s zvQOQXsB{9KHijn5X_EK7i%W8i&$K#bbAMk2C=sK{h*TH(m}p*^=n*P4Ex7EbKa0z@ z)TjLQ_GO}0qN?fzaN5-IbT3dh!`i?^JH&5dm2a%^N4kcVlVKgI%sDFyWhAEgmx2D8 z&s0Y}h*hhGo4ecD}i5FV|!Hu^?9nWe6`PAwbjb>XJnR zfGdwP1{^}yNK^oP6HK^k-NZ1whfkygldECWH>e-hFkv~Vk*?l?pDDc5*b;hhdM4dh zH#}7x$T3jZ5s&4RUbAU9i2fPlzA_-De%P(1V#_$hGj1QJR?JPH^UP;q@-R~fXP0FrL>FFa!yc_}ufBSje7`%X zXl%m-rxhop+zTpF^*Spj#Rar2v}3nGZ|rWB^f1nAzJ4)%oB_WdGCjz?7$BzS*rdiD z;$paBD0ZfqZ%IIzv`%7e8sgJ*Q}0vz7+n~u*6dyio4cV=B*cW>SoPvVmhx*QrX$md0U9(N#b8%V#OhoF+op}YKwS;) z3ZA*kU!ZB0B@mAqu_7G|MWx6$(#3xE*AIBqF4BKi+92ds%1&im++uAT@ZI)^BQ}X_ z?jIxN#Dq-lRqUJ_v2HUm?&D;_=`$2;_f47`6;MbODr{?Q)+4?vBw_www^Bvi$@uG@u!(DWl+9B(&eK}|FfZgg>(RR4$-$jPW z+`7ud0qZvKh5bo6pM|wXbVbs}e0Ir|T)Dr8yQ)vLiI|D{iz42BF1Xi{G0VmDx4^+K z-R$+7+a{B#(Xf@>e^zfT0!d!)?Gtl0z+{jhD1yrz#unqkK`Y+hk9}qOC{3AbN{Sia zV6hl#K+0=hie!wG1uYy~EVYAts^6lx&N;^Y!rjs%kMc(zpU{clAVO1mD_=j@zA{-Qsw#|8M7gQx<`8g z+iCRU)XBF+cfRd5DO3D4SFOu$t7&#o(XMr*FI{HtWd5Y{oC;+2A}+Wx)(}H)%nu(D zFKt8J>vPKIS`z${FKrLcrN89VUr{`pRrsP1+M*MHm3XSzItZJp|C^z+P6XB9$vct> z0yxh07OFUHQyVtg$>(Y$bf9s3!n=_9nIULXAaXOk0LdPEcVpL-;0JiIQZ!Nmf6@L3 z%maxHhT9cCF+OYIr)R3J;ozW~Tq2Hmj&-JXf^^G&IJP|Ekyq3Dhfi=I`p zW_-0G^KckvL)1a8b@(yjDNViW#q`7%hf7ud>#%9-lji(8f$1D?2=YP)atf5nPoN%N zWlQ1NG^o~5tHgfYWZ&Bqy@W@YcfPrR2-&TIlG$dHAs!LaB-Kx_&=_mAimU~jHOb< zFH2s*jLNK>fYvogcA5L1H)F>pmam`LJ=#9xikL2>8~S@_{H5HZc#8Fh+^qdeIpZ^R8;KvF96 zg!MZ}nHbjWS2{79Ii4rhCZY#V;hLbS<0ucd)%tiKa?&e)uc=8LL@|Ii91RQpBg_7AWEd!hr`n7<&WQ5gEl7~& zwEpZI)YQbI9Mmy+x^w8=ux+{jD$_F@uJ}oH6bXY3U|KC@;k;c-55C6k*sV691k1d? z;9SiR0k~Q$;NBFyag=Z9e`K$ubvcaA#ZKKA*q;#2ihb-e9Of$?zL2B!MN~JD&_V?L zYi85uETQQ;TB*+X>|Jw3?T1c%s{QWk{5l15Ny#Z^R}bKzPKm&K)XIL{^ z&%%!4CAmd#mUx&ecXcE>T?DHjHptR6v{5>8IWF{hZitjt+N+8)H;Q7)@(Mjvr`~QsIxtzL z>s*pTbAQY8XYIq;GbNyp80iLmL^{Omfn0S>0UDt24X$uTNNGAJYdpr7da zsnw3hhwIgmyCi7xnp2FDY&xk%p?fhqvys^TX&WT)j-qGNZBC!5L{cyQ9O{V*nAZo( z7kT!)y(_@iB+grZp0VZd!C{k5s8LaPgnDmkDa_HvOK;}0_doayQS4@4-pVgeDL6+} zlr=@&ZN z$U!AiH{Ve;m(qRd*?{JIU9;ll;d_o>tbab;1OwU}U{p1$rTuQFmGEiq^=lEhTMH`z z^_!Fs{3QLkdCjzY?MS}gV-mdwa&InK(}1&#fL-;hz!9sIpSSn@wT>0|O`zgEjSJ>X zSGhgVb8stjnzv*tr9~)l?`*Veq|ZGRYZkxEL22w`{62PZ9vfDqg-!$|bRG#Cd&&== z+Tx>(9klJMCHFTRqqCE-G8<{sC=2eg-Uev~XIFHKF3zl+WW{&dh{oRg%Y0F))?#Y> zG1O{V^ue_*c0Jj5yABvOvJR-92)HtdLoHq%tsmtmP{{E_f3c3KuHtJ=|Z0sUG2HlvPbeXR~cAf=)#@ z;@StI3{xV8Iu8|NBo^{- zqmCvPT0NACpYFh(hEFc2^?ibj^3!pX53&vS zi^Ou=0mKCbzDSt5Sk$cCznZvo`Gp;H)k*$)(iNC@Jp#Q`L*m{m(Cmvh=0%(GA4Hl! zW^a8r&uWpo%5G9$X0!1(jsYqk&V+msi$}M_k;mv-+B*j*k+YU6jgMw(CTV%QH^jfA zHEJ-WTwaQ3Quc^9-ablkzWe#RSr=~i`u;QqL0^tF4$QjG^q^3>JpEUsi+-X^$=6~X z{Y0Q|m`GwD=7)Nf`*`{;@D=eT_(z~%hKhaqYCo5=yo*4h(wBhJ54|d;EJ~_sX*axt z7ka=Ba%E4!n1XNrBrfnDI>4+IZ2Xa|2I1Gul9w_TD%$?LPr(SEPal%0&C<13E_+E5{U;AQgoX} z`!#6n^sjyt_^{*yb!&Tzc%p#_i^$+Oz}}NDmvnOG4fww7nGls8=b6MujwB4Vk05fSCW?D*WQ*?LU&vc!Su(Q94Z zx%8TNl>k;JW>lXtW0^P;H1(vsx;>pJp>=O9#_y!yZl?@mQ)S!$(^ml+W88d7;=aZc zkMa_ZM@CJNCHh2u4hB=s?e{%r4Qroy?wb7)&L5|jzl_+EnQAT!yB>9vyEbqWNEm_W z0+4$klt3nj-?4x%8srH+crfmFV*@Do&I$gZDP&NmCO#+4Jkz$>D;*Uw1TT^O(5NrR z9DC6AYF|-lncaS#3QEynV&8vAoLQbqUZZlqp|c(9z{aa?Dyexmox)izqbnPgkzsha zB<{Pm@%zD6lS~6?{QRrG(X~9KS4(HzZr(dqBq8?N|T49*?2>Da_{W@%)+)||H_LE*g)NRxct_w?-2-*{P{m`Nh*5V zMAb@z^*9ABQ$R~R=yue4XUXgBNXY5K1t8b!zLuK#Z|lOeDtk@;=zhhI+LcFw>S}x^ zEq*x3zy1>ox`ERqJ|c;16ZHwzm@ehRRpY1D7y65-v`kBv3YwQu9TkZ0(B-&_C3TWq z?dRM+yXQ}R&I&{;cd~~pw9-g;w-|UC`=>R>=l@C3C>uLRKN-%%iSC%Og-PYbaN-8I zf1RVoJ=k0|V{&ln!E(V^<{$G9PHs==k#HPe-WBbTLx%gFVbd=jZ-gm2G*~$mnOA^< zM8o}coW44NJWtN{m(3f(qQ_=tCEzaTls|JqnDYd&(IPJ>y_v_Q{117uExQ|kNP)zz z^>K-X9n-anGKNFt|B-zizcw})V(Ni*XZQ;??3EVI#0gJ{MX>qI^PN=-XE`=FXScS1 zTQJ`!Gg_-?_OJkN)p@a1sr-0LTz*juG$24yTe?krDjC9QV;S=P;>Ut1U?C()xo|;NN?6BHMj@wg2*R+sr}N0=h^% z!E=JZRmKX>l*o9m%3sHdZdY?FDkaj?k4O zo~!k}%y7qDy<60Lhh^CUO=wtsWf<>gH`)E4zyeys}yvi0~i(?mJT0Z30Ul~ZmY&@%J;XXoinz*^T8^jNUi1 zIA)0)_9&i!x6YdhVupITq?r+a7hpDBr&z{qBe?odp0XYGc%?FuQeLM&9rGr7HQ!4n z?7PR(6GOoWj=p)k8G{vratHzudYQ8R@DvUu_vzOgvr4$e99ki7t^ddtI0}4@BSDw^ zA@xOSC0kdr9M(yA+iJ6ZHg=!0omf;Sw0d4rb&%3hUK$}o2)^W1$1I5bi;v=h6vzad z6|T_4_QM4L^8&Z;`9M6&Q#vq8iO|;m)Nj&U9*BWT6NQWwez(tgSK1AiqbC!UOiIsz zV_EN8ylmUiunq)^k3f%Jt=JpUt(4z!;yGxt6TlG^TaTC_6k_DO{2cL1rnM9IA3M)4 z1~0bi6P3&C6leu`#+U=(Px(zmRPjsque*TsI9RkZQVDmRQ39wqf)^%H4O}@C_ti3+ z5Yjb-gy5ho14kg+#A%HK@A$hT(DG(9#OYGrr+oNRLWg!G>WCrjNy&2h6^y{Js&)DH zdWcePw*?dxkjweg)eMZ!T_#lxJP<*l5`(s{qgY`J^})x~?aeHw{J3UBXdp+2ZDBvx zlvYB?P@@V_p!9xh>~oU;_VZBjXezKYV0e&3E?9oVE(toRJIozlKg?3|ltyR~*#6We z;>NmyB!<4n`Au9Q14(OyQbczgd^<=s3Oh@g37MQDaJG*Q|DLr!ZN;xR=S0QF-b1)^ zt)T1Se99Tg%3v{!yW{xIaju5yMQdGH`!z#=vn!|Y3`2_LSp5=O_VoLB3#E@qk8}TK z#k1FP8_l$*o5KPH_Lh#WnJQ0LrFPAwuV-g{TM_JPkCu+CNLSu;I;2SQ~|52M0Yv^Wn9D3Icj z#f|n0yGE0p(yBN;NqD4N@^ZcZ%qr0x2T~#g2RQNMI2Z0M-y!p&+v2z_KF4u`u%sTR z8P^*s*-chfw0?APwcm~Kc>{@ig6>UB{t1=o18{qkTQZL~sBfihDoqXbw(Jz#@_Ds&rrO9emDSWuWiO+%6kwKbdt zuhwNfYn%|iciG!#Q-}BltvvYQp~)Oje(^?hzwiFz9~Zj+k%261!;+O5_Rj;A$JOp- zeXwxo;_DSKEI=M9E9dzzD2|Sp8KU2^uZXIAQWj5T@TT{U@1Uv?0`Yjq3F@2UIn}Gj zAiC@s`7cxEf1{Nxx3y`)(o+(@q8PNCLPFimoa8*EmBbQJ64Uc|(7I2FXNk`G=Gp>W z`}`O1eiafI(3?I52pf?7W%&(Mjwk=&alm1h&|4}x|8|xC_mpW$kh36I4{*et@VxTY z)ef{Bde4EKdAuCD@-(gX-)y9)_Z_-3IgTtro@b-w2O0%2zGpzNXnRA=RSicgTVpm8 ze)a(r31_eG1J9VqWEev)h0HQ74(QlDA2LxItVFZS}3+?iK z>P}6EqEUcCjc88hauR*le|M5Y0AfMN;f(>Uwt8t-#*!Zl)k%{0FpgU{AV|7_(4h@ z)IU(t3t$h6%Fs_T3YsAt=w6k`S^R;#wMTC!NLg=)Wxoa-quOEU@}*V44+&{LNNK2c zApSzXueHWIlzkjy+TKAKh{MtOk6y|c?~p>Lb3xDFi2IUI=H<2QS*mjV%9bCMn3GLp z()GM#@Z^5Y!>&=2jByWr#icfOb$xA(%XK+?t)x4ZPly3&r9l!US**((styf~TNqYa! zcQ=;rw^&T;*f;j)^Nqj!wV$7V`H#%MC?9R9*$i{g6yx<;%3ynO<6l{C%C5Ssp)!YG z2Cal>&$h<=Tj#kW@85Tr)~HLh&Kq0IG4kpHJk;w#>ho=rmDA{NT(`bL1_?U1d;>^W z>!ganS%C!*DC^6(BG1D=c-1IW`&Pr6X86{q$*86bXeYb z3rVTROttC$I2UrCk{hU98Ac#!n7|p{eUrmJG?>^p{9_F@IR6e`?l0Rr^~BPg&;L5u z6_VXmg=EFjwOqZvhRpKFl=I2$0mli<6b~u(FFuuSDlBxP-v`BXc<21?t!yr`=ALyw z$+e(F27-;q^gnH~N$LOxiV8=VJ-$a;66%P2y0t%L5PoC>li0VliY~3R;=PLiYnyuu z9{}5u;j!L+UVvas)C=(O?CSONCV#yo>wfXUBF%(9scDOW-HT+SL>38zaLrMFu208% z*t>}b3UWUcUn$e_C*0uUa;>HL0?NT_{#_y?a$a{%l@T@B^CdD$4d*e_8d-W$+Sb18 zZ+GrJ(+_#w37d{0+{e66>^N-WBmplq)17Kt?28TyZ{ecy zR*%{{M4$yLeJ|&eZ$PIC`#L2D$KifFG5Dpw*Me6SBtUSGx|_%z^s$eqDRbZU?=*UQ zm>TL^5AvtzHJ-`suSkF9au7t}?^0EFGhV+_3=kyfrT&se?8B3{@X_!g*S0Mh)uq%^ zOOmtIGw|n5#`VZ*VE30<5}@&M&)t@G1j$MIO1sbgYtBjjlLY|RMmeGk9DqF3^A`^c zkPa~8FwW%W*GG!r$K)A1mr>+&rzpkea*rE(D}Y}H9Y zJ>!a9`msYVx**GLA~FBomfIMdA|aXIMGttia8x<#4PxD8J@0PK04l&@ug@zL4n-ZU?Cl?&5l(~~qRr|TzgxBYW?)Z4}^$8Dh$Qvd7 z!E$|ZkXeMSsF7SHrth3+&*Cf7p?hEqEOZG;qWK1LLFA{8O?i&=GSuA*9kkz8nFJ&# z9u_>T4(N%AcBEL&x{fmExJE;1^YGMFj>ngcZLGYYo{EyqX5Xc~UVQuIsS{yyrIp#> zJV7PbOfa#t@b1n+Rifg5WH)1eSsin+PaY9H+ZoGtL-A4{sSI^GrH*u5orN^0RQYO7 z6HUr543|9o2qwq|;Xi>#MvUeREetyxw*&ci7avcK+vNW?SFsi84@tEDOBxSYr#_$| zDU`6+pTL+Cgx6I)P*wpOkJljKCzX^v{3sGW|0CJyqMh%xb}scbw1$}9lC#F6K7$k}2vF^*JUvRTpIzZ!cni*r@4;|9 zbonyw#oQG3wHHE${V_cj6&~CXT@x`fu9JQ0N_^f6wJfQcdI&#<5R)z%kY?RPOiSO%vq9f8*RUPEpn$z+jXvUDv2#}-sGO$ZU(pO-s zDFt=tr65s^DZllyzml$(GsqN#39O{OZ%h8dmMeKDpk2(?i7UdvImSLj(k zUj#F`YX?E~H+1qfswanb1hTbSxvZ`hr2iz^zE9C2_$iQPHVLHvr%e>qi;U28Xj;P+ zf2WL#aag*N=m-Dw?3XjnfjZ`Notc*UtP2k$8#VE^<6lJU#!OBCscZbv)vnnu`D;r> zW*z5l-)&-4M z*w4{&NZEDBwMT2YnMI8tz1)iJKhJ4sX^3V-OHeg(K9?GXoGFaxC;Rkw>t{<(aWyr7 zv+82V7b0X|T-YM~h%zazB*yJ6hNwPz_VbSnTqQ@UkBjw0H72m2c8QvD>N6X$tdgfA&6>kiPcZ;;6PsJ{=CfyL?=Y^cCB8Y5kXeSuWW1 zMan;<5}-@B_hKyJ^Z1&&aq=5L8Q7y7so%2MGmX$LTQGw6sV|@!9nVpx6*z_PR>xs< z|6lxI!4*k!_DgU-a)I2=@)6&hNCHwGAXb57COvLdrR zLr(}MPV;@{OF49&4%_+&sZ>u$Eir5N68CnD?4N%&N1{RQ6$xHTKm;%4J0;F&=l)=% zpS%>V<9B(p_K@2DA(f{KlyaGay5s(jyse}5%v=UuN%f+FKY4pgLg>cH9q4-(jyS_w z{qR2fp=j=~{v7S}e3mZV5SuH6{Cr~OeijzgEt2X_jKVd%AX+S63FsZBb6_bwes%BY z=5o0;U9iUaVd25AGknmXp13C?d*<$VrNs$qy_!H{axraG5()V)*I58vpMEu|3~PN0F4P z3u00(Ouu4p<-{Q#);Y9T{D_<6X8ii{#6mB#03Dgc?L9CCPWiMEHF{9u&vrM?v0>@k zhVj&c{aY`FospYHJyA{`K6yx#)B|~cf}IAENZm=d7+*6m9$iFnd?rX)3bKD^^{Fx)+zgTx5`|u{80jGVl?h2NQ+`;{vC8UgK{sGK{r!ZSJ@j zeK@VHl3%fph*z3;E*`xWKcXj%)cAONybvp$X$e9$w(L5^O$Wx!_$}@Jc=Zcn;!@So z4p-Dx6;(^1ty)i1)zDu@9@wBK*=O-PT@WGnye&1cj}1;gBzD%m)G1QjXD1-Y@RK3C zJLZDU+u1J#=B{OTpy;KCX_fWKUenCF)>76)&~#_7zoFY+;H$K++{SdIU4PE0H7#{H z+`4KcNxf~zb=$B-5_e=Of_^@WGUCDnpB0sEyWLg2v>BJFs$yQVeP%=_8Az?KO4PAfW_9hK^3@_Qk6 z!e*ju^1YtB(wOd}9-`A&dN*cRHzv^fr!9L>qb7xeK-reWG}D8jZ!ow%elhi`bfxqk zDJw2Ii9NI)5p+>(d|z(L~ z6Ck5o{>ZmT7y;~m-1wk~J-OX?Rj4N1F-qL7w9d0jf4TIMo=+16B#=)J9?n{RVpY?kdt-{~9++&ud> zt&9V=eVmrv2xo`}lf`0c3xy4NoZb?5`u5J3Fv>pwOW$OcLgkzSm$qp&n9W{A`%RBt za747ONRA45dO2Z>lz4}y(>F+jMN@J^!Z2>y1l2IEO*j5b$O%gA*G6chgQtaq6HwpQa$>**Sv(e1%)sIl*kX4&<^nYDE;ViZWkAh%yit(y z_3qNtw~XoJ^G4=XIi0M4n@)NGD8@N-SwIR0l|e;Z=rKIx!3~>h(%a{sPpP)Oupw!P zO>t9E0IRKbKD4?Rj#REn68D{#8q{+8C#od>NqD+Hul;X!PR#ls5dYp z*E)1PC(MY&1>6{$v>ssAmE!^>fQbD}w5so8u=u!NzU)LB!h&Q7A z0Fta5#4yKFe2IY-N<=NI+mKqo)&ABx$n%RtwUmpSQFF!HdWTq_8OU!5&^BoSOrI78 zW6n`djEG+rn%pm!B=h~J_j(~*BM&}m=mQp#hbEookKNMH$i}RVoK?yI&QAJ^fDV4Z zKf%0g0S-)Ihk+b8Pgbb}MNzM_Yl6TECfFa?7AdJVJ+%mPm?uc$HAEQf`M_dvNG0iE zzY}gFv0{EYpmHVuNS2Dl4lyqE`WZocS9uyZ>;k9Eb-L3USxtNgmkeGu_GPmA8NEhv zQM!t1D*`^X`;W{H6{CIlD6?qS{3T&{W!4`de4)abAQt*nn(l}&z-iWZW2 z<*`n`hFh#4J+9un}%vi*(U9lgeXxTK5 ziPzNg`F`av9Sk97Ph!Sw$d8?B3lxOj4uMXFuzf2p%{HV9jVhdNzwPB!9E*7tuV;~X zyChEQ!muQuyT2=G6RlXb4HKjq;6`)4CEGb-5g3on_ zL2XF-f>Vklzu1vYi{arf;+&y7)?7Cj24Jk-dnvY&Locll9_SHJ4R%G#eim!l=-xQj ze2#R4aF&?PT$Qu@4^w9u*JS&!VH6Vu6zQ5uw{$ZRY3Z&_I>zW2Fu($&r5i*##w12} zhk)c@bW1aG#CYEQzrCOCuiO2*wyTcwI3?Fny&pb524r~+s=D}c)>UQ>8e3ETau(}Q zXyO*irZaP7PTY8zlN9{o!;i;x?ygPS+aI1=ezo~KL22D|kj#eWqtip;yi6(KV5Rb{PNkOB4B?*&GJW`c|Wcen=2qf}(WBL-rDk##R<$ z2CaeRCM*`)qk}$@t8L__*mmC3w{NDgWyJC`mD4008rCdPkA9>xsNdm!Ql^+ZBez#q zpzEcr6lBqwcxMg=?rU=l=3lA3PM=Tc5%byq{5licf#giAai$mY+ssDr{5}_Hcze*S zzl52Nnm(+zE^wbk+)4le zHsP>O{ObJDXt^Jjqo&)f45kfe1;1c^Nzu3dM0Ix2zZV?7EaZJS7_CD{L3=_M?@Rki zKKxnU?)siv4)q5TL>sGJAFnD_Otg$vvxo|)Mf0t;SmyJQ+_dIvKYZnxADF#<2|X^^ z)#G^Xa{F&sa~nl8qOyDVL0wDwmFi{5e73bDa$Q^j@_ZEGa|Oz5%uX*JhYwG_FgcgI zdu9?$}M=c+EGp8!wi#!g-dszT=+{whtyuc*F+>C4U|C?F(Ky zOU0nnwXuv+z(Imww=rV04wrT>#!w#RZ{z!`-5M9xKCUdD_Lwhw0g@%fgvN-~2*kT* z8s!r5=-x$*`;L;b5@mmfA)e%!RBC6#M#69Pj*>IjQwlj!wO-fqO+|X1JlNVcu9K6f zMkNd_G`Z52(Sz#nMUuy@o5HG}e`dgkyQ1_m%fuG%j#JHxGt>Ol{f`Iteo`Lj}Ys8co-nPwxE@%+%3(D@RPo!@pe`wZ$6sjLnre^7DS#0{FC^a{)qg=a*Vr z6TJ>d;RHwcy};?bu^=v3N5o^c`0huc(&)wHH;6=y;vIm<@L=v19r9lgVg2;~t5ZR7 zH{U|1ye1+0@59m>-gD#@$~$B77z^#ucV&s<#sq(w+n*0pR)<$1X z8`V6ltFI2N*Kb^%jTbbp7OHfA{#*1XI%JM0U?#X1 ze3YtHIE(3WzdNWaNxbD@UxFOKrpXCq9&(;o9H4+7hfelLjX8VGYt@x=_j8UkEv)q? zYo0{QF>NjpJvc=c$;hupbF8fMxQed7S@_^)G1pK*bMAsO;Aqzh`?0NYHyHAvJ}D)h ze7YVmx76WtCH{raJ2KiTAYda+E54{0+1NQ)OU$bm-~6lAACR+}r~GEv{N+BK>~v9^ zF&MKwt?tcO<|o@eNGVzJv*!AZRA}K+v+J3ImfGciMCV|9i41is?ZoNzzM3OSk->lo zHagw1)4__>BUQuRG*NDfJ`6oYnh{4Ag%=iS6fKTg_xCQBu9Ql7zeYn41Fyoaom^3i zK?l=vI$CrE0^;EtGm#s{ot{mMjM@sYibJQM)n4X&_c+xOuvmfAHpc4G2fOyiy*Ch2 zzQ*J!?WE}J{9wi?%zZI_73e6>Y6EdBv% zus$U!Nz&Q;3*dB5Xz@XF=91GxXUO2I)kFpH2>TOO{BRV9gp3VIk^=14?w{ZV<4zdU z_u_;6ly2W(%S!xkCNQvXDDLfmZQ^e1xfyT))7J&G)@Yeze%a`g(U4Z}%eWeUytNls zkyS)G?&V8)S%L1H&atlp%iX#>@io65w|Zc?l6sTjwhRFK*mSEa9%(&|Xr)-# z@i|#Et_6Di{@O1(AKXEGwxFkt3-oEMi63xl`tB%)T}Q7s;GM~*=iS0x5~>Uvu5w5x zx_iGlS%I!Cn$mLs&E%FPH^!4R+HXn+B)#pK&;H;tR;goG!Y#+|pS2VoraYZtuL3TY z%RR%s5^@S+YOJqIf6>qljkviws*6PdX>Q*CCJ0qhAf(M*BXO~Rh$_n4BA6K-761Lx z?B$A;8JrhBD?KUWPPf>e0u=smN^W$?VDx!fHQ*-P%(x}`3f3%XXHYv2GJkr17Yr=g zH(Ac2QHtr)nqp7i;k>Dz4bz+1{Cy*d)zh93VRG#z)=SWzM7%zEU1L9=H$gQUvNpXo z6p@ckm+?CqHaJwALyhe%^5S#6f+==&oUS&SCFhd9a~cl2!h%=u6}9-F%GdQQ9QRI<{I~&#t7X}C)u^lJ1Z$XM)Dh1dilKJ8 z$O5Q=UucFC7&CYC(O%N$6*sR$W1{Uz4@&3(d^wd@=#*?X5Y?FXZ%DHGuN^Pj29(N_ zPU%68UL;nan@_x5jv3WF$!Z4MB)acIIOitd_MvHOe6qHc4WZDrgEE^4oWknG_Zy=M zT;ZDfH1qaG?GNN^uZe!FT39FOB{tsjq{RnVq4vh%-8LVRZ-Xy{%UiCo_8P6*DcmK91ITrISzfuL* z`O(&rJw7cHmrU`&FFy1FbGRnDL1#=W`W8Lr3O3Tn`LLj z7tdt{y(C24RrK)gYIArDsq<9i|yR1gsML8n%Bk3F&f{f9(~!q@TltY zlI(LDeHfEiNl|2C!eP7VYh5KpdF17;&lY6sw_B;VlF|beSmPk%RH?qaE4P+#ffd2u zPrRNajLpxGm)Ewd&okG@jslirl8zLVugQ}4S)DfqdWAIH8j+p*?s5{rF6@=Uj@V?o zZ>rtaOoHHIxBrN!)xN^a)jjghTmRwUc1CIi%7$MzAO@Q-V7I``1J@@w)2mB6vuH(M zjSb|YYSdAF4xSAZ=t#HA5hIpIHqZ8&9&g1}M;4`c{)vVm^3dD)6GO_S^5nk=bA z5@Yf9l`icC72QIN2JuPeI6f2*FN8v5{R!t4vtjfV8o<nZ$z7G7S^*qh?E%j zwv~wJ<_3=yC8{z73SLI1dbjhn2>3yNd3~?fIj^3!M66QJs)ol9lGi=4J_xVT`s!)B}Dr#YecN}l{{C#M0 zgkC*B9U)E4qNR>)6+fChp#XAUPn}n z`Z^SVp8mw;Bu;7<=Ds}5)|=aW6?3+_gd*Q>dDt24do8Yx3ccEqDUal^;u)@S#c@u| zZ&TFf7S5S1BwbQHyoWY-6D?r2iK*Yfh4*FiDC}yms2t}e49u7DxHvPTe%4}wLLAWI zx|cdGt@a ze}K`KrQi;o@>>?%tq)qH-|O-f`+O;nlG3z{gjJB`M4j4Y$~if{2ypH}z}kdYp;mS| zDlbH1et~n?7u`3S^A>~vF}W&-7WOw(4shT!5JIYKh6_eIHct9a^2k-x(!ux+KXY%` z5L+K=SEx~64y~VnGn6^nR|tR7$%P<%fj{FAWkdGw6yB0yvt+qL9*vg3sTRbJQX$I> zZ$*Aa0hVn{u0<|be0~Z~2nRY1i?3>h=8c`EiNEcZwyYk8UF;=TlP>kP@YzLuCM~;`;7jqiA}vXM3X)kt)B`AFYv;G0!{qxf1wi zOxZc44%e_e&{q93l;NK|w*k>WX%H{ILa!^Bninp7zvcz&pm={@l4Otl?NTtMC^Br3 zxDraeY9=W_nG!Gj1+}76pexD(WsvhES1Nbv#fVoPA){qz5O4u>P+t&QTf=4cUH2#V zZLmR5M=%4*l}W)be~0bBx?1~rWu`lr4HwpHni6#|9jJQ_*~Weu7t`=*tM1!>?0qe_ z~I-h!&FFR_PpvKVLA(MP|EwsTv2ezWQ|H{2M74GWDfTQZv)hO*MA4ZFHCM#!7o zt%}dBttX02qi$TnOsqWYDH&f{-Red>cMe{WYs63PGHM@KQlwre0{CZG3a0c}l9D@>eP{Ii(^ zy(P~7aSA2fqF7TIZzWF)X&cTKrrWHf!+KB&pQC(>MEssEY*)w>oS)|U-q}qjV%UH# zRAN5eIs&^0)fd+1a=38pdLKvFjdY-B)VE+l!S(Fkq<=WzPUXLhSd=$)PPJV0k?=Wk zy!i#zX-^?{m|n|0(AvZ5TUoaWLje1sz@GRxavl|@FePU>gJHJ#in zDQviBLgW8-Pq)8ocCvER%Tm=ToZLC?MAy7%nR8^_TVF`g>pq2&oODZlGc*k>7(UzR zf~xSX3aPUAa~HGb6!@p?bzE~ewbj)1SSWOYF=9asEn};GuDZ7z*Y7P^pEs5p(|Oww zl~MH}0%gmCJLH2%Z~sV{W5Auk_xpWY+p#x=ZHv8?gk($M zPzc;0ozmx$-GgDb#`p1NFQ4XG$j_URM%AhgaGX!&wMFgo%dbY;EyzrALs;W&n4yxDELBqk7Q%&O0-rsM`Rv)2B z9o;!Ftfc?=ELZOAZ&5tFDBB1>9456MkwyHJCyRs$qe~(q4@(+e=uKfkf33N;o8I=XTEQw~b|(0gsg=;JhrF z&&QOwl(>9UO$2^)mT?kJw!M0Ma!6XGAWM%cCTAA)H6`C!_@M|Y*O2KCpV z9#G?d;_ri$nDplIrV)~+_~XHi?sScnW5O5K6vk>c0G;Zh=zc^&CH5`!;M^g#A#trb zAl_fgm$nTjC*OV%9vK8P1t`Grz0h5QdaA{4UlvBPG^*G)1Np1Ig_{3M=kfoS0j@^DYuX^dLg zFDnibTxRArKV=)R?15vnG|7+FvwixyuG%`7>@}tjo%c6GZ8?XsdS5H^*YyrV@Yd;5vx#$Gnry=P`m4DhMpY*~Zzbe+#e%FM^0k|gaC8E+0=_3<~Efis1z;(@3B0yys+Pk8U5#Cp0?DAOE^ z9h>#SK>I%-|22d`K**&Jnx+Id4b|LZh1815D*OMwWrqX=x13m0U9)oal8hNH+{`rv zieY!@Q#&I4YWh^gP*YmkSw3> ze_VP`m3p(_34V+E1tUHOp=#S>pvGL=7g30|oNGHloY7_wr=2n9%9{p$!i@iYtxWIN z$|z?5;zaU9*-XAi9EyJ|lWIQfKP-|_r=l(>SCqal_Y5xY`f!(|e0aUzC-Zc(eqmiI zH zlYAle*Y#w|gP+%IKK^;jJG>3b{P$Oy_fuJ~Pn-o=9(JPp_9;$q)!|0^ToNu1`FKI^ zZ_#ZRJqZ8Pr0}%zZHHg)YQsGn05?8Cjtd+#0lx1l8m+b}okQs$j&v=dT~%rRxBe$i zy^_e_o{J{Ye?(8Bu-0i zRY|GwsEi~oO|cE_unwAl2JyDpy$Mg7!1-~i*$bFW{^cmNw8hb$&EGz5x`}+NYBNu? zT*`iqm0|1qM{@tImCE>Q@AIFF<~)P^ZW=C*Z+bl4H|9yl;xg&`(ivhYc0Qnq=4R%y zX@0&m+Rwb7#;f#rW&JE{eKcv*?Yy*fPBqBhVD(Ka$6qg~H+V?!_Fz4Pgj^?Ki9qlL zPpHjLF)#IjXw@SvD*i@&^w8uPbv|v1Wpbi$^mmTDpKm?vb}W>)&n-mMKgxpgULrZW zhVtkIGFjU~>uoIu>)Zl+ykK9GWPBd(#(@X{Js+)8`)-_qW~icW-IG8oQA&F*r6;BhIfDB`4?wI{{gFSBGU+!FADSirs&O;_ z5jFEkFI`O6swsOnYjfxjXPW|qPVxK`YYlt2M-Fgn~3XpAJAGh zyku4Z4g|5eb)W2ok9AE&bJrA+{4S9`?$lq;U*F596A-%0sUD1sR@V6ElTI04yqo>u zt5dBKxwGC`{jcBC$xCjA&P0z((XC`yj!v`4Cl+RV7gv)$Lo&zth}R#?Gqe8Ov94!~ zmzpLI7Y!J;?x~y~pzjm<_`PGbHIk>7*FV(qYjLSg$&+3k-^f6;8S~P#&_!}*R9i%0 z#s0bfj`uMRwDR(#I%M~(lIoY)Y^*cRuZxjr@0H*EAcF+*A1t2zTVCWI z-R1H#-Wp*^R?;!?Ot5eb9DqwAJBrK)&WqFKGo$nyM=D(rY6w@laQSuSGabHot+bS+ zeGLa|RZ4*&H3?e6s>!&i%_U@Nv{dWvZ^pQ~04J3}dg{?4(-SbgNsVbZMv}dSYtGu4 zajT&`WB4x9yIrry!ISZ(v6W{yRuO+fg*kKDq1gi^!K^;l0#UwX%>5WqZKC3{*W)Ha zeO+s)m+S!{m^SfBky#fivFO={1s-Ur#Ay{HPw|QXdL-aGYg{57!v>y{MsQ~MiPWYT zW+4V5^&gP}R2O5Lby1B?hlbX5hB~hsHhZx2B=rUkYq9z@AdsHH5ilc^kFyc*Ml1?~c`3ZR~u5?7y{Psw%mG~AD#Dz<^ zcENS6%u{1{Tgi_8HnFeuyL&&Yn|s_9Hlv`qFnI(MZ8$R1$R;!(Z%$7k?Q3fNetlMX zV6Uz6R*NW}Xh34KIp_BA#F0Qx@FQnAE?8Obl~`ULBt7Z}rt7@_1N05=@yL$9P_o0N zu9E(VxpBlyK~$$sR|6ZDny%A%jltdm!oDIq%M=)RR3|Xtc$6HRX;=E9OfyN!>lJ%L z!;a=iK1;x2x{<3*R%2FCr0AVuSn08{OTrt#hbi&*mL2&mgsgLOx<+nPl&0gO8F7D~ zic9IHoG+>iwGWnr>`w}-@5>6OyV?CXApJbAQ~%-ub|$-{N;q~Sb-Y{Sq%PR|(CLI= zX_Df-xbnr&1^pvPS^Sthn+{#}w@nt=#(R-@qmQ)J`Gb;bnTyyIS>U2zdjplrX+_Ko zlRK#4NZ8yAA-iuQ9dU}}nS@3c=7~6q?X!~n3!>aznrS?RWIotU04qlo?Q^y@U%|bB zj`DMp7n1s#PXk~sWRO3+sW{-ONQAucfpMHg&Ud&a)UrU8Bcmp%pJlo^1&oc~p-&XQ ztK|4v;vPEs^SAtYXx`tW<13E@_u6RYe=)Xo3sa2|q317TGuY*%Un9h#-IU-a^h{w=>b?sGFK?a^^! z+wzM#(aHeq2Z$V1hVIe4&JHP=FK;FpPe2D|>3ljI;w|Fd<1O?cS@a)b-w;XjXH2IV zAp9oieiu@4h3!A0Z{f-6iyl6!EeR`#Ul`1A0B5&*JgP6gFZK{H*u>z9OM$aCJFhB8 zuxu-HmkbB}+37Iy!jd#zOW}J5s=pf6#IYJ2+ueI}Ms+k24dvK7yEfUO)_uVgQz<<1 z_2)Vk>;O|Xi}{a8<>4Rj56=X!=miwb?H9`&W_@qoUY(ab0~uf=|xT z@x%;J>24qeyZJ?1d}wov9|gsT#!+S9LRYlN=GUzwHd|?6U$iJ;6up~oha}(Tzv)xk zriv^Kln_0uGW4-ur7-k)HO-IKny{n}$N?Z<8wOAeGH>6aWB?^qOul_G{qqwtXEK%uun z;)b$yz55JZAgS0cv|h9CIQyBoo2LP7U8UFR+~3ooEI!k%(S=XVndt*qf#}oIs`Q~z z!}OJ>FGH{Mrv~1niv3~Qb+pQy zSZoGBZ3Q_zGTF!+^lB)p9%$Ax?W%ch_;ORY$Hxl=-N8BSwl6&v znKQeT*`50CH@X8!#*TJniFYrG)lJ(u%1zn7jC*rqWAtQrklVAW@8+<4}gCjBz*D|dxZAmktUOuV^M z-ILhmLkr1Z?AS!|5dIfO!R=%YqjX@S^V6(>S`;j7+vCc*hOCadvs!H29gR-%ZU&HLIUHlRcDx0nI z5a-Er*4l$)Z+LQ<{kG_9V+(H-463L3ZpU0-En9Cs_)SPS;5fEI&eH0-0P%?a`(>qn z_b{X;zFghV5y&`Svx1X_Ht?l&I!3gJ{Bwq0w|>!)G=LBH_4aXeQF8&pUhyGP^pvCP z@EeGUpj76(;bG6AM1xF}GaOiNMbVFa`S<&ndPL?}NW0NulIk>%I?J;XTEi-nvD7>d zxzwnA4JUCd=e_tOucfa+bhnsl+Y^@x_d3}-o2{<1sE%H_qzm*7<&b)W*5`9HLv4Ru zgxD?BkwUGJj6Et)39K_1z3xvJ=x9(dDtpks)seV`9#1SveK1z%>hF=nvboV{mxA*- z6`l9J+e+hFM3?LKcx^-E&mP!wG5h#qbXijb5hc|1&^}HBAjl!X5{m!^4-)mMeY|YM z*0mvs6#M{bFNo1p!xpNw(E4o)^AHo`I>2;;tk#8ZboJ(ZFgMXTa^`xi3oeJ1@rTZb z?bT^is>Mek24aaBQ zN;@%AW5sWHmZ(fF#gq3p%*>xBa59~M_@yEeGeUPgx2kz%?8UhQ5a^wN*1Y0@KtVs+ z?6b$giQ)^0v>O(8GI8bO-%pD$)f;2%!p;URsP*hulyWxRya5@14M%bavsm#>pWcao z#Q0x0YpqMXm`Mw{(+(d)tN;O}KDpC34+s8m>`Al@b2fw)eM1(KeqVSiAxX8ZtzyF_ z76LYfF8q=5Kk&r}FUEY7%o6ArE>PSQU)(iGuM$kFpTjgk@b9Rre0Vd-O;4hY%!I%y zO;t_5xtz|}e#UfAoy@g(-7-wZcg~awNLH9WnMzXu3XGSVfoh<~)mA^8{6$e)b3f-% zA}oTnexd^=J7_Muv7RPg!5p>96^Mnd^rqizI`Ez2OkUAks!t40B$hf&vcV41IrV#td&)RH&cn^uf` zDu#`Cyg|WZi;5iruk7}`>5d!9YQBz0n-^%1bv!7x=38R=#~EW1zwkuRz}&a6OGKQp zjNI9P$+Ciep!QvrzkQ2`5X864L##|`aHhTJqx7mA{Nj`fv}JfLA-!f9vsr&l=$QwZ zvWwNa59Fy}&2L}2R`=(*|8v;5i;m)ZHN^-2x2fIkHSDg2v&ti_ZHhd690@V>v$HW= zM?ZH5#QE$3{xs|weu_~zv3D<WwE-^(v46((x`|sZT%$Uo zd~D_`?V0FBL1S(Hz8}n|y@<0Yig34k`)Idl4s>IT^{VrL#!UCi0b9Vnyz#JK*F_0M zJrlKx!S9aR2ph5;g1>bO*L17oc^bPe=dg~o?cJ2qh?2P?)=2l6Dxfw5vNgJmNKd#{ z*q{%Lv?flN%7X*L=qOXr;Mw9vpX{bW7pA^l@LTxIb<=1i=fvsM63@|rWDmh7-wiUo zy}EKy_wJEe-2sxA_z4DGYiE4%kJGGudvjG?-DKv_xY^dCf0yJ>CbVNXo|i4~hbiXY=wlzGc-Vw# zr!mHRHls^!sPGMN`J+hRe_^{m3ZX3zs{^=XH$=SFuSXPi~VBwjm{0J*04Y zfyzh20mRy18DT$KFgv^4|!`n&TB)u=^~*mcnc zI6t#u6}M9VBOh%Mbuc#9#BTe4U`xG0z64CSJZW!xSiYCjU*7=UzYiAtD`re` zbmGF&ZaauePYz5*9>|)vvGrP86f0;RDqdt-qV1E{ihu@ffu0I~fEQnLO(o@IJhlD6$PJ2?Sn#f#z@2pK z;LvIix}VVqvo8h8YTIpAZ4Zob3KnglodWE9X?+byDe(bb1qjJm?5upU)^m_$!|}hN zQv_vG>I%Hwch-pQ+kS0QkQYyF@B(}!W+bAh^x?|)a-!>gz} zg3XN<+W?z@qb#Ai5~>a0vsU`;C5nB%+{rgsOzqh{n-`{oO-0`mwA8;$M%2VH>E9fQxx;k)qoa#Y zdm>OFX^1o}Jhhi>YS%cJqV=9BTxV=^!qQQsfz4c%mH27bBB~@)zKG6*zx>d6@GPY| zTHMj0M&_hD2sjQ0u0SIHokwye{z{Z!o;sc`xCZUY(O_jK9L0H^ZJeRIU=6r7KI2Rv zZ0V7UNPs2&XF-rr<}nQU?MCsa$^57yPlU!$_<&w(X;E0ThUaNtq|LtddogSadZYO<_7<6K1Ji?Vw&&H4M1qn07CW zoKZjC$7p+I_(%|Ez1Cv2+mj+LW_8BcX=z7ijg~+f936fWVL-?@X}ChzGRPNJ9*Qo@ z(c{xkzA8VE!bztPgRpzs$BGV7)D4;rOWWose$ zKc0H>wz`_jDqXQI)JT1YQx)wN6eSNXGEgoP(-J1(!`bn^zToFI;Weq#BMg!rCQ8En z2)sfc4Sk}zOY!gSw$2uwUq=rk^DSJpP@$Y_(nlr%=v=e!5}wa#7)(wtOeKCNdXk7* zbGEkpiJiOX0P!dE(%)|jvv=i3e~6MG_EFh24-4Bz@c}!1f-%oUdw+Iae1G^7JqARP zhZ`xOy{0VMoZ<)M`L;pAu2`e4E2i!0`pni6!OpPjhAT8XdDw9j^geeIMaBvGK=#Ah zn;zvC5=u0xht>($(Gb2H@QQkw?7Jn`wC8ipffEszz-3;RmA<~~EFpGB>lkxef1`QK zLKM%6#=9%W-1wu;Vb@0=eKXy72#FbD_?_uyQRD(_@puqe3zj>r1G-DQgUBqqXv^;v zX{LL>oQ@7^iTP7RKqG|>0DPy_hwA}^-WFrC?g!ILP79^3+)A1}hFq)-t&VmdO|27R zrm~j*BO{MO9dcw5e5=<+EpeFmbkcV-speGgUHW3$c7UXSxF06Ps)44)f6`LQ^)(N=A= z|D+i1g!{Ux>hkefC&%44vOFlTL_@9(;T%BHTS13xk%WtM zwZ&ICj7i!aFl6D4>}r1ykAtDGBY;26?Q`AfY8z+;^r1^2n=HS!8jLRK%CusB@j@9O z?=+Qzyb-*FtO1Fg%h%)%SvOVacL%u(v*-Jpcn%d)GU#!o~WSjohuk@h;(EE`` zo?5uvHBvndR9s$$2I^$&*Di~7E&}j1NVFPT)G;H&UnlhLO2%q>9guji4Q9v~SaBLm zlpCr(l`GALaHkp@nl*v@aS**4Gltop^9+MlkC~1jhXOc`i||(yw-oby*W9H)wCgSu z{emM1l0bDHe9+=*@2Ya0qpwzu=GiVL_{-|i(pLu6iIkza=TUFge5p391@(6(biyS= zrIJjY1Z4;e?+m_7WZy_V;q5rQPNqDjg%lnrd|5%4;c5-a!it~UVhumbZWai2iKg0l zbR5r&K>kEG*w3MGJMN$uGRn0ldcLwBo^mN=l}JbF_SD~O|5(}N0@@jIVSCIcMp##H^?2U9Mb}|XqaoYR%UDfV^+^== zEh#Yz-EM-0i4A87)e&y{5LAHmJ(tF&bYwBPqIh7pBM*%8TzWi#8LM_VY`qCKWAaWUWcs!cQ{+ zMF?!+#G&dNknR#;10n@spn z!##OmC032dA8Hx8e60_Cm>Oh=;S@-d1HraLR7~W5-g6-Xes@ow!v(LY$KHWu&uQ1% zMd!MW+}XKrjeJQxDl4e|yMg6;0bioZUf#o5SUx%d__Rc^ipyDfqTau06qq+mbX?e? zd2fMy_(t@y>gC%D%nB-Em9+oz0QE#g3Gs5 z%lbo30ZO@*C!!wdtz)GD0Kdj{&rBc6e@0v2j18u;_Wy`%4(Hy(gVR^hhM{Q9w&?R7 zdd7!Thwe~Tg>EKK zVUvlQSnj(?@AdkLUT#I0$hoGv?Hl}fTA&1EGcx4 z2NTX+hMih1$N|${>PS+ExDU;dDm1{FXKr4edmoms#68$mdGDEWF@pRKZrU|$@pYIs z!3AUScwPee9$$Mafb%{7j?aZFu4z5`XBrxr?-buV!8f2gK2P3P z%(CAj{MrGipT(j2|rxA(Qgj4<}zw=Jg=wijk4 z8jRUIN9J76q5&?3l#c?I`~d=ke<^^U$uG)Im<@F2>WnJj>_=NYqu>0Wz#`=ny5;VV z!8KT=sCsJ-&ff@WyyRA2gGEseBt0Z%0g91t$+5f1y08qcoY6-lbCBv%mFPR79?LJ( zCRgx_Yd9|;D>pa2Ip4i8a8jc1P?H(v8Tw_k&^l!3r&(4o?@)I^?fXL&>Iq>{5YgpF zhfl5~#&kcEXP%;0+|-OKxy%e9E>uOf9S}Y|VZsfz^+TWpqHl#QG%el{`=loAJ6G6} zUjO_0bXX*^f#FM3#{kA{1`C)AI}gR_VZ}Qdfg!hyIE|W_Q-oNzxFO86U9V7p3 zsBALgmMut;{<)^Orf>piY;nx#@tlR3q4+H+;RV0GabL5I*zLiD#C{Vw33X7V@eK)H z(5v*2PU$~rDNDl_5X93%Vnc?abM6qOSAmdJJSjCiZJ-Uf~W5@jI6>b_c4+d z-?B9!!>z3Uqq?5Aa{r@l)NELd)?E95`pg%S@4Bw=x-{g0;s?Jd_joV|D>@rWbn{2) zAnDY&*~fxjZira1#Nl%NkWZTJ06B@p1%%)RYpt+1dTHB?KON#Xh4}}<_>$9(4OeXbRk+t9NlY<&NZ|-+`(fG9ib4Xyl=&f&BGQB$C{A^b-Xqk4bONbv zsm*b#yT+9%+7pFuv~0{S(j6rqH)yft6D6^{JiaqeOHP6R)b^2_{C4m^B65B?QMikl ztQ=HsZaY_lk-bmXYxzGf*{O)kR2Anp1tykTcTEYdhpr zY_V87U-ND`e8Qb0ugqlvtnM3mo}}zct9D@;Pz^!b{6{2fv_sw(9OawM-{6?x-BRvH zePn+?u6H|jcxjZ#-XvCgYu@u6`348QHs1b^h)$&5x+z`SY@JBz#b=B2Xjtcpsce;i z6}b-hmn|LH3-%7ZAvcjJDgCKDD!kL;ev6r}e@?a?ZIlN5eVJ8;XF`+f)m)v86CZL` zF08mjbM^%7j&pb8nw^@+}!rX2Y zh~-&xL9D6NEC6)J39>S_@d1HH(QAA^C~Xi#7;UvK1Oxz2R&K4Zizru~enJE#Lt{U1?y5OvVhEq6NYp5+lU>fZ0h z0XJe5+VEG$Yjo0iR(gceR(>VesPoXKdeRnCGz`6us=y&T0p!kSv822Hg>h5`{V_O` zK}&n1b|v0==LbaA64I9sn&-P_$2WS1#kS>al4Gku$xDCnWgUzY!pL-k<#{So{q4;$ zefFIaHLjxJ$BK$Y`;;vh=mN;Upz+FV_2Sd|k?(g_Ow-5I_+~dqJV%sxk?EOMShm#H z^WXTS8UXdXVocIPdd4?U-2AIq?%0nzGv_^i?~DHqvwFZ0bUYE~g3rHhl&KpJv$xP) z#!}eSM-{y(`_!YH?6tu;;FD+;l`>GM`m~pBEbJ&Q!7NDhuML(tfwU+0c~^T1ah-pM z2^|YS0OiB{xIWVK@8-Bo(l1BKPebVRgZ>kzG#?>}@6ehS^5-j-5k=e-yLF{AtEWsJ z05V)e4^&@7d*J$F^o|O5_u5~IpkFmNU~ihwH;y8;l}HRSRr794M!n<(FYWE?VpxuP z?8;4*$y{jmre5?P$>O~m9)YkMF7`UE2vw@VfoF7r>noa`lktSBBzsXjlTwYKF+|?; zoqEOw1lYOcyMTM(m$KrK&E91{6Qx|4iJmg|Gc#c0@*Fn;Khf2#b{aWv+?|KTtz&6I zUp9JoN91|?A!BPwkTQH8d^Qd)znE==1Qw$wH;eYfvRoZ7u3UqNeAKGpw%-)i>++I@4E^$99IlnE|Zz}hb( zLvQR|$~Hxu>R$OP8SljfFTdadcca61sT0U4`ow|^KayJCP~rd;@b~zi>tho=dXDMr z3C@^!$K#s#@{IMa)L;FIU2o=RA8s)+yF*sJE(jWr{0W=+>e)f71m;pV2sW6^-l4pCyNPi0aEHx<=STj9Q1KDtU!i?%lwJHkx zwKHL4-_qr0!PrIn`)q3v(eTId>g=e6x{8N~tE0an&Bi>$PIocMx~I_=vDrLfDn8h? z$ugZc;g#Ib97B7;8vmxp%hIW_CQsUFtSilunt?_}#$wU}IX{B`*($TMRJF7>Opx_G z`0ULT8%`)c;gcIw4q-bU^W;TTcIc86cE$Cj3V!_}Yqhir{w||){RXC>gH@h20-gc!t~A%0pIlV8|C7l(pT)<>cw#SB!@6YUx-^xK$TH(9^1PWQA#7zD zoY(I|g%qB>eovy$EWe$8+J+$psd~>iL#YhM$KE?cwkr}7-PyZu|20|Ay7EQYFul9Z zH@!xU7W4Soy)z5C>l7NjevdY?<4iL0*~vb`EYqnXW+Mru9m;K0gs!8fgtW;n)CFg} zv6!i6gX!A%KbFoitjRZQsAo#5ywJiYB?jYAI}V{Bd0oO&vE(eAdG<&+$~!8dO3Lb_SoIxGP0Sc+IKg~O zp+;7HO_{?g^AaU+ckj^-r$dpnQ31iByq!JM8OO+HuEU+pI`u_r} zVEDZdMUdGv*QCI5SW};JKq)tF-tyCYtGK91pskQksZzq6!B@c4AgxNn+XHjSQfbQ9 zp~tfGb}Hek#hMpsK<4Ch4kq#O;zFMteh`GZaRPiGu&#Sc4i?qmH{ml}c?4sefBHJ9 zM);$&5i6f~j`U7xcPv!E(upNI7uSu+Iu8Sr2jpLuf(O6NnVDvQv)(F{=I-AHeL`O z$v@Mm#Ya}it4=)w&#$+raf3#~B#0+n*){T0SpHcXMaiC!vcKF=`jOVzS&i7|zn>w= zV~*MP!4-*bPg3kSRwMX{`R+kEHuv*uj;Va(f*qiS5V}+2 zGo@5B8^G$0<1s&SNSKO~@Q6W`$vXG<`m==#uHr^xrdf?Zm|Eaok%hooUVpYnuTz>H zLd&OCY}g51DLor!m3(uckYz($B#8Kfx)XpZ=Xttskc(&VWL2b${&$SD~-nI2>BFwvIG^aef@1xVQJeLG~myHhoEu|o@i+FzDOurl_21tzXX`qd% zrnnIr6HcH?;3eHzPUFJzLiD+osHOOhDgX9ECJr{;drs*gOslRLA+6w_OHa39u7#pz ze_e!t`n{cvQ7v^WSX)WY6fibkVUf0~T3_dOTX9r0B+dpchJN?_dsrq3J zGcFJ{wnTO#gvO&gZPHR?>gbqq34KoH;`>*nq3gDYfzDcdLg)`pjeZ;ARSfvGHYlq>3VVUPu{BdHdxW>YM!<3i!C7{CvXVo zH<`Cck4W@5y0Kp`g+A!xF=T3#N7N|t?TwC(XSIHvqu)p;ajhf!`H3xACD8J$(T=|5hg4(oPY~ZNj-Z%ch;IFmE<=o3Jv0 zxMh+_Sdbngewh_?`tX@cEwSo@xb6#7oN*IC4o>PBnip@SJIuY9(at!En=OZ1_K^KY z@=8u7oun1@)M8$sEz{LQ^z)Md?&8V1SWve(R#RKMu`c$4f_<5&U)?;M!;LGj;Ln1h z2Q8&Jp?o7vB8B%)?4S6{*Sh!W=7F+e9 z%&>)qsH$2jHcLi%LZt&)`-yyktw)POzj$vLuWa=2w{r1wJ=2U+lVlCkimM)-0BlFK zUn734D!!yYc`K2B zOv}XlEoREWr6)TokznQYd-Vsu)|=WCus^~NsM#-G1)kIN+JDY^U;l!{j(!iSZWg3$ zzd%ro@=Y!$_9HyZbz>@lsfGz7?^I6ze5CY*D&xSq$(?yCH63OzGNdQ+qB;|OmcksSNcjC+sI<{ zC-t-Q`*%&TP&Reg*YH~^=Vx$NvdP8yvhV%FASE2yaZFr8qRnX*?*o>(W3K93^XO3h zjgyIqz_-u_imj+BAHbX0zFixdw0!?;0k5n%W7eeRJVeVrav(7M=S+g8J^BeE;}kAK z{`cS$s|mqtyfNgl>4RhO^||R{_1LzCg(FplcEoda$lJz=L5lA!tWzomD9rea1>u#FUh5@1nrX-0EP(1) zca-lZ?{`X84Za8N>OboKTGZ%xO7XCO*gBi-2HEPgMXj1h(l>n{L+t4b?)#SJnrwgE z`;=SV>s9R^3F?)l9U1w?d%}Pvok^qGpd1)Y<6MXWZKWFVE`AG}Lq(Pq(42)1~JRXCq zo+>fM4dF#^9-J0d)E+wYrX{-Q%-&C&H(E3j%`&yDnx#lN#EtG)-VNzwt!s&{jArEz zUl_n(@sQXzS9;9Kr?_b{#O*GHzMU+%r-I^&%TidQrC+G9BJ<>1l ztoJt5M|2-D5sfs9YUgxv6r8l-oAvo6EWbS?9jj}O8=TW&u1f1-r$wFX_`J2^jB`Wb zoFwnz+Ygo#duoI8c7#n72SWRtCg$Z^8JVosX8*|B>_ma;ZunYhQ;0mDFv9Qzdsc}B zpL)7mwmdLFp%Q*aL4hdrFFl#rR-m@4ud6>Yz27Zy4(poVH!!_4yCD<6m=Tk2T|(?j z8@?B-23PZes9{TpT>BydzwgSR!l0wkbOltA9K5561U;bhWLq-@QsH(N1rNCpvCZ`t znSvfWz4qDuTBdD@XHp=Rr+t3XDW#N~E_-OD`8IklbN@hR9~%Z&uUZC^@qAvScb$A4 zp1)vAf#im@n<^4vY;z?W)EePJy8_VoW9ksr0a{Q$*2_`rt;mx4Zhu2ZZpj1=#LopE z2KAlmbpwzy(bk--^WK$2m&7;FcHqXWTdS%rxM&f1nq*a*SvmhRS$P)-`AqT&9NGBHDdZ zeIJg1_&ho>Xkz7%x`hIZ6~O(_iil6&Jr;_AXU$ zB+ny8vjH4gEj*t>r1QD(lVa|?e=ou%E6f$IcOVXe+(vLA-Sh6s*c1rOzxAj~1!*-V zzTkV_talH=th|SuiJf68eYA}-mf`W{-xIWyMTa%>wRyfEd=ln4n6D?sTVE;bX_h7P z5_DCj><9)H!Io6Ofh=)EeKF`tqqC*+u=yJE{C;bd*_L0rId0Jy>9N6mYes~>7XNjH z!mJOiJJ;_HVrf^TE?%z)+&~%zLc-3T%%c1KVsn3iyQ&6ph)pXR#`u;FWj}|s6gq|s zS$o>DD4hlPVl#xB^84?%xo9!N6fFI(4H6rgF%68XygOCfWWyNpl?}T{0H78|P{B3g zvJmNt?AyxEnIrKFaRC*~Xz~(>wOQu!rIC+xG6?BFF5jk2N)yqw>|Cm)10Sl)pKV_w zuA8TL=LSMMS#}KXqNTQ?ToKK4U&?Z|3*}Zi*E((iV@IB=T6k-FjmiD5F+Ps^8i)Mr2T+Kgv066XHlfS(J zxj!F^E(0Uej>oTg*3+|yJ)Xkr{JwM-?BeNT_-8Hi8^C#{ zP!D|+AOy{_HFyAY$jVqncqFygD)RzrOdW%>xVoK11+zZoT3NO)dmN|9OsOST`SUA$%VUq@u>1 znx|h-&u@KRbV@)ENhpf!`ka!&y*jAcDTsj1M?&sJ6IPF}o6cXez+69>u~BJrt#wkH z=RT}jtq6)bqPn-U^jKEm5CGp7SZTx&;=oOXJP9q(|CtgeQ&i9PWtZF0HrHBoT zsUH!CfbH2Cv4`$-kN#lWGKC^UYA$>Ab8G_;qP-!W67uixg@uF<_`#LvSYDen?|{)1 z4VC1N{*^)aCnX(US|7JRiL*;T8WDOGKc!03acH)p9p3)L@t_?$Pp@nd|Me%TC;Rzz z6+-dw>Bo+L*w{~L83T}*KZl9Hq^c7U>8j+1#}fHK%k{uXNNuK$cb2>{QlBtFZ)CBkIHj2H$l-pjd?cm4@NBcrKj?`3E=Ju*+bC8r4%=XgTaIIFIKJ(#>K7qikT z%LmkG^w$P0r|wzUm2J5+4@HyDRjk`fE?B-%bj)VQ^%j*{x4;ixEQa~r?~rb1^_M!op-v4%T%#gZpDUO!=0y}F3FBX$)0VAt+YsqegH^o zO1fRL(Sfa}T5arL%6uLF~7zxlPOhFmrv za5SDj(2tluFHx{(QCvQcTyOkF>I#Va__Yfa+jHZf7iw85&pYAm9=*tvp*1DHI$-20 zZ+mGpyhQyU$#N#6K~bvQQp72Le`QP#r*0-UdcSL3XKfAEv}q-(DtRH;?9 zT{+9qV@kwlEu&sx5{%c$2BKPj2BAv8;@1)0*Mi&pIgia%ZDUsZDA$~cdGpJCDCU|L zrP&ZE(E8wsz7VrskG;CI?xe6uosFG}-f=@O(VG<|%m14=LCuZl1NcOigcf=Ou0)^n zLx1^@A|UlU*=!R8vs_IZ*^hNbWXcb=EVDc6pt~Jdq3}iNM#tR`^%4mwU%Cpb9twCvSYp1(J#g5NO|y2?Z<%XW(w9t8&*D$e^}zZfSd>F#ysAbfCpJ3-DjeKcqs?L+*@W@^0Fz`v*2LS2U9WNW2GxQ=BE~)OQK>p@#mSI??EHoQvlU$tqi7cCs`OTqyE-?x4P5b^tKs39u>@BO*yV(S z#kTlVI%RB_xdbFUqMxbyq^Ny@aerq^dr^Ul_F zrv={hI{=c0lg8<>EwLy*`Z$OQt;9;jkVod!5*kXhMNzlv1wvl=uXG;yyP=S%(O1-5 zm9w8xETVeKKlDzD5IS=X2t(wapu-!QeqnP!Fa0GA-`h_fH3p8Qn!II4+USWev(`k7 z98LBF^_$a1$BAUVacxWrjHtVQ>8`tz?y=D5M_P%n#1ToRt$x@n3B`#Qpe#kBrnvD% zVS?5!O~|8cZ7WNA;_sr;DuiMCqELJO1;V@)sFmh}mBi{@=brgo>3`$~Bj@j9Ha_&M z6b}%*E9Y@(wmTT&j$0>ItYLeuMq{)x{-{+E`AlT!K=7}P=2T@&(rzBANh{O5P}k^+ zca|&PwZ#Ia@Z)nyM#Rboy|#9}qf4V=$k0*^^oN3T$g@SKcD7Va#LdwAgfp`(LiKIo z=Z}BW*>rBcrW8?D3RVrVQux|YvmU{@^sLqOx)7%QaL$G6wF~ECRvG{34|s(hHQ@a> zTV~55%s{@>hA5q4!nm{W)gn<+&$guXM|96p0_*^V()hka{g-;lru9J*^e`3WoYtv{ z=B7ix?vC$7Zd4`wIJy-)t6b za&RZC{xg}_x7Tl7w>g%p`Z`gZMnqG^S|QSE8^7v2P4%ic{lCME9ia*fOP<`wbEIsKch$OdK$|-d#sx-FnklqN@|N+ zx-mJgo>^qNR5I}cY#}Lg{&Py#Z6V7EM)Cd;h7&Ge6WsDEkY9-B&-+dF@2t4y;~W~e zWfO-opg7ceuDp{S%>rZ?cy|oKOYp;Wd?)CXFK$BEP>2V6f`ag5lYEB(T6s!c{cbrUsg$1lCo_z9cFSkvtk$@guRaQzuY` z;+iZUI!xh#SpgC;$saTs-DtyTqdtf2Pi9RdL}{e(?ScHxCvC_8ESxv|buE4>BeRdh z8*mf$G6S(4zM1gE?2YQ;2L-<{`YjT643d>IamyorNL{?%DOX$v>}k%3gL`YFqde=m zw&rr2N!*58+CR09xBenwy-9kt=p}_L2iyYsUp-kkS&5QBnmaIJ2ITI_pK}ylq$YJ8=xubCnZ?E$z1lwO*a7TOP zq2c?nt}x{4O#kcq?~X-n9+lAK8#0+USai}r@w}vjXDWKvl>}okSBeU;gNVxyy>Njz zLrvYce;R*j3#?hJhN{W zl<~VUsQ7MXQ$HEigMzR9_U@1Gs!beFF4na)Ky9YeEi4*WZg*(@J!0%W8h_X~~lEe}K= z6Jhq?>=%5@Bl$IP2mL%vt94g{qWd=XRxm>QN6{}oFz;Cs$8!MJPuXCQ& zW%%5);&(SY0=f4t9O)uiG zzMvv=a9b?I5(BhjKDcA{!!F`GuXUOF2ydxYmN-UpWN%T;!cxgK!IYurzHwrUz+!!? zjLj?QFt-lBsDUcP{Py6$X+>o>N`s=SbgqF#6Y_gz-zTm>d?mmYMJv6!FekXx%8sUaY#L~?(RRKaYa2u)Awe{1N(_Uc?bPrulWJCx) zU|POxQF1}kq}4*&2Hj{)z~;CE(I9%a6GvHyllj9K5srwp9>3Z<*Yt6}tNLy(Lk2mH~e<8w$g~(mxl^&n6;E}I(9wS z_bU1|T=8BX{qB1YDzW0d`4vq)ost{@Q}a?{hs;2sfK-MnY@vhXP$4o^HI)Cnh0L#O ziJ@h?dT6%CHGS=dqn91X6*AiE_8{Ho4JOPY>B~jT9ARhGK^DdZog;5{t?a9Pm z(Dm|oxe49u7^0a z%C20fxst>`t7l6guii$CQNbPYLRijp!&1t`;+{&oMpAngInbsgil;JWa7{hx9D7h{ z2Hc$cijTe%Q>-FfDCi9MooR`OgDPTOP%612&gh|>2kktY@`9R+z+~^|?K%YC8gRnl z5}Dtv?Y!nuwBLtu2Yf{Xqi=5U{DP$!Z2s+|EzX~R8yW0K`51iTvm3>hpg^`b3QDJM zuj1!(|1!schB~ZsW_grS|Fpk8q{)VtX<|W4$S+$xWpifV=lGJ%-E7#IZ>!#_5$*%w z2cxSl>@_nnje|_4`b|btMM(ikQ)+@*em?z-o~;>9OG>i}|M+!2x=Pe9I%T;xEOlhi_f5z5dtF=uZz+n=jWNHBC+#nmd$}vjTOaw zrDEk7)zug|N>^uPM~J&n*;fnsRFBxP25KQ1q`yN?L-x~2@DAXqn?<3fcOWM!y>P;O z;a&Y6&+}VR>tSVA_JwZ1h(f~@y6w-UY8_5~L(Ks)>8Vfa$mrZm;`n+O%G2eV`$hJa z&b=0YgE%+?9`(Q+xQkGLpiyd5&d0q>0H}gQpm9{P72xGuD*S)LN-Y#&mFoK2mS_vl zS>R43rew;=_J>J6F%SK8F)g?V=|guwC$&Ya?D9=7{*DofT>t*A>Q0;2F#8IN5rCdq zAJ*B_H!MS!W2cV;t}>B zmu7|5(@1HljewZ`v~$(r%9}fWAU+@q{Y|IM=0X>yp4I=m`PWCXuUdve@59P-kF`_A z!7Yyu)2HyMSG@iaD-pZM5`Ty8=Dv)AZFJ1oyajy5wc%r~y>VJ9*B$B71w`#y{I-hn z{W$4xT2ILJ`-~{l9alNmwib?=0bCQUSI>+(fM@r0#b*Qii8`yHroue8v$+ve&Ez`K zF22Mh|AJsVcJti7r8oO|Ya4C}ZOTM0b=IupxoiJZdDUG%mf_iRnKy}F#G~d=KG3~u zXY5wTTE2$`Wd;trbY^p%E-Sh$SrD@=UiA?1ko~IGTvcP>?Y;!{?;MOlh4_PML7KKd z6|EgqMigHQBPzK!Km&XA8Pn*qxkK^8{2!i#ooHeI%)BICOj46m-xD1uCv}XSZAz_1 zS_6D>-7gy8zDsV9$P_A$7Grx_RPsz{@xTDWUX`IjHt*^Jg%d+I`>k+&e&+k96);DL zZlI!CGFncmP-m^^nXPq+*!uW+koe||jr?iuy&edVPO|h?HA|%0PG15%LPnhe^O8Sq4!Z($+ z#&ozwX|GSoOP+%mHO!j(T)Ef=t|%;6zRaH1Hl6TZ(rFeLO)e?9Ij5Nn@Bfd)@3exC zKZiFyVsQjiUX`ig2+wI1aavD0)#H~gJmAY=hyKW)<@Eac*SW*NV*|}E^r|~uQ+Z0z zdsa^0Rv$v%0Q#FPzwLhq;W@a}y;L5;5og)fwN!4oY#RG8o~qLHgo;Eu+M)#pMc__Q zbSz9!yI{KCYQ#mIgv}W05ma__EFj?&6Nmy~!Yx$(7!k$Qz5QN~lHbt%|42-CUZaEc{Pz z8+M;;L5C)ZXG^=&X9tZCpchIGMrV4MDGeC!YILv(eZ%zi4U_@dW{?n&;@Z(YUR1{$ zO!|w8Vpvt#Xnkek8HsvE-bF`LW6o3m+se&OxeEU4ElTkgOjq57*2pqVnxSvjxki!< zzsaOkLKy`pvApspgXWgq8W&Ewm>ZUs3vB;hVTM=T$<95n1UpouIErXqz#W7 z{+_0yzJYoV?K~G?UrTFZs9>pcNI&s)82pc<4%M4wiD@9V+tek$0(V9r?;4G<-Me|I zxk7P!L_fCvZbv|J;oJ#L1N?lJLs`nazT5TNC!5pT6<;wOV2RLLU0JkDR})YfRUC=fS*PZhVg? zG3qRdUFX=tn3V&! zBK)j-<~x~t)zkFF$!C zdGW$FMMGw*Nbc9Z~D#_?y_nco=!?SQWNwGUIW zs;2}we%d}A;qQU)5hxpRJ)=I>aDkR%=>9bQP+Rv>ahcR%8mRbSVv6;%0?G!}#u>l2 z?RApx@uQkO*;ejBv5ms(E5tghS`#MgwwPu8f(N7L?{k3i^l5-|N9(~Bkh#h@+sRreV2`z*%|k_cFiYB)T=Jjk@SKVKVz@(J z$6cp(9-PHlLJ8wGb|If)Q?+uKjRk^ie}#jzc-PWn%#6L;ps+~U-pw!?W4(szm004-hjO)7IhT$fQw)mvZ-pNBb#_=o3B37FtKen zz(m594}n*xN9${X_Mb=GJl9j!X*Rlt6+Xtd z?)cjq?liqEt?MA&YNp%Y+jGTOo_!>nHAD;lC109`{bDq_VP;L12%@Gv``l;t?7GuD zX4&W2Uyhd#-O^4<_PI$`ZO~shP<8%@Xhnu?71Hs>LcEvfB{W46D(7J_?=Xa>q;0aK z#&2(EPJnzF;(8ukS^hcD^V=ffE&_DYRgGw)5XhG(m~ zd9R?EzUAFJTtDEiX)1{JDiFl;S0?HL|g#94%kz7dtMNVbns0{XAe z3})~~=PcCA7`^cm%P2sTB9sMZ&BAn>dc}6Ng-6$>wUcPoi8_V&PE!)8;T zjFkVNgVOu$M#hlE9!5>d>j-S}RQX+=gIiyXs|L=7lQF6BT2;2+w)_Ow^rl-t9b|Jm z>C*i!&(s=Zb*kvaE zcw#SkiADM6*ntHPGqn_-6@Ge+$`=j^DiqJmP=%hRe+?)4J-^(RLy&lg41De@FE`+F4xs=`V{^Uyl=bNd@&bm;Ve6 zl4i}%tG^s1SSD}p#y{37RM=m*wJpe8%j#TyzpStH_*@Q@g7Q|52F78`4xU)(yEmC# zS3r`ZvB65OZuiIRo|fLRo~6OC;7`g@(G>8@lz84t)(QZVSiElqCVd9CAHnkjP~vKB z(K$!DrN!G|D_OJU|NFXp(00a#^?9j z9}*WW@}Q7eq8e+lR&>ErLzd|cIPYyG_N)J^I8X@k6M7kuY2RUo3Avy{PTe?cFcYul z98#AmN7Ry5W3KH}zTmljs)1r+ZF#*@<~Cy}7lCH(*rTsY9vl`F`;;#A8zvhK7(QO7i59VI-CcU3h~ZGGLrtBenkVv_}Y)O(;ZFK zp$8J0T?K7T-4z){&}9F3WQZw=pdi}1**CM1g{AjZg352jGc!w~$*KGGHdUb6+$KQ^ zbS48Z5#pxzyE#|^T3~a~=YK*T`1nqo%9QQ{Qb)j53?HvSIZvYU-+CD)L>)_XV?ai! z0`yG^96>8=ofhOs*2h_ZAf14+XWUEK2C!odWIJ;sE+WQTx$pMSu zQ*-@~wOp-bHY*sy4cReiA!NsuaSGK$8Ti_MiV-les_R=rQGUI%e!N>~<5Y$>lUSR) zjAI$ezMY>N)f{~=hVM87;aEDL^4zoV<5z*MP26j9`z6Ga)^B-of-q4pj`WGO?mfsg z9-ixcN*OMDXaH8c606+3#@Y0w>S*w5dOV(eAsZ8fO1>GjtP5MBJSnPm74V@Rzko|Z z!9-e5TD~$p-_PQxsFs#s*Ky=H7NkGKI|&O-bTSc4-3iu)wF+N7^;hmTREisRldWz1 zOGRwu!OfZa8}`ZZt9;|~xuwDW^v9wdkoE=(b`6trJwrA3r;~LMOzP*5zXGzDKDBvKqrdJ z4xRi`d#wk8GIHEw?ib4Q*bYFCgk5-X^LB8ymBmzQRdI)*XEq&Pj~nh=J%gqNrrjwF zB$oH&XyM=q^B_9meVxQ7JDP{?edKHuu$fK6L#WW2$X+MU4$!jHA8B~VHJRfapV8P~ z!L#cW5^zJBc9m`l*2c+nJSG5%Iz8Jp=?9`w9ggB|8mvU09lbW3?vteZJwS!4ltbm& z+PlJxB{bGq+OM5~BE_>4V|~Wk9S+)xW2YVH;+}+#v`78)%qxR5`yDmV-mB5bOD_Pn zG(k84|wD4{h18)VS#~WHn5C>E7JcTyuHKWx^}k@T$ik*@r=NP+kfwffBlT z>D=&m>saj>>d`=VWBDjKnDdb9^u+1xVZQm1rr&=gk3*bXRk}kSpGMOl5NQJY49^-j zNKmOa{}dYNB4w#?i$@@G`kPq~24irt%-8ZY^{}$Jw1rwJ-R=>X`N-axT(LU-iJz+r zyhN*h2Z}9YM0F}qBGzqDaGS(N0QNtU+X_w;LA^^4^Ct-w!CWyhu&<)Y+j847IrOvs z*fUiZA5cIs^OwZin!M5<-S{MqpRK89czkSw8c*Jk2rT!d!8<+T|AC@W#EnK<;K2En zhQMpZ7RLi1=#U4S(tuOx7Io$i5cw5ON5p>zK>y_6`PSPoIn+Q)d;(SjCh{hVx;HgW z+VI5jUAcKaZ5w5bJS$D!8a-k&h_&`tQ1~giRDM-Q%4X?772*u$`}5RBs;-~V`*>0UAQ}*N1200y`53V zA7qf&A@YxFmSfmf@}gP5H|KUMgAW$Ugl^^!&R(e5izBI+Q@u{m`U&}mwJ_}(KnpjW zjokCfq3LjOzXc}!$1@I==4nq6t_S_n^B_E^B%(}oz*Axt&9%t`era z1TaeS)C636z40nnu(9#(P`or?Y`l?8P*{v;S2K?&1oBJn>!jB8e@bX**NKo zQ|WZdMx6-7EY(tV9?;?E&eCwua0v5u`>j^|9rvKptsCxol;FXh(9NLlPl2p?zkA8R zWl{Pew*oQO?k}M6cB-xE^LCjD`xfNPo*On>S9!0jqFjp{4Mj1la3pO!HyqtV;UG&Gwr}#R z_*7N=_vN;CE5_o-3$s}k_Q4LmMfDwerNY)wBZLL28P@WrfE# z0(eqv&Tco3PQMxdodp`*PV)yXUyS*20&5a-r_5g-~H<)mX)3FM%w_gL8Lx)e31>pb+17C1Z-4VaZ3B4%PhJFx~W~w zz73DkN8L zJZP|+rr=m8{?~#r$9wp5Np`s&+c??Lt|fX|sY8ylg=-i=tzcW%+>wpCRSugWM7bCo zwJew~u-7G5v&Y*mhw)0Id3WAfsc;=itT@0VcDQQa$0s6nH4E^5gOlD@gLr|0#w%)| z6Uxw9H=L!V4X0fB-0Q4j1N*kWiL ze+UrNiu_~6TBaueDpw5Oj0XY~9N)Fz%Kv@BT;6_&ysmGhz$ie`Mqdd+1s0k?1q6k$ zzGT)S0W?*^-w8F@xXA9nK1R(lCQ|Z*`yN0y4tcnA>nZmEaoeBwI_xvO&+dw*CxQ6* zh>o1Pe_>_To>jn{LpkwAFv6$W!|?BN8o~}BV}i*cBK9PmEsPVd<6VElGX+@C5fIyBx8YY}tPAys zFYx~Kjms0GLGor85=yj+B@$UNSwday)YJB3fD5oq@pXsV-Gk2B;5Umwfk!_6rZX5b>2Q?^)!?x90Z4h4RZiO2$D zq)iMWcJ>hiS=LUzu3~=oUM+u<(eN}H`pE{!eVayQm7b|gn@J~|(UC@9&cX*mYqng} zqEeTMqEie}4anb;_D!`Z^{*M(!Zd>V&Gy>$6B3RD$2p!W>)$1nBy9^Y>OGh}FvS%| zO!QC${N7;<+9p+RlGgg&5Z-m*2##*Yt3SyJu<;+sEl2~=9Vw)J^&B7C-E3d&ecpVp zFBg;H(=v5p47iu5J7FdBHh}%k-4}M0G{176zt%G!DP>=D$~HxwgXSRoH~;D(T$5nC zip>yeS>fWX#g}!>Y_m`Bd@oO%WCELWwTQ11TG-dMW;=NzFkHBmlc6AD8}o(GxJjpXE^1 zeE?Rc2{#le$^4cluGqhYwN0mD233tbJGuQxBrAVGn855)^1L#F*|BSV@;I7HlSAlo zO6pF zN=n05+sR0^h>&s0GDr=SP*Q6JnN$ zE~wedC3Sp&JLbYhRFTou+7VZ|8~xj4({pyv9?rb_AITpt;EdHfc{|p513j;dHO&^o znzM<0mHO;@h(k|EUFGfzpXEl|N$-0SuaEjTnWHXh4gR^eDk!7|gScAL`sj^z7N+X_ z9RCfK{cFI*Pq+R@f~DIX#XuwLMHD@3+@F4UZKv9|R;fXiE?Hrko?XEt?qQBFAdC)X zZMOx?`xjR~eJ?fF8*Fx{ee*EQ&zdu_3nk#~m1!=ae&nim#&dX<6cXe>?z*zpUul>v zl9W6l7v;bG)JRtrHi(wD%$WWrdkE~zzv)_f3|3^_0hxJ|u$_iQtq|OCRJ}Qr8iKjS zLo<>BjI=ZbAU!uC1scn%Hmhd7@^Rz9n}v6dOq|qk>wVf?`n10Lb@dAt%{4O>x@ zGin(gY7i zDjk_iC6dH~P^cW7W*d`A`UqiL)7CcO6}!6f$_Y&zdqZt#R)rT9cE#uB+jInhW3KjS zEl=i51n@U6^fBi3%U-9I#6-C})hux=_LhP?Fj?|T{c+5Lh|eMFc;bB0Y8JFYwfk~9bHcZq)|pPg(8T%`2X`DIwcpjo3WOK4oR_*yA2VXbS&vu=GK=9qL1P>?PG0cnwrF}hQ_B}d07iNQvU!Nz{i{>Srf zFSZ?faqoNI*Lj`i=hO*4-Tq{LT(G${?(XMeTiP=l2e0$oY3CC5L3>~=I_l@n=LaVp zS3ahHbTO>{iScdB8a(y8jqA65w)DbcRF3*pV^l%>SvB{X@THoV zW)Ej3{t$~s3E{e#;;XuT$1a$w(Qv3~4KwdW=*zJEg0~U|)*ICaRQ-;;v$)WXvG>W_ z^z81P+udZKh$HN>s%=O+|AAQNvp+kAT~&HBv#utduD~`J+{cI`&H5{Ty#J?EyI!*Q>+njI4_iOZnIu9MCp>1b$Q@T=7ve zT71kYQm6S@FH04tmq|B=z^$PHxexA^To)Gu1tEg{vu9S8I=h9e&}VJ#issrHpWDw zghliD*BUIx_=*j5bBt?cK2y0nU=f;gT{OLS4ktIxHxSH^&t*QCsn*UzG7 zn`ffkPfRG@S-q6g%zI3Fd+&(!UK7v#}8%&#{0NB4cy4l zOYH}N{?D@Pr!*hM_NZC1k2HpB3|kBB&K@YcqI_w_fL3h`m9az5HbNCB0(tsiOFRe@ zn(iL{BTkEJEvanxA(_Badn;DW9q)?Q*CTCOhDj{fDzYj3(sb=r=IAY4W5_CQHYgxQ>r_D)`S1b%(3K!! zA;TJ~6X$3ta_2?o&qTt56hzPMleG28V<|lG<0*s(!)O}irews+Bgd~YN{Xg)>Wr#w zyf5Zu!*CiXO<%bWUZlxVkF*F1{C54p59j2m%M}vJfD-LBmwd_uy5!rx?UY0nfJLw7 zre+H>TkqPWf5ykZxLuUhsl*qM_ahF!P`ueFvLgP@?ze(e&~8=TMq-bkFD4wDUxZca z)mzrA0V1ce9ai1O&;GDFrH!BKC>?SIPpvS- zWxs~t5rm_p&zpi@clLgQT>YCiWV&4S)5X^-ZoDN~uhE6^R zfrMbSdwr?Z+2REpm^3*fM(&T#ZZ=zZIj?{Os&JYkFO5UOf;occyB-S>C}4l&@}3gg z`TV3*y1YWQeLzh$Y75cw0}oF=75NS%kczdizqpI{$)mT!t88AInNVzf)PAz5a+nh5 zglnEF8P|VhU9-2VBe~n|Z8=;418wZ@_?1}D14ii6>i|%59~~=2U_z$?J6TdDl&;diIjMCP97p^kQ{r1I|IDnUj(cA0NoNT%ha-p(MAuRif8({ZM{>z@j5S{d+PJ zv>fKa;6V{YNhTa|hw2g6OEv0HO*Q^Be!QrK&}ja~Yzd#oPBJs-LCjhXOPxPxAtCjJ zns%U%1XpE-lE|J?j@Nf*zgup3M(f;LjPko}R&UWwKz0#D z2RR^Hx*)=G@H0|C^yLe+#GNzI`s(iObJ#=l)30RFuL6lkIVtl4>Q_$^4c+S#hu}X$ zdW0cP?kL=V(vwcwgJj4NG{}|eq2t%~GN1oQI^&sxUR23S$M{)7Y&Y>aCB>dX5b(Ry*Wsm+kq#Z#0jRHksh{oIz-rg$Y5W+K)-@${B3?i*I3zzo zw$7BVer-HhO2F^LJh4B(Eepe6YTucxkgokCrKx2Y8SzL&C-@Vhny|c4ml-bji%jy2Se6X+B9UbbSZBBOS^}ne$g?o z7Fh)h!&0NU;h4|ZRo|NyceeC=pifo$rFi4QujFTwkK%%}W)7c0b#Jf3BEU26XLIUA z84?x5jg?$x;ftT*B+| zPku1{tid#Qm&)+;x**rC=>JHZsK~Gu7=Khqj67A5WQyzb^EukFGmUr6#zGUiqGN3$ zBBW7R1q{`G#T6*R&s&*t#DNg=vVB~jXeMz|{;n8+Gd&#QB zLAn@Mg-+S?`y@y!!PW8k68}e@%JYZRI{+`X`yvYfZbXbo06KHH-LVx-(U3SD*tu0Dl=hP7k}j@U9+V6S>RC8!X_mhzw|R_z z!<`4*;S(_?@NLlH7b6*mCxCN1aj6+ZXj}0WasEnFZf}}*OQEE*zpM)DBhXmA7?63v zxOy4yu||%{UW$j-E{jErux!Ii8gt0u0LbRhUcV&b317gI3L zi~6pW$?S!~}+!y?YrEZi|<-YC7b`4d2jZv0-5uW`UaR!^hPpTHdL_Zfoq9o%H? ztr>(PJvDMU_7A@@(d!GwhsHN0T_9mPym@Qu?5nOvSZ}TVhdNUNUw;gOT$eQ-RWOK2 zvpl`Su?PDw+n_`g&*+uzL97ri^@-Get@BUHK*Gt3NlmI$Iia!qwE7$nFy$B0wOjl3 z;BZ;>qi_`8WOpkI(z{jDO_;c6NVa~rm;QnB)Mg;mt;gXkg6R%kXPPN{A z)k1xLEcf3{$+x<9O7}h+f3%=cb070$P|M+w1*v{?syt8zm|G%Wx-=AUuI5xLa{K+( zW%jELjF2%Mjt}atf&?AsNhs_rWpzbe6xa7PjqY3j*xupc4w0VCA`&GGr1}Fs&Q_Y* z9pl%{&n%+NN6_u<6}-?%YHTsq6-Mb(<^Clg#%0PF@p4y5TuLxT@@=N9Vv)pJ^4mh3 zQOBKrIj&RA{Tc53&;vPsYoGHTw$!kSgYVH@QZiDFqH6m~QWnmR*6nd|+T8Jj z@4gwn-NB|<;1=Lj`5y`GzMaWb)$_rz-VR`7>875>zdy4WZ^Oi#kvmTnh~198RC^_9 zilH?Z%u3Y<25N)%Oc4zP)=3swy!$9#y&>qSSYG|_$>Ko+BWJmQoQVt+28g}$bg5F- zwxz4OE41BWN9u(^l64QTQTmC5w54OSQe3O~vi7~}Q@dwOXc3S0RjJu4{G*ONz)g`| zF{*$Qv*nQxh-g^b2c2ZH`?9KF)3~(eAX!b(!QRc&n%x^g9{oYl;?d=^GpnZVAZr)zv;;@D_u0Gk1?U1T z_CB@wrdK{om2Fwa$*z?F-##|EvE-&EZh-FHMr1o|zClo4>tlF?d(+o(`Wh+Oanhj$ zb58$ZR@Ygak*}MQusocODwg}p*XA0qft5r=!A(JN8n~meQ0ODDQz>EEI6k>!T8m)e zVJBCIG&nRL%M_|NauZMKHn5^4FcOV=y?>DWu#=je3ux)^OlC$0qgJZMSOuzg0O+1C zAjW>daXV{Ei5fcFW-WEM)6#>jw<qL*$MC=>?0!W@kGlCl`LWM~QTCt~d&nTZjbtMOAX&iTGz?g$xt-jC!3 zm{^h21L@AlRDH@P?m-k8%$^C&g{c<7Cz~al&CH?420AXitPOYXe$XcR-kg?d@D8Q_ zkvQxF#G2#n7zF~2>$Gg;4DF4HRz{Xig};R}g_#!4+xN5wKKqw2+vru;80>~DoeeNe zM&qBeHfDH?KlqVOPo zbbr-J)xmpdi$83>BM)Pf^v)QFEPD6x}5m+r@e0(G22& z!9e=cn1WHmyG)a0&WI;EyMD~-Pm+CQsg{NGfGCV+SGWiT#MN!d2UKaeH{ZE^Q_(K> zAISsZKW(M%L%sHaCcXM9JL8=7OZpG}YT=+jg2G7rZd{d{_V6(KZ)Y zx-{aGVAU2$#>yuxn8qX2Y3p{9K;dolyM)bEYzMS-%XJ?Apq4eh*J+9wZIE7Ou2=j6-e znJz^#zLnwX=2)xX)hF~ z!)CAE?2JAxIC)=yTMgoG#HOH}-lJYY1>EcB3-Lvy=FMqNW-?aLf53qUh5!OI)v6y9nC_~tIOpR+-^FyV`m?T?1 z_5A$DWQXy^UwCb>Zu8e6Vj7o{vU3%33{Z}x@{0X_S^uaILdQ$6!W;a{Tb#EYuidq3 z?(ysnyfhVC*szP?Nx46I75Mj_f{JCrodyf(;(e*&164=nAbutSX<$3DXHuun2>HAb zkbV`?D)(NfcpT2b-VeWB<4r!N9T&82-W4RBxVzH3Z%Th;|HO&w=k|Mw^uo@GdB!bR zhrkkDW5bK_7yk>s>D0cim|@k05)qeaL(5&h3GT1yU*Q;zp7rt37nwi#vKruBZo6e4 z@{&hF=YTjIw{?C@xPSS}v2KFPEes5OF;a@XU@=kRF8-rX)Csl&0IYJ~$N3F-$j02> z!t4IlEVueI`d0$%f{F#cjc@%L(_06Z%58T#t@wNR@HC|EP_=tH;SJTJpkak_xzUcA zG=rqf9f&)EtnRDv(+}hSfMoB`bN%I@l*_2Kl1!gFwe7QX1>h{VrM|8td%$w*6y3IY zeXt{Ov<}+<2<-tHZZJL= z(rP?^ai#D5ehb0Bh_;1@4@PC5D8&ca7*gK1o#k5xRNro4gcio=*YaAGWS$E@1)lv| z4()9YKr{!Ln92TV5iPGdFJbY0eoe-tTyY#4by3`z{$6CX(UVBcmAxm*{E2sy+ncL4(q?a8}ya7 zn{KXH)_gSz_1U7EC3KjO+Wd)4y}F0iE9kjt05@R%)TpL+vnu% zw+V#OW5E%GsAXcjx0z4_S0uqKCFUPq)QvOF!KXaV>rnrYjXKgel@t8EY?3xLLU%J> z>FC-}tE*4c`VvL8S>T)&U+GF-w=)vKs&JT!y@g6`SAnFP@U7c59`&9CnE0b75w8@V zP7#?E4rce4lygHnV6>IelR`2_Y!mzR(b(z7yJ!=vLey9-clQToRD!2`=>+yA4w7<$YvJ;rw@V~-k3#@bR&q>AWGVmF8S!Y~y&|H}~%Z6~I-LA;!gq%raj{PC)Jtr5zHa3iU zj(lf`3xJWFD~Hm#fUXQ8Urii@t4|XNe&dp z7cJryr|0FQIdGOSVs!3d2EF#JYTy$cTp1Aw*TIY8`zIoCadIML{~w8QhdZF54tTSa z`+M2W=E8js&0^BQuxQ41C&lgPlOz#Nm5x(+52}IjMRv%lX7x)c+7n&5-yj8W+GSG* zw8T^zcx6HLFPk`^xt(ahRG#Sb_xXN<+0Qn3d{vlYnSPYk)z*+03D(n1y8#gyEdZ;< z|42*`1+6X1FZNqK@T;tY*x8v$vIxQOqS~vaZ|nZ8TdxMx>}@FXLs$HXqq)J{#&o%uxFM{{N_Q;xl!|1P`MHQy4iysA59w6foU91`O<4#5%MXIKXa><(s4 zUX@gpI8bJZL#NIXi)=&kO}GyI!6-PT{n1^oo3M6>WrZsXLz zJC=02>5_RK#&171Ew#@kZL@}8R%DlJ&pFS_o6O(Dy2n8pA~&~_0m=$rTO{_W_kn`n zjV&c*5GnM$e_FGGdRpN#>(!g9`HFI3HcCKiX0P}~(j${jLa*_ug-aZC(7ItgjTlQ~ zi!dOZCgu^u)o2jwQB*}+duLTXOY?B!49J|>H>YPJ6Z|GyZ;?C$R5U^%JLvAcwf4IA z*o-2)==^3)OQt^zwru~B@^jE(+Ix?zCLfQ9tW-^p6CZzJRgE*gxKql{(e? zB-IMz{$fI!jFK17P8 zvn&4PZ@3|PmYfCUOq!FK_tSMd>O6Nz<>*?F)@riZMPvK_;D&zKp(efA7_50mYr(mk zJ~}-HD*qB5TcKw9*5;Usxa8*8vWdk5KGzVdT%|HNsJ}Gq8QZWE7x#2an%me=Y2+rD zD{1eJJBBT_ZWH9g%5=PT&6uD3a$=*WmZ{T@f+dK_6EouxBqb*vH+nA`rY7w-l5L!f zmv|XG-${iIiN*5+U6+db00M`*AWjFl*>&;|$NQh;#aTow>X&C387Gkck>r4}hX{qi zK6b&^QR-|Wqr~RZ4Oslqct(v6ub7b7ilB#W9ZQhFlkD`4pdc#kJLx-qV>1VzOK(!E zh-j0ViT%vm|I95LMSEF1UZgU=zhn6Z1=wB+J2t*b{=1%&pF;Gz5Hw6YQa)fb3h)wYSksaTPIJ+7OoYO`u56x+6uHXi3*8G??vsj_+TpF znr`seU65@cb&}x)_%Spl2inq6k=HWM=?@v;Nl*ipn>0oyGIDW^*EFDEn^j2_Shr~f zb7uc~T-ojL`}8gnXY75#3+u1zQ;bsp@%Gycbb%&QR8^LKh|`h5_euH_GDcq~wGs!f zgNl=2SCabbul#p@>^6(x9l7IG)hcsV*VFdqcd37&PUzDEt7BsV4g-NDWjpM3!hamF zzMGTW8mSKc4>)1cFsr;xOco-`QTxzz*9g~c#Hu(GqT4Zh%PK9>b=0xt9H#TXR*sIz zlvGU}H?Ze8K^&W|jb+^UdE!_n&I^k9b&jYfJa&B=LMu-JEbn!jKXhmKTmzVq0=sVQLMcOrktRX!Gk=n^y#Q6B7lY!bLK1r+!+PKE%TSGv`H`>z1YqmxgfKC{=xCDM3^kXvrQ--dNxY4I}wn`XhB|Q&+?#0SY zCyB*$O!&*>B$n?9 z_#;}`@3_#L_yRe^{Z&dObU(;xTNu877#B=uYfF<$^r0XJFVjmpq{cNV;eVPsUf*IK z9FJpCanA2CB0n_pj^At9PE z@Tyc%0BLN|V8Q-+8_Ubdmf}UVP~ow$0LQRT6=&?Fh)x4E9NC4iAp&d|!1XvN=>gy& zuX5q&EzU$s__Pw0ygL|8-~05ss8yTR0ZPl;8+3J(RuT<3Hg61;>pmoj@E^&Lz zCNjtBP!h>QV+&qlU3s|MPfG*upogP7i#&4^z%ziHgF6vCbD*-SSt0K#4xp>MHs$o014_zWWmC zh(xOW*8VCmax)M7taY~ybrr4^prE(^v5v34KA_;#;QjP*{jhvnsW~G9I>~5IhCnZo2D1nW2+` zWbxsCtKfxS7MHHltLC{>XayqYvt8B2{o|{oiG=%xJee4!#Wsv-Bev|WMrOH!~jNebcO9mcSvFPr7m8)PjEqcazse4FXzc zX)dR`+jnpZ z!>shDBV1PVPL=!2Mdk6OnA>&ozEW+Q_U2*86YB%E$EePXQn{P>i;5mMIF6EGpge9_ z1yVFbo{MK%%-WQg8|>v3R=tTYSiq(esF$N`9WvoRAyc25?)QnYu*JrG*xtKSbyEnT z4%`BfZ4%1tTzpHN4g8EJb;9%GixT*wd^yo9l*(`fAwe( z{hxrF`LNpAO^Gnh7Y~>-SkZh{TGCEN10N|8;ojS56k3APv+~VvWQKU^>jA1P9N&Px&Vn5 z-#qf1jN51CW-`q|ClZ0H=T@!9kR1dpOk@p0Hv@5Sm(?ZBubeF6%1a_t_R@OL3+EDS zzlbiJ&B$lF50V%rNN=eU4#HuD?ShC&dOtFZ$kees2l%s-4dc4SxGzP_$|&iFhJ`Pw zpw5ph8xDsgraUJhSBuP zm?;AuF3*Hz`q5F?l9m&EzLw{%P43sPdTx^vginkYD$tHvlHo|u*k*WEDsLzooOLh0 zv?=1{JlzCs%r$QFvJXHum{%Y91IC{ zxJ{G+e?97m3(2~!Jv-w$Krd&({^f}eD{p>7oRJa-idqk0f@DK@Tz}#-&AXV zF&pCw5WCsQmaTMfjF7QAW_$xhl0wep-wq1T}&YDlrx%9(%`@MAheQ(Deo>19Q+-r!+jN(fyM$kaJp`)fQ5>QvG;g(_kR^(4j zQj6cm)XnM#EJ#*TZx$JL;q*gK*#x%nWoSph3Svf7xY5NjoC7z@pWz8#iZV*@2&%Iz zVJJB+lbLw=#NVa)a*HfU`^ER{pyO@BH@;Q6TbU%W2x5aH)j;0Y@vYc##SxH%TYQBk zGs5rwbI8EEpz*Pa>|9g#aYzf=g7AQ~)KBiu5@idx%xuyL5#`ui7sEQBk;a?J{p2>u z-P&Zyw5`8rn<5*k&KJuNX)Ha80ML?b`6~g^Hl2}(BALu`;aetq7UF-OvJ3gFYE%!a z3)~Ee>LP;(mkZ{Wfq_mH3gtsa8?zdj2%u#`xV@s@^16>49I9pz(;zh!biBSBNXsRy zHk+q<*%r*y)r{Aj5823Bd)dT~2@#D56m;=ZCp<_c#_4De8UwsDuddUI_$B@_d3Gvkde8_M1;_%Sczj}i;x{FfF4a>adff>M zLrUZ$<^obiIy8K6a$&tsiRiqZL*-dxliZ2J6F^B1{;J}}ae9eAFh{N5d|F#$N3@(+ zTc1+C{TUW>=9k6Wvv;M)@p5oPuf$wP%)K_*WL2^dc93!8a5d6vWC|4~^U6yhwC3qb z^-qT8HNtzSXax5XUJXI+lnhf8HO9Dxa2@n*hVwRGh*M$|=-7oaZ#%GlB5Tx`j^_1l|s>yd~*qK!Qvq&gVN zj(>8gIR&Ajz?9}vqB{r;Rp#ALfm-G)IX~zztD%!?lzkjqf7F(@KM$Vf5c3I}Pc-dV zbD=`fsFGM07-WJ-kAnb<57}uh1f}%5X3lq}kHQo3z;+ZxzefeiZmZvQ&N3=a zVZ8h0^#tuL+z;TJMH^$tk^5sGlet`Snvb0)^AU>nKf8-7M0GFYZxO&h*!T@TkneP@ z{tEFzw{^UbdrI&}>gJsOoK$%5i+qg=6||QiZ&vg#z{@d6#k@UcU|tmOF|zqMSfJaa zGk7WQo+4*(zp*6yqlU>S_GJRyydBYvoCWlkiFg%1Wa7ukY|C}|;rTP9j11ijk=4N% z{7@aOgz2rHt4gx3L0M&I);#j_pLp@jZdN>l?8XC+)y4AW4eVkMarW3YgHW*CyJ;b% znosv-Z1|R6YULf*cLEbH4^QPy9^2NjDV6lj(mF)`nZnGq{4TtyEKKEkdJ*?KT^8uI zp4z;lH%fDqHf(i$F3&9$=x=Pgq_G{h4YK7wNL&oV{3gKbBh}{}Z;n22x(%{WhIX2m zj>fMz=79Yr(>;Wq`y^;gsI5^1mqqms)ce~T^OHYB?Ic~>fyE}BE5C^~DN|_gP>Cu$ z?F_&Q;tXAwqJ_%Y0S5Cq30hEx6&6Ir~fG{G6b7UTpZjICYCQl+#)#m8j5BJXma*+ zw$#gP^F$1H6jW*LP0S>9WGb)6&?I$4>H`mrmWqRguee&y)G&_86Y{IvZaAGdM7EZUZ1Rk2TH{`!n2WfBV;2w6U`wMmoRQF0L`$zu;5 zgf}G#XZUX{|GS_hwHW#yWq)T`n3>)AaB?vCgo+Oxnq5|9p9{AN((g!|!&4;pxq}|1 zb@COnMaal2m>IZey)U!R_sOg;{$1pC-m-+<>Zjm|73zEsiQL!=<%|E1q>p^GS$Pmw zGu>2PH^9`4HzBs(qU@WR)oIPQ!nc zU8&+PZeA(n?GFl!HrE<^n#Os*TB^l>7hF18TCSW{tBi<_i}%V)6*rBz%g=)&JkWs1 z-Y$9-;!TZW{9d1*wwIjeT6@23N{4x?bHh@?-t<#WKT%g)`!HlG@g#{_n5d zSKk%M*xTvw7HP91r$QpImxj|I~OLjU(Halkl!_oo3+QS!qtc|SjSUtT?mzUYn z@UE@Nejqo0{BpLck;m1EKX9`y#U+`hX^!&Sa~(e|h4+{0dS|kq6-bTY za?B!L#G6-{`gy1~9J}XAp>J#d0yufIIh;wUt_#f7@=6ds@u1u+rxhAfFM0TJN)st`cJ|3acGbnq(-@&%`EEf29o(_+#O=i z&Qvj)vWTvoudnXwd8IC~8mdt;9xaE-O5d2s+ZbhM@{_!ltnKKyvNz!L_jhtgxdgj~ zzdq`VA2I!*;*F*)J?$A*Gk{c2bp;m3{`ToASA_Q}k`Fp995k<2j5N~U?`Y)WEe~mp z)dA)LxOi0+joRvJr*e&mPcU;>xga!d%eo8QHORj2bFI2OYHxqXVZN|igs((8Vf7*M z4zp>0J^q`?U!^DVCOk2C^;ctKb`+;@GxSpc)h5+9uai4iwFy>X^=ZWNz4k|Dw)bMC z1hk)+Wkho(YjP$7$5oC}@-i##rB{+Negu#6uYuch|0Ch5#a${83zz_TjOa(`ANfb9 z+36Cs+-QR$3JzvLnh@ILR=}bhCp%w%Lo1?e)z$i~6L_tx!8oLjaP$FcThwMP{&eWs z{NR?OZuB_}dC!c7p!i@PX&%frwXIE38+2qe3Suqff4)=q)!gOIGq#HT*DT2O&?T>w z%bZpd`m%j+kyUML%7nOewFh%ohrh{!cdp9&QY^+sPji3#BqgRA`V&$OAjuP>cm=*;xrv>_wO<|nZ?!;kkcq28 zvKYL@R9B6>9tR%*Ip7(yTaO#4pS4SsUQ(AhuwlZ>a1kO|XM`siN4KWif6LImrM!PW z9;8NEQvVzFFUZHnVCk>Pxne8|dV0|MiiY?HpvjiKd>S1` z|430It%{3EdnwxZJ)7<5HjHD7%&Nw&TBp2#4U4&fsOvQaU6srM-HWNcM6Cg|Z-j7H zT}i}Ld)d_jcHh9vrYS=4nQUU)=jGQ`xda1&X;IwbzPTN}AhFwXw$jVr)e~A&w$pXL zoeQB$wYDPJQhEcmmsaI%0tJTjbl3QO?OKr-0w`q&eFj3Yua@zzmjl&+e4ZYqg<~$W zp5=vON>O!#E(p06h9lLT#3Bz5pt0=F|47tZ5{#{-C8i)+^@OQ;@N)?A`-dcJ;S$0` zdZtNS=PJ0|Iw&SqyB zzKa%n6823*ZPK^!M>V0!8}ozV?b<9lwqS(xwXxuMpDV+$b&j}M*OIf_oZwts#_&*i zyo|QJi%xb?trUT0Wj~m{9%rYKC&iPw5wiK&$}e;slser|i*L4`8zlS!sNBt1It1rzwYeUJt9qy19?D z_S$o~%45qN#0~}0)xnU>3ZGb(($x#ty{UEuUxeHO@}sdCx3vDs9qXLU5XwWg2eb5V zI+G=mHSnmB)u(l1MOpxZUCZTVXhPh~9euwLxAZppiVIPE2$+aj_>UwWc|!Z8YF)zD z@f^c5DavxZj5Rd7o z+IK&Y73_11&3N%F2$)EvH&a^d{;|B(+i+?-m;}BXx~6TqeB(s7?q~A{Aaiz1Y044@ z|B3w+@<(p#`J+4^sh;t`hOEj)_j*5)Qh5_c2Xezb3-Kn264&-aM{OohxbpcWQayDL z_tp-|M-hEaoO;;r2F|IKk*Wy?hq=1%tM_58B99ahS z67y}WD(XOxEkcI!p~fQq@LWnG38K1zwf{ud688BL(MgBhDQt=$aM`F&OUf|7?8M_| z9TS1l@mow$d-={t>XvQe^sjhPPsEfvrx?RlxQ8y((-X4z?B?KKI~SS_OzszO(El;c zf4J#0y98ucYB^Bu{o231;es&llZ0S|?(Q{XK=@97>g?ZFaU;+snX1Xngpx8BRHBea zH4%$SdlJ$0;5j-t+TGvZvvFtL%Z1pI<|XnExVfk}CYhY=ZmLcl*{8X=Q<1P=P~J!; zGMdlgEjJ*(Sb`PHtv{2Cu+_Ozk(zD=1ROI$^AlFejP8_7S09J?^Q0;HElkjQ>h<{i zu@R^co;8~NGhp;lpV;U#v{#ThSMsewC5-e;|q8{|AD$lzG z(M&~y4L;qoxl)nb`tDAg-+MFdGab`eJf$YBN)lXNkAuaAS>j-fL(dQ$a+_VqTkb^+ z$Ocle0qIA9CTUmY>%#m?1<5wN(~`J}&wTr~T$*R9Inw40&n1p7o#0G7Q38;Uj*zAV z`=nrpLrdL0rNsldsd4iRd^n|QY63Xw#h>HUlceqs7WbDPzE?4?$Q1n7CjhGr+(S)fW#R7`0Lrsc{JY2s#KT80>fOOzhA#^uIfK79{)r zr{GDh>p)52nsYh@#q5*k)?#Y6%4^(()M1JjyRYWsPMLseG{vVb<-1(C4nF+@DPhj( z&|*as*sCutXSJW{TB z5-_ULs5Re$%I*nMHq7%hOZV|GA8*uQU<*2Y>uiZS9P*|T_N6$nINN_0sZ_c zlYDDq;gQHowdE@DB3#)-yF6+m)0)5AWw5A0_I+;bG^Y+qI(zyR%G(>*> zdTrr7($4y8@tB2r5w!E>^b3DE)((Z)8kC)e z#ACd{KW9TI3GCK>XXXj_?f5B!os_&x+H|gMdTbtU$~UB%z&wC$WZ`=^+XUJGQvr6R z6FwJObp){#6#oL1zPP#MwA^6mt$1+;i<0oiYnF}rx^uirrdj_5Rbug5+8U5;TN&FP z&>eZOZwjsFrc`is_k+12*~35SNYNu5obmi0;;u9Y$C0X>T5mI0ZeCW2f5TrAbLVpV zQ-?Nmc+=^|1>{k$R5PrjBn=R3)bu|~n!LD=G%S=jQYB`}XLj``K2<08cQ5*R=0Bhs zwD0S_JJK4QT|(a54EvYxKc}15|D0~bl8yhjx<%To*Z+I9D(X|B?!H#wZ_wL_n1^4c zdj##WmTPBiqqemjoI61)E8@3u>gP@IqTpQs?r^b{vUxn{))@yhZT-(*#$q-QzJm-h z1A?aUTD+fS7L$4z+3>Ux_>tzoJjE>|!Y(c|VVYOMjN)SN7-@3+{N&BsB-6$^(T-W> z(T2oS6};hMNlM=|Qg>xR*&P|sK|#W6Zq4JjpJ>8+zh6E5kEFdbtAg@(+R~EJqi#31#GD|hRn`HQ zGA67CRlQ~K>8YDh03yf1Zu{+0Zt=Qgu*T%B^e=lKRJh};H+#q2<0;VHT#oOn*6cz9 zLPk^&JrFheZoI!YE=&5#=z^95fXGUVpx$0k8CJMOd*2Ht9PM!W@n$a0O4rWXlc)_o zMy)2s5V>Zo68TG@9Y^bnFq|HqCIvy&9eYCQQd_9M zSg>-ES}p4J^l) zM@}`FNh~zm+!TQOC&a(N)8kG$zYNW*BR56Osn$;?{g6k61;%>+$I*F*v-P-rSgWnp z?6Oyj(wen5EwziH_A0Ss&)6+RYsDyPMeQv$B8XADMr=Wh*lGkZW99qi_x_VBf91N) zNlwmrp67l(cShHLB$W^%VUruE6i%5a!Tu1)#)OBqn6frpu_A6FT*5ZWQZ5(asv9kA3&v$(V`i|nm>x@i?GFEqxr7ie z9L3picDI6JtNC4r=-0QaBI8jXiuH>%c*7h%{+q5e(#*))42FL3a1A51a+v^{RnSfg zzQ^@ox~NntuYrdLeSB9KDv{1W*P-~&Quo@Q5r>|sCiwiCYy=|4A}@_Lag0|e3iDJb zj0q3EQo46s%(ICZ0ge%nA+6Y}{_>j)K`Z~8we4`?{GbjKamp&F70R|MYpFtZUz#7d zC4~P#-~jhJY9{tM{FD$ObDus4Ck^9sB4#+MVm*%q%S8i!5^kM9%i38%;kt;-8pw!5 z)1Qk$p9@sDMY-}Kq`gGZsxl@db!O^%?J&K$EQB7ntL6!2iS1+jfJ-|t$1sI4h1Q`I zpExJA`Um8R^0K)0n_Xs~b=<^b!#JGbOlOJhM#b*MnNL5xW+C|X5k@f7`>lX0`Q0p? zQV*_xbR2CQ(&E$ljAoxouVLbqXgMJNWyMfvmV)$$A(^@Xk-F<{>L7yOoO2$loMq9r zGw@zDhk4)Y^7z%}(TCfPO1Kvr**CkU@7=&IMYy^|gqS;{^F>%$5eq`q6@g#5EPjOZqYi;Jej~U(fOOnlV z=#h@|F2;26X3};>2a!mFA)A+`2kX)s$>r?ftNUT8|JsG?aOC^27SrsSTa^>Ya+;(OZtiAf0*rx?}E^htX>cRc*%IjX`%;)qs*Yb~`>3Eu(Y`Ajhj)>3t_d zQVeY7q)4wUs%-V~`o~Df>GCr0Ba}xUD~L2XtsiEky!&$H!XVptQ@>-`#W^TF@7Dq^ zW>Jk)LLyooSXY}Xo!I^yRKk2fwQ%3fNc=cW+SuW0e~vOaB1hQ z15R^Ol*SvLTW<%Tt}y)fQni8snI$!^GZy}lwgf9&U$$R0NYbdb-a~L_f36^^K3{z=6(A3mT8y*p#=(lnK$5a8ZNWssF4f8O}5)Buv#PGEg3w{>U!!k?Z?I7D^lSJq6dJ zaHT-IXF9RGnpK4v7cmLXOB@eB<658L*PH)objwDNS<~NC7pk&Xb zIUH_Hz1f4%4D%iHoh{$Q`C*8bs;_5~9|n917U{COZs^Yg^c;!kugxEOd783kd3+He zN~N(QwQ`bK6QB@Fi3Ls`KckGf@&~4t^Q(!wRug(BB0=N&o~hFirbi_&5slFY)B6bCK3}X=!uk{xrn%EjWdD^O zbzYcuUXWm|OC9vQOAF_HDkUOwh5WG1r~Y47DUk01U;K>h_0?MOPwdS0-*g8uuS~aS z2n`#1)+`GRz-xkxNB>@=j#M{HH%ysh*}H;gOjmAPko0!0m8KB6iALoup`l%ikCI1S zSA`CLwyK%G?A@2!BvTadQjnjj5o^=-Z=RpI4ZCJsbvmWcV@Y|L%CJ5ouy#?(l=+xu zk+`FFmhXPAF%I`s=Kj7c;LeO;v5WAImq&c$tTFg+XA!dxfff@Y=KS~`ng2^C>Y{QI z_v;-2r4e~EWPWmh*F*_;Q+p8+Y~a|ExCobcD9I@PED-#?RRm2t54bTUmW*O5=l?chXED3}>@59;5*?BM_i`9V7F89Z zekTC+Tbp6`XP@p`Y;DQ5(WOA$Ji6!kmq2n^!(~ao{RH$ymN=~EG>KH*YUyW=(G;>(8k7CVW>Mcry| z8JchNJu*FBgB?Nu%Z7)%RIR}dpIN@R^^sZOtEhr@R#B&{CRMJp;&3l7*8BxbLf}Df z2b!W=k;;`3W_m7p*w1)(;L=c4P-mQ1*xUa*MlF=J_*<4LvzJBQcRB5|soA^$1!6BA zxC(>!V5pP>ON(&m-^}kKsSMPOKP}=Xewg{&X>K3YO0k4f_?_1T>)};a+5m=EZm4V) z_?vY}qK&16>sFZ21z8#IJv)= zS`pb1hEy)r`yL-*+TkC)z6+E00MDR_V^%vgE(*Jp#7Z9_M@+XR?-y^6gaXYpEqr)Q ztp;xY^@>j_x*dx2CcMU})|Q%I2$k>LB8Jgo^PECU*6kkD<^=xa^4J|U8=PvFhIY#v z>I0>@;2y0jBH=P?AqKeg(Y~9VN85LE!!FHIMvGgGh=i^ivn0n-@HKtvHkdXC$v> zj;CD(CIHOFLYzZwD(B@yo$J*2FImWjjYS%#!v$4^%SdP`Ta&yja!dcnvxYl2g)qP9 zD?ppi7O$x%#(DabQq<))rm+jp=azzl&?f#_TGbuQ#KO4Y_k{Kf6oxn+{(JOIweRAi z5X=ldejrrkA@rQ6!a?;sZ_4CwNL&y`BW5WD&A;T>;jA)?LL?69k`GI}*q-CK3s*tz z*D8JiZv1q7l;0|!RufRkYHOt-4#ijmXavih4m|&cLzvw9) zjPJ`3p-XF7zTatkPxlU0KO<*Msz0Hzg_prpWBwAod!XR))m0gCJ&8EB>R!>EJ66Si zMia_^DX(IKy9w;+6i;LO7VX-n9YTAH4d=c+CvU!pg!4hnDJpsPYV(~GpYAv0dS6-p z9-r^hU3KCD(aG+z_$7kAJ?qdHFG$c4 z|HHOZ-+4}R9P*%A({EQIri_cQ3vU# zHV1^0=b-2vScXx!yq;>0zVEkiWZ%RS%w*sHRJl3Hpr8&)qwZ(y_t4A_UzHtw=;Bsx z;X-c=*LUOIG|ke`_;5S7C-n~rHHgHxPZ4h1>%lS$I=)g=sc$C?gYR;|RfpJa_@Fll zip~kjy#{Yr+FS;Yn0qbUGw*L(rgV+Y1)DGIr&E{Koy|0#wpZe0dmt|mS!*9~_h6xZ zKEN|Z`>Zn!CiBqF)^x7*{-%3q(5MvBeqon>hDoLEYes;GDf;hGH}O2E{O>$KRRmz( zZ?>F9-&$}d;D~G2xCON0ERlTqk*Htl<(0Eh3Q-?{X;8I%{l|6XF z5jjSR-;+xwxQ+-04KonumeY~%LCB_*(q<@|NXi_f$VJ0-&>BvLMXY*68lgkdna-es zt=j^v0Up7e3+7eX=bzX2Z(a8<+`51_`lMQuT&v>8SB2svnPHX3e(?Q>rrsbhcB23& zsrWD)E>vtZ3H@g7JG$@;Q0&c46GkNzr@(6E0%V!6dbiH;Yeba~)1{j8>Qx)YVEeaT zu}-{;y!lRGt5?lZn@p^iYt($NZ~Fs0&#Eq)ONtqK`p{s@c!jg$3q3;YUK)Y zushI^Yr(EnT@&1g2yKuiVuToM`LVa9#l}6>^4KbC507dM&ShG{iydBVrcM~E>eBp3 z#9~d6`qz4?M5*)F%$Z>FLTRoOTK$w*?_f@Y?Sltlop2`OJ=Xt7C|0g*0#&?BHR)wYDads6uIK%*g><%q2XxCccqE5R-&33paMT3}R^-giQCj6-w`)$H-2YJ|2 zyyVB>Y$}Ivs}x zBFJj^PJMoJywuTYToriDkithndEqE!b}zQr7^Fq-^z(b8KY<;bZ7VRwN>r( z6!uGM$;ck zPNg~Wq3-dWWXCjl{0TH~xO{5sEX9mnG)up76wB2xyOh1sGtBIW+`k(TUJs6P^Q*)< zcFSxaESwcM>QZ%D!2T0Bb@E0UKx8LNWTcks5Ws~_b)8xVsI@WzWzC4IE{O-HzfH9e zvumD_sD$PZW!Uc6czwh@wOf1HFli<>+2VZSyaRrO)86V9qQqZ)JoM<+ zUytMcov54Tk@@pANpgR&@v{!`VZt=qQ)?nAsfQ@%G>p;4!85|yq^RA0ROVfi8;dV= z7PeB(Ul_6?j5E?#EpCb#dsQY=6AG%T8teAPuOt%}c+~iYe@iz$hG|aKQ;N%}$(#Bh zM~n?QUzu9=X<3T3r~;tG$*>UalW|!H|9>R09^Im1Ar>wQlY+J%0lG@`7{>2V4U7q*XdS)iQ zb{kM0fP*;eN7wA)Gcf`$i~w>jlCO8DycA&>*a!$0K6P1M^6K8s#A=sP22)O|;J~|z z2$P;qp%Xh_g>5F81J~w#LluZ3_EzFv;qzPVKd|g7b$H~}YtVT&F|6W-NS74IJzKD+ z*ql!Z%F)a#4yVGm#SVGD52fblUs*J@sq`*?)f6l>F*s_-^WrNR}ENlJ{49VgN zv&o`e$c-zezlUs4Kkh0(>aaZ^B9yn~))L1>vfByE2fd#{aQ0?ctzC4*Nn#^!e^FS>K9hp zS%*dUMiTYXCjIz~QsQk};1@3t9`91!iW0zR(v_GVZP_zRl%O10iTGJtnNYIl^AIa# zr#}}7?j8Nl*#&PckUsv^$lJdcdL@Yt>tVkgHeddhl!y-ZBz^aL;K{f*wp?8RKR1q; zUCEo`T_Ynr2rtB6(mcQyuEr$Fy{!nh$9EY)`n7UnGQ2OCp|_K-YCm(n`FU6ESy}vy zF^;{z9yDo|qK(|(V~rFa&6p^(?3T*0XKX@0O4WXGJviWwI1jEAJr|T86%KilW*Z_l zv^!C*ZD>$!l#-IBQPy{|Igb)6^-VGIHV#^3Fw5P`YR?zwi8s^8=1QFuf1q9Jp}L#p zBCOZswX09sy3%2`hcUS5MeGof%J|BVg(;2!4n<$8>1UaS>er%5g7?g`NW2q%@s4{k zyq?F8!=>i`usUTtUdf0haZP!hM4n_T(RJyNB@wkaHI}Fpx^Rpnk@{N;{^_m&(>w~$ z=pXclYc_lqz3wnGH4eP$c=_wz{-Xl8MdFWxGzGx5Wf`x-v$6}XkEeP(sXqxnZn1w~ z0UM0%|C05_B}r{ti!bf0VtPcKHx!&qYC?hkm?zTxvugwakxQz7#MiB4#;dWXgLcN1r$<@osgXOurs6=2$xw|jX5eT6umfS+;oQZv8^(bz{4gPga#NUw@^E=l z1s2h}dH694G3&gAYD|h7woKY2XK(7Ib61L$I#)FENfi%CO~aFib^J}Ms*mK zy9YZZtVLB0VWoXli#(NHQ0{KBoFawLbTejZdW{kmVPg3ty9qFBede{rN$0;}D-s*d z@@$c%dd+6KYWc11oOxMbxgyet zLmFDKZB38aa;alyzvh4IAlTPF9?xOv*}!8juN3H<&d5trq(wwOi& zdCm7;kUEXhylcSnXh|ffL-fFhDYf^LrPiFJLwelbQ!0I|hg(s6BX+eujDAOW8@-1L zAafN;A#2kpQabl{<`krsjqRS{Bn->|(gNH@bog93I^@Y_P88+-^j+f}XO7iiPKRc* z_4lXEy{g|+eA6BJvqswkaD5K(VaMBMIK)V9kE~^D413xS6@c%&huWThO#( z@K^oaC+PC4y~i0Qkf-| zdXo;&t~Y>+{|xqkJv40-=5$ezVw1+8*yk!j$6hziBx*@b;%t-6jVI-jPZ!!kg|%gK zsl%)Sf87Jf`X7(H%J2$XebXvR{(Go7%sK;uD$M**wwNH>kLlZ-~KHuRfX? zBJzq>(PAC!^#C>-_JmNXE766}(k_GLn|>1GWWoXy-x3IN&u~bT+RN(f`SA)TcPRC% zeN9M=X*TExVCuqI#{BaA`$fjwTa>i%bg9>?vEu?Dxr{~+9*6$jPPs_VE z0Q1X#L0%)3{4`Tc7Kmzb6-y(Hy9+Ii?s`*es|0&cC zm&5DCwT;RLt2X7JSjGdg!G!r=HFEZvJ5YI^{a)GPwi_D2i|%FnsE@V6Hyav!k_8$b z4i2EGTcGiiZ64q(is+4izjFU)Xn|D zL%bxrhP2TO8(*-oYXY!?Iu`+Uk9$gm11?lfg`2EbaiX zRtezSY-;Lf)Z=bI%yIb<$nbOJAT?JvPF;^l$Kqh2h<4HKuon^HDJrr0()z%SD-E;Y z?_4AmqK|)F8X^LV>TS5ZMI`kaR@+(yZHyin&(}*A#zUA2OBsDsM2T5Rk3d2iI9TcB zJK=$*kSbZ@6#UGYPuAZ73F2De*#{XTvWRv$7b^y*30;gTHT5xsZ#IMxSE-H*;-Q(`fiIQnII(U4+5X zBy{-}R1BB5H`FADw#bvTtO3=S&DpJ0iA&WoYO4cvKY}LG!_QqHzq($|lX(=o;yb#{ zG9usTUnG&N52F>?H! z73_aR>`;}wWCUnWJ!T}Y51HLHiwmXbhkI@|GhEAiIT7=jW!qs!p(=5oS)%n48>r7@ zJ+M-oZWY}DntI_ZIn=ODD*ZPB?y_IXtHsZ05I!FS0dX$11tYhE>F~- z8}@80vde(922@V}3S7)5mM6~hU5*1C*Utq!4yYkcUTx7s=U=v#pn=Lx`mYzunB)%h z4yo2Pj%xO$R~zJ>tjt$3G8X@}*2F$C_oorJHbH3fVuJZ>5?|jn>;vo=xhOR*gli5o zeKs3p_GBU0!Z!rU%=vg%bmdThc}5dHp+zEvSdo`8m?%ccvDBN2_RYCB zRhn4@=IvkSCh{3t930_}RwKZCChiTDC1_@nW2Dt&tH#}`&h;3d$n$#3)BW#v#_BGB znX;=*xxkghsVDWy4dv38h6_~Ea!%qVXKF{uW8_eq?6_#mg+qqYVaJ(8@P@@-wPN)T z-_a@-cja*U*I$RyGuZ8$3@tumid`R=nJC?CR#~zwY3*(%-E^Yi)zw*I*PtSiwq>{c zw>#3b-~C)B*zzQRMd<^{(PT>%-%B;*<^l1DCu7vww`-#Sg{>K~!47TKD=}TcP}&7m zItg>H_(mDjc^CWKW~hV70gUSiOE{`|Jqy*v87GS6eMR%kVc&&?E$~A1PKiQ|$Vs%( z1W$R?AHHC-OSR({!EHRtqtTiKteyRO0Kkd{N4iSYpD6B-;$U-Mk;9>uz#XF5K679e zn3-vE*nIJ(M$G`X=Pz0WJocmrHUd={lr=vu(qk9~mR~hFKlNi)O3Y3x6W-?>1Dmb+ zv41!JYz~?OhoC|+J?7tk8D3Ri7_-0Hf<%DiB!~XJtWo^4#GRqvakOC@z$RT#L=zjn zoTQ3v=L6L-D;bZ}Q9Ngj3f-9$iYd5~haL#MxEhva!qXG(pH^x+;d2{O zj4>+o-5(xs-C*|?)@t}JIf+#Kx;4A;MV?|W=14TJDE#^MI^K+3!c~h%fRNReRSUf1 zM@JXU7s(Z{P5t9H8ljsaDlm9HYPz*35NSyF)|=?M3)fFz<#p(VSRJ7c#w z)mF>_4Hq*L=lfJ5s72pm$@Bi<<|O-vS5x0_JEiv>;V&}uL#Iy4umb2qiTpBqVmgyk zxaJ)JSjM~^VQh-o6*!n*oVkv(9CIeiupzln1H=maO6@sU2`$X7Nuib-};@& z(jH-LR`PyHo&N&3qjevu^JCRA9N8(m+qC2-OqE)!eu^S8S;87JB)RIG(Loz6vX^0E za4=1D;gx*H0krsPSh~-Ns&7aJ?=8eV7cw*ub{wQfTNOqZhc#AgZOu+9ZFB+;9d2~w zdR+|-wC|j9q)>3HxT)#e?0nPRctZhnMRYX4xG!4zq6&LVmFe+av;KgxssH zm01GlT$x_U^Xaa+=XnI7quOqo(#5%==hJCd6)D@r{#~*R74oN8Scq-Veq1lnk%kVN z`xOqSmz@h!q1-iGz?H;oP~twU)jx$71f(;QmTcPdLb=FZZz2dG*rL{Bn*T*{ZF%F( zsW|jXw3oXQN5>!1`7ssSE4oUkWh=xLjOJi7joFnAD}O;3a;;dc+hbV04&!+L2B^5t3!bF+7JYYC9P@OYrDrcU75qJ}POt7%L}#g9p% znF}swrv4+Tbx819IUv(wof4q@qR|PJ#eV^no<)q0r+JR2bh85gcZXy)=*2JZ?1`Hl@m~k><>7L9vPj zXeZ2L!9sXEpCk1xWLN=+uM50J!wwphmCh7`>wHL!`Ul)VVCKw;J7L{o2|5pBxh99pHe@aJSFk4=V78 zm3{cH(O>;sLB3JiUGZT!PrhF>inbn6;dcnUAg#XiF`%&(GwzPwA{WWM6bYZC``B2b za18%4H}A7=UX0!jo!+j7pU3TnN2+9Gq-9XqN7_0>no&Skh+gAk79qxYC0|iJ`A+@SQp@Npv4z1zli0ERGmK;E+KsxL zs;%_f^fQnu&mU42$n*>*MD!5alNU)-4swH<55CvT`06cVoNZ27c7^>1bA%ktRU{`U z2Dazw_IW(AMwa6vj#gJp?Nan7Zp%&^CY#(~yE=$@?=-VCD?*)MQfJ99e%SQ-6zs45 zN$3~Vu`1Eni(?{)bEx|t$-Uhr*~9k`MmK%TJDgZeUGW?RZxl2r!D&QNZQLLgZ&!82 zPFH5Kp?hAr-7LrBv5J|CmQG7s>f_Lri#_fDTi z=7T2Eh(IAawQ{6a^?<0!0OL#ct0mY;-dA@MOa)w8A#E+3P0>kSXysm}qesaN#QA5r z4g0efAMuP=&U2u+-mzJvqZnA!hSE7n0d_q7>SN{AG%HP7rD`>BMz2nx8HRplm6Q0@ z7^w(@V#Uj@U*h&N03{1zUdTN0kAA(Ouk3~L+*t6krpmXrt=MseXLfb?jJ2Uq7pF~+ zy7e@|6BC=_yRuWWLlnGTxjTEFwc(v=ZYK$~R@<9$&xS-p*LJP0maQ3QuO0B=9_8lh zC9>bnlV}#9qoe3G&BjLD*6iL|%(>G;en5&!sNWR@UR3|kqf_+7{=vz=Zl#3l+X!Kk zAiaVLHPw*?2euzhyuXcHmu8-un>WUCUl>o6SL{(B0u)XGmKq#W<}U~5c2tz_h-h^s z^e`Qda;5M!^X~&v7?~JtKmFVBuY2fyU;dl?ZdE;AtCX-1CX%g&`;X*%4R*Z=Mr;6( zr!Lf$-vV&CTIPk+h%DgFzjeV6LpLtt)e>ch3PtepH?xrk+>5N!RdM|Ks{XC+rO&^x zM9@5oy&!N5lqPmfU8d>Ud|&_JjM9tCRRBr?tFyH-`J5}9i>8%yL^joi+n?N|wAx&8 zhd55l39V{e3hYIUo0L3QE2@ z_>Tm&!}oWYz%?QaGK^Vu(M%K+`61@DQT;b<$H2IQPg|n85L<_8{A4Agh?V+l@;tV zooxZ!Humva%Jvpm{|v_o73-7AP{8Zb>=I&s%ij%f)CKotQMx6;?~@=sMbeHHthAk+ z!=5)y+I~uC{K=Z0d3c0gdOdNAj~dnnDCz$cIryfq*t4Al*VaR?*zPu{D_zso-BTI- z%+Pq<@tKza-?yAr?4wJ`dX$8MeplbPW3m~7jp*ch}F>TBEsIf3;c+S@B z+ZRs@E6b%mWb==#gI^8t|7PvT{T)k#V!F_-;j>AZ082uVQTH2iH@W8w`M>2*7|RSD zRCCgv(JBHfxQ4~4aqpEg_P5#Xgww1xBaZ1e7)Ocm?Ykua-K->8`@Sov zdc2=B{n&l|Z1S5ixF$H%<&6fT&vjFo;EG5o*(NDRN!nN8FUbd{@Svkkj+!@@WA}dW zVjQeR4+3fodfD#EG#1sX&Kk*~;_!nrBlZgcLhNQfpvEVSpP2#6cvlYa(1kr1U#Wkf zXQ@E*^STo#sQaXE87lypPN;MVchZj5&H5stRSC+#^6t=BPqYT~chp1jaO}Ofovg1* zwtast)Z|v%9_gV~<&7^UMAEOC&nlxd-Y)U`?u=05>@C^f!VWjS`ulr*%YQ?nhptJe zYTACFLztU{;gWLjNQ(UkeW+eFi7^qv&xJazv{xnyH~qr>x72h zA1X!}>kX%blU4hl`wP1~YH&xi@d|LNSqf)++-jL@kL2%ntwrCpZfQ^Zz821G2I5rC zI$DY7f4na~mRorQCWaJ;F`_pMZ#q2`bocoZKY0Q=uonr(cXKO}RE})+& z=l90s-47OcA>Ag~_7Qr8=+>b#-|3UwhfB@{PS~1fNztbFjh+QSHOH>Q0X4u;piAF| zjnwhlMWIK2;iHIRnVcH>Q#D6at(3EPOin>-w(==WRO2|hDq18T;ZO^0Rf z*jS!_Z`Gim`>-JAf2fMkYDTvj4|Ko|u#A)e>6iXr0^8M@AGdlOrqxuoK#QY zT<3h_uz0nsY)LsM3*ZD9 zr1yCd)8#kVA70;G>%*5V-KjlXJle%LUK#Xqe2%y+`Ji=p?+AAt+_)9LSqs%$naI`+ z=HuI)-5WYuQ00KX5Mc3h+p9)xX{`yNp(=HU&~Lus4~Q0myR9F_xr>8?D_NBQl-_{_ zQlDeRtC+1X*4LG1_fs9a_a)}yfTO|II8>}dQ@pUw;^UW2N0Ez+tQ*Rgy}U?ARx6BKKGw*iNkXg^Uq2WOF5 z``EthoQ;L$97;$jiLsxv*n!Tjhh^SBFVv4z?_%GE(>X$h^nWCYdGLU*Va(1!Yd`|6 z(~08aR(g1&gjo_Cbb7x#(#v&|?onloYtPU#Mk$*=Y@~Fb@O83U4@QBLhQHKg*odGT>^RGmDIKBm;!xitl+h98BetD#j@6X z5qk5_P)}G8AN^P1XQUiuTwkWXSPOx)&hFuR*G8kM)~J|Q2=MSWd2v8u|f0S)~PZ<3yA>?ZI(RRs#~mq14W7v{M-4!)_6vp5@nCu&RCPAjgjB9B1Tt z9?t<|n7hnOzGjXMo5^0#4`h=Dd>9{rQp+&ov!oscbxca!}=*YhQ^+%gJo=Y|aJB@0P%x#DPU6;`Quw)8ZXDRv+AANhoqGgXZ;pfEf?KPxFr%_T(!S zv^z=x!|q~3!3A+*50M+!f9fJ5O_Q(X#<1dfSoJ;I#H*wiq_nX6XpH2d``e;CGR4Kd zH#KYyV8zUW_?8!SNb%MA9(d}ngc6G5-^3^F(YM=HKC3SsCQcnvefZq}N<-gAV@pCF zorfZf$<}szvp>w=U|c4OUDC|_xHjxk5N#<&TH^wb|HYS2e0}mk!xCQ5NGuAi4HR_g zT<9MykMs)11F9W{v7GK9`$((tPo|sp#Jp9rT(?q+HYXJVidUQR;G1H70=Pf#j(NA= zv#9(5RZh7ntGoDn3iSAZJ)_$1v{C}#HmlD2G0MNAxu2`C@=j5)9PVG3su!Y%GEy#? zf=!RSt(8YZh^TaMo}g3mBOQf*>=RJX`O4kAxCT?#X#g0hkBHr>_FJ7;B0<6_sX?Xv zzV$qV3J01H$KZmeSpf=4I3oG3BTGZQWNot3?zZP*Y5U;(rjnS=84(`VGZscH@Eg*L zSJ)pblmZI=wS@LAUN^ee4&Uc{YGa!AgI&1$Q)E(tb+8zl*H%6Y>b#Rmv0Jeo9uf8& zUx(Z)#IfbOOcYTowe=@IO?WIAw4Xft$!|@bZ%s~j)pcHICFFfw+ACYfA)V}4w?2au zu*CQIG>QEaZO+Nk%;^t5%%}IR*i$+hJh~UzSJe6y=|GN3Q-UyUo^JGymJs>?@=C5g z&f05xH&5W$fA(wvwGETLM$aXt0@uG z8<#US%7uS;J8~r)Z#K!?bM&d22Cn)b)W%X5Ww%~yh0JdEhAI>DH70TKGCXlmH^(G? zw_Cgq4y=VFhj@_Zpj}J$E({}b*@MY+QJJ%%;n!<}DI&lmUx$mOXG;B|5)&N~J{Fj+r}a49uX`{R)nmbj!brcYwv23tzlcb{?RI_5 zk^Vl}QULHQ2Pf2pp}OXrX!TpGz6*2HAJ5R7bT5Eiz5m^e5hkW z$ES8C?W7k&FdyOOWfU~ofHIrB5T-(0M)$e(Lq$7lwtvT!a+embD$!fHd5$(*F@&23 zWNRjQwa{sZFSItUKOQ}IpD%*FFg^fpUarU>-F5M$5ACIl_f8kR` z4JMf8iasDbfpOCzWPV=dV&4;rCU|1(C!mE1nHhmZvH6(Ysf{kHruUo%`{-<<#MfpN>`^mPsY2bqfzL5NHN#(YSZcfKuqe zPn&sGKA%nn_DO@D+SvtBZPBhhrN2Yz7wQ}8awO9?!fyxlt&nqV3O9-dhnR=X_M^|C z=Hg#BG{FL@`R?J11KLtcLnUzFVsmtzP_)~1(|;tPp^{7T$2xErSV=iFkk~H`+hJc3 ze}T+VplxnRF}iv;L=)a6*NPZWO6-zT!mvsX{%?x2PatsP0ONc96Jl z&}jEms>R_)q-RH{H(4p|)}><4T!({6t7(ndcE>!s(--vy(TnG~6tuF9@bheV&_00$ z6o+l6f#{w(Dg5Ist5Cd8jOe~Lt8;KIs%zkpKj*yl9|_pDBQeCP%Z7JZRORP~%ifoL z2EG?L(l=RWv2x=mNiVa)(?q9MDjMajyg5;0H?>Z)=qsbzqkV?za5BISxR?HMel z1=UfdI{s}Jfvb4}mvac~>hB3mKVw@PZ0DDTCN@mszcgcYGQ!@Lx?f~FJ-gHw+tkg- z>uc-&k!X^#`nal@3SCe;j`i(AJ`E0_oSH}`Sy2D8@8S`|B!1olW>T?tW4z*WmD}p~ zsQ$=Fyl~TWsJ-x+_&J_V;C&f$H>8?=+BJ0| zUy^<%VIVPv$Rr?|OX_2oe5l_nu*x2*&&^}KIz-N zO8CqfH$KgGj#mZs!Vf-m?X$|P#+9Q50zdT`E6vca ztevQR9MbmklgQk4#T!PgXY-TdR%`l+55Br_GfxyZr|u;^R@jN3$poeLJh1@ECV%_r zYM{9s6#st7YDI%T%!Vz&l(_yfqd$?HMsW2p)2qWS5>%ck$P&NBFD_xCY~tpYPZtD# z8hZWq6DJ0JD&rzR?#h+s!>H;AuCVDdRp`ntl@qwptXqOwbpvTU<4X}Jr}(0}Rk#lk z^s+bTqwwIPc>bWDA>Ap$F}#!I$NlLNA_R8gG0KXh4dAumI;a+7(Fj{TF(103gs6f1@fmiRoM)d+>5-N`BvneQyHylX=p3xfw z#_(+l-vBwS*wJImpzO`?jN2_96xXa%t&TR_`Cfq@K%11|{VRWP(8>zJlD(&1?dgD= z|Ky&rLE0yp55U3)O#0<7C$oO!x0ti5>Bj8Z{P3bZ(e)4=J@uI59o4`w@1TpcxdO;| zze4yL$0>u%J1O}Z8Gi77R`>_a7l)D&XJ@ow?Az5ZkZpOXLx{%l3ls~4?ohGYoH&>X zcOEt%m`J7GYx;*%d1c_c(|e@_vjanW4zIj6<5Nne_c6YnhUZfs+B)aw`N1z)()+9f597xS^D~oZ1Gy*RKKjbIXS1ICd{w-uQTNK)r%tw!SyWBG!M-k zs+_E}iG>~g(27m**+f+dXt4#@>3#eY?fH&P>3J2`cRN}T^K8T6T3U|f^}S19F3WNf z(%5bs1mZY(-OK)3TD*DVmG)x&2aNJrwkiFAJHykmDbKPJpOu{!zo*xORwPrBvw`;Q z2ei{@`h*`siz8lE!7Ezey+vECfVItj@qcvm<`Vk^&O~`WS2qQ->S{=-stvJ0wwrj>OMc znTuVNE0p>h=xGeb?SPf=DV!~nYnj3+BBiK&e88%9_uhmg@><+l)d-gt@%*D~5!`}l zYpb#OaHH$*cnemJ#Sg0BdttYH$!4i8rQLfX@8j+hd3s)|iU3?x(swU$f%PXI8`*5$ zIwtO5SqiBQcKZhzaobaw_ZeM=Y|3L^OI7m;s0g`53h}DxSxCm6a1&;a*~x3X1GkOs zacvzjCo3LgquerQ74T28+#Zsou-gJX5|3xl61V9Am1cbQHZ}z8a%UmAs zOa`Wql(JT4;2fjYQGkWgv@P0dGRZqT9#iXmyu7XHtZ<6$&^;%R$J%0a+DdcS9D~uZ zgd5@TwBiWV*l(Gx!Jq$V{&W}BN}##Bv z%<6QrLh8N5iy_ElhSs@4iAmMa>mgck4VjN8n_7l$r_bT|z<||E^C4q(6FbT+@zg5( zqe9RM@UUiC}Mi&Cs# zZdml=bz3m_Vt9SG7zrrZ&kP4?aJR7txWHK2iURe60`nv@mpz+6lc1p1ea)kz(8Ok6 zZp3&|b3(h*1s~S5F(BNn!ANhZD7bu>>Z$7>w3{T@!1v0p4o=?DiE1chs{PTtIDK-& z$!ty`Bi8mc&>^F3u6_N>`?m1t+y}2m+e{1HXQfL1kE8Q&XY+mAxGvf%T56B9rL+{a zH*M9b+9S5AEr>0MXsc+|_}aCr_Dqe49b4^9g;+64jKqi_^v&=651!+A?&rC#`?}8a zbN2J^drakTzT?CX`|;S#kz}xO)hjjC!@O3VEgoCZ$9lKOArr@lt1C0?diJ)8{RhF= z(_TNqR{J7 zeV>o6>r&zs=vaGH{ZbRe8&*;Tol`sAjtX?%7G=#!u>;uW{@NQO)B#T{mg+wGotu~{ zKIsW5LY@noHz}Aks}G+TXWb_3e??t^TCXgLVdE6O0QV|h)V^;JdRZH$+&DZa+Cdld1xxH@a1mOMZNc*Xs@j5j@T|}` z-9E0LXIYiQ1AP&giGpu;XioH0VjWv@9Ae2DQiX*Ub>oL5r^v5~lF#(tN+TCMpNh0F zNKOPLK>M=@KzF~$gOo2-<*%b0b0*KG79JVk;}WDZ!HCQK;zCdP>yGp4qx^!goNk_{ zwJ%i*?AT5B-&mz#;uef$ZV?lIcwYD4)jJsInL5|Mmikr*usT}!($__b^L^zAy}FxM z=6gl|{THWsN4qbWb<$a)b3?%1=7IW3t)o9rDm$U5=9wR@wU&J+!&J(>QkD+reA>k# zyNyH*{Gq{o$C_H*k?otL0M>PY=o>0~7AL?=0lFh@S&Y0@P;=l*8iQ}xWfoG2TRNsN z44UKeQk{@x-ns)9l4uTB=aKhrd(^QR|$cMAPujnS}mQ`8_M9QRZolTZZt?xH2|*1dO@ZcNi+VOmT4~eOZpE zuWok-)<9U7Q!|%KSk4U{5*^u3QJ-g`zO+4pgssHpzjUkae-02$z0yJ9&G+@{X!p$C zk&)D|Zl~>Io*Pu9t7zTgCO1GuYEBA*MZ4qU@qh7BRmpj|Hv&cRv)|k-5WOhq39GMU zP2-5xmWgN1i%6aMj52G`Ju`GVAJ%2qYgJ65Y@c_u`+b>dVA3fQ#1>uY${;=Kg7@?mcP0)$;bbF^il$2?S) z+xROg-aZ->v?$Ve>U$%GD-m+tsIbxFjbn8+r^n>J>^|xLgYyE#-2|IFv%l~5G0N^e zomeP}2VdkClV|Bp7K}WrP_=zTScYPMZj|?k#2Z3!MCB*=K1FS`5dPvO|F_Nnic0C? zn2gc$aus%;)x?BB=l2TOUn|vW-!b?bup1IQzqfY&B?NZ=Kg-N|iol5e58>e9{)-!h zx%2!Us>bfB07?YhLsvy3e+t_tTN%*Q`sKd)eE+ItYL4&Poaz|QmHS%);JXXoELAXb zJttX#J=ZwB`4%7e*CO~i@2~s`ypQ`r1_UcrfM^ETfX ztpOs#%G*c7d`ViX>E!QGN%jn;f9apxjj`-LI2D6!^zzWlb69@s3XGL`dunHU97nUM z)0Dg<|Htg_=0ki+t>#kO z6#xE$Q%b7J9gFoZ8AQ()T>rU5_WOMcn3AH#crE!zoO!=ut8W6K!%J+QrkbwbjZ0Y| zE2Az4@Ya`&&}LH%Th>3S+i||e&>Mm{dA}qZ_3|A3=M_t6fo?_@+gjw8j2UTt;m4S| zfF2lc580*KWP8oKXchZ--_IE*$3PQmORFuDVmy`BHEl%-#5(VmmOwJG{=;!e*R0Lc z-#UnD&_wTCa**$iLsk5mCM_tBLARE4qP5YO`v<;kY$Kn0$tZ;L7mIvGD=M6E_8!{~ z^7Z45@i04k7XVM~d2^qF6x7qbbikIq5-0lA?QaBw+m)_PuEc-dAlx__s2M^v8!agU zA1$&Y2{N&}{@hE!SXdax`mtr`8&e%cjMkdK?dFD_01oct4FBXeLxBQv%n@(;OL`S} zQwtriY-%p?VKKeB7A64%e z>d$9a(LuI$zF7%C99cU=B{3svZ|b6b^D2tF4`QOttlq|o<4WG{9~sx(_P}U0x2DWw z|4!rkxl$8M9?9&J_V7P{`F97^8DSRJ+m<}$NBg@D7n`uh_=-x72v6S8>1l0mN}t>7 zd)U8as}7|m=;oD?=ruB490>j=2SbYcA&VR zuaVor=q-M~!O)d(6R7XG7{r!Xevw?^H*9Ze%>&{rU6i{DUeM;5-as)zLFG1N>#6T= z$A|9>Gw!N%>IC<7F>sSY+S{%mC;cND8nVCtSG{}y`YUc#UnQDh9Pn+ntyqAFcqV0| z<=RGxv1BCE=3RDExIis!^ke(;-L`0Sw+!RLspEAG-sm0WhY-E4Ho2)fnKn(&HnaZz zt@f&K!~=p})E>%FSX*!W2#=g)rS(bFW;{PpjOni(cx;b6d=T>_|L-SNF4>ZN@n`jjka>-67N`j(5BD(>pq24 zbl(PWkt4S=H-6lZ!&CTch(DucwqH&=C4fHItS}k0Te}%Ce@%DyBSM99Wz;2Aj;SDUOCcfXxO=R~OA!_GbIazpaU~ z@(|8ChL^#FA+z1Kw_9{pDn+|aXz3B}8Wh;L`&{5d)&OEBVK=t2vLZOV`PEO^^sIfh zEt^67dAE&t4Sp?0lAv4pl{s+!v?hD^bhb2leXTBDm9xL!6&hc+p4+vAXiKkf4P$D# z0rD<0NB2M4p0K(hmaybP#wCzIzALsgu#wA0W6u;tLD+LkDi$H9EH$!5H2EJD0lXWF zwRR$2E^=-}(kA}4kr5n2jC2Re4tw)U)Q&~hzFN!ZMi*6s9+QXVd1KGx@n;k+HG{GkR0Yq`AypY8W+QSd zZESXUXCUz+BzSU$FJQsDsk;1?6m!m^hLXFYTe>QB0il(PE}|Y)^mbsSjOf5Po!d zH)`|DtxfxA{!jyC>)%pHoQ5j|@LJ&GGH(9T>G% z5hAxaN0HomH_a#a`0DB!8X`MImDg84H_aEl+V`OuXiitxrPk!e*_+~}HjAMea_YDC*KMd{Sx}({!wwZCpFXy)uzW9(dnD_S*fZxf0Wf%38yy8blurRhJ zJWsW6{9)LW!k{{e@L^rLFMK3Ax75{CaLIb}F!}Ezpm=ePtof zH#^TuevN^F8RmRp(~cjHhK^dQbo@Cz8#ViH`|IOoNe@~YQ=77vzol?F%A`EUQnGw> zUypp~dQ~f**n&CuW8UF-ui?rqfOnLY7pApwAI;EprqXGP=CwjhRQ{-+-1Yp~SdU0M zN$7=hXs`db6!g;l9T9Ftilt6Je?j&mX{>~5YmQeQU8ugA*xyJUnE&0FqCBwYk@&)= z8qjp#4@(n$D)MmI3aQX-M__C2t>^feBG=K-uYlumg!5Ipij>z*jmU-|Ik&S>oB+8j zsq!$!Up-y~sKkt-M+qp=RXWTq{?)HEQxsT=_gtw=oLB4cIVLiJdV0`zGTc_jbrx;g zvmeQ$kP5!zB7Z%Hv!1g5)63PZe=f=1pc%u+mBhaeqb1K-Z6bVCYT=PRnB1Q1hT*;s z{uC6o+%DzADUX#JN;$IQ5K0&NOQCR58sWpLkIU8?-NEYBC1zb*sTp)l3rh-mTu!oR zwOCElcUF7vp8v=p^*DEdlbv?AZ07L1D|AK0_}bMvbVO|S@J#N{`9V9yYHE-<-I}2J zt@DCXyFPmxR4GZcYw5;==}J#Y(MTB%wcH5dT;1s72hFpbW+4!(uRj+YH-P{BdZ1oH zeUq0OtC68Ndx`i*^{|U!m|1B4ENl&$j|E4dqdv5Vt+X2MX`3PmI+?a}U$WC@9;f_N zIH02Ok)g^--xGQy%CKbRQtReDMAHB99N6=(-ZX^r*WTwvi}&xFxBz+cEU7lQ;=G}^JVQ`v}0w9X~Q>8U;`XF(V|lT z(bFYyu3Q*(qN(efW)eVlf!?rqzMr?G*e4xSo}2yg3|PGK-pn^*GYNnBwUGRf6te2! zxuh{ERlZIb-j7_CFHqm+6bgZK#bXlh_df);v@ffBf6|r6rZ1%ob+0fzlgB8@U-ai_ zS3Sb?t%rr6Yy85lJqye%w5syC5o!>KKj}Ikg&R)o9w{l$o`Y8kGES=xT7J8W%&$9t zR(|7EI7=f4`1D*T8$Xh=f}x?Dn~%rwcU{Z*b7i9Uj0{p`Kjf@V$nK7`cik~&P5PiA zw?{4TM{4$LEG-HYcwrruzV^H%)-lR^P%+tngjy!;<>5m|KTC-s zhruO(r4K9$@kr!hY~A1Ie{l#O>8S3?NN^h0evc)E@JVr|-Tp`ATLMwX_DE-Z%C!IC znwIMNI9~{C{<`{6Vg(b(=Z}Eg+W0dCt@?jdl`2C%U3FQRwwtvVdc0yD$#8r$Z_mh=#)EBxpG^+N-~Ogq3#@803eDq?FxLfM;1^dT5FW8LMLvOEx->hfn^ld^qL`gV`u*8bekM4?HqsXhx(&A_dZ^4m%M>zRXV@@K(jNt^D8yUf-kX^9 zcrlT>c8oOcxJz#)Sr?^2MBT@uhB&D|jlZ`~?ZclG_Wf?dxN_Ib`_4zZ_vFWF2;g3H zXRiCBgEM^F@Ie<(MmOsx@Eat7m1oBVVN?xDfUzbcgsT*6?x0 zDD9G54;93w5ijv_%D)u8f@DEXINH2`k(AWjA)+1ffgg_QYA2Tu?2HoSHx)Cs{4F0x zV?X%jq%gVq3~iTHo|>F%&3mP2AqEyBZF`pPs1j&87+tG>dz=)>Tv=jXZKJt}@bh&9 zbFbz2ulSh#!VQNCK+AdJiI5dn5&6WQ)xyyEpldfAUCx+nF1>e4-!Q`qHH+-iumU&b z^#f`p>*D8@4Do=-%H5p`a}VMjkA1Vt$M~$(@w}D@tU!@zD`)3YT|nsyPAyV%rQtQ3 zKCY=bo|g2F>LqF2nLo44Qq?*1LAOX5v#*WfuOm>E<@TAxOn(0^^BV~_kjXZ5vp}}(Ci$^ff*-mVjN&(=4@c+vmIIRTwtc{+^^G6Si5g2(Xb8?`k|LyPp9L^TG3;#R zFVv#;a>3VmvZiR4aVj^+%4vp8u~mhU;-uc~(=&-){c=SX?yZ>%#rTSHBU(kl9_)Lp zT(cAa;n}89f7u_#@{Yg|+hUUcr!?c-3LjYwdjDaiFw3H@Ec{~sS$uB=iH7*S4G-9H zgp9c=b4?+($SyHWPQ}-OvD~OXdS|aXFXOI)I{;$bxI^DA6}-OfJ?LZ7I?b0B<#BV2 zOWJ#Fr$3zb`3{bH*8?8lUp^pE-ZAR(w$x7&%J{&4&?FKR`CCk#H->5UV>?f0D{5y4 z`n32dsA{kk#audQX#C{y&J$lz8FP80}_(akde{z5w)^s`c(+ zT4Q6+UQEzL4aaGk^6QT$8*YDo%Kf3Je-ko`4Txp!W+PuK>{vnF90li_xys`-ima@j zRpHGsHZ6xY`hz$h>C37uG|C>fG8rOf>;A%pq4klDcPf+wr`IcjBdX(Erc;{2hrQ1^ z;+`5OCB+vtEm^B92XT3=-uCho`;E-;oB1#yb2#M}he;A7z|e%4RQF+NZng_{?;;s4$vMgjT4YUxtf$cR6cr)I zuM!kN3a8Hksy1o(qS^(nF)yDvNA1@2Tuj~0K457C#K{nyJDFZj!qIH8C7em4g>tKo zuSA&)1fEoi){Kkxr37sIzdOA7-uph@_@Rqd`EkhKOYH+C+$uwF51#eY3i3z2MUxs5cBjw+D+XT$9=AZC1M(Wzk8pZPE{Q>LBMbJ3VVkZ zs|Eq)pxW-+~4~`SE*^3$L1h|s+1btBh0!=^H~xQF8vIB zBlhF;aVtz)M_cROpFStz1R8<TQUXF=xrV+^ zjFE0?y$ChkoVEq1IMM>pxkP1>{!9}wJa4pMw9ML~t*~4qmpi`|z1O7E{nX)sGk8R{ zT@l-P$p;%-q$bT$2K{IX2uL>#KW{SKVvY@!>E@8ijrSLdWq3;vZY``JPKaA+1iF=b zIogTyO_cr0ZnN%MD_m8H&JjeBtnHVlGZ;uk_Kh4~4(Jyds=S^`mK(=^g*e+$*Zcs? zt~1D-$B|RGn^%(DVpyt%kkT=KOXq7qWv*_|jB~D*7Yf@KW}ldj=X9Nmk8Bdxk#l|V^rOG8JeYxvxeIqT#UrD9o1kJ^G z8f;VO%{)D&&9UM9<+;vq>^v}pn-bvZoiS1`iq^}n+KjMd-*xjvAclfGU%zeKn)tA7 z8Hg-&#y~RPB;xu*UrqCK1v&O^qwd-Ao;b^K0W7ex72WZJu9+S|sCYiWJe_qU5_Wc< z@y+l_6EJ&QX1CO;E~=cPdUdqMZ~<4GH0f$T!k zE}-Ph&!i63ij+f`DHH7{eNI-(XN)v#IIG;Khzwl4aL|LeX=nB9`qWNp&IYcdsy^&& z?5?8oDksCvc|>C^;zRcKP0sI!9h*Na$fI9zPR9*!!H##W1n0ZQ>42rq>G{I=2C8W>1~&&IPubVqx0IGZLt^MS}F z>&gV%Y!qU4XH=#gbysS-%2Kbvy-I<}7U9@X4tG{M1E{57MOu>=TN&6B#d2}Fw*T=! ze)6Vtuygyq{6}S!+kVZadiUy84Xi4(=3+ZeeEy?ck9MvoTrZf)ocDL11v1a9K7ZBn zraeI7O?i+0oleJX<5|$T63O|J5&TWw^uiEovjqgi5Id;KL&ES!zj}r;dT5APw4QI(!9FK_&gZi%-!y zy;?%W9_}GiVd9=-97Fe+S`YDO&8wj@IzRMf4qCa@n|ek+KDu0BD#F-SqCU&daq#tgqwUtKIh<+t=uiZI&%bko5Tz zBxC3_F4~&uCB^28Xqfu`kE+0``y2cF#v4=jaFa?xXZAvsg5QHpOo@7%6zDokuZPV_ z${ocT*~`E6CR>dUx$f;|dWhKF&@SP$Rs}Xq^P8tmuZgSO|3S^!C`XlW@^#KqsH^!iu-zwgbY-W~`f-+Q)Xin; z`bja!x63PB0Zi-R&xW2=7f4P}`WE;TFX`Y1_`MDNzdG?6l#iGSft-%f)pLOl!M5SYVr zQOK}+Ei`nsQiCD}{T$$$7me|N&ZGtBxht=hXYKXrt&}%0^teh^`oGrMKo5A0pWWX1 zM+G*UQ|5IQf9fv%{eFBwRaj+^z$d7Jba?=ho7X6}66U%xB6=+YpF`iqN?$UbEX)BN zfqs>_pIlguKspC70D!dC@1KvRz_(jRaqoaiy*R}81m|1xn zS-hB?2ntDg^=WA5h1t}dM7?)%8*LleQo6Tk9n>Gy5u`Bcty@ZoxV0}6Bb+4#Az$r3 z&0H5Bl^kJ|)xT3K!9zvGsC5LtT}_(C>Y?qimkBGm;ekjSt}&>bm#B!;k3v(Og2=`O z?$r*#|By=*>!VlBFkWvJ*ts-Mf7rWpN95-;KQeBtY5Vz}8T{Vuy;PZNCn0=jVAueb ziz}s4y*As92;jZrQ)fEp3D7JyvYY}cUdEYUj-p@ESqzfQ+00$d0 zl_SdS^+@>@TM-)QTebmG#IfOrp5}deEo6anCy7fwJ<#kwD(7Ja6ZLaNklXNruNB~{ zic`qolk^HFSHk4A`z|VV5yWhSC$o7-7BFNbH{L=S`ACB=l2s`%OW5_Y-?IOrN3;}p z5azvXLD8@w7-%EU)tW^Xwe6*PwqY`qL<*yawc!c29#*bRw$VHDmr8pHeUGWP4|2ce z*6^gQ+CA>g{q89bx6A0PGM%Zzj0DfUPHYwM?S00%Yg#fC0u;lluvxhR6&}4;aB2>^ zWQ2sT;IzP@_i`Tiz}X(ZIFTBJeCq_2zpa35CfGRSJyFo&QG4SPzMfe748m)ZWIb`B zlQ>_UWYNK#ra0rC*s)?QtZ5|}_oBjyRD2JNDLuPq&`4vfk;W!;oR`TNaCT@?r)2Iw z2vFb*d0+YBdS+|sl@x5qWbqce(MgTaV6iaY(C~O{U@p_1g#xqfityAdZR~gn-AO#N z_aFN6m4e3=gZArHKYDMIQKC{w%Y)Y(e+nWOaXoHFulwN2)6b}_x*`CJWf}RJ4;>@) zz5~O7Yv}!5^oM9J;!(ke)4*oB%KFm@;`%e4yNX&D`V%{BOv_^M+6C z_e1vtHxMh7yqI*yXWsvbQ6}6BE!yA`k_{&FWEe2=%16h4D=Y{;e{*LyMjHuewIB#Y zWeH;3(+>~3bhDjizDh)lA%6P}+VVT0w>5kC3s>bt$5Ul9J>@6;g&EFSdvxelV-I-5 zCh7`mO_ChkR0RKa%NuWwf{^fp@#qu|6S-5*#kN;lsQbp~Y1P9eVb6`~iCQsd@tG%ua1H{!S($0+^hS@v99(AUzNYORc815=XO zueLjcb&e9|ip`=ZiUt@Us_V?5#=Lz(=hF+}tPI=`4>at#a*C;rC{4b9mF!e4>S&a{ zNFHG+nCKylpm=Q}fiP%yJMqso{UH|6&W@+ z4$4_$?gZ?h22$kM!OdH`eEgwJNm^I6yi|NSN9KC(Ix|1K`39VNd;fP}YPH%#2K_W< zmjW)sqs$1mOwGsw`8 z-rD50*j&{HIBmhy>QdOWVa~lsOYB4~7`)4bZ&IK@F+?)F7u{-la?*}1FIP>)&7 z+uvTW)A;G3J%h>DKGG({Sf-7_yD}vw}ir@ld0rOp! z-B|ARH^+&Cc!~evf8bA|r*~)FeYvvkT+tzgmT?Y0PV?e~T$^cLw_vMytf-?DFYu*i zHX^g=vI{ww_b0Tq@(p~^)?%|wPI<#;WrM^Y@9|(o^ja%vS2+e z#D#JhjOL~cl|yJP=cbLG!>-|eJ}sypS$cj1e@){o*4-uR!Q`p zu}r!0+9;L%Z2wCZ3v~7^st6$64rjXxuY(wkjsb7s7cXYWua)Ym~)grTjqXHdx?}DF}qgqQ8FCX0QZCuZ!7B}#8V>9g zEH_F;o>{)EPfy)`Dr~iu;wfPR#;P#u(5=PZ4|hAF7!3!E3_Yy|&VqQ|7gGcci*+Rz zIHEUDz@@Q0K79ACFZV_3@A`(`YcVDO=Iyhdo^p!?Hyy7ATy*>!{O$onTFE9P>Rvq+ zXOoG)_KoI@?d4rH7vJJJ%# z;1z9OWV~FMGO@1zN$yUtR<5XaMVEDe1u}WObmfgC=WUM|$E8 zO_fJHQ7S6U9&x{Cy85o|WQ#7!5OBz}S3v=kKXJ%J!cR0xSWvJgJPUF6iQH+^rqooB zgZI@}d!^LYl%cBRhd@9p@<*PTG&9V$kcu%9cz<>Na;peUVV7i@9XObbxDJDet`^eg zoyBO4%)~RIbSlr!qO!VEo3BUWWIYP1xM= z|3RwZm#%mw*4~b>@%;g{nyw2)wK@NiB z8&ml7KPo%iglImaYvmb08f$?3Qxu?B{yg0;;c;z z@qt#8H5@ESfCWPkBepXGk?)a2Img@jvx+4n3PnBxG1w+Yx>H_X?=4lWsD+kN+0w$v z4T=QJ9Q=q95!U*&UK%xTQ4rwO&oR>VP^)C!<4=w$Ch|0dGy3*Zm4Idtcn)XNVB#@O zuP_sV+!?QsIqQFS+DZrJ;&vvQk8?2x63sW-cibcZv81&(=BC@s-qKjM8XY>(vB%PfFNfHJogOWO-~IvoP8n|!D_7MM6@oY> zSlHV4gg#QF@1;(zobVx6K96qE5-j>xWqi33%eUW~@b4xiji%pzJMQizT6rd_2PP%< zrr#;@{?v^{XA4p%1bgz-{RtbNEB|~rsCu)El|U?$&k1L#i~x?@-n$X-7Y9pIA6B(G8(mj>}+t2T7Wa z7(_Lt0g4|^Vk_}HYS`E1Oqh(OI?zH2Pu|DO<~)Jxee0;#dFW&XyKi#%K$(`(G0VAD zFOf|N4rw|y3Ly{H0ITrU@BORaV)IX=?`DPEv!$l!{Q!QEGq7inI`ABq^o!rV=r(+g z)0BfHCmwMhT8b)Eik-uRn+aQTeQuC#{?@|03E7Hg9Ak29SJ6Nwvp??__HCT%* zxDsibRvMh|&(E(x%!;!j55J zCr?D2C^>?{DY<*@*z+BE4!^_7tZO=xKyQlpH|}XIW*0Db=C&SxXEj$WzU!B8D{>#~ z2#~{tFMhm}>W4=ZCxOoAw;G)Gic)D^$Z}v}dC?)*>2Gnp>vaQ?(=~6oLwLbDuMYOEA%6 zFE}iq*xb|D4l3-HbJBaL7!`8_bNiz%czQ(&0*h^JXp^mFbgZl6_`H{@e{O@3&nJ&4 zkNtRMAuN`aNh80vUK-HSkQC+FaQx#&&R-W(oc;SY$EhrdxSxqLGYq#Z#Qr-)NA$w- zCAVT=>~-uH$46a1HmMV5h9$qiFePocwDYeE!TMst@2sD5p6}PWF{u4TKBs#9H}0DMm=7mf zaxZUt5TdaiOVobZG-^qX8`VC-d(t^J(ri6}HE+?wQvm@gkL%uEljRPAe@B6ZQfE-^ zVRuMjyH94SZ}L4rvJb;Ry>kIPJR^0Fl6*Ych??hn3_a6Xo3{oCF@72iupwmzTWToR z#QXVrExQ}N@*MjPQG-Cclj@mrSC;B63;)&%$oy?8F_Ys^;Ld>$1_J-RDdH+8QC84c zur@FwZ%V6Lg^Ne`7bb(dc>2!=7QEFqA)5tNyJwCD~-hA!+uS2g=>Iuk*| zQW3K~6Atlm5lzof2F8kTka&tx5Ob1U9xb>3dfdx(WZp0=j07g`6P&&UNoa`=)Fi%; zldVD#LoSg1yTH}n?80qEzW=sQu3nj4@2{G3M7+;b*i12v23McF&3*2kvjA+o98y(g zNt8aVp@Z1>RHuhrnQ3h%T7(@5#2{a43t!3$2>qjiXpH2tkYzx{&^ObCuAhAngZFY2 zCXX^XL!Pkew$O+ZL$QiT1ETg_c3M(ptLcYaBTrHVa{{q%I4d z2L$fnG0JHj(Oa=OVSAHVc^z4eylzyIN2!Xrda&Or)hVcMI_cT&!3uFn_r}knMzfWn z!Kf?#G;JCtLL4PjXUo8kVI6`kYL92TvUMj+pACi_gwPA^X*0rxDw|8-9S!-?-7BCc zougA1LQ#+qhK#B5_&Dc-oDsWp91gniz(8utlwbdIe;fhhHCIz#T^?e~7{$2~B2lF&+T zAy)LRWv8&yxzf~d`c?7|&trK009rpe9h211%b4{1h_XA{X|-6~)68&0dYyaEG9PQi zko6e)mga^X5FaZtwZ3h{zNAo!wkzgQHy{kl_?p^j<|=sA)wQQI?C=o0%ty&{z|Ejk zd>0@JoX>9vq>C|mFLp2O*#zwEBy;rVMmN5rV2Q)hhtEgGk$A>N$!pap4D%G!{+nJ6 z>1(NK;XkUrvXOR}|KRC6?%}i9Qg&-ABCk++Br(?aq@e0sKozUz14H`p|6_|nS++4c@J3FM>OFL$CVGI zKmoCzE=>pwWTyFLzDvFt)XI}oJrOots*zi~)NR{NONiu)7x2uXENigesnul4EVTGL zDXLS3!=x+d>A~4YYniU$N2|U48P-cOyh`OoV$VMBsdCZ4kIlf0Ha zsT@5X=CZ^h8ZSzIDXFB08b+l*#=tMZC@A8xxu)GicX6-7QJ52G7Q|$&<>vSvV3~*E3>m z`X$d1^^=sKV;4hPDd4@{A9u-nZ1$6~tF1|f7ZqfM%Am9pi{dW`I?;25oq)xAZ4(|D zGmjn|Ok1q|9x|}pq`#{P`5R0o9HfkLsyVx%4W{6RY97_S^0yBje#zJlRAn+$3WMX; z{3ReKrj2PY6SaR#Ko@yOGCnklOZz1JB2N;C& z3dT+I0TULxD>CH@66>4lwxRsUHA8NK8{HR`30GL7ymc~{Na)@#4#ji-CR9v zblE$39G@Y@lVz&y>O-nlc>L4j zO@Ec}2q)+{uX0M)mM!%W1kn#hJfUDyJo&J`jAAw)eQ8IT+|L(3)ntf1`45Mj<*hW4 z(-NjFHZ-u1u!g>5Nho>=vUmU0#j*VEs0Q(dNhK$&Jw{%O2w`*G1QYyahF z;Z>;?-jx8tjeX(sI>n5mO6eZI^T&}YE4x5UUTb;JQz)iBga?EbcHKS6eje;Z2XO&jM2!XuNHl2h{hcYKXmfYYTS$!EEH^ z4D5Cjp|~@o+^jp&Y<}o8lt!xkvVDoW(vP}fTq?5%8OKz^D`8LF%o}C+b6dl2WB_6! zPhSwIXB_G;{a>xvV;|p>)~DkZ-wPfbam(V&GU9vxQPFMfemRa+)-$Y$M&^@E@Qc5q zffkdd>VJz2QqO>*&ziYf5_dee^l61Bf)v*5;@hXhNx=%?si)fhY^4tg(m8YUVW7zv zC7-bSZ6f9nd7&`D%h{o%PqaW&A@K@)LY@?)bJw*hFMRN#>e1NvU|Vla^~ysqlcaqy z!nZz6hC@1!iy*<;}p{ zy+xvgf~@^VCGFGZa|DOQGuo|ar^;ltpoX^E*Z)NOiAL86lZTEO=9+sMAp*-iEx~mZ z{sJejl6UkLU{$@bsvf7LlqyCx$63IbNosU)bDs6JPtNoA;yasZK`z4i^IT8LTD*jM zlf7lX$_*a~jC%%|R0jpH=om&J(oBzR`Qqh3a5lHnYF zyzZSr#QPTC&TX;a(WNhxHQA`BijN$PM}%;mig(xj3@JQ&i`f&VK_z-=Jil~v3kcB_I~CgT8QWDiuxDfqzjJ4g?CBqa8+)b z9Aoh| zNv+v)U5=f(_i{WJUB7f=5B$um!uy?qs6obQ7Po@EvzqI$^Pz&6J|yeLtwFy9m^J;k zK2-gBe8;(C&6gVPbtJFa^gDiXIez2e; z@y=myqb=zoTg6UTwL6d)T-3m#p!k(pp2^no*j?%7Vo^nI*~+i6Rvq&$x3+tv^ujII z)%o)BUZnj-&}SlUqV4xZva+};fpcZIBxB2|ErQuftYbLvY_ls?#T>6fWKBdliUmRX zbcI&IXqv7=*no}b*A^A%;HHy$eAqR7m71Y!;SMpBUeuM#f*4TO6bx{O9BPEx>I~E` zJ#(;c4QlI+Gpr;lPY+#oE!EBB5qfd@lm0ptGh);<+&UrZ<@if(ifaH`Z~z)D)tN}+ zix)w#8|LyMWpn8(lC}-7iagU>Xphb^LDXWOl*Su;Y}E%DX_?>*za(_O*u3CgU!}ub zLIv_EUyJxA62Uhs*89TAVod}6pi!Kc#o(`7D!dYfHo;`Zc|G~XeLhghrcjSH_d2g1dsntQ>F}6r{U*i@c^f_p8SEv2ZU_3vp|`^+s1Xw94{G3PE+{;!uaV35-x_ic zC{mN*_Y`~jb5^Dk8Tw-H)#b8k{zl>0a#A`Mto!U-9FlIc=75?A>W%-XZY_0) zUWa4`oXpf|EA%PpZbq=z?kB1Rg~e7DwT;(T?I$~6TSM5sy@8I;&B4=8BZJaLuYEV| zG$G{)ux@APu6{i_t*AtlF)Jy{T%p3p<1mf&pw^qZ{!fi(#C25E5mJhF zaEj-tdnRqC-1|nBx1gp26=TPDBA@+rlUw^1hD|o9sQ=^XtfQKI|NoDoA|)!_Dk#$3 zWzoXu8ZhY?4WmOvLOKKl1VoxKCNV~X#AuN2E@9M&G1%b!-RGR&`Tey&?tgZ+``p)c zKd;B@@#GJw8eFbddg25vL}PZFEM72`AkCQWIglKB0=Tbe2AY&V-EdBXBOJceXn9c_ z+D^B!;l-{ZDHI9@_XK?{C8GqPi@(PW~TG$Rt9TMIzP7Z zZz)of2Tw#Kpg}R?=Tk_f0KFWb4w~d=3^=};|=9afVc+wkfd+CRi zk=zYOz&>Jl5?kU4)7a{t#PA`9IQLb>zeZ$(gc915i~Uq76~3%J)9ZIo{K&T5Cf*hF z-Ta5>XXxjyYpZYN<*M0fsj-=@?#?b3tt&o>qTV6Z=B+6%GUnR*2A!H^K@DRTNDE%Ihh$gg7az(_AGex?RGJ{(%bz&4PLY|F0opXODZurwK# zARbf|{|*s1>C83@r+1`Ce?L$vQNFsT(mxRqhlT8!6*HHknKVFEsqu}T3c{uT+G{yK zg|9t2cKsE+i*2i}bX|}t5E;EbW!a1*_HzQbt7WH`r6-@{2frWpm#xI-3aw9Dj&sKb zSF^itNzq*|BM$Wnb<$@FC(ohr{ zfN}f8+0>BudH`>dMbNy?{ndCXk9G@g8x%HCLXF=9x&&vxN7t2RTd>7W&=QBmh`-MRNj$!hjMpDc8{SAGka1T(=ITSLwg7kOOAkj|tqb84X#y`+F zMMjILl|hh@%_Fr7@Y2{i60}r9XfF<#a}zhS?Bx!TuzLt@njl#ENPbSw^m#NYacVBK z=Tx~Jr*HJgf5T8ut?W-AE5Anb55LM_{v%1_*ZtOMdT3E?=)A_D`hYk(ws5Vn-OoC_ zrIdc?njjZyd&%Z~y-lxF9sVh}`_Uzq*R!4fjW^gponP^r81GV}>Jf}P<5{SfDULOY zFY|M@BdvKaTN+&mb%bPQ?^}ZKv4dv>Of7@rP`K2=_2g)j<6A}h)641}w}1Imkfeuh z_VFF1bsr-vtG*sTkpEC)sczPkOdaq&euh#_W6)~QV1BScTD)hkV4%5`MzAJIW3Hua zE(b~9`YS|g3KD^D_M0c92J{3=MX!cRtNux(=ME1ruHoxxb_H|DeXx~WwUNm^c%v*8 zx(r%_-8VOFYz!2nktRa<`!^MX&$p&m14SQMmPD>9^1S*MnnyevJqn&i4G;d90Q&G+ zu1E$j#ShYgaA|%AHA+XfQdd1)W`mrSuro(N5e%=;r_w=pz7PtT>53R! zeXY_vgTB!2?s|s@(P#dhOyNV}4f!h0I*OMfH$4@dxvh~Nq>7?y$$@z$ctC(91Vkg) z?M1+pbH^U9L?cnXCQht}w(YP``;AbNfV9pFzY0blSV&xX=R8?#*6WT$x6)(ygpBlK zs5Q@*v?-UQp@1FXmMIl%dYjXkeL{psza*?+cklG@g`W4VOiI+~ZEans_^wG2B?eHBw#t zkrLf|U}a8i$>@!Z3{lUSw)(3A5^!hl}T} zNqL)Oj#9iRdc__?J6G#w_SNO+M){v06sI+0)E_ONPQQ9{2SZ8R4~vYnzg*wonMixfOsBP?l>PCX^vd6j z5HG==)|QlozCoMe+}y9{RSwfDczuYf<sMqqHMP5EoCxpwWkUnJnRe2PYJib|Cua-9;aFknSyLtx0Mc~o zn>$5l#kUJRR7%wl+(Qy z$9onU3eQVM2LR8S#HqYHCycn^uq5dxeLLC4zShrK`S;Y0tG1V?=hxhs0u!D-;nak~ z)oWb5#mY=iJJ`|1lP!0hez%NeBsmEtds2IA34590MHqJ=6+TSZHfzp^i zADrx`ei8G{riB|eb!%ftL_5gbD~VHYKKle3QtDxTMSHro;Fr7Hc9y3))_|0# zK}l@}dA*8r6!4b2et9do8rgVS82;joh^Kgp{-Jn(V~$VI)l{%7b$xwJc%{J~s}`fd z9j%;3sz9Sr%3TY>N;^2Si;xDhfj?90XFsl1QL-Xv%h_Lo`Is?rPu zUCkH{m3<$b&c+DQ*Cz(eyx#sneth;f{=nh9+%-gAe1N!ZotnQ+XZPoeXex<)ZpdmB z267?a;{C_sF?(={UtWjR9)ONm(uwo}jm0ETLzNw`tNR`Q3XiZdyBU3<=+dDqa<@L6 zPLnR(RhUhelm{d>vF$!rX@)3Q5Es{Q05ZyN<;kEuJZ+-?xh5re?~X2~%sBh!Ny zZUAO0PO7Z)jIVf$-HQPz;*R@y5=Nex5$dpD$8IL`T~og`Z@Z{LKRk6DzFWD<Xr^-}BJDv=El*pB~wBwde2x+V!?Ld3U^_ zR=zRX7)J2_xmd5g_5JF1Azt|bHaXm3EpI}}Epx4^+~YqIp(>X0;nizZB1)5FCWD2S zFLble|GD&#z$!+qY0fk$_Aj*cG~3x^VlCvWjFny+yE^9F4rdZ^oeVY80LE3sbjzE zSn?c5;2PVqfq_Rs&4!0clujq=UhXRw!vL(dPWW%QSH9l2#+n`cq_KAi-Zsb+Z9U)K)|LqmF**GIwl7?s(Eqc2-Kk!{sm{3E z;B|982geG)OjN$C5W$|Un{}3_^+{dFh%L;i&=$TdC_)?gwdz(ok@A^2d^*cfF z@dEG$dje`vlll2Z%ZoUd+&1i@u&^5-yyRS;TpCp%%?N5ETDQpH5<3rZHZ)2eDK3-Z7K2HksX-_fAeP{5-FF_MNByN;N)h zX}O*%3aQ8wf7OuIeR`>z^a8~}=}SiUky|XFVxvFlLQ3QqIG=iQbP(ygBogQ){8(N7 zYFwM&<*`tHDOA8V+UrJ=`=s}m8kS#l+d`wOVTZ26t$XlSw}7k3P*WIluZuUg(nI88 zcxb2y!7$sIDBgOVe~zs2+f!k{4i=+45TtE^N}G;lXX~FLi<@@6a^K)DGN}ii9%v(K zLT!vE5ey4d;a&iQ+>+8<(-q+$QudvKL(DvgzJFW#(DkXzA0{H^6Mxyp*SHuCv88!E z8=HD^etu~J_ze=8R&IZCgnpMeKh!xgx`{}N3hTxE+CFzn@m-SjS6>P3m7rs!4gJzv zx(m&czQq-L8GJ*bxVnOS6($qlflAymRN&=V>xY-MOdZb)h=yHZ-$*|i;U839EpETt z@){$)<`E6luFW{~YXOL;M#fS>B##yRC0Psu>%GB8YV)2t4Y6Ob@_;YPvPjHDq#%Uf zaj`~~X4f#pXkEZX#VE+jto^pa!xd^JCeyj$M)&C_FAQcU!=3`f^-h&rr`wrRW7D*3 z$IE^dt=G#a&r@P!;?_)}%xu%HrR=X~M>TQbs64qz1%H@UXgT0{cTM#l+rK82VT;lN zc_P(GUeQ4-&&_pyJmCK)b|spi1Zh^v;qU6C`!>CAT7U}Nu2W!Nf4iE*=4?Ko zwxdxzQu}3e`N>)34wJGlhAotrag&X(X!3JvDr*-3aR{pnVaCBdFrW_O>`ME`&g;|y zAO0hO@*qMv@%$F#Jh@@VMnpR5rkgQ4Dt|R6+Bv6xSxP9_|>%+xz zpMU&k;y0Ak<$LD$GUd$Pj9(XEI(N$9pU>JqW>4mE-pn`ojvs8?Q#rjcc#4IakSRO* z;q$84RSbT-ICF!y;7PH6F{9B0y<<&QWjXFdr)iZxTZ#Ou;w-6yc{^nD^$LIuYOU^K z!NbFBbvMSrBx=-M+s}$5aMR}iGMFK$Z8htq4Z5dw+>v}EOD{~=boXc2$u@NtMzWs}+TMZ-n0V_8V-tBP)Rjl= z9`b$?c6g)k&tD4pXc+NGLv=(J2A?0?Z(q=r9164Zk10SYMg}zs(AE6YKCBE;rq_$c zW;_F5W-gAM08r7O*#AhV7}%waQ zo{oocMq%#4T5k&3CN}nevoB~IC25{}+(RSvcQb0#Jf63>i#)UM5?-^))iBSFmufsc zw@ZJ{q$m_ZhS}YoXj81%W6iQ|Kus%mQisZ8F4hZ)tty5S$~7~CiP*Z*N5M=)_<-{e(q4D6wNFK zdFRUg?=!?v61`|qH+rfex~OqcO0KX{@)B}?KMvg^S=ePCmcGyN?_b&uiGQI$(oE!m zwvBaID~?{|az^l?>{eyPy|v4riAuNUlT~X`^n%=9NE$B6I=Z}<(7$lnFtvh^w-Z&* zRh%}G?KpB>?B-40_1ER7{Uh5qIL6{TK;%zjvEr;l%O5y?&eYyFOg2d*4rOPz1i>Tr z-Ji~LIhlM~h@DpBXX>ru-*o98aDR`hnDEX?V+YFcg^l`e5>|Fz{S4!xjFffpiIv&QdSHC)rU- zB86wQZeh$y^ZX^x+l4m)ahe*ke4cI^ujL0OS`!Dml^=!hA2+dQXCRB6_am+iGby+8 zf6;uuxm|0r(Ut%U;h$D8`FS)g;G3RaWM~{&BwFUcDRakKU4cmTaL^JD^ZcCT0?Z)8 z9{N+y_xf)Ow%Fl!d^kH|v7qR7N(q{%JdQN&F^TiK+N_~e)VM?&_#s_}5I~pYY&~A_ zJ*qMv@x>W63fs&FJjE!PtcB@CeGv+P}a489G8#4)rr=9SZ7wsr|JXf5xK7pcnz zSLyrg)t(Pt5>7h$KPpDFG8WX9$FV?Q;}zfz?o(&r%)`~+-^BKXv_E$mnwA@Hf5Qmx z?G76xIM;3NDay(MGxkn2CE4vh}6S) z#h%jBXq_(g4!lDSxT=Jhq&FKNTKO9Yo4!Gs#a$NCS11|DAo11-!9Ow*+po7GFGeM1 z_Ty1H2AUJ z>h-O)i)<^H$^iKO^HQ7uxVfGFpC+GHhFY{{QF*`4gJBMxCY4FrFL`1`$22g@q)w!_ zIv^vE&G@KW8)94UG<9$D->Xs_5LGUfSS~e{qIyda&Ek`q$u+qL*Lhq7RWVy04lCPs zuT!guxcDJmTCD3+t#s&j0b2^&t-3(MYyyMVpTzFIUz3nPow}XqjO_xK8Iq&yml`xq zR;M52Ap7(Zr-D!p$VLsa!M=_0f|SW40fCM2pGNa!-Y!*z-2Of>7xz?UI8ZsE<=ojE z+xAPy>MB5&+yVd==>+=%cfwB}emEecnA4)9h{$QZ#cXx$d;)Cw_6p0P_HK6=?L) zA&$+B-k`%=+`3-F>bBrFV~O*rRDRsTxX$%+Bb~e#4^W!_ZRQ&$$sn_d&bS6*?mOd!5LZ_!r?o>6z@9>Q8kEfEaT^8*ZsC37pWWhW=sh55%;KjHTCxOq%PM(& zEnrE83K=4|!?#_XgN&1GDK162ScMDdLm~2>r90ZC@ta;&jBB|%M+P%WBaWfX_17C# zg=AeJ3+2v5yJ@E;1qP%#32A!}VpR{qeyNF|ZZLsr{(pZ_d-TTlyO$S6E_HVc0N(0vUqW_ zE7|fQzn^%}spN!{$KOSBFyR^;CvBEW<_EXcxNNs~#@qUXV=7GSzAw>LQPJRM2y~RNpy0T1dji7hq#qGQ?-9$<1B+iZ6Oz0M975TS96lr-0EXQYs%5-_6(ZrJIrV+HV;*>`gV&#>;Z;^_FV; z)kB9Vzy%V6fDiQ5X?x_%f1aG-Wg1R}^H(9kObw@k^oXNSIp>oTCELF@?1A2D5-a?q zxeaK`cm}jPz0sR8CU`{%aJ^)zO$vwp(>`~l0*?ZAWtx0OEu&se94LQad=v7idFb&8 zs{#qhs!hZ6F{*gol5Ewk36jvWDMrra@LBxH;}^fSE^G_P>r%tNJm`uPP=fJXTMAEl zcg`Ug!!xr%jhzu4_#&eG?MCx=mYWszeEsmJ zRFyXNpLsbX2Fv?(6T|caDnl82q(Lk#5DeJ-uU+%lQ628U?X0=0NXrLOqU!kkV||qD zi&p~)nMN-}JOd;_Mspw#E?oIpTWL)j{Dvk!iicmNPfoL7pm*4nDQ`SbS(Qrjdf zKFTn58KqRn`Vn>L^$+~{m~f(2(Jjp;ZZgC11efBEq1{l9UrW{MxBVN&APKqfks-Au>IHR zf`-_$L#!VW#~gL%aprW%)lK_T zjMcd%s*0Nt3a<}oT&{_3qR+p=dKft$D(F2xzJOgfRxCLugMcfD_POn*Pm}v%z44V1 zWb$8mBGQtNrmS+ExOHjUxo8DMkiE}-VgDgolN9s+$>8}`%OHtk+ zC%>RC#D4C_jTRS@mzT%r4n|J85S6=;IrkPw71{O$AJJ>(Y@u3@K zpd=xCO6t2RLf?Uw{u5qibB7CYQQIVn^o5`GuA0MCo5*3^ z`$o}&<4~H|3?53gM~e0@ORoLGzn)u3cy3WeCy29^l5?0FRt&$ES}O2ctvX!#HQwyj zy3p8-b6M8*F-{5Tx%gy;$-x$v^hz)5KsqP3ZQ{;Y=;+I~;01MVz8+uG*~+X^%KNmaM6~Q}ca* zPS)^O(e)O)6-*jFYID(JsaG;dDE7!~fPW(hZtx$_+)!|Nz?`oPz+|r?7g3~ck#;ei zBbpH(6-G+qQ$X(mpoY>H()y0q=GA1=jib01Qc)1)xNv%cweKBI)O3@bxHRQQ7PCNX zHxCBBvGS;PNJ^{o`;Y@)QhoHZh*E!!aPV_&6w!RdQ!(9pNL#t1Uo_pSbYW`?nvzUP zXs10AUX8#j4Sg6g2c*)yBT4NgWzyF;FkK;UU;U}X89x7DwBv^UxFzrT@eOyh;fzto zDiw1&>y`-bYQ~ecqi>E*!7KI4xtyr*xn*UXv69S~9b!t7nb!27CdJ;@b};-$<5Rtw z9#MRcB8oI{^v~#LDG(Kb^Im?@;Sv|QFr3+MIB28s?DfbL842xVDggSaYr5+#b*BAq z!!rFZl7L*9vZ4ZJ`BU!noSvAT?au%fRy-fUhd64E;auUuHNzY%F^|+?ifVeOM zGt#K-fGk^aiW;cCv5vmGc2TP4;nBNP%hYOrLrnS9b9*P%iSZgodr;1Y5`gpbn%psk z5C|7NXI7hd{@QN#>}evpBm4ZD?)~>*w%#9CGq!Y}W)dnzr(4WrnLSr)YOYKySCi-# zM}63vp<-8)b!4vNqH)*r+AVhfkudJ+EOsBPXGkrI))$fOP^R_mT9kGxau2&Zyu-J8 zS-#7PeR?(NLDBzUhBdv_iFELc{f)M;ZbFW7@Ewy1=b*HhjV5Gr?~~1kLBUY-9;rJIcRuE1YSfnwx5uobAwrz3< zyaQee8`y1z7Vh((45V$Fs1@LzQHDBdrK;Euk~Wy|-}^R(8(M%9>ccbOE^TaW$E1`{ zW5;@T9ogHplFE!i#bxHps!|${NH)+`??n!LQzwHGy@HYcxyg$76l*&&C z@?57bFL8PBpC8pe}-9aTUZ-wmlBagS!xpe3DM6*@CC=aa!7xURCE_Z%pGhofB zQWXUW-;7yN-*jNQW8&(0X-AgHj1{4K_pSYIE*jxv*VWIR++EYnM7d*2@l$66u9$QM zlxWiY-^&rcu8ORXl8eN$L7bY`HS$+Qts7pMsp{nJ$&AOEmDX{l35#0H@?4IqYd}9- zw{gbp0CgKQb-Z~wZ=n@WeNK`vf#Nu!^gy1Fr%H$o%qVfkF=y`U zBVocX@vbt)`#$XV`4*8{mJ^x%s+X?-fVQ};E(mivQ&aU-nuVF5V=p&)+o^;V9tCs_ zIt!jAh#TBkyEpIE@3V2l?VttmrE(M7~wA`UUm` zK*|PwG}?vSJd5Ae%CK90i3yp{jMj;FGwc%hY#)?L<$I2dc2Y;(Q*qjBlb=*Dvt`TFt?3$>S%`GG>|e$Bpj2UC z@6v)RL4_5*!nCQ*)uT~vcqwt(KtWJC2JzkcL8mN9{~2^%8%cO(#hs%S<>0|jwBgUF ztujWH)ykcd(PxbFfNq)~x@a~KFcvs0gM-p5C2`%+!^xP)s^1~DpkDz}N%Jf}e zM>erHFyy2jC@)eeL{iefY4!)rZ`3-wz(Dg>>;>^A2x#arP39%t;whCZ z-QdS7T6Kzgu=I%akw5XP9PVLVpdX8X>%){>Qno@9**5M*cg|n~T=K@HTK^+?<#>8e z>F_1R=pTvO-7wiUe~(i7$-w8q;L&|{g99tmTrb48{3gET+Nxdu>2@b%n%&Z0itfZq zSGc>^kiT?H+hz;Yw+iW(L__O}vY$NidjfdB;#_ zEz@H-s>fW_t6eF2%~yn6)Wg+1*rUjB5~C$ygf;%R^!=OyX#U-sdu9ZlzhQF~8f=;J-aSdTYi@W6et})H zyU}*x{+@8nJdWJE2mD8~=eujpYa0imtY>PL7|IQf%;OaeDeNQE#LLcKSjpApXBcep zMst1kiR1im@|Wu|!z%97E8|pW7FE|g9hb7C!RJUfqbdtkF^KP+pA5!yZrU$MsLKOx zJO0s`HDWnq{6@ZbiBlfR+B4JlSI7&AL};(#zi%PuMLa{n$s3ZzHK*K*#KpB>KRxqs zhi$Uh)cpyej=MB3*pv5``O$kbSU=e|8^v0PNwMYpJqHK77p)IV)X&NeD{WgNQ&o%& z4zzD=xWwz2HJ+EVVC^HU{p?}HIpF{cr-{In>p5l3;kt>tJvmyJQy&9tc73nSnK^&3 zZMUk(a$DhM_Cie5zca4miR=q4QqV|RAI+{le#!Fs#1j6_{hZJRZ-)MGU zZ(nT3Y>xO5>ULOdnF%hheEn;HHFe&~JL527PrH7^p{07EVv=TAm~OL|W`IZLOm>w+ zJ%1J~K}I1QX5Khg_8#Fv6KC}tiEpYyA6Q&=G3d*&=w7bUpvsN2=h|C}&40}Uj^yqu zJ1Nt?F00hHdcPM$yNncUcghWVbSmC>H0-Iz^MlgbpT@<=FF}jbykWfpRy52NS6QE? z$Tx${n9>Jivt5kr@eiH@Ke@R~(4HiUs(@zri3fV&R^8#E$7F;@cr!Wa9%UxCq@fJ( z!}5Lbk-QV5O5DLr^iWe;`di`*8W}NbV@L3ZDiblB?W_^TM!$zyz8gQjK+JyVC!#n6Y4yB9YUg#?1&8#dmUklnVyss@uHDGR$g>-w)bMuD+SP!WoFqJ#!#?J8{{m4YU$6f`?kl!S==i_oj8QhH#n%&feA`LNdO(J*#-?ap`&C((`?7NumoUDQN|yy*on9FdbLSWwl4$wAT1eu~p{h zo!VH%XVUGH%7I=yqUAeuX691GTrMneZl7cm0K4xVUboKwkCF*|r??wgjIl>uk`asa zUQfvUd|NLa=T1O*5CNZvYC20RjdgN{UI2h^M7V7u{%VZB9{Fs}jD~3aVQ&p*fh-YM z|5p>fQ;P@Pi7%Ou{#wqDcbmMoRhj(hidT0wT3&QHd?z)c@2g8 zdI5f%h(%;pFwfHa6GfSyR-flO@;JUMTXBjV>gWL^_u8pFiZIF_?eHHs{B$~0y>_j% zJeb3A-(5g2_hP`~N_UqQT{1FF9zWHxEY^JlqFjH$K|8><)nX1NB$cmTr6zv(S)b~h zr-dO6%US1-xeDpUQ~`{e66ZV3ir1`Jze-MqjWwm>91c%)Pi8B*Q^|sGGwY5ANJ(r~ zXeqFBaOYl}%q}Qy&GWP}llPoczg)lW8^h3va?-L;I5Raw^<(XRds}4Y~}o)USQIk-SnY+dYC<=gTH;GI2(RnG?t`6*$Iq z!Q%acn6VBI>+EYOTsVeR6Bk{e;#IQPEB3|m573LvBr8Y1Wiq=-fiQ05JZTUC)`_C| zs2~a{BWNNMjEYhm$ds3ut4^`atqG7pprnT=tYhht;z&X8=Um9kW5wQBp+e)99MKL@ z^mt3vU`KXokMhI*a+jwWvaB-hGF4Q@&oXGKgQ{jGMH<6+=+Y@fy?<0*Gv+9Gpg0+- z+8#THy90$0X3&s7%_fNiW8y!T3<6`R?F)DHOp&kUq?o~I<@xBY8-`<07kPHz)8z_7 z=%fCgumH0VvgtN~fb6}Ech%YKir@E>O9zu+&Z+A!ZFYm5Rr{4nAt4zu6m7lq4&yqz zySsbAGy7S1E3}npwEj3G3hy@DLgT|$!QvyI?nah@jX~wdY=?8f9aQ5vP7PiK03j^k6sC zF(b7(WBO=ztI&XkO>48hIVfL&@8-h8MqItuC!Niv3iOXLi2Y*D{X>dS&>j9$gTp%c zX0SuHdP|)J#5#Kyme@7^&061C)+x>9@H*4rz%p8jRo8-*EfZHXMfz>ch2X@AH{bE1aSe#( z`^Y(8z4d9%|7PO0%K2zH9Iz9kNs|mtbmgf;23YUU*#Z&}!JqYll3%d!cLi>2!$gO2qh=75E-{}f*MXBj~?=Fbib zwC9Jd9_qzcj=K?TKrB2{p@k>0Nuv;yHRMrX!0ObEP{P z?-IC+W(o#vPhTwfI~u*@YZnjY#ZG#!y!%O{csShB>+@$sua+u!cmLqI-)c zUm(U@)V*}jI^m0N7iU#(wJ==Z`6jB|<|Y%XWRENx&Yr(|g7kBGacO$MSQ}$D_FunS z%(#d8*_);IeU5;6{K4UrO?@HpdVxszPfU6AlqSfCL|&)Zz^+R$!10!L*IaC z`1&iQgPUze?H4WwFE*7eyzIelTvHyOtNFmx{>aY}LY0@u$;x8(rQPqyFMrQC#jkG+ zx$?HJfc_)CJ^iiguwr+b^m0%=WC{_}yOm+1$X{Z_r<$E9xB}#`7ZBp8df_{z!UUab zYfbdfOHqq`YI{Ps25WV*?ESm)(Y`nip#M}g-&PK}BVRw*aH_u&5Uk6f%Km4jBxu@q zPi8=K#zYGCMv`~pBGqs1#$NdW;Z?rgR7m49648#GV!r}or&Gdv{-ooihy|^d)8|`I zcs!$r^?0-N>z`W+ndTL~~)okQCB$tJC z+Y+0OP&WMZi1=|_JP;~>A62|;-EGVxcfH?4d{ zIL+XllO$QS>Z(D&qf2?~-s)2C&yi|#cA_+(-F?Nu?{5c z@jbAFG=#kTy4^tbju5!vZQlL0fJy*4PQzE1NH|oU!@hD~)^8?-n@8Q&croQ*#7v)Q z4YL50N$7Xb1A-=_!FKq`B*wd+%UmHpY2BQI75+x42 z-xRS=Pi^$7BU*W&iRLS@;?qBhptr#*=@zb^NS~ZJC(yu|?u{YH;AGcYbr*(xz@k>t ze+-sZbwj|Z8zba$RmTt#%x1F(kJ1g?kC3Y{58H+SeygQU0k@1@?WXsTb(M8BTDAqoSj1F%sE9Ls0tOQss4DUU3? z!4;`owzb^sx7kGx+;_H(aLk)4hgzafj;YQpgSVjH z>f@NUR@Q?b_Cs|FWV-Qx`~`yB(6(rUT{(&Qr8Cb3sQSLwC-YR?V`7a;Q+7b1qp{ED zyZ)RcA<|OO8+|J4Wde)*6c-rWR&;^mzzIkXV>28-2 ze@gXD>3ks|^KDYMIa`KK4};g|P(CefchuF5x}bYO>e>S;m&K&cD$6F*1&K_~W}~gF zCJKT$a{?Un=wPos5PhSz-{309A`zOP9LXsP{*UB-RU0P`^WJ6Lyl(-C-)GgQ-VQ~SyeZCF$_F*HCH_qhY|vjc~wVBL^FN|NGs?{bX?*dvG1Q zu6=fX&g*@?UP&=61s)U0`QpwyFfiHk50sl^a03+nADyWu>w_a2MvyE5kJkHP7pGr4 zFTQ;%9KlV-7tWG_Skz>oM%RMS4|^@Mh5e)n*+bs#*#Ow7W17G}2Rl}FX80Ygg+iMU zDPX`c*@573_~G_dQE5;|0!B*j1UJY24f()$p2Oz`)k%W@zL$9H~_MMXsT4aZx-u6`87zGnYH5tqe3Tg3kVi zjq%cItChD@>CQ>!ABJnWk3TOW5+O*$18>nj z?gW*cl&Lq}7yMRnZw8H`nMAhP{Z`^R#Pe&U+G(R$4M?Ew!OvfLWrK5Wfj<=APhAhv zA8Cdv(vo!?z^~@7$EjL17I^vVEmg~iM1^bbQ%^2j%G%#rtTTZ7o>~Wb+1kkEa`ml% zW2#rHsxH=j9hPS{y^Q0hQ#O^2-u5LSc{!f}CW&sJY2=Rh7@2GVd#eChy&3T3V!vxc zarb-`hNZL2bA1m~7F|^7b#VIDTdb_8icS48o1Rg9PdDIjs#K1pCUmvjF!>9lDJ~_n zhU!h?{X|t4Oe*#d1x#!^g-Ge?foA!_FmbvfSA;%eejdOr$ng|qOLCANN$(#*qzNs{ zbOrUu^~l(w-$hiisDLF^P9Ra^?(J*yw-k}DX*Do*H|(50{PCe4ir1`ZLj2lZ&02k; zg20G=%`=l+JAmh~go%!35l<(2-Y@6cSuxmw>;)Qlw^XL1^Pd-XK2qIZ2PQ~a47dsaw`u)WM}Rgp#EUEZqqVFQ;qV>N4E!!^gnwuBEdRH8ri;QpyXo_f_Mfi$R~s@= zHAwVbU~OCH*6{oy8&OAfwc(Y#@8x~wp5Hw@6pktpY_$}YbdD7EjS^J0 z0t&ky<8n$6y+4VE)yXjfp%6U5ysNUiA;D_&>EG%ytbi_*B;Sp7(u9)K=*Tn`>gA*9 z_Tc-{ODKVukiAi+6}ag{=kkvX&D`>5`>x~jnqOHoZ8_%%)t&74>-A*jJg89fLNPw|XitJ#Z`5CjSM+a^2kcT!@)~elHD`+{ zDBdg91=I=;Lx^>a8=x-A*wZh8HdFHS1ZMlVF<; zgCy+P@>FS>zF-?krE;5y5FG_efDD= z%D9{1qPy>K(%VTE^leNDr4Q#p8v(n^(ew>AR{kWtJ?;CGe;xOome&8Cnjbitr;c~OQ23~%jKm^D$cgG@Y&SMQ$)>>wB1vz29cPKtv{vYXC(`kn2dJU#EdwsBVs8YS*%8s{5$ z9hd3U7n)Uzn;n|3Mni%Y`ixuxiqp2kn6{@@K-}WvSUqy_MeNRYjoOqX9m^#lS0Wwv zrwt+ggGQZIOaYv`5=~{S#!xkhI2ZZ0*QA<9V(6%S;C+8zcg8Jaz)%}I6Z2`{ALH)v z7>~_SEAb^X7Ivd&woh4UNO(gr*4(VxMbW@`q5u54SfUvXRHJj>fk7Mf>gX>jiDTJ> z+9^qEtLF0x4>sdeU74~UZ_b$(5fk`@XH{s?Ey_r^5jZF@SSp;{|B5DVra&zqr~*5?(*v4fc<=m#4GeqtVjo*B0JYUKG9 z?)aCsf3Qn8EXhkRoUK3s(aA~Uo$3cncl1G(8ls8vH?RGH!(nvL57A~5`L(Uz-F{!Q zIE33>iqa3_XyaK2#u&%{tZaJu7bfVu2bG_)k0V){3%MYTtXbM{{=3zdVkeHfcpwn! zPF8m!S#=w0zP<6)W~_N9$h-$8OElg1M13w6J1&(%Bl}fDa8KQ0Y8n+FGx9IYt)#`b z(-NA-KFWK=rMOg6XZ8ukFI~%-A^TihJ;uZ5<~E%Mhs?$M>~c*gf;o>ss>FDO)`!cP za-FGg%eKfUxR}n$qi{ z(O()i5Nc#Y^@#fmR%`hoKjL?IbvI!*w{o3Fi#}!bUlVMiYE`!3dsR}CJori=wn~*M zvc9Rv@Jhq$HpNXJcDGBhBaO}@rL_zEmpWaKw9hqZp=n#PPIdosXOv{$z*zPE*9S-N z(nb9>EA^n#4wz5x4-G9&0$=?UdJ}fo)w~w@TZ_`la8)Xp$q?{CBU0Y&#HvAc>H6O3 zzD^Fa`9#!7DE|6=@atoI#<%l-S^Le{v>m@D8h7x%`YV}r7K?h zU}a4mwUl+<`m|o@vW1#Cgqe-r4-a1?RjMZZ%ZO`o zD%GOk3u7dN)@yia`{erEh;~H;GYuUCY_0hE1vGrl4pl~wN9ZxK+|L_t=@ur~R<7iJ z1~7$xFxyi(N!|ml!)15oEbyMm8eey=)GCKQwiigog!nCQi2`G5iz!%!ED&p35 zDR_sL+(xuXti-hO>avyDN;cLS!prylhaVu{ZR#;8>l_DnFqx593FbBaV;R$Z^Deaq z_xPYwe>VZ`$25Q5Tueqx<}ZX3F=M^&-CTEEAj1uIm|O532>aP=Gn^IF~*B z1H>PHeqOn@U9Z`T>IS&pUeN6I`n%qQHfcu0NbB}|XemOSCm}7iN{ENwC!rD>TKh6i z^mvn)QcC^OtnYtxeCv?OrC)|sHl2U*?E=^tTmwb5+s!sqb_n{mCH(v;v21xyt61)d zy5Ano7h)3Ja;(3U z$&w`4GObvptEgjTH90LgFWVId#fBHxZm1eWk8w5Dow+O6mgrTGD z^f{{zPdh`Ut9j$1F_c(0*VfG+nnOD^PDbtW{M31leM6zlS{lIax}BcX1|Qg}mh{o{ zd&K%Y#M=K#CS8_92%z?TO3URV8G32ue>E(xPRuWLc9>5$G|M+O;Ef+pOq?ZQ|83Q}H%^)T9DK^{4}DUW5g zX*qwONGsfpNMCmU%zgD((6+C)i!)q+Uuf1o;N_Xu;=CH>@K6$;aiDQ_@aUP>@9Hvh z*Qs}}J4!g}q5^v{J8G@rARz0%pp;arpsypUbwF_{i2MP;O5$34{r>&;HHa;eA_nrZ z^>^HS5}9C^#1PW>J}pdbA5Nn@24I!PGCLBMKW&#m@@J>`2wRLgzew|t$t zsUE&~^%qG!OhT~PVV|%n9;%iyxYgP|myB`r*t*k&ZO`$E>?uRKx&v(^&_V1D>Gs7Y z*qSu4R{p~lbKP2bz%Q$=UdQhQQPnMTle)~Vj0sxPAYC#i7{sdwTAxY{;#4g5QCO_} zF1&+qw=$Nt6%p(CF}%6G4qNQ6v~p`waevQSR<0|xvA#gC`$?p3PM<)b^UG#QpYr74 z?z*KbOgHCx9h*#+UfA2O$a`hv%)-!>{I@ovknE~>lfH>82Z121U`CL=e}?Ik@syU* zh74-Z-4hGty4J$P4Tpig%H~eEYeTuqxJ%OKsUUef(*>55Kh_sToF`4+qx5%cdrg=` zWkVbyqsKPC`ha4MIgJ+qE$r^PqiC7s>?4xdc2ua1C^%a89@1IRT!Kz(ogW{Rid+5DxWQ)XxP?+; z5mf`w#aV#|&s0I#q}>RP({68un<*1dm1$yGkl%0MtzDIX@+zasfQJYtzBT4IF~uTU zp5rs-Y3Z){Ren1mbhYZ$k+$hnKT{lUN`Q~BF3q(P!0b9))Kc2K8u9Kotv{Yi zl8DKlVC~1Ww2`dt{ayO-S6vnocvxUFfD&390SpZlmTgv6t@3#UnZ$3uaWfKAG z90gZ8Ga%nO<6*J=qSi)~eP#sx_h5a6MjG7*H2vvOYXjx=%@}#7hWqJ6*$b>QRg0sd$7{(1QWVM{J9OIJskM0rqv~%d>T-%N6DxEV3I(q(iT z=-Hf>6fH@vD~u?Vy^k}zyAb^AUw|3p?9Ue7ps6v~_oW|nkrs5R;E{d>7m6(1TRB6; zsGdQdF(y7yu?$}8>*HjD9jOZIZ7ntYZFT&S|K64#vRK%hs;|Yu5ttGNqr}ndAv&UC z_&Z{;xx3;P&~3$DI=MZfGqEQ3UE5C4N|tZwqn9fp&rp;td~4F=J$ z_c9*Toe!7?3?>$18&ox$fhVX*|hR-Fh}9L@IsGis1(l zo;P-774S&wUj^Pn{SUVCo-mMx^qCt*@h7)PtvB&dXuk+e7w-ahIOX3%K_#p(2BF`eC)5L6fT;|;sW4d#OJG|D%HbhIZWn+!k6 z2rm7BD&N#kpk50yV(uLBxq(BzecAiS3WZfXpYnueJ`P~;AAWohtTyh><|@J;3eIv` zvmFvyf(jK_{X=lYvAwDHn`r`f1C>Ur5{2HIrXH#xy3blDNa2P9t$K;Hw!9m=R=JE&di5S&77V^N zH&yEfpHp7d>$`puuOU{Q4DDu%cSuK>L2Vx)!#7LkN{UZ_;_E&EExh6z_|iYB%qpxj z$|FtK!;)}qwnH2Kfh?e=;^!*e1pUOZ2MjYVX<4Zh)0JalUj6Vq)MmFEeqXB?YBE;s zwQuNAp{{hIBn6w5pC@nr?}?W1G+Bf_CNo26?mJ5w#w{LXKX`A6c|C*~A*4ElG?>WT zKJtjUoz2lJNCxg<9NrwM>?uX2^M=nrHD?v}p*XE=y`ah$m?Dtb!(@jaxMF`pLJ0Oy zozXTZe!lBh1+p#X)Vu{YXts;(oEe@|PC$soc`P7h(LdHaet!^t^R=ZVWMvqdQ(5`- zh~P@=ACXSlWdog@r`Zj-1a)bL!+T?=-G?GqlUeopSI7sT!WBJgk<)k{d4p8L&4djv zwkw)Na{u(c-Vg)kPhYov}&Qy=3p8oI{<-|M%jQ zw*+{*UBey6JFE8`eSB?Y??cL@HpwdC3j$d}ijV4OgJ85n0nHh91;Ha*dBfdVyU~E!(IuMz zzP;CkX#rylrg{E;&2#p@vO&uc5$(K0p_NVl(6?<(N(}?-T+-AbP{~^yhh)51n}pg% z$~QOfq_XU##UwIn=B`qqU|Z63|19R^>r#5NSkrGVHXk!OSI0)7_Gq6Q@%Qk@ zext=TKgE!93Eccfk5|44>n?jS z_k&EZCfBgOrhL5{Mz1n3*DsA^=JR=Q(?LPSM%O5Dw6DH4`cWz-`f8paH*P$}R#?P)9P$h6iR|VaP7OEHK1(hX3uuOOU zoo+{z1dt}mCKi#AC^IA9j+iq(y-=Q{9^K0bOfQb{Bt+srJl> z_`+%!RvcIUl)H4sqGxd3b8uMF=CU4x<*)Ae%-sAMCcSXbAc=>Kx=>j-Wu|{?aNTY^ zoL&sxD+36v(^;CXi)OhLg4zYR3mxTymx3B>h`V8hh!!3YV_{jvMc&I6dXNe}WV3Kq z#z8|up$#VP;2$V+(nnAIDn_`gFrexLA-EgAlRZbB= z=e2n0bWcic`_iAP$0n74r!_mdAk6OQ4$`b^*}>}4{ft1lLRe<+l3@?rr{V?TQMiVC za?atT3<1JH_^0myyj@i|(Rj@?0iBQfNR^n{NS)H}-)E6K6KTz;yyYaYk-sv1+Tn1m z%M7F+a~TZ)U+|z12J5 z0XbBX9x92u>MB!FkwzFzeT&ID-m(qGjojh{>kWnZiQLSs4!nbTjA^Y^F~2*)quPoN zSk7^&C9G|bHTC_GggYd9OH$f5+AXl~g~H}{+-sWM7e=Fw2ir{V{_U`$=S_j4mN~;G zLR^E8h>vcOsj5r6=8nuFEr_TM+v_4NJJ^~)dKxWscH-@rcQm^X(;cAfz`j_EqA_S% z?9txGX|=Zd;=!)$K9ccJhSX`?h;8->%4@RxN!#D`N@Fj-?}v_8tbFIaFE**j!*wow z!w7}2S3R2XEZjLN|CpVEbAP#I`6K5ucO_eTd*4C~T5YbEP?BG_?jXcgO}OQlI%dVi z3vkP;bQi?7)h^xVxU$%CHKjN+y3qn>w101|&ii-_>SI4)*=}+Z=h5e7Yf7>6Uo>Qd z3QY3H4h4O>lx6-E_6Nu!D?!$CngC#R9)4%-=E4cK;#aK8S}XHs4H-5xrnZBNi~V09 zb#gspQRsy6M*99^9V3F}m+MZL2X6F$apm@6m0&OH2zH4@TPB=Q-)6vSjSJ>Td}-G= zU-Qqf-07Q(FFpf>3cX94gm{Y|TFbl9UmB0#eY|=~dd4F_d2v247tt5&sa!_Y4=L^C zxU<>^GXcs|EzTlwMEQt@8x81Pardgxme^Jf3dW?xxk}I;xF~A>d7cE6^7q5)r}emh zn`;WEKIgQk?;adNx-EmoyRgE=C4Uc}`e*b9!CwW^ZySnAQF$BgG~(?vETw0#O|-v3 z^;i!m8?n4KgRQ3h_w(2hMvHUa<_W}Qe?)gT0NkDgaJ_RofD# z;KtY{@IuV=-8G+p(z?kFXk3%ZIcs?*QN0h~7f0p3RsPa2264Ox?*2#T zS33!SDui1(Lm-0KJRGwGRm2K1zWLe@+wieL8&?<2Fgv4I{$Xm$4_dTd>mQXy?tG|# z-L0c^F0%o0KY_Qa=5)mQh1+vPGSLT_n&Z%|pwg|s$PPbrV6xwL8Mm*Mw=@EFdu#-q z3mU?^*x4=Pmgx;ZA5~oxi=VjcDLqYwm{haXpW_h39^QZC{eo*w{56T4$eTN-UNY^ReQE zBoS?uQpIz`^*u|{X<@|MP@6J;J*@r~{`l^5K4s5R?k#0gatqeRcs4)xZL{<0Z-<5H z){y92hK5)zWE~3RB;B`~{l|aHdOr6W^cf8q!o$jYj0%>!M3M3j^r{?0Ids(c;M6)9 zCc@M}HUzJ6DyRDz_0iY5I%%7$cAF3z=C2jt!uj9lvVJQO-A8R?AMUUN@cqo=_sz1k zOkLOPY!Gg&Nz({T#bK6M*PlrgL%Y{oUrFgvg~my`V|pgJE`n{Y>!bTrP>+FH;98XO{z6RC@-m2QS zwQAGK@e~o&aCwncpalzK{jMsgXtXBDY@#6DGe2CzhT%};{d+}Z^7hED z!!H^6*S!R$dqeKHvYe`=3G~iaazV;PbqGNA^BLZTGelvD{tB%d)W5H@*YD9TWjEgH zPJUe4$7uCJV~lXu`JLCkw$g3T#(#95XgD8R8qaZV6K~~;X}*%>7&J#4w4K_OzfMDxKORIlg5X4%e)0Q17k zu1tvq!YxzF%dB0C1X$`0bV{RRWsQ-mxR9~GwRGDWbX*B?>=CgO6=@-d5V6z!EZD7M zG`FV#D9)lHr3k;$c<#QZSmw|Sa_g}CvN;c&L}CG>#J@lNlG@`a4+^* zd_0k{Z`f5Pkr3}X7TcJcwx)rPGUKuH!NFx`!@B#vD%$M_&#tXo#=drN2dT33izRMH zwF(TbWd1%EcOBEqU-{$Z`2d%dHE? zf|=}=R$|kixHJQfYLb@g{mIA`3Chjc|LFc5)O@^aK^k%OxLJ5{3)@#eF8kOoI3A6T1p^hHX-?8Ql3JRhkYh{DV(D_rYiFC`~3&V?{ zsv`LxY%rix^xzOa?#V)96IFh1U)2tKb{s|3!va5@9(aOS7w=KzQXKqzHri9aocUbu z7R@5;Hxjn??eJy|hS40yJxna;V@ht-<%_OzzKyJ&FWptb3cg}CJ@}Pb3%1Q3yt~z~ ztb`2Zn=B1r%l)x~X^S}+7Pb-TN^n87h0iIyA*oMMtAwILCiZG`SJL79ZD-i??L(Be zINOHb0>NPKGEi;`83>f%5A;2%F-g9rU5FoXy#!A7*~pMfJ#cr`5PR51b0*O_sUiST zn=2nU>kd$2J$;LUvO}(c7?s#m{M;v5fypLmXs2(@oNKg9NYGq!xh($fyRL7C)6d)Z z?Kke<8}j8SDP-u4#aMA`7$pJbO_h(;riN`c7u{~@TaMk(mq+bCUH`N$+Yo=vYRk83 zz;`gNxhj}`rFtImuo1XoNgqg%q3YZw01%Av1ht1vKufyHu$_b=)769#s`6QNeP?{D zUzExv@Ji|^rt4c5sIy))+Sklol$w8aJ|{ph-45iiOi(R~glaebk>Eq z0;3!8dwnDRpJ8dgnYMt>Bf;BXXn&g5llj8MjuA$$Dvj4R@}>*@0}`+5^)c=*4|j_; zt~;c&-c`9}O3$Dhd%bAwiSlrkbwiT78D?=XUv~hrUE5e##y#HjIHCdUFWr03<=tTqkRd_kyzigndK! zLi-@5ARmgGaDI?zo+{)k8HNlzk4Sy^Cc0V(1Z#!8K9|K>=O_+6UTyffS8Y&_md%KY zirBrEvRFRw#ItA@LIa^v>4QmDJ+&vo)29w?o`a*-M%Y`BAPz@sM?^B6x^$U2VWTl9h0!eFE zVjpBJ@hzqcS5)2q0aAMnDc0hzKAU+I)I`3wA{6IjMT0Ui9Ph)0udRJBJTe!`sqzeb z$Fz=+!fv)SI*B&jxQu@;Yt&ZFF)Qns-55+w>O5w>MHIgjsvxZLKK(T)S#8Yt^lg zmo_x!+Y|qg-p*gZFZDtCUOLUw2ejU|n+&-Im$df^i8^B>PN>L47u$>6d5P4ig6Z<&e zm8#}giWw*G{%ZY+$J@fO9W1=jwpZiL8W@_UD**458bx~FF=n@uY|^@NzcH@p`zj2& zH8d;R)0c=GR;j+~^ivPZF=MF!wv`h*H#ZddJ+DWp@67r?`tfjP#vNO;i_;1<*KgN1 z?s02u<#~@8y=NN`AT7e@#MfbGM(Ycky$Ag7(b7_$yR%wwY&T|q*C-DM0q2KlRJeYh z!H>)TXt^|9CoOb7_L?SpjYCY9EA5M@Mhn5>T!x4NO^d8a z47X1ap4e--ORsarG38YniYwUW99&qHpT6fZA=S@rW-Gn*rs5=Yp>k5iuxM^!M*4L{ zb^UkHhzvy=1F$%Twjdh-?`(<3UviBTEHmAU1I54o^7nbT$N!GF9FB5wL2&CCirXw^ zZw70Zbo&^+&XlSgy}?PDHg)N zC$`u5#HKSZ$8xMi+>aEV-`S@bgtfQ*!cLwe1Ap3?2QT$vWS&0oIyNkIy$Y~keKRgD z#zx%}9F-hz|8MO8vGAN_a-Wd-?-k0kW@ zU@Ikf{6u8kskRr|7E%g27jFy@=S#4QvA@{hMB7NRH^8s>2Z9CBzJvwHad73IkzY@6 z9;0D`Sy-B>GdSX!TAeymKQymYWgH4@{5$)$8;A+zNPwN4#IWk&J8X`@d6*I8@3oRzUGukqlRd@i9B>~V#Pr8s=|(Q6F>R(!rGjc2S#|RCXA>3$XM>Ha zJs~x&MPjsULnb?otZi100reQTV8))o4mAt?)1S6}wzoS3;c3Ye+BF+XQE_f{Oc&N+ z%@ptc!ss)o*8l6UKRn94A6B&yXP99Zyh$itr?q`Qoh3uxzMJN+^_{E!bQSbZPD9kw z&>B6!QesGpYqQCDF}Lb{G7LN|H0adp5acZBs(b+MLzu)oC7t$2dY^MdO8;witUHqG zHuP8KQYSF4_>ky7ucw>)&8De}teJ8OI8ZR2PlL?SwyNapl?8Q;=B8#u(~s8gcIN8{ z{i#wt6kt;urVY>(IY0#qU7V~a8;-$_14{g@Z47c7Vzp(1(`||uJM#*M!1*Bz_pb-p zAC%SyNv?}eBiVO>fl!}QPBq3v^#eEiTt{63D~u^BYco)wY~d%O>kd0YHAM2c#(MOayoQ{-GVMe;?Zf_+(x7zzmS zr5#=paJl09#(chItD>kjzYgdiV(3KCMw!dK=P|4wtJ!Rrh5{pL*(DQmu%1Rd`G-=c<_3+=}->-ZC#1Z=DBTy zS`sgm&D+nBOIJ9YY-~?iOt*Me78~<5CKJEv|1-)C%qlzD{lY_wuzywV(q;oEu3qN~ z{6_=96?n%rabc*pDdT{2$Y+q4 ze{W`}LNi4m;f?=1D>gnnhUtL)U!}wcRzdl`czh848{e#>P{Q3 zwepwON?hc;-88O-<&%164dc84S)+Z7(J!Ium8Cw|y4MK$yQpF7XQX$1b@5?8+WEn7(@ zE1$X5hLYnZtiYidEc)8@{G?50$>5*W)>h@e^S@QY1MNvvku4kf2&l4M8TrGNxZsHg zigw2tEp4CxxGZh^2%u>i|GZ8N7JlypDcEG>S>Lbw%e;nrTIZu0`(#gH%YAsGAq9sw zDLkyQVKsf*Zk@ZFKpzPPuv(=2O6c5Goo?lBB=aMM$ko$}_(+=tH=#7(Dpq9b|??7pp%sXxeir`9oTtL}s3&S8)Z|?KmhkKOZ zO<(zo6_B`=5-p{9uek7>&q-oUsfT%&8D{!+Gsjc9udC8mUs~5+>eYAFlLyfGr8TX) z9Wc+`a3bB`5FI_BCzZ|Y=>J$ArBnB9IeRiN`w}BF)3-1XXt!6*#6YGwwYMMuOdqPP z^1^t9BzTsYtws6K@n;oAFPy5)!)J?DPv?JoGw+TFCK2trcons0%@gUxr*6fTxGY^$ z5n9*z`TCxsst%ly9E-!`a)Vxv@C68K8|6%GiCgna94##e>7`vU*tP8Z9f3rswUZXB z_VrW3;#i*gGk;q9U|m5t;>Oq66qhc&>l`oN+=5d$=T{rA-e&37*qU8O@?5(9$N9-GVJbpvBq^+H9zeNb9iy9l2VZOj~wgQ$p?N z9ScSuf!;rsYy_0kQrDd6*c_(MpRZW*@Cm0&VY22_gUA>_<- z5X4bdpPeTVjK7ke-Q+R9&}OXVbrisy_8@e;Bub+Gp}h)&g&0Rb09)_nY`<`y|L6$U zQspR{!c1)BU^pSYfYMb?4*XNtJm2|v*T$NDNQ3Q2F|R)0?%cf9;)#RBQ-$6@V0cvq zx0Fhjv}yW*o>g=q;&4e{pp7`;;pPra^<^3AGlA#D|8vgdYk%|WG|O@e*RY^_c<`=FNq9edbD)hlz4_!`~&}|#!5?Zcn1U5 zp|tFB$lqaD0yP3?qqPE(t*9ZWu1hguW#eOV z06lv_P}3yc#I~A+IgL${$yXD1C7YJY;DT-|zj>suxkcd-m^c_)x9RV0Cg?xm{rZu( zgy_sn4E(Nt(Ue%l*mR7ZxTXBv1)OK2sEdrcCVlLpj22^GhwY5vA{FDH4k!lEcyu+S^YD z+s+v$?av`cB6rs2G`gE{3R|yGf=vqbbwj?j#BC)GAJo8HkIb2@pEQJzY5LQR!TgV` z`V*|)vEABFMpntXBmEJ_b6=6`b{H9DiEuEq4YIzZGa08{f^=)WtnS+SUSK}gNBN8M z9ex+y2(bRzL_ky0%?cjKn^_llZG*mk8#N*6#0cb`I2WF`@IT6m_Bu&s$)#0IKMUw% z$liPDhIhyv>)?uwV>3x_+rH?`$aWLo#ztKK&*;?meHx4+q7iF+r- z&uQQKUI^Eh&-W}B0|Jv-lw8;B9w^f)rz`nAsDkc}pO~v5!Y9+pDMV7-;!r@^>u#@G zQwOY};<3jO`7TUDx1ILjf2k(L5>78l^%_oi^F5efm6|dA-Cv3VNCOtrqq*}~P_SSc z?B?aU92wL@?9RtGj?KGH@9kumy?zR;h9yF+#!wp(J3Q)#IaXI_V-afSQ=LqQo%B?# zw$>@W_gv$*6PbUj5JmQ>sghZ6v9UvS(-=sN;S`TWgvSYjSS+?KF^KN)1~Q!U^pkjd zja>dMZAtgTjgyWZOm{YBEGn`N2s31NZ2hbF@Z`_j>z(qb((9h6*&L22JEKu};0)Pe z`9viMw;-VtX2m-3E&UTET@~bo71}<=#z!cHYRSg-5LZ{G6yRR88rl=eNfQ9uy3VCU zR|JI6)*GKN{g1EgbWlAx}I7$db@1guQ2zG@@s~0*`G|ZRP(KmkRQXN_@}5Y`DC}=9{^PCK-||* zAcT6g7I*>nm&IfLe1m1R&Kt>06I8_#Gx}EXfd>MxsnS*Vo z27}cdBn9b`oVw4%Q4Q|QWF~Fmd0QSJTuk)nn8P%-Ve%RiLtfF{Wgq1cG>xne%H?`a zQ9JLGlWP_enoYQUX=Gswn43dKJM}qGU1DyZ{!1ht`y`*_HPc&yS?UE{4Dir!6Dxel zW+;k%a8)A`EiQi%K&0YBncBZdTi7Z#5aChk%O$O)+jZqodE!^tC5r5D0?)6b zU*a7uqJf}!@iOt_)V~QT<3ILd0&JSs5jV&tq`}@KjdFkS5o5?oC(D*uMop>nyI2%z zi056@OTH%wzLEAT7FQSkDzH(kj`GN{BxA~o=p2pr^9`5uW?cQ3gj)Gh_ zpaYjDYu^2gCn(iNSBXAOQn1+v$2_V~eE5>VF8PO1 zZ{T8CHHaOlg{APBdW-d3lbGZ<)uJ*BK7k7tW?5l}^VNH$-AtGW?8Y{Fg^B!1MG+f5 zUXS5y*{SNrH>Sx0Uhn1UIMg+#3TBKgJiGk+pP_9#S{Y|JSBT8LEk+IDsf3?Zt37dT zoI^(K!+tI?gcz^;=syK^oO z#S@oU)o7O8Q1f5Wx{Oy+^WE)gUhRG;O8S@-{pzk}1c)B8#J7?A3Gt}ye-bQHl9d@T zWP4(HgkjNj`jl_eR)}~wIS2K7VqduJ%Mn~K{HML)UjKtoh~Lfe*dE>+L^vUm#Q7&j zp2+)6X6a4?qMC>_JRcy=V+ZEXzM!Ey??u)K>3Y^9ZKzuo+HVt^FNNsRF2!)F+1Rd% z&XK-JH)NJvaLQ<~Z{U6%FNGgn_;Wj4Bs$2v@hN5~;ZuRO5!WGqlgx#KPGsk7=ORIW>jKeQtNW=lRUN^Euji_ z|J->MM>bkksL$o`r+=AgJ=IH_mTPWr8yk18*LeKk+2BK_y>jv1!MhA!$s&Crjh#K6 zJgx{;#B{s9V15uusc*!9q_Ss$p`UtK|MbTt<`}R8Mdej1*hyHAMYQLLx6Ym5jukPS zv+9DWpc|IRWh%T5PQ`fECHp2|Ee7ygj4%{!x9A2qr>j0#MacO&YuYjFw{AWEbLq>q@^;H| zTXLFtE28;F!`dprOSIx*YC8f9P3a}$~y<&VWx7f(q2WGGvIP; z@9~!^s8~P=J}@}Pc$hwy9xT+D2~0ud@yR0e{NJcxB?alVT`2831lq8~lg#}g;XV85iX+tAeDE>TvTZiyCGU8Ct| z@IZ7MT(^&OHZKOQbF&~m6)9|v2*gU8(g+)Q=7WNGWr~@mP&Ph?b5i!^iDb&c=s`K$ zyTkl>vWN(@yG#~u)KyXFT82SKeeCB#evIOrkE(g6lDMZAjXqm;;ruBJ(jtaU*9udM z&6)p!R<@o|jwApbHzj+XReWEV7tu2jR|k zNkQ_Lu2wtqT&zXQ1YDUyCvJQ7SG6hYc~T19CEM=0pfi+g^g7bdji_Q#89xH|it;J| zHrwErPk)>Aw!)cE26GxsrP+PFH)i~O_w<5{1&yfwl|kvcWwt4d4PSk~K|6*P*KltuTBL*FF#^fgPna9N~fbbT+2sa}lR&(=PCzh3<|R5RVu zuEFtne%#8G7Hzb!e!bGu2{Wb?U%!!QnNs%pcctyLU5${U8|H83)U4}3imBJ%?0PpO zXg8dZ^H0Z<<4?=Us3vLSe^T+&=N7vk7b7#1Ef#&!UStZyAXu{5Jj5&;VhkIsLf*R( ztb@EL8;`G-{@ST~fCJ&z@F|u!LkcJ%;aY}V{&ug$(cC&gN?as_(a%BE3E7#@1TC-C zm=6lbVzTk0S!rqToBWU4mj9%%26YZGkiD9;tvF%h+)ZC4hnOF3N+J$<<&*5JAjae> z(PIha-DS!>TjKWKkH5N%{kHSP1eSG^dbwadX*I7}`j7VZf~X*$Iqva*{nIw2m)WoE&IuzO7_AUFbWJZ5s${BQpN7s<7_r z%wbn{pUt{kPSN^#;$zMMLquRzDFWm~e|LIdn*+~g?Tf1xK(J#beMJ1P0a}J4q+J9? zw`VU`LfI@l;a%k2>YhSJGyH<5tS~bgrxax=d;YI zc6AJ_{gQKk6uX@=#R%n0tnmv-23E30$Z|eTQ!G`f;o^=!>DFn1QaRnTe`Y0(Y^te_ zi^{Cl)O?ZgI#N~w#K$Z&a_iQ|gXPYPp_QuZops^D#^H}yAt#jXk}WWsYnJ>s{C8|g ze+I;H4GF)onFl}Pa=4@hs*oIrNvQp>%$2H=$cz;+H(0wpP+r9C;n5Px=x#fEhOoj& zvoO{^a^h`moX`JMhoiCR=GA(z+)cd9 zMzV_b?_gR&a}66tWVmH4Jal3= zOux(gp$*fvaoF$-E2r3s!TnTzY`-X zP9uI#2GapLo7V=!A8B6-zBa1z3FEJc-ja)c+5U#-&p!(45*C#Rb=&_D9Mcj-!A2x) zSZ7DD5Dli0j}VU$ia9-SRoWWE(N_zX_bj^wklqOLgJnz;=vjEqx3zOhIoFup*igjf zgRj`txOYr|QVpgMW(~Z(g&Ae}w0k#m#APH1xK9tz?Gg*ce5E0_Wfv4O`^UUD%9HGx zx}Z@WOI+)@0FA48Sis$8m5+&kmtzNJj`D@Uv-#Vvs2@OQtf?$nMd~oI*`0?bL19*V zpH1%cvTwLvdEc_ToJMbBMxF~E2a7L~HJO5TMvi{bbU^Faq|IWmOu`v!X=OLS^OwlqElt-k$s{_qgqB48Es5LW+K;ld7spAzx!w4{h2X z?1V%w@2!Dx0dV`{iNJ)3W$kWseVxt0kO0L76n!h+rmvs6VH^KSWKC_>JR&?g0GOvw zljZmd|FD1`aqkA0G9~cbz=U)QmtS;oyNkdWrC*e=1|Yz0Y0%_<(3b31!vLWm$n{3c z^Ag3SDmA7pbqq?j;&nPK_zG{VPr%9itLXead6@MMipK3@V}Q#69w=+zrehryls*h7 zWM1=jAr4kt{0ZYDCAJa6*ul(XLH^+;9OlcPL&wY4%Fl)Da3R++EWUi#EVJJBOyNbt ztxx-jLKz@l4wRrfZ;*3FMwZc@xFe)_pW{sZT;$x@6@P$}q~11f4NB4@MJtqOHmnD4 zR2t-!o%4>GemR)uUBaBInHscZ2pNMF_3V!dpPNh?G}&N?c6V7K7te7~mk;6w2j$|> zHtgJzCYLk7s!8}cJ5({f)&6dpGW_e=58>38{V>PwNB>ckI>fNwJdes)iQuE6IYujY z%+p^aHwyiA&k~;~IeO^_%B`qQfL0#+@r_ zHOa>R&Ip#ka@bDm;<-eGnkb^mJ1Ki^z!Df=-Q`*AS@(g8j;&Hg z4g@F4aK+S8isWKBu3^{N4b4g_3teJqfEGLOB6Pq@%{vE<&i_$uPdy%Fct?SR=sLft zkQ-E7tEn7{Al3)b53OZu+IAt9zZDl}OR->-X-D>vae{TtmTUdgovPXaw1xCn%>9dE zsD$rdb67j*Ivk5mvKfqd+J!T+e%(iD2F859N)>rJ%uk!i7HlRxFV;v;S)c1l&OJG- z<|GaJ@6bK$U};# zQTs!&4ilCCQ3(T+Dd+%X;T&2f-P}8;)W9(?pcN1mz!h6({!)-4{GKDI)D4$@f9%C3 z$6X4s*IM)->rnUX#MawyOL%QVeD*q_rUkA;Zvf{F6{Dzb5}j{NHvJAjIl2>`7hLzM ziP#8t;7=;j4dQ)54l1*e_*xTn5^xU`Qw~nVLqL=$rF**RU#MBFed?>JEGvz5TN)FC zAX2z{g1t*hbZoJ1PVGGQpYzA)6S6c4o|mTpu{4rYwJpgGqko^ckco z3NF-o^B`Z4UiFE&;ObnqJFb2|T|eDZi9+ zeRuxi{P`h&Ah$^AsE1ll7H|%z2k*3Y-wKu){#c7ggCh%jjbCoHjT8MG_|{F>*4Osz zQ}@*-yUr#pS0WU}<(+i7KHB>gS*LS9r)0Y7jhLJEb2@<2_K#vy{~L?6)2T~)oY#56J}|G1s?b^8Zt`wCDAc2=q&UKcX4-prBw zL{>kfU~to+jbP71{|!&#Zc4K>47ztQo!_8BSZG*s}c^Dn$xm{RUMmv9_J< zK`@n!U}1Duh9@J#bHNV!aUKwbwRD#y7K&lW3FVrKx4#$jZ8q(Y;9gUfsbn;7jWoY> zscH-SYCNEt1d9N?I=oG#v)Ih5!9DIiq9HMe7-L5wp(<%m>)TZwLiCcoY;SH*jvF1B z+T0&)^jy+fU;(&!cipEzaw#lFWI)JOI_cd@ogHe#?woUjR)V?Wz7s+iygNA*QV zduB7r9+hC-VkONiiI>dDjGx|{sqUC%WP`su)KX}ig%~=5C<)n>lBF~mHW$Q!p+v1a zRA`4MP{O3o7G)6=est-UZ(pZ7cs5>#1Zpnc+m^$*rhY1lJMP~;^CrPMc#P)FJfhD6 zja$uDbN^%u^p_n}Rzw-*Hf7AsU%uPCq@PeRQd`v(biNeavx7&XuBbE^kP)7jeHqa^ zWbP$SpG5_J;Z*bWXsEqvRS@UEni$ zm~#|{5PnOgIfM1?eoMQ*2W!67RV*}gHjTEO#JsB-Ks0c|I93{EeJ+xUbs^}3wfekz zIB(!x%05m8t63uuS^52IOyeSQ)xpSA2E@(!DnDAz_e-^S7UvPN4zGd*RDQI z5$OCh>`0gz@QOjIK|f?F-Gt$uS16-Yp8PEZ)E6~S&Lu&6VxzsuahpfFW=#HxqCcY7 z*j}{>^nnza+Y44tuf!L=;5Ldl_Cn}1tPUAlM@HVNLDDp0Tf-hGh2?Qnyk&Ghx)7hK zYUp`bbDI0(gXFd$W`^dBk^!YhvBTOr3G`n2jH%#T{r42ukhu$S-7WLHZAF?O_skp2 zDf`7OBY`4qgwo-PSHD*TOF@IpuDnq+TMmD*x(9KbHxMD?Ib324L6D)`9JYlGpZ+Bm zc7nqacXu3FLvR4+^fl=j<23-Em$VMUguT(Lv2QX$my^n44owkTn3s;RjRWuJlMZV$ zULXg@z*&Yo@JaVNvjjW4|ET!Eb{p~74ar&0i{&dxXh*PX_xSi7{_QV8QdA2rRj<&E zE)*Za{*SG;+ZIW4=tHO>OO?4Ozv80=g8&e602%sM(^rw&UsWV^;wV+j#=SI@5#bjs zo3#Fw!-|sRpJ?mkj1FB*UUywFt_wssSl>&}XDyoJO8UpVIT{-r?=CfSqJq%^1?>lj z1U&jBEt6MAuRJK|8YavNYbjg z*I|;9w|h{>9{i`I2=bi!^vp78|4a#>Af!!LYnRT+_ zTvaHA_a!|!&3=s~l%F&R;57R>9ri7uG6hrZ=X&M! zF{Kx{6z}!$wc34RY0ao`Q>#IqZr)VYtt#bHiTkVHGs3xr^FGhMiWQ~Etr@}QE&Y#t zPm9+o8Xq&KnitZ^VF9~w87xjwmcoG$mtNL^6qnh=OBNPHC{-1R&4LRo<&uWHclX4o zf6JBcZbGw&nY8;Y54l}*kOK6v@U0@fDP?IGcfR1#ox&xgfEZN$S}}0G>dx{e3=yPS6FEREwQpWDmmY~*ZZ*B zJ%K&>nCat*j?Ar|nNjh&?w{RF9=`(M{c1RdPB?EW(=hZe)l1fKt6sJ;}-I54ZnhJ$C6Q{-J>DB!qV+O zT{ndN%OD~#4dadtNxA-FiQTf(LH9;$21K)))BFIg-FB$OGlI?q zBC9`+?b2QxEx%NS0>CCKo5@n(8u+R=WAO36qvgna{Fdhk&pb=U`=g5{gZZ8|QWHTA z$i8);LnlAItY8~ZDzaO>wh;G$r;>hma0h7uV(ml;!?pO_W{nh>*Zx=J>m9#pPI+5T zUPBz`2K;;Kw9ba6oDc0^im!b9iN6tzuasbKFX8?G?M4_Anj`oUCi1%`w@oUg74BdI zu|w{5m%1lvM>+JAm{)wK;=4mNXXDl)YVBT@ZNn4_1BA=M67F`~X~ghnvRUG!ew4;a z96-{nW^ldo;CtwA0Q*sAa9kuCTw4eGq0lmo^C+I`Cza6Kyb-Zkv-PPwIx{sB zbrHoyon+`9@ZMc9cX1ho7qO5{(^OfdT4yMTW7|jx2k@A;T z!{v3o9GQ(y3_`c!br#c&Ds6d{4j|97ywXU5mpAu{wI~F-&IGC5#2w9kp5v277L;an zPFR?;;tSb}TkX6D67XX3Q1;T^Df`f<`uA$3V2sFCa3Ta!5Sa!p0WS$*4)8JlUZEX3 zp+e10i5;x!9w<-oLFpvZE>{=NyF;s;=f!M+Lj}x7HwHdRk=oY#;U_Flvwy}Z^RVL>JG8lg?|g z5fthPr9*6Gx-HoEnpujxQK{WGI*MVX^M8hwzXPM7F|kbKF8+Rm*BH}w-6WbOJ3n@S z0zq+o;{V%=7+McWlYcp@@+m5r_m&M^piyRl!3o^fIh|{SbmDoZJbWw-{D3C?O0DcIdtHP!SujMB&R#y=dd zbeHszlt(Er$XlNuv-E+^GQA@O?B{h}{3L9P`1a_J?g~L`{}b*+?&*HVd!ezHm;7Gz z>U9;7g*#fT0F-xWcD`Vr`lQ0ItCuh}KT40zsSd+ZW)O@wVu^(Xv<{>cHo_aSgFRB{ ze!r+rb_gBMkY;%A27VXWwqIEhc6JH*T#Kd>E(v3+IOM;;AI(V*ii}dSrg2Lm)S!Ys z>Ye}ro2(E(TB}F3&iQllZW5&%sAw`=baeZ!dx}ZW)3(+mip?evs`bNk;GcARe~6tL z+9SA5&OwDmTsEi1d?m!C;|ecPCcXR@gXBEQ_#zMH3>GBDjQlEZu21N|8mvYA;Z>&4 zP+%SPeW0vc=Vt11M?=hq#ImKJ7p3_T3|cVx#bu@YUKnG4^;hWPumk48rin2X!3EEq zx4bPwJhtwDlt*B>DX%zP&IGDbm+s~okOm=Q?B&SOxmD$H?Ok0tH4m2?%)^%$bvBoM z+(*Z%n$!fFkJD5AycPMMAgD)BKzU%hE>U+f$fz1LpJRk+okEs=q^!rk2yC&wY8Mm| zlmz`e2_iE0PC=_dU~m2jI&dl$2EpAViL?h`VBvgpf#wNP_aU6yHn2*;){yKd9xfYw zMKV&%D|`||6&}xnbducFIcB8d1Z62SBYBL5 z0{^4BPD`>0T4dy!*%ISDQz>(r(|&4%2$FAAhlf2N-B`*SKjQrR>D8we7>megaY~~~ zrckkLy(*O6&7!>vA(nR`J*Ez(EK; zNkreV-h4EsZ>8|iSffPPY$Z}e9s!tXPXL_9Z4>7rjY#3H^(x=ECM})@U3t0iZv%7? zxr}SqhexW()WUmb+|lRdB1gPS0bLi|mCcp2^PT6o%%3%;K$fs!9!bv_lzODmn1An0 zD8x7ez(P}{Ywo=c&MBYJ|L}|&_y;AmkDe^)87ZoK z_w=Uv?o?7(C$2&(`^y8k)hAxLa~{)w>pWGP&8)HppjP?*)h?Wi$}YCkYgy8)_}wLv zUEFCTb9yJ6(|#i7Mo;qkdH`N}QKXrcY~09dfv4@+*}{gI+(N3t-}8!dphhlokF-cL z3#mytTH|8Pf&6s6#u$|3xR~P@1jA}l{-Wa!Xyb{`lY@R=zqhA9m;~$Z^7Z^jb^m3K z!|vXu0S;wQds=2fC4b!Skmun`?{G+N@gr~AL2LRF*n^fL?7G!E6d$GRslgg0pYb5~ z<%x|1)>hT$_sXk?S?`hb@PmTm&d`~C31ZanrOL*mWup|<_>b!yftb+ZgEcMTbIQpG zIYYNZ$#*cQJ+bO4XRfJ*J{_WI+<`FM|CSM;(ild={9v8gjW;jb)e>d#M!MVDTU|4{(^ zbKFG!-$0Z)qnor&Wvb;JRM)?wB`ido|9pzw!B!!dQt9ngfMBlJ4Vm8Ip~<3&wZ0F@ zMLiC^+m34>eOr=G;$w~*k1$T#mDLxl8?)wL9%Jrs)qtS*?Q}1OMXKzyvW*W2@K@st zvZmSo?JCgHq{ro-#>Vp(o31XuoLhT|ZYWa~aWkC6pwmDsFw$+!P+zLku;btxpA2|3 zU1CB-7(02yZP=GTi6Qv@@#@uqL)Jxf@b<8h0n?6bxiBl~vytHft6rePm~1A;!C3p| z`#$wxsi&aS5f%QE6K9)G=04w5LB-94mlH>HHs&$K+KOnYCzvOus#@uSgKjkCT%?Q`(;qxkDfF~?`exCjX z5)VM%{WF5c<-GsVGI^QySn{r$mdTaTZtC^aISjd{&9jStX=rSE1#ddpg(KWEg*7gk|G5PQdBfcHEx^U^wbd&9Lv6_;K0sjKnz5kP3G`tW9e< zs`T&apYS*zOcT(s{(zPG3Lr1A4$2)o+G)1udd7#B?i*=YbaVP4<8P9_i__Wg6%tr& zvCq``jSW_j`t9{14a`bIxDjT_FjN&J! z7bSdapgGvRA0H?`khyJ)Raq5M=~Yg#XB^4qCzm;qY_ z`9)*gL(c-u!!F4NcC;yvTy=uS_vK4!JDy^yv|&*KGBw7xWE;rP9x9RieV2dvqpdz; zOk@LX6jHWur=RzS1@yQ;p{7~1@>BrMO`14Yc5PwGGl^qFWu zut=8IqL{5&jos+;yug?(^Ovrk8O~79c;hX?p6z~hM!hrQZ?E8tPXB}FoyD8Qz=&#qe`k8X zX_k~QGDd}+^@|KkbF^{@B1ie!o3xEfY!?pqCp(9N6YxFvs4hMcu{tddQ_3=0gkufC zQh2ek_GVYZ)nEKm>I6+Afa^k8%-ODFC2HBGd`ejwj=+ zJY|dZL9Nz@>TBkLq!+vje&*Ii`xtNg z>zLS>da-9eU^_&IRx{-0Yw6{8It<4YVrNsN_NoT4`eV?i^>0A^{Yk0y;kJ`WDR8L# zV!AZf)6=a+)+EWa8o8)EQb4OZB*Y?N8?tJ9yo3rReVJDxr4zp%fr3QwOM_Ut1dbgbw(-X%V0`=r)be z`-cBfxgn#p3uXshH4{Igiy`l|3N^W9GKw)+Z$UdmDI1 z-2=u7)g0yM3v!HLS*)&GYy1;%ZY}*1o34^Eb|T#2LpH}k?~xcwpmtM#YHF(E!Tjnn z4S`IjZlkf2UzyxSD6d4%8F`9BgK}W>r0#YI;*(w3H8*89PCE-RBIR5({k8$xbmc*q z)UF3+QOZ)T^?$kfIPFZePm_7i{+JSl|6F~^xPM#~1Cx6GTNfS3*84hfEx%#*v;rx%(_mQMJ{cUbNBq4_9D#OlH%_IJaGF3ycMLRsvF6nkq+W#q@lK7u zarEh|_|LTB;UgadZ?a5d_L}X%R5RK@5rAn5bpsE7!IC$D4;H*bDfuejt4wx--C3yd zxnf>|-=?8Cj*~`~7O&kx!9TuA0saJc^KoyQn4BKTpx)dI;~EvR&GOldrZTPkt2k$z zJl)RC$X3Xo!cWyWrtRGS;f_Ri99Myg}Ok z`M?U&mUqZH`WR&kV?`)L_zg8_^IO))&z%ilHR6~PpZguf{5fcW{BodK&M*jXlYC-~ z7VM!+9t_po6puHbaix=jH3Z}?nUQY49(A#I%|G?Bj!sSVTKZWq&}p>ztVHv6hQEV5 zdE(7q(;CAcdaS?k1`6{xwxek@#gmwOZ->A8+raxpx;>YaszZuJ-CCVbjXW{tn7W%(`uIM-tm!L0c$^Yu4c6v_GrJC zP_^2ov-r~^E?0c!r7`W_gANBix&&=X%P^UpAGJP#9yA-5Vo-QW3FSr@IDje42lY8=O>$QMIW zR11=~NFQ*{K{GfB)TGEJlvkZ8^EVmc)$gLdBq9!g+CO$eC1hH2Y}`B#y;UdX8V!x^Z9w{TRoI9+LVHzsxzgO%T6x6!eg7=~u1@|LtVk=yOWe0N< zGk;se;h^xC>UpW|xX)Go^|+`9@HXpL0W9Z`lGhJrXZITdc}S*%N`NDYNV1@&VEd%s zR?*KQcv^09L$kl?s2(015Ek{AY;Y7!0I4oPrv!2m79L0T3fU(KgO#7tX08I#2r=uz z8KvHOMkz_^L30NpL0+ETNUu7((=!V^VrlLHZJ3ASlvpvy1Za1f@HT*lMtJaBNszdH zu-`GVUwXPr;jBn}YlraO1QO#py&19QnP24%Xr_Y76FiA=`!AFZx9+sRKVg8o2zPV^ zE=xVCVD|j+}o0JhGI$i6T!gt@UC8KK5c>PPQ~Rd|-5Jw1saTtyB(Y9fkPl1fg~VO5Y5 z)U)d{F5%*F`jH~;#V-=oIpY=^Sp+4&{I(j4PD}GjkqMo|BpA(uQh~l>GpRF(A(Ohs zFB0fSpLZrUvTvw3CqxKZfYLc%HUFX`z2R( zIJpyAexSO|44a_*IIr7}A~}RuZ}3!ogiFq2w7YPLUBb7-(njnxL@NB5@EpgGl0dTC z$w6q^+)px2k5+P*y(&bJ&*IGtA9LF_hZ!XwCe*Wz@V^K8t|3Gr3ZMTiBfl*QMRE7k zaidMHrhF<{ZkkAe%~Ni-plaE>i~eZ`l+~Xe~tkh`#$$Rps(9yPayv(6n3H$r$T@m$Xqid`?yHBO{e{mQGMoeNfxY9rS zZd%{+;u;astd-Zx3HklFbLwY1m#Lo+r`{O+$1Rb~mz2Rb3ob~SAw5)tGRCzrJ%_cg zUP_2*L7hsr**xmsL;`wHHP%)=mf8LU1iu=r$F9MpcqI47{T1WAfel0)*POTsCpvW~P!qWO~e z;cA?&Y!g$l7h8hdT&#6-FZ z1yYbr<1gmy~UFsN=ZKAU)VG=(OAD4uk-t@0E6=sO(#6_6#)RqWgwESzDLFT>0YwSon|b%Y7*L$ZC#h0#3v+1AGr zGu!$RxRwCx688%GXS4;|n6e%p+GAJY+cRC8sCr(5jwFGyUSt0+qX|c@OO*P09yc|% z(aX7|Z+SIrvv+UuUosbRQ%*2V91GSJwlber=T-v9#Yu$7n9?d$ZMP~RtdAVCbZp~N zP32z1nSWt!_xnBse^jHKdjsOnBFDeXR~ z`}(bCatKZhuWJ1W6CG8N_^F3!M$EG_m{OeBSE^8ue5$tJdSvvZ@b0K#jY&j*SXAWQU4EupMZDHMaYj#Uimr$kH-9I1QlEsVGAN2Xh zM|au^jM$2*~&G};S0HA6%J}dIbEClG2v%Z%v_q`FDAQbc<(J5>pOY_ud3**&g!}}T)6e1 zgG*O6E=SfHsoQF#0)d@N0?Mz9DyJGSy6e_DkE-!~A|8X8MLvksv2@eb;=yXic+^yX z7&G@}DnlWsXsaa;jh0vk>J?{d$OM-Aak?JseYv?grYX41U0Se^-w4~H)YRv_tA~`Hp?yrY0 ze&gil6O1NGVbn(R=6j|@D0*_^kfTHgj=h`mr0Hy5p{vTObS6=6CXR(9_W0{kQ@`B{ z+Os>s(=GcGZhTd1zaO@SUGd7w1*FaQ5HxD(!*_&zxO7wv&C7Y5z7nhISo)uraFnFw z)W$x2y_|I%j2Y-v>S};?DKNhyV|1M$#D$=k54Aj1wi_oY!WA8P9BMxHypul)eUN@f z%|1pusV1Ev98rV9=-TbSs|fv^?rIn*cEz>|U%KXY)mr>bkt=X~1H4(*fVwZO*ZyTDsU)F!i)#4%tx zzmt`ex8!63U2?THt$*?Rc3JC@+==`HJYc}-sD#_}{JCnVXs((eu|-rwFR5Uz&A<-i zK(9u}vdmHWXEd=qL<~BZG{Z25ICMdX7O$ZX#n-rX3lrNdf?2ZH?A-74O0v_X<$H#e zYjcNDI0}}c{n+Qme=xDfn?A3wj|)F$SUegu0P2L$1^HGd@3c45N?PE30R|kLg}ff4 zD?2x$^ONdM8I@~0-7Gg!OnZ_EWk8AD&uE93!Y9^x7W#lS@Q;yjdw0XcA9;@1FKed8 z(RJzlAJa)?w*JU4!YqWLGri~xV7l}-RM;ZU6QypwTqSSC<#Wh8TK{C+{J~$!8m4?( zRMqWuGQppnKE*mF%U08e=ToM7q#vCLw8x28OU9L>no3J-wmo^^~7)3x|=yzK*LrvBkg@54T-Y z|Np3dTsa+2z+FTLD4VXY+ySu|IMAA-{uIsvoBAbAKn}6Gh$z2MbL84-6n3=ePVoV` zdwAqyjN@^>hWK1-0sp5pPjU71s^FR(#QvZ4CEh59##DA+tmb(aU(@?}x_#Ad`0;rN zr?0ccd+rY#BHOu%uP!pfm=+srS1nsahU<j> zj!1uJ?&vfVPO0{(3tDv(I8DJn%Z40>olY1~8Y zFqmL*gnwk9+XBztG?S|At$rQCgBqWV&2luSm_ADz*+tzBA%a!9zXH{kmX4%_Ugu}T z{rMob42tD!3v&#q0WV|98y_#zMadc@N@C`sN;gHB+RB)(OWGd)N7cR&d)Cj|qv=8@ zq|Vj3*QFe)Jj#499$-JgW%K)!LO-;>)6x%jhq#t|bLMA0x|2s=CIrB1P4DdaYx9NY zKm6sxXADET`!*1UCkZMN^QW$U6h>9$dsnflm+IkE0&6kB=fRUY-#GR)>&F6WX{rcA zlUd;oDQvT@)G7OMWw5|<9VxjDQtzHk+N&{x+E;SRqb1~TeAipVrmiNLJ$&tt8@U+Za99;Wgb#-CJ2rLZNgZx=rULKp3*!@omkdDkgGQ@Bi5 z-Pk3Nf;5w@WeQ_=Lvt}cTqqlK_xx&2=dO?-JKK)1Bn2_`zS(|&siR12d0KOazMb;5 zJix^!p_PeAMS$y`Rxr~U)4LS|j>U!%ou|ClVXfS#eh|U5>%Q%i4!MWldDc*Sm9bT) z=v8cxzt_dY@&C$8;21|Gcqg1iwf#B;N+5ZIRJiNWU(QB^tPjMZ8tk~W)ANz3K7xIFo21c3FOnX1?c$g`ceX53tYUw^=0B>esS_^7 z*KYr?vGNy6r!}_f!jV-{k=EG1A3gl&4%cjZ`yQ?{VMUxLxT{3gL})XLc#br{7k|*O zg6e5Nl4h4%UM@jpG5vqqH;uxB*DtHxB)&;-=&Jj?Wuz2qiI>_?TncZ?fWnjF+}-S* z{D-CfLCHDm8>YGt%2q=`TB0PvdqEAOJme)O{8s^#BigfrkJzeNn`R?~)?rhqlVlKWA;L zo_EAGHK%`9IyAAI(aFPB=M`3OW?xwQb?0fivCe#USBgYSuHGU3!Au&wTflAIUd43x z2`wx9(f~0M8)FNA+{uKDKWCRr@%{4ON`wAa9uvvlsitewF-E2C!3(>dR-W zKa9%Lw@+4F3TbdRM{y{o_}q>E2>j?(P0I$w7^an{8LfqVPO(UWR^OxSDyO`6F6XlD zCV=lL7bLsUJN$`>UWHLm=@69cgtgAy+0blG%OzCl#V_CMH6)h;yGHlEVzS=tFrUp! z<#Cl;OT`FH-Rzx1nJ@QLrS1J0j{hCx!hg3E0^0hbhc8&`#_?c&I9W%Ub3Tq8GOvO@CN+ek#XL{qLZwh0J zJrQxq^VYvQp=EfMaj$>Yy$CRcj6ZrD8R6Tc_NMw@J00UL11NVy;1d1zL$jdlfzeJ5 zA*2I#7saPZ?Eft4^@-gJXf7G>$zY^yIC6$pDB3fjcK4s9TUN5?}qcE<0L0NwQyO&zQyTluR#pQDda zHKO9e$pV~R0~><{MPLUNYFZa~wq{$fNHF=I4d^-0aR2z}1&LzmNu+ zh2e0_;#FXQA?@Vl)oI3Lg+Y;3M|eN)&eWK5YPhH$tYpN(K%#MHF@yV++Wq95ChWiR z>lv_yZA`XHf$fYT;u@M$Xy``Xi*7#G^A143BIUMaOMpcf7J}}d>PdfS0-=B8Fz@kd zC~Aw$D>ebUgR5&C%Z7qv;`2H60e>%hgZ286c6P5&4)0%QO|;BI`KBrt+IOTSxp+iI zV9rF;{@;>)oK2-<9kq{t;R$#*eit*MM!NVey8AeK&GXdj@TS7$vB9~e?Urdf2t@C7 zD&84zB0F?RiL%_K$TnXhJQ=$mHJVbZ=^#RGbY@?rBu%V-H?Xt%@-q?Fnnlqfq7rvP ztT(MUkvdc37a~`Tuq#=Ei2)VoQ<|;5>N7bV3GPo@edvX2{Fj^_T&&0vc=53PNu!8n zR^;z^a~7Qzx?#Y!d>7)KQDieirJb|Pp<@I_*@P9TN1nK7gqU`OJ>>ZDOGma<&}~a( z&mpSxkO6q=zl7Kd3$U(ck^Dl*>V#0n9~;o69FO!!bbVTLL*hlr>+qboEWN}Au55SW zmq+-w%>kwwu*W*Q2-)ua%SwE<1p17YN(CqF!#J2Xip(ALd|Ma$HCgZmUybY?+GcT> zo~ysZK{VCH(~Crupf%K-1oS-LSjoD6v!{D)AsFDc1Qzqa2fX+l>IFmfup$;H9oJTGvSuT_a!Ajar{+|l z7^!&@X?vI!(w~rjSe#ax&VL_lCMunVxSp;rgvT%rJ-?4wbc^(yJe1gsJA!K#?A#5~X*b+VWhhO6!>aYHg z3%W)uIM%(M7ZW=zRG69S*u4+e%U`lo%?LA>_W$Nw`6$msGIXSeEMCoemN&N? zx*R_gyj5DcmVk%wsl?s(X}*C9<#~<^@o_mU?WcMkwAr&%Cv|)|#ELT=U%Cb4mc<&? z#)b4O_c+rAd%I_pl&YE5W?dBjBp4vp5CwRR}}(+z0|?1=Ti;RNRF_*EbZ-b`=?eN%RD4nq4WN$5Y9kUED|I=as;tC;Bmo``@6CJ_ zk&ej+ER4eSjpYXW;5Dej?h>{?=ITr`d|ot>MZsvBy_(FgU$N(Fry4 z1+%CZiCzcQ$DPKLBk8)K`SeT#i&BZOPL?%ZUw|?)u)sD)yDZD~$qLQy2epn4!{e91 z7aXawsZy1(2XU3ybamO#CxZS?B&?Muc}=fpT+Oj69GD`Zs@LTX0*(1r6A~(7rM>sc zaJ+9oIC1_Nx`5@h)AJ>bLlp;~8YCh()z<9qc#7s^pIetXM*=E5o}g|f9AF@Lacnh} zB~Uy5cy?6M6KRdUb-c`$b<;XU4dt|{ZI}?l50n(kMCad_ zM12L$z>S)#V;!68{o<*a9l9T(oJSyO-NrSUDHr;Y&^um4evU{{|tg_Z&N zI!I8MtoqI>cn=h0d1lDl?&P06^{$>mMvPkIWm9))Vzr%=sGQERbdEFm<7cbT-DE;? z+o$PX{QQ43opn@`{~PzgLXi-WE|q44bTdV1Y3Z0qGX~NPq7sghmR7naF=CW-Igr|5 z*kJr zA7wk_D2{$2n!$A$LXrR6>rsVAtFCm=uq=-=VomAzYzcS%)w`okD$A!#JeE^4whxgP z9agux_$XBP6;CRF4LCw8VYkl)-dZFN7HS+<8bvHjUkKcz(AqkI8PY_@en?fH??~MJ zQ1j@kK?NPpjoM!&GJF7z>%Qh zJ-pr(oQL4e&G(T{%WDe#Z?-@24|9wlt%Gae9Nqc50Z08)?(<{5FV+r&r7!JU#p^yi zxgSDIHvu1*JMk@O-r|_8a#m@|`w`q;UtXzxbKtVlBJ+0hilsQKK-_e;K5hz%mR=$L z7k7n9<{{h1AzaDX9DL0CptZyh`3bL44!>%b0t2mgL$Rwl6H0z);xTK1BgrBLDSWm) zvX$~fU&&}5)9SyS`vOn8LO*djY%$yh^rbg_H}J<~?!$#cmeV%>!4okUlCoug9~TKM zEic6ySPv$YZ*)!3U z@lZM^53{Y`u>C&i#7LK}IvgmvJ}ad5H8+~@(y#=dP+fE3ebFH>ULCYYR}LEQlRR?u zu~ICwXTKUaiT=@zZu80&!)0yOM%-tzD0|*qfRi?DbkEbt;?T55$GZl<8S4*Yn6W!` z8DUCeYms(0vW@)TLkYV*orr1%b&rs_qQgj+6W)eTrkeOTTwCWPRT^-0DGA}&}TP&9*>^*VjmmrsBR%?)JEZbYsa!vPiC_}nZ?^NaV_&j9Iexv8lO zket-R$z+Vu@>~i_a(hC2d>=5+#(-@0?m5>ucBkmGiIFfe>SH z$lFU)EoEguIddA+z1Y}cN$>8o+5hlTYGjJe19Pk=F7XR9kna#eLF~KE4*vqY(=Azx zfxdq_&bZIE0`t_eMTDqiRJhdfxf4ljgVdzw%R07}CZw#b9ZTC*wW_q=&Yz$6g?5#C z#pU8zs&plS?%Q8Zr0I&D2m1b6J$~itaaBrMo2K5co0)BQ$9?Z90cBLn?L`NxQ8Kv%tJAA z=(FJAJnT6<4&8F#i|QX=tSgDG55vHg>^tIw>p6BUKuPU zY^sD>ncwuX%lyVk_5@YdPt`PeL$|elGIiCEPO3FWdVHs%9`7)@l0V!YJ#)LxI$5N2 zt{aquMeU|dIesTOX4h)I{mCqb)fX9@x|~%&RrYacHcgFJQWmAF%b-PlI!jQmg4p|x zw+|!6Q9#JBg3sS3T8>QprKVRlH9joR3MTEoYrL6 zefZg;!A-buuI9ub5N(4cilKUQVH=qAhSmrhBayZ8(gkW6MZZ8_*rE&>*U)c9I>Wmf zuQ6(ievpP__-xBqo4nK90?SC`h}fq9Omp5`N{^*Ad|ANuvNhe_(W zzKOzrB*slzI~$3irpHHn`h=-fRDW|7+m@o18K~BZ-DV#kbju|7TGO5u+p8T#w=HGv#t)n zudDsmH=&Mkv{&vz>ZNL=<8S|m=AhUxvg$oIn$RgXozC66{_MZ(uM1nlf$Uj5ywy33@N`z z{;{}r$BxFFXazg>8LBQ~?mrHz9C7K(Th3OmNJy6{qZ^4_wq$GD6pi_DV}B(8(1Igg zn&(^>Cu-EiO;T+5T+1r-5q%NCg?^Gdi#3teDyPUif^zF(Ps5^9t*|@=T7$p?4x3Su zyT5oemOwZ4IbF!9uHv?^)3QORaNaw^mCdXG>5lPPhTn;%;oh}<4}^XjPfv|4#+g&<-o zAJ1ft08#FE@MOOJJruiy<}cSeYcqDRj-6pYUGF(cFqn{(Y=g)4AK!-7c|6KdZjjwG zWhcV5Sv2Cf+|278Cf^plwVVt$IOwFGuoR3g@M1kFMH&9Iy5DdZ6lh$Se&FudoGt`~ z**uzBb>@0Yaq^R#UF>iOpP-siu-1_6&?>e+UkNL0pp>wf8u~W3*7M|i!aC9|NXtU{KaXs&H9?yaIy~(!Af`I ztLaBZ9)9Dbdi&Cj!`2=-}~}-YEM6uR&|clVp!I=yp!Q?5N?%f*>}#-OROSn*33mOlM2s{-T!Exx(u+ z0Nyx{zSZ6n(L4EX6XAT%KzE1~ri+_TxDr?E^*?Fxbd!kFP}pqrb{c)HgV$XmgaFRG zCz<63PIlsKG!HoMV9O8oWNN@5QU&?ttbhpv#27Q1Xs*&9@|%c~SIVhNRYIfPio_#o zQCOfHOsAI`3cM@P5iMt5wf?!5rJ~wg+NwZls!!{%q|aO@g9~scv67QamNI?f0Kocd6D6p($? zRicV)X$;H2fuIVq1$dJ`mu^Kxy&+O<;v}4+IbZj0SA}pcAKZJ5J)qw7^)qfXp><*Q z_7gjZO;PU71*hTu9-9Tz|J$#!YlJs7rtBuJkZ~ybff{rZ6nvbC3sY+0h;oa3?ZVy- zzD8q_)D1GajrAYF?9ZX`+((1l&c3@L=~T<2-p;DtA*<(BqnS5y!4K=lAgfcAT=9|| z;{DmACor~83dehI9Neua%N^BAuQrF8*L-|#op{aEH5)IZ4F{4iEO3sD0+XT3DxUU33q8F9Ti zlVRI_Wgq0Bv24XfY6#hnN|&h&Q|zs?`jKIzIv3H_SuQN{o2LLqH-`NoQaahU-`jHl zqb?(VkF7J=pW%WuAY{GZj}-~^QpeDf(J1EH9d`DF^*J@V1YGw^i#^WKhs`Tny>?gk zQ9W*Fu8SWX+5+?1yZC*+?M+^vQEFA{zHJIG?s8+%m92QFkWa%>CkA_!8TY~P+0&(( z!6&s1op4<@aBs?U48$dYhpt>zm?lsW?Nx;bVDs?mtzdE~&1>TILr7QJT!57RI@>Cc zTEREGljO%7Gltp>4}HA5*S{SqR=A&~OvSZFunJ6bWfRaH5!WcX$?Z`uGD0P1*;FoF z#X>__fQKiNFv!8XqqqB)TNmf0V|0xMbw$Z1wF;do1sUAmts$zj>JkmNZg{7Js(L#T zAFBP!#TR3=S^can|30G0b*88gEGi(t`^|HhCy2SpAeSIh1!HNlSIc~pYX;*OtE*^N z*y;ptrj*{8<>S?$$+IH~{raGWvJJYsy}Q1NX$~wcwv zF@9cmp}os}%YeVZO4Oz%8a*iV0l({1|YslV6s09&=%KZXUy9blXEA3-4 zeKNQ^<=%;r%EBUjm-}{H|BZG5i@Z$!D(39bpCFDwhtz6!yKy~yjYeuFOrYKN+(y~O zD2_*Khhg8OHGl2#Z1_h;E~$%Gxq8LrQT^QZE8~`l0sv=#t-_A)Vx6nU?!DX=H4S^b4<~Dj zfE5T_EYVoIS)7*IvVs*QCvHejShcUSO!(s7a`|YxBrle`LK>l2x`=q~@=iw4dpXOn zZ|BVW6%;6{vl}(54&iP0Pp!8-R?x=^Q&4VK)_AyKUoK;McP0TNuzv@8|3=`HTaepT zR}h|Jcv5rxZfkv-wGlI6TwxK(xt{2s;L^Iiz0w)GT;^ z7m%9yw%GUVr1(D)@_h~+0S`uhlc>6~8naLvi@Rnfzi`6a8~I?4Ckntar$+tjZ0??# zRAt%%lWemz=%cF13EX$3O_JqsT6duIcx~5vXY792qV@iUF*x^wI2Fi^XoEE-{OPKT zm0l&2n7l)AOJLLv9-CpkvI^XR- zqyPZh6=^=x+AtP%C5^13s#SVdSj2bok&nLy>Nbi@8nljxg& zAld^Z0erQ6M24#nYhO$*YhdP?JBD{zhQNEKk_{~{07Fh-w>yZy9V&d^#=(KrkD(#a zcl^7JiWELheE>==`;H%@RBteE02_}4=0dsPZIcRBi{3csN~=nRwM9eUT+P`^k;5iB zNf^fBBj{xv#=n+ZqC{cQfsm0z?u<6o#|GMcK=5SwKqL3t0O{xzF^vcgK1r^DP7QiV zjCj*{DXhki!mo)r>bH5Sp>b$_tavb00M6+=&XZP)B&lYbIaCodr5YAc`i<@Hy zYfijsoQD@sCg_{fC=1;ffxa7gIhiI|RPK_N^w4u2RRgPJrP5Y#1>|BgD|Am~IoJ?X zid$4($&(YdLTeF)_VRN7?&(I`AmUXrIa-*8NnAptduaaBab1{2Qh`-CP5;$gG#ZDN z6!r>gKZhNdd=KHfrG+#cYLDk05jP%cxE)4qXi0RVK8&d{OEcni?$=43`aTqD+e^YZ zP~_PW5b=CfsmQaHIq~z#b@|FEHA8>N{QJ0C$2-Og z8Owa`d)-WQ77HIF6KdSOHzkjy{O~&L zGT#f+jJMEx3@RXqIO+FGJb2f1m8Akc0*j(|K&(849m)px&5{;duF{ z_FO9fP>|(c%-5KbtsSCT!I9OWot!uyde!OShcoH@K6_Qc{oU;TF5tjSxTE%&1q)3( zw#kvL;*vAsKay1thsi}Au(#t#Jg+e9ndHNw@d7KUUcY$_qILm4F|3A_e?=5UXet#l zlg4y?x4rhcTFj9`p$Veqm-zjhi#LjOpqIh_HlHS_eBEYP)$rmK{k8FA*ur;`2`=<< zFG5HE!Oj~gAjUAv$wj+?ZtWc|)0h}H%x>IweTG#l{dp&nNx{lzo%r#CZ2wCYu5{iW zhCG{EcB^^?`FL@t@J6~-@-F@Bq56axy<43qs|+TuGe><>_&%0&5?^lPlQL4uf#w;^Bs^2Ldkx$HA1nJbY=Lk ztr>y1K0WDPH5}n@kfPYePPaNoHFneB`z+J+BI)Jo=m_xf5O*)z)3F?dF9#Y#*KAbymXklW^5}@&8CFVviFvA=v=?7QJ@)VmEzi z7gwnyumSw+=PYD}5FPaIxt4|RR0a%|knY-AetAPj@z7&=hnOi5^u`A$hWDyl>(c5} z+!Xh53_!JF8m9`G-EvzX=z{?{4s#N-b-AjcX;a~8PV8b41A3>pd<)^ZpZhxMy{p?t{c+eJo58)nzQ9)St zdk<$6{@EIDCYExnS&VV4CMIzR>;-v{i9OD{4>h)OKw+{R%B2a!NF*($gIWnUEMEfb zRnOM{UHF|%;aWqV;DG_OtO47iAex(z1(JH4R9oo|bB}>W!Iq0#w!r=Z8JEcv=urPc zXc3#+_r4awXnAZYva1!AKX>&k>#cpyIaw@x{ z=YB9?8Acvw`=`Rk_Bo>e>4UZJ8odD=eTz})*7s1)z**niD26Jv8g#TnW0o`GZQ00PdFOWqn70JzDx%U#qE& zb%QpCfQ&*|w6Eg1mg&CI-Mgcgr7u^uK+?`U69(dHPYq^At>Gt*UBqJ11F|lbX@+$> ztAZm~Oqi3bqZOh#3GBy|PPn;mtOp;huBRCW9&vpN*2Cg{n#*g`f^l(%$<(6WYvhT2r zqZLfn3PC<=^dXYFK907p_+@uH;9Jdg-8gzF^*qWgv3+jSc9>n4rwPzkUV+p&LnzF> z5h$NK0f7rruhXvVSLQjEDSOdT3N6FK{xfEdwvA9i43;-e!Dq!i%5%X#lhM^&fp#@X z9{o4$H$xW(4KLIVU0nbU5x{DYrXSEQv=2=l6vlKhn7b1Fr~O^wsdUHLDw>im{L178 z+F(?FP54NTTwV9OvSBKd#vr!5{xs&s-R9yskpro@zOO{y#Cqf2UcsGUx19-Pa( zmT4f$CqcDWzFw?9gj1W(=nliKo)}_x6R-q}X_NDh`@FZ>5T2T?97ziIN3W}C-Mxd2 ze;lC+?Qq^7Qde_f=C0s&rEXS(14<5H_n!640fl@5=l)rV_$~$VymX6(P(R;%(H5jf zTAx$3g~k*v5D8ncKE>ZsK?%z{doMA8;(E809e5z~f#{jMLv7#_7eAC=nwWT7iXCaw z^=MJB%b`2So{9bR)Z~hGW!XM2veM_FtV8_5vM-CDUo~qtp8EAD5;(t*t~8$8#{iUC zpyoo+7qC?_#H}Too?8<^iORvqfuPGNp46Ho)4UCkSa6K}a8~KQ-GyiCu~qRWX;YO1 zEZfevnu*mG9~&!FsvBhYc`T9CQ~L9{d8%J-^U2vSXigJ{*l96hFM*}GjIL4RW`vI~ zR$N@#=0I;->LxVjd9G&(okXWs(sbw5Hmzr+8Ci+B!IWvKR+>gZ4Bikpa|)=CT5;3% zHA#iR$Ptg9?FJA z8_t>DUyoV?>07YVOakjAnpRzNU-V4nn5ZTgG#nMKsp-0eCYJOUTLg$!KSBTWw=Yx- zh38d(KRT5LuM-whLuI;vlHI}jkF`RWi+yX4m2WkaIJz%a{6`}9Kx$thayi96ROqqM zJdejH-AEaj>F}@Gij`xO^{C#Lke)9S&JusJ3~_H^MUV)K5|C#9zg9CJ`!M!(M>DGN z2U}LLQkNlZS-}-+%gu2*8(NJ&2Fa_}Wc%AleA5~9tD5FQ59tQ*QQaMooWcYT%mY@V z5ZWFFX4KD`y3hj!^8NgX_i+8#>_GkB?6$>t&jW+(yQ-k9rs`q639jFVe-ePLbg-v! zAkS1|;vyI`SK(3gVg!X`xJ~v4;=?wpI-3!q>#|GAH*>yc85VI`^t;`El`|JU`Knxb z^DiUa&YMrUC$J-3=_ts4J?DQkHEDvI9 zJ2^*(kiBmE$HWsPc@OHt%@`^_fl&DX29!cmEg|X?^0D4&itmC{q|Z6?4<$Gplg8Ba zpXF5VIeX@-d(YL{2HJaR|Cw@E&e-mrdXaqdndf0(bJpkiWBS*}#o(Ha412c>%8 zeaZ?OFh420_uhOV3&TQn#UJFJsy=VEi!caU&#sB?=P3YOX-^c%n)nflKRqx!2!!le zv#cyqEL!^KFRR=58WOFjQ7Z3=`b1V2+ly2`$8p5(rV>@lLCfu~4>=EHxxF?Fm##IM z=#SVIcQeVpNZ#SV9q_E6*I@bo?k1Dh9N!G&f2hp!AOp@gx_gM?UA4e0ETLwf^?FS0td*D>1~!yjl^%{# zZb{2Yj|xIKWVfK(RSLE~j_jNp?5E@4H0QEe3D=62hP$59mk*ss%Euwc)Wf-_o#u`3 ztSq&3>$)m^WPv7i^f?XCHn+LjaoI824oC7;lYu4|@T=xf2)WL}^6o@tTcEG#FkVrU zvD->OYy&z$#@APGA<=0ZCotqS!z$ekIJQ~twO`?6Bf@Et|Aw=~=coh_y_2DoY9-rR zKn(rMwolb(m@x>a{uL*56WI|rJjLR`Snji4qA_n8M916iH36q-dB8{m{ZVbpxN%rI zo0tX@Jnq}3{Q((GlV<%;vE}zzKE7l2@Z<_0(u+pZr^#2LeaDcl*J}#5s5Nb@ z7KKT7yUbMshal{u|WN@l2PST7Q+g=Z>K3ApFOGF*IwWn7Scw@5~W-YAOnGJM>+ z{OZRX`s?YAfNKoU(6W`CCfW2~J*+{ad9R3pL|QS(xFoifqZq%?J%ng9N)jcM=%zcf z$r(>N*=)U@>61EEQw1>M9R=qSowfI;}kc)Ln8+D9M*29SB2Y zfaQZv9rdJzDQJ21 zSS+b!LUgc7zyqInso9h20#4ayN(*An|Nr_PA zN%YHlBTH|_(p^`Z`tKJ`Pp$!Zxc^9?S=tG9Lf;fyjNHiHj+X(YZ8SeM5ABf#p-F$? zyN+&D;*~9O&08QM8(+8^1D6XQzHJUw+81+?mAntpJt&N)Q=r_7od~z;6m^O`(;}kzK?7fs*U$g_Jn@u~DUz zZ>*Ms94qRt1+X;}sKjJI=Y^WNOY!=A%b^4*r>gR*2PWk<^T|lS@{iTr4!cJ% zyWJaXy3OJe*Cb1K!fIDLz3vsS&#(Ep5s;~A0S*dS!0>{tETNKh0zb@krDJWa7mmKT z@h@tDhR{oED?K=b!RJRVAGH z@%;1IJw(!*gS84D+3E>`-Hf)oV_|-s@($0km>8967!Bx`zh7+1Z=J{JB=bP0(b1+A zfd3plCzaP;o*_m{e*0>P+NOmgLVv>h zwa;xg!e2lk&KFJ{?X%_wm2qR{PWaG%^}c50queT0PFW&GP(btu9t`5Z8Y!TRo*fPw z6%mVsH*M@}T?RKQE(ID!zNWzB#~xKNP`j}%v)<0@9WuDdY?lU{m9jOji#*p#!qTtvi`Vz5 zQ|SIT)&8EQuwRG)eU`q;C^juO!-17-_Nj}GNAJB{ zEX`8ao9^=e3muR1FAFMvY&lluFn(?a_iZuO`UQUwbX7aEX`Nu$7!)R1XjM?GYhJ++ z#y4dgg*8sbQ(7trCA^qjhXHRaQReYNx?X3FB}ds6MYtYVgx`vlFj zG5y&>Z)S<&WVxWB;ixfa^2n;9q@(B|JZdQ9Qja-9TCmGgs-{F@!P2LUqQ=Vd{!qM* zoN?EcqD7Ih@r4Dek>$UFC3%y~V?a}hfr@WtTjY+^&e2%@=9s_luq$|$IGQi6NBape z!`S$x$YlK_jFFKWu|X5Nx4McVQS+mU70Sn*N$Ad0KyjDTMuNdqM~(#}F%em#7z zM1yFf&@4N=Dt}RE&f2xd%}o`M5b^*ytlsY{TXE@wYj}HiHRz=Ymo2f{l98X&(6{%($``_Ybb_uhM(T}yjvUQLh=ty=+<1`URF2h z;h;WvuA8-IT=eo1dUb(I%eelsT(JXcSyg|Rph+NL+Y2)n!>hOqTfCp?D0+YxZzkBE z-2B1k1aRK!aQWV$1K)GdZ{-x9M;0J;BxyQTWc7v^tG8zk7o$)&Qnoq6=V11}F0Bix z^5h0$-lq$~X&=fmXA(V1@|T@?k_&)#$upn(=NNLC-jbY1w!aLBADKyOIAq14~31=tlBTCI#~3y?K5i-NdB`7kk-*ejraTEI96KQ z1r8%K3Z^B}YGyV(64vH3C-Kj4E<37+l;@GBbV)~D+lF!(s=Gj!?!&yVyFNlZEOFs6 z)YhrvX4BpF?ro3qtCgW_!(2~I+xcbOJNL(>KV|5UVqTfdT8aSA!c4>@l)s>D3 zeutP0+dSr5ac3%zq421F7vx;#v zS09S(ofZ?dGlA~k>Zcu=e!mO1RBNi`>*s0RS+Nd3ixYfXajdH2592hGW^3`9Hf{>^ z#>s?gLN`iMR(Q%(^?aR(^ZhUV?Tk22wU9!KPS(aRe5F4jmuUV&$3GQ8e3LNp@?RH5 zZD7tW5an8jjgOpcTtMf66uqpsYY3sr|(yg$9SE%Gq$h^dwgIE%D5mLXwoChKk~>sxmiZPSG;JrHs;DuL8| zL1UUy6B7Am&DjJ*Fq7^PrP$I9g0>Mr$}G3Ap}$<>bgr@Fg9 zS`FLvdvRGzFiT5yY1*UQ6x*^RBj1^AYa899x`t6h@!mip9OE08AW@Sfgwaz63 z_6R2Jxfg?H;nynO!{YGZ?)X%!lKf-g`ic8j?Vf-Np`_r+JVTg3Qo1CQk6K6N_P>C! ztD$a5<-SXe0~XIbmy*L#Gb_ig27)R5H{}i#TtpZ|qr`9plaWEkfgXw1b#2V}LW$H*1Kju4rj|Mli1rEtv zR(e+Wu$VX#aBjO*(u(N6?8C8j{kavNDnn!o=5KK8aeNn?=zF_Xy(me3outce!o4O> zWCGE(M0G#5wA7A?xcHnnK$mQfV<%{iv*;$Q^{KwBCZD=#q&`#4$;ml8Jyy)7q9!~q z52&nDr7JW{y}M z-06o0jwK+H=Pu+@VfrJ|b$*fxT3Gw>Jqf}(f}rKDVW#EQ8>G@+VY}>pukff|pjIus z=}6R?&fP{5JA23T?Yt<`eQV(sj;9gAR*RXt&#+I5X|1%@HGKRl0L;*a;IK)?z58fT zwYzC8`FQ-=IK2&#Qt2ae#k7*%{%K!t*8ijm7|pKW&OG1uMxdsIv<69xGS~4&!_0JN z94ybDBL>3k=HG9{taAo5t*#V>&{Id*TI0XTzk_Ok$`zP1(%%0*xT_;FqtP(c;F#^N z*2|Df^;snftoBT3aLdT8)nReAW)T#6CMnBV4XBxHzq@Fm)6kOe!@^y&je57U%sEL- za=AXO&?^zunpZKFUSD>9zKR<%s+_|*AH+|CRF_cHM6Mt9NxnQ(xPLQU0OEHLiTuI_cBB6G+du@NI zu}ZDbzgYq-ZMuAY9Bz6tB^}RWXe(*yYiXqHju;aXqP=&B_oia_0Up`fRW$>w}owleSzd zssJDyuyx_W=(M~c>@qT3yRCY3FJ!TM=k523hTR5!t3`(^BZ)@Tdug-0 zvSqr+h@t?jI!~l(c=nub=@Z{xxmaIkE8VvYeu;j3M6mni88}%4h+Bx+~YS7{LNe|KR;+#B1KCsg>vHV_CtL#M1+|#3VBI#Q@19wKh_hk z$J??SWW>$N26Uv3+b29ZIMtA3Y39v{O%fd(l_^c(XX0E}EH}tv0G!83TDoym1+e4- zj>S(Gsr$>PYxne4J$At{QJvBam>-w|a`3-GqmUlfV;!mG7x2 zC0GAkG;tP@NcqrYQ;*~@mjmp^)q{I)aHXr!2V@JM*njfbZ2K24(Fx4G_bGYyE}hhQ ze84mzJ@(%nmu2od9H~v01`?{OD<#B%Bwa>8$zv_ZpI#E_;iDO6I~K$>M#F-y?UTft zW*^s63DP^hiQWA6R+U7=I$*f%P;Esg)l-TnjE9qFfmnkwNz6W6ykdnyA*%9_iWUxY zH*mNRd=Ubv_)0!46CC!`6b{=&0{8HI_VwtJ?SgK+zX@LZJYk|R@f zHBUeKB~6zZ$!nUf|49BnfPC@)0mu_)tG_)2xp1^LC;#|&`~{OV!ZT?E zr+m2^5xUL%bb{#lgQyuKy8?zd{R+VT`72%t0)6aXYHqcEy7&qItjjQ8pFqfB4CsFg zbv+)eoR0y}9qoO<<`sMBAez#xeQIlnyU1X9suQh%GcIP|+~&ll#QvR^UF+w=0HWia z(B0jXk1aU-`a0jk7?7eHuTB3CMigurO$4MT|KA?)^EXf+ zg?UK%<~JA@Av&N}&D{yfGzq`g7oa|hH^9uoe)tG!)T;4Ce&@>N%G;9$w$vr;mmS2X zkfi;Vj;^MhLhtWl*G!6?z$G}LgPA3ezzBQc$NNv}B-(j$-haK25XZ=mO zUSx17`J7y>5P{yZQ2!5;3VH4A$tA(eLJ-v~H%w&VY;oABNAg6|a*US!?~#Jg+5fi* zrFXBigr5>14LbU|VVWcs0N*Jl_{0B5=4VUhK%lN@j5|Hi!ZG@gG2mqGE}%7+H|xfK z>+oz>Me61h9%VtP=xb53=&=y~SX&lVoz~YI+~SWX7RX~}H&5WqZrLsSj92^ep%OEW zH-Do|op&;_qC9lib-#Y#=Qw~r3?JMVfAz+XmYQNVz(rx_A~3g*+1t1VAGo-OMy}5f zp3}syRpETn9REbhY5`rv z^j7aH#qqnRF z%7*^TQ7!VrdcqPAm6*}q9BXI0jBiaIQAE-${+?q@qJ;VeaP;9lL9JI=hcUG{1G9Q-s9->nCabpB=a zPdE1kcvy+&W&#n`*YU;tN{)LVaz(en@B6dWQo4R!8lz6-%-Wf{&uId6C5(o~7E(d~ zk%YH$&KvO(bXs)7GJ@ zc$(trG8Z=KQb@DOW6rc&5-bLi^E-v|~iFXfHT=x^PLU?Ix z9;H8zeCa7zBSrN|g(j6+Td*Q7S?3V4*ca12ya zqQwtuG#b;#8(T@~#OGBY2)(dSrT3({jskFVHK&i|$k%=pFN+TL_tr5zOj zZd}`J^DhL7+xzYvsQ(=mVH5w%_hKI?qDhiU{%KL?)bS1OE;>q*vAU|ze?}e1UtTSh z)8@baje5Ut0uy)ge(J<=KCh0qxAcbBpGUE`ee4lt<^X!KdGpT59Sh40d(Z8@>%2PO zuV6B6yy2ayE>cO}A$aJ+9(3T$}ldaygn6Ly$jsqlI%HcWKQq;mgaMM5) zTOn*H)MZ^3^?9Jv5U>3#8Ts;02*!@D#w~z~wz&||W^8x#?#F*5tpHi$SiAhooOd66 zTntl90i_3v`(kd@ZWiwVjprd1<_jVMXs`19e)H-I$)3(n0tFpa8X>^x-BmwAd2zkl z(C$X8g)?W=1a$sNyGhaL<(AbAvZ@6in%WgCUQ65w?!zfUu0DZVjqKf;DN#*g1cY12 ztRuXKQUF)j{@37Q+DoiizmLD_#dgJc;CKqj4V$7%aaG85&Ih~M#Uj64CdsMMnS8Ok z8+7Sx(J0~8K~968wz*S0;mb1cNxK{2W%wPJZ%1(zs82FPny&l}59!L*vsFV^1sVxE zY2t!tZ+)Vm#mC`>{S+Y3$#EN#^Jj>@0cRQ@CRS$Oi3~uslnCV(Jg)!<@2)cMw1Tn2 zF&Ffv(|d|hE^F2GVY`RHeRKV2RQAjC&U0()-+A*RfC)OkeC8t-i@e`+0N6q-x)86` z%V`F`FXO{{{N__fNXf$@8F>p#t^3JV)!tmo{>dE_a^x4qo4&tdQ>oQ+73Q_7vsp}Z zPrc4^nUnRro?=^;8*RtTM`i-#gPF55I+F|>%2Xfj}OZ~o7ANv>DIF*~Fja^_D=v;iz>vTQDZ8xd& z>SL{M^+9@d(rke7#AAnw*zlIaVl9rWt&>u0n?*u~g;J`7x`B?47gC+lKzUE`iPy`J zp+A9NbmnUqIf^91{KMvdK6rAK9q6UsXzZ}br~g|zIFrOG4oM<4r{TSeI%{NL@mDf; z>nx*3>p5K1428Jj%;jo{6Wr96&#i#ZFT4Yj_h zQTISSLPhl(cNYiGf^(E-OrrH5u6e)uh5;1PZ1Ok$`hzj~JqD$zu%3IsDB%72tOV-K z<%=wyb*#E9hvsEG6SCCN|GtBa|ImxnlO#)wyla+3!K-(cgIn$y#||)vP|@gt&_1Vw z0>8n7YQH|~TL@e|D%3IwGiW!P@c^TXYP0AKV|Kj?SY{(%BuEc7-TaGWvM5&FR|z89 z(Aq%@N6#MyVOEMeop#w_$X@WTtk+JsbOQ&zUy?IR|XsF|+2q{;_w;!PJ(*To3ja zCH$7Aq&stak0Chgc7_`tLw7xup z>J=e1s1efc#YAp^Z24ao3JPyM>uZCtoE1STWgFsXJ9}jgk=+nC(vk zraEj}KaU*YA?r|x^x zFL0T>C;Dzaz^h=7KPn&RP7SKLncf4Xdi|-&A%C!v=V3f+pzKh$^>Jjw+bLuqUr}nF zfK?uDQMlA8h)2eu@{jgtyj?$e-H4-XYnf|ZWmMhYu!?y zS(Gz)D8J3HJMYoW;tMmStU7aR?$(Kg-b@u^Pr3E_*lb?`agXWagp@uyfBk;Nwo)HK zVB6N77Qb;S^ssqLJ7Pv@Kk)SA=XY%Z)cz4?0EH*y>1ymUaWIU3Qx%G2MIGhi{_qxg zY9D74t8qKJ&`UdcqiK<1r%9@FHQbYi>Ss-}N4P{Q3WncvV!Q9nTM5dcekziH`y-D})zAr_kCyYkkt}ieR$-^jPn_`Bj)F|4*49 zMg5b3LKQu$rqLpArQ0}(WUBzdzr?}skNV%4N7z=lkd@!3RykCnpF z{=FJp`U6>3egql=iJ;eP^9W;CaVy1}u|(!c5@O;7>{>y-QnONIQNJL>>3Fi9x8`p7 z8_6|RH+xm$+)E<0y#<*-`s!88DojdAzcvidRh;#LuAa69T1nyZo8yY#u8bo@D7N(% zO{s-~Yqnl8>!%%^ogJu==XO`gQ%>M@1HD2ILqC6d%xJxCA4gLt{L)B2spsTR6^PdV zq4gm=f4JN!urHk=uEu(QM4c|-r{G<7G9Do7=ECPQ>T5>$3AzuWy4d|Y*aZQ{yghpuqNOCZ)2iJs0c`_ASfx_U=gB7GkPC7 zM>hjhq+tjMNK5CK#27J#v~-Ly8Ql_tjT|ucefE3)+y2?Hh8qSHb6lh~&}~`2E^&V}*Wr;5jf- zM*L2Yp-$NA5&TV69L6UcQQy2j{DyY-F-X{>Oub&3$2uoA)7cOoLG z21Y{2*vSH(eLppp@FCzWKY6fX2QE8lwA9JT50^OWcNUKJs2^%5zHPczxvXRy#1%o}rMV5mthi+ee8b!{!`N00Fs@;^4^GvnsV(4^l zKjTz-_SPvplsm95mSM9yN!6n{))5s#$|G#{@UX)n|D(|x_s`*0wN-AbPIzt`b%>rS2?uk4Hn38@D96vUu-=)2(+Np$xYa1RH( zv;n-z&m5Wh;wDX_dh-@c4ngSnLU|En(U-c_db4o3ZJ!n=Tk7O1P;`2g^055gp9a2X zbUj*M-LHKMPd^2#(EWoCJ{-#rLnXa4%YRepI{tRq>U+4%5UJ`=7am3gxwN+eFt-W3%LQ?$Csd6zniOFI zS*6xe5mN$~<*9JZ;@ zJUt6NLAm8TFABcVeYKcb@cZwtS3d6L2@_gu99Yq=+yA49-rVf~1hiwxvX{zZ_f(%X zLyR3fBV14S|58)9O{#*^a8X9e0`46QlHR#IcW0(ZBpb_bcKs_h&B(L^N z*#AoUV4`79|EFK%rOS&epq4ENTRF?Wg=<(gYeH{cAAWY6X|g?^x5v(#U4x^^{<}9< zim`#KNkyu`v?%m=?jLMlLq_$`K>c8OX%%uKWGtHYr2MxVW;uKMiQ6FeTdhEzMJgUT z(&w^c`2-Fks{*u72@#xDXyI$b=F<B}q=8Ys)=nSp230|JAd%ksV719o2tMoJMQC=lWl2CieIc;j zaskSp{d6pwd5yXnUVM2oVvJdNUoD%|MDCs}ao}d^y}R=kzdYq5go0K-&jk4rwo;wV z+aAuYduTnl*l7yz;C#R=a35Ha9yf|Bl)i9K@`ks&)XzyL%&ipq9YVHm3*Im$_IYQQ zRxp%EY%{8x`mQC-2HN`_Rb@Jqo~4JNEz+5H3;uTZ4y^#A?-k4L#9FR}T(S1Q@Cnkl zLn5YR@ibg1W)Z()AZm3;x8U+IfxnJ1_bUIHVyX0l@EcSDTmNq<7ORn4OIIe_|4~kF zZ*;ub;=3R-w8F;E4420dt#Bpd_ZRWo_dEaluTw+Uyq^#eqqfYGG~_cQ9RKf*u!bB5 zL9syb#pCDmB)rcpilzzeHO!L8Xve!mC}nWNJVx6i2;I7g1>X)4Aq53!juVR~A0uG}`$S zPA#~Fv(RGZLweB;|88wr!>O%PHbu)o{p2hK*MmoaVk|9OE2!cdhB$qo_wir4{OK

%kDp@v9y*K-n-miJ5?c#m){`ssEFD{bktjZw#$vZNvB-nk3DddGCoOYc>Om~F zTPEmYRgXq14!l_68s**&eQW6KaQBO}l>GFT8q(){-Ly+nwLGsX-fom!wsN{f3uaD?8_Dlka}#P9vZ+bLupg$wH*kMIKCTJ@hUMe7Vr8oBgdO&a$pbM^YZCY&;!` z#T-;AQI}O-X((3D^)75c*0;Z$Wz*)jwc_!X*k?<)Ynxmf<;nEn9&jjO--yGb{b>XDFU57uYCudDp!z+NP$NP! zf?>()?_AeIum!jtKerJsU1s?_d~+2neYp2NzJ88TaSyouOg;+@x4 zz*keEW^&4_&++kx1v9`Nh9VN=;%!P(jYICWo$SMZ8~!^Ea94wX%A0vuyCWP}D$_>d zXlXfUNGCMkZI#)7iI;c5qCrZNc}4WH*J)c-p?xZDUieAM@9Qh=!Y3^RZv;m4nBS^O z5(t5>?iOM!nuPa!J{U>-Q1oA@oer-!o0}Dn=46w%K##XCw;OG>t{Jkb_~?XYq^}OK z_=(L@#()o-tn%No7@L zqA+^~brkcYQCWWlfhjfkxR?X?!ijj61Z5R^$Tp$zR>#;cj;YSLrwgfe1={#wmr}z# ze)tGKdT^ty1J~ae^A#vnp;zsu=~^< zgfXM~nPrA{(&8NE=Jt+iIhq5Lld8MZMceY5cqJg3V(ttM20kXKh}Jf@r*7w@IQk;8)GY5O&r@zEmXuimZ5<>8Ezs7*obk$#n3e=%QI9{Uj=8OA=70DNW5M&> zzKpLqS~v55UgFZ4ZkP_UnI;2^Ns50&&~H5IlACE@BE&I#WZ6HPj4lbk)r+$B(x`5I zK*iq3YGjuUX1lFpr|_Smc&Ey>Zi2A7(;b#=vm5SbAv`H}hg?oB!c0ZM1uHNdx~Fw- zy{_3!{_jzrTO<}7Tod$d580k!9o*Ubp+QJ*GFK}D^qRvU?qs2w7}4EIgTrR*QVp35 zwqqB%Bu5cgmiObWuV>XOr2$TJ_GvE1)E(W=NZoQ$$h)%UjSt}XeyG<)&0VmWHelD%OlH2wo=_TqR2^`1wWlr*RG24H?fB!b=$v|PiG5{&t5r;;MffpAiIu-Gj8$Dw7T|TKgd?Z zf{S;oEr`4)6;sGJ9^+dVH7o94es4ZOPTrmcv`Xm+X7Bp+LY(u(@}3>oV27)I;Ee2c z3Dwq{#ucQp{XPK9-r9Lv$PrSHF$a~&>DA_v|f0)h?FJa!Gm zGvs6?=g_iJO+m9e+I;uRuI%?Jc@9?Zr{T5U&_~E(cJhNtT6G3lT2Ct@9Za9E8LJpv z?7q@9e95vW@(Q;Q^8`ABV>ydfU1qW}Ri`aF#7Miut_7`0YhH!C*Q*^s4HfVw{`Os5XlJ3^ zsp@HI)(cPPUhK?EI2dUoRGjxH%5Q|aNBr74vN0e#t(J_G2)3yj;(Oi6 zwNWpv@~Sa(-6n6IK}AF-d+yjR2OfnL!3X6AxKEA)`kd&I* zfRQ59DPx~JjOQ2Nc1n2-leyK+=_=2zK5BMvQmIIl{eDuZE8O;=f6i;D&-n^{RW%i@ z#8mo#+GIm+CF;NAE%+Y|L9==%OlhSc@oBSFuluXSdkd)jrcVnQQ{s@nfbVY>Q1__s z1j^>OO7KCa%P^s6J}Bcv`RrvRhs(^M3E^D;Mi%!6~sm)91~{xRT?qHbaAM zTy8!Jq$H=mcH)uWtlzDsJDsC49K!$J&go(naWSmW z4^`NUsI$4?j^A&~jP{<=zk#&A|C#DjYW=#Trzd3_;7ggrCt1WHp&0dfGoqJ`%eRi zggyBY+3gh-6*gV;6cXCq%>68X-Teticy3#X2Y0WQIqxmp^G)3md` zbm^_nul@{7A*JWqy7(-)Y~2<{V9t1pyfiFcm&=NU42lf|96sr2(s@0o{ZrWNzdM<@x2jg{Qztw5#ug7@ z)6{*~AfPVMIL*S9l{nY=sFPm!@bH94x@SYhYT9nTPabG!b-$tKbsJXIx!PWR;ybtU zdxK}@LNO;#lNznY8S0QKmn?X%?F{kpioC7=JhtK%MH*XnriQ?poLenR*QQo_YIKb} zFl!-2L=RaahF(P$81YVjR%#aHoSceq0cq#s62FI%5S3O`!*Q2Tj)tX`ebLtf7Oc% zdxuco8vt9i2wMGiUkhe%Sq4Iw&kQ8S(F~AzKA-!gKt42Z6`{4Df@R;Gu(tKJbM z_M~q8GdJ1)Y=#b>PK%s(x6`?B{m2xwovebwfOczep>f4u7+S{H1X0E^12yVmTU0ds_e#LGM{gvq{bhU;#M!*s29cDg4Yv%ft8VMZ=fz^ zWRall87Ie43aJhgpAoI+9ij(#9X&x+UdF50iQfh@Ol%OZXL!x&I@4t>w(y#7L^zL; zo>N`&D_FupOi)vxlwA6?pR_i$`!#|O(($D8{N!ooFY)aKiyj-B5EQd3?~Nm^J-dlj zw*)`B$r{U)<667UMfS(UUTBXO-eO4ixQ==@l7+EU_<>qdb~%JBg40dh%QQ(n{F*f` zHb;ynou1T_ys47}UbuhhMrP1-t3aKqQy01PWi4A&x%9kj@S;(-3}L~V@n1R9-Idz9m~>z+o{jVOuu2Q&L|=5?tbG;staF=2>@t)yi?Fv zn%esGNciAGyZ1j~PPtdGbtg69pg=YxHOiSnyw)X45hkq9=WX{l_IZtw1*cK;#LeiK zugYeDQaZM>>i~;xUKc-U`e1q4M;w*4K!=H^$DoQ7gq`7cr5|owt zvh;KAZgRmgZ6&N7%%;pEIteUOVcuQJ$q@Pi_7R8cFIier+Jzm~RdnMoFK zZS9r{!|*ee29>(GH9KAGI<7q zz%|qu&k(0<(Yms384G>L?Y|1s(2K>-uF&?evfmq1UZ!%#4i{Ti+UK=Eamjf^tW85~ z@Cd@YDqjkdy3@@pEyfvGSjDz*WeTZ1ENbT>fxTJf!oi=RXj15;aCu~(R9?q2VNxQ< zZjf*at=m}kf>(~_3zYEkxmh@mh)3Py=V3GH7wH#hb>WgE1Z=i@tKB>nX#SOoK^?gV z)eg*N{5jLST7He6Kt$MVe*5l?dC->1XoSC5D5|zH533(34*wchx%#12^8v_2_3w_A z({~?5-soDtdH2SM?F+2s6WbW?rQGbqI@-0RBW0sD&CKJSm+ZKLxW|)R{7Fd*N3T|t z-cQjtJi+hk7!ozVu1*)vx1A=Svk%7ZZ(r-q1kp7FSA{qhLCyVEN962^??hF{R_<0* zH%x#HSNx*?tH2{r3<8OMm!YTj6apk>8d-kfY0z;6+0<(_jx;?FJ78xibU#&b%V3XU z-Q9y>s`)V0-J}Zj0dpOXG#yyVIH_2R(u3hQ=y<%(ZwxuoBF&o2Z$-1o(KMt`ki>~v+9@d!OF5Lso$yk-@sUz7#zrTlh ze~&7^vG^y`&Tb2Sx&r)oY{D%d&M?z7UNi6Js4WDm7foi2cJFZ^K+kon3CtW+t)Z-TpJ$S^U8T3 zjqLXZ5w$mH5|hjgLAE0)jZEe(gz0DK_bJV1KeGQ2JNBeElFJT%SAwO4U8bK$&n_Sr zSL{+L#%BdOY`Z>=|D)Ml!yf<%o1UfG7B(Ui#0jH>59dzlT3gqXP{$a&2H*~+NAT^i1sW)bI`GG|TRo$`ZcaQA*%1BsJy zy)>WnsSuoyY=@I?(S3dJz&0jp8tf3-O$aoy_>*T3A&K)`&^eyLwmCl>zsNf~zY1y`J%s z+vZVymoCOE-;b}nymrKLjFGta-8|W!#LZGi{Qx=D-BT?jsC2(0=IA;)I)ZND1uJFN z%mcr|hsGd;k&`fedo#$2-e+n!2bhq(hI-t9f~*&|*6DLJseKKAz3sTHJU+?W<4ZCj z)GE&xZ*7^shAXBfdV(}Xbe;=0Vc<%hbevGNUflEye-fqtkuB3BY%D3zs2wq#A%n~r z%C-(2U;)H7^sQMMeD+dpOg4>x~Yb~ z%IeDeMzY&wJhrKIYB=NH%omkGH^$Qyjh^N)GprC-;rO>3Tigndv7&`9gGD z^}9YDjpcm`NdI!PEpHdZw25p@DbL1}#2!F_>DylBWTdd?DsL~|Vnt`oPS4@s@uM1> ztE;@)!vsv%HbSC@jTY`bohjV{;dVl5n?0m=dQ#EHgQZln~B||wP$Utit;7sAem9!=NX?N(S$$shcK-_X% z>&LC%`SM#@rSCJ2s^wTiZRhbLM*eFz9&-P?YP#vnxbA3q4saoC?1g>@ZF-GyVed-T z3!NOnUJ>}OD(QX)_oZDkv`j*l8qbrAIWL7=j+*r62n?P=>x93(?}VQ9DT==2qC_ow zyV%bdA9A7;jYq__+%!P_l_Sn#TTG_`$EQUaRypm@XzmODqI=N|)#CfTi^K%gf~R{T zLR-ouY=bvGaaFxP?uQC#=#MFwyKOp^m$$3FsA%u(rO}&il$Wu1Cs}1mzsZGVaB{0M zwXW~x%C{yn%J+syDSk#D!I+8SczHihh+dGRG*IB}^$wJ`x#8E+5}oIh-zm&9(xo}O zu4w;$87~3jfTN04VU^Z;gx)PxctVxisiNc0wq-leI4Xprt5p3)FpI|5s-X^;0!jMo7Hf%x}W&(?7Bn zz|)d)1dJUqIV!>70%L;R@?dfQk}bAxTiE-STZn^_FNZoV=5lF+4qhD+N#O^%z9ctN z!bv1XSzYFM+Zn}CM-+g1OlP7V!Qml&0#FU;@kU5an8M=1#e)Cdlcb~>BaNz;T z&@HUgQl_1fJs^F*g4RyFZVA%Eb4wm3LHbNArZ98!8P)0DCaGz+U^v+VGfcz;(l!|b z_5(~0UXEo{&-uyMQW5slZF!R6)6$~_Fa^LLPaH80AF7%c*QrNPlkzME2F17W{&i(8 zLC-1%x2IcY@{FkOUDHVak=Mb>D$5VyAUB;f?Wtq?`ZRp@SKZrR8`1n4f+710S zuRr2wiv0T`lB=5q6C=r^>wHH?(dfK{^#D3`vVPrz?kr!=Nk7{Aq2mDmTAFoOg=y&w z17hR2!e12R4*E4$4@n==WieqkX2!S%OI9lgzsrwuxX{>!D2ppkD{@0mzmz12_y!M+E~iEG|K#lJfSx-hw{=Dv~1wlG~YjItfb)00aoETdOBGtchn>%5NOma}Hd z18O0>kx&~EGrX$E;^H$Z>t?ZNWkKd{RY~q|t`;38D4a0Kbz}9rn@7_f1k%xf(jkAM zueG?*T3-Gi{80x^&LC#RIvr*)>oOAjbBpLgZTpflAxfSN&uu!MHu-2ha{9$(tRuXl zvyim3xGP?_6_~+iikKd>nmy|>vjG?wc|?gN7~guIV|3v2<4_Y7g7>j%H>}pSIy=ViA`(Yx-Kx;?FGUt^hNLd4~#TSK{_Z|wp z+WxXy+BF4&lV3aru~^Z~QxAnIHs=41FJ1SFX7a!t)PYA|Phm1@=qLse?HwwDVi{26%e= z0o{pYYip}#<-YxK`n=%O*=CABFEz0L*5J9u zS->={{Ct#THQCbeYw+uKv*2@m4xtQ>qC9qkEGmc9UFV{!yuj6KnX)%AojtLR5Z4QH z(a-T58CB?|u@6G)P%wncsrLw9L3UWd9-aX@_v^@c6b*dG`mWPJvJ9!YG8U8BjS?J8 zPF>wR2h@GXH0HA7*Dz2)onv-Fu`y+Yc)t&i7?U5^vL46Y{dZ!Z!ygOScak}*`_Z>O zv2GQ76E5PPo}(8% zF}|j@%$xmu$}R=VGU4(qSih>n(*LM>QFi6EYEhdnT}Wkd zhh%wGwiKbQ0V~5*SlEilR=w_X(-&{xNpmhLv5}Oj)g89p8|)MR-4bY+a3?mMV*<*s zf>yf7O4Eld>`AonzouP}KU?fAq&kWG5zcw9=M)=Dc&?_6g!q@7FUB>p`(3JPG+YQR zJ92HH{E2Sckv*BThHY-u6{ZzFFM?pa(ULPFI_8q8@N73|{_tg+;&3tG&ii}Uj~jH$ zvsJT6J4OAg$&qTDe#vbli&tAxr z(0JAen^fH_MU!AF53>W+vS1w#^W5ah&HvGGC<`sH5*vFnZ~OJVU4{F^IPYhu2>68BphR&NyeC60dI_7wRBVHU7EvY zh>TN!JPn|d%zK$

NcI$)uaB;@uW5Cdm;#ipt(PX3$VM$dxQ+OvjKlN#*5aIW)(+ zHQg6ttcrVGOLh-0%r^s=#1rlCb-dnnhz|rFh*_enS66%Zo;uYszdw7$Hub#K-4+p{62!RXn% zju$G=65I{^M`-wXGkxWTwzT#mqk)-lk)GSC--2i+|8t#E z>^L@{-FmX z?oXTZN)Iti^}Ei_f&NDmP=bimYvd2hUVgO(Zg<=MgS=MSLwhd7fYkS18d4~+?5bhg z%MHUNL&f?5=N;l3s@?=5st}LAJ!L%4RAM}9K zsAM`QnA&C(;#YbMd(we9C2xMcj9-zZ-EE-e=Of0XJSpuNWgeCrp)AawKsFwq z+4}ZZy*##0?0M_;9C@&?6F?LIJsztiL`KUr$ZV4vlr@XN8sYhyO?k zWL%1`W{VcJ1r5;$ow96%?Dw~&c{MfZpQRr0^Q6BwBaKzMG$n8}$V}xuh+qhL09F`T zCz`9N9moq2qfPU6*DjfCE<~ZI2bvsde<6(?{uYf)4Ocy zoO&txnow?%UV)XCN)C$+`RET+sz)7&0_CgR>Kc$-I3 zS30j&S+m=c4q$H`BbrGYl|lH7H*mJ zjrZ2N$~v!4``b0XSp6dOyms|NHE$-a+Vxx+r_;B^k{Kv$^w;x4!OEJ6Y|DmECKh@D19N$GOy_aZOQWeGa~hhfWgM@-{%Z6J9xPSX#7WYY0;IXbJdg4l52@ZgC%^_ zD93G+Dv#{;MD9C!Y$taF7v#49#ln0MFI-g&yU?W9msG@{5rjc<{T&d=(weRPZr4fC zH=!{_`A2LN9{XV81r^2SbY@^7KXb_4!`N7wF5l0q?P&LHZ^-VjDC-o0PHohq-Rvjd z8`DrM=moN#O@bhtkH*IIfg#FCwIe4=66?6$ZZ&O^Fy;0g8}CZ8DbZ3-0V3OQ)j&mf zKg;3b!5bZP|7cL~jfl5i9pr>nYGzw%lhj7h@I6Xi(+sSTmaNSxt=+oa1EJOJ%N^m3 zM(+|R=O>;>P5E+};qd#Pq15?*SeSgb{I-;OjXueP+28+SXr_gV1|R2@zOzQMUBt5i z+uL*Y#4R~Qp%Tolik~}`tC%mJH<<|4%T`v&;*ovPpF4U^d7WD?=f8ui@{j06@ti&P zFYC9EZSrTvf}EA~sX^HhLRZ%Qc6X{=>3!Pc6IAAXqhrtAW;@ij1le-<^Z#N76&*YL z-2d(stN@v3w?h0T`c^nOjRjoZ_4AsaWs8%Z`4@aG$KXwP6`h@emc3f&iwj3W3-EWA zvt(eA=BUUL%ArB)R|w;6nX`n-EkkETXm8SF{T%L(ZKm1+x7%t^j&!e0RhP7%N&7{C zTUUz)8{0=8ShbGJ46lW=8o}U91Z1DK`(EZK=9V&YGy6Pr83psL4bs5&DB>ROc^2RA zzqiYzLS>S?B3Ks|>Dbk1x_a=5w%mZd(m&+->Y*CpS_#JT~=`MW5sj1|CK3$ z0&~8mtBK zi$9`Y26OIrScV*a%y;$2WQh+vd&!j!2EUg1A&8oXNXjvPiPT$o|SdDs6IuX0%h8I8Pn-*t%etU z)l_v5t9w+|l@^rm*=QNQ(WRPzmj79j|E%qB^Kw4XimmQ})!h3Pvy92%U|Da%u%e#i zMr5FD-O4kYIv%SU!5giPsIQZJ_UM%}$ZMuPlz*hYBA76cTC7RTUT0GxdtM@ zz3wH`bO$f-VYH12#a!%es`C}r8m@Z&p66YK z#5V>0k-9g>b>*8|)ik{KYb=&CdCM#$CXRK%I0*~1Q#{rStfW&NO;-xOc z7s0ouv+d{3-D89(kqbXBlPMgQV0BVQ`GRJP%|xk1rtkRYEuc5pk}5oj3o)ykf*Ncu z7S3CCd_l4lktG^Z{45?c{5hKm{sXhPc-LwP4ef_r*39#0wC`=2K|NZqymqowIsNwC zcg}H#h>?9W6gzPwIZmLN^;BpQ*VIp&$N>)xKST`AW+2;Sij^I+C-O8qBL&GKoU-&@ z4;@hzmnAC~nx7kIG8G=tQ&4zXTHuXfqYQ;Vnb^)fKNO(rg<<`bzgsoe3u)Wkf zH+Mj|B9@V%8U;8|Cf`}i3}2Kw>^}isR_vj!c4a$zDsH=tbFZ(z&c4(}VnLLrf3DQ+(S;Ag*n3#{V`p1rUnzxMp1Mq4sfV;7;gqWjd0_O&`#cvTn2Yf6e+ zUPm9lV+FNzGp8!RCaAB-RO)U`xM+~cX7{O&hzl}ZFb}!|%Mxl~eZuC1g-6>cKO)7Nz0C2Mw_ZjmxZ~ zr{!^CFx!I}$mp@g`Ot7yQ+ROoeO-pKydRXa9ZO2J=+s0+@t=vheV_vMnbt>}qII^b z!eUZXwpJVtvv(Dpn--1|J)pp6NqmO+AeC%&ha-MKn#C3lvsP%JVH>*ABtuJ-ixF7` zWWVHc0I+mk{-jQvr#i0TD4j7Mbky3ZY&-nIJz`Bb_uQm9U)p7-C0Vw>6LT!wZ(_Q~ z{o^JNd_BZ70r@iZ2J^eLzwvYV7rk+|_6~uGkd|5@pHjL>*zS6;XW_0%d0h3E=o>4~ z4_?i?Ih`gF)OWKrlWPlgk3oL{RvU30knyTS7Ov7)s3a_V_$f@dl<0tVJymQfDqhIV^sSTd`y7SuDPg^crmvUwH{T+j7R;Y;R`g7fMnKo~ouZQ1H5CQL~~czT`kgZ|j_?vxY_<$!Mj>4j;VoMCj_p!=GtR z!=%-}Xt)|}cZKFbQVVz3bDZ4nd3O1JHd#aJ)O)%`;$f9((BX7|W^u;4X>ORVLsZhj zMd?{qD{T+Ul;A;`USS*ctg;0nBIU!YV+mWO76kj-yh z<*!j^#7RLWWmV{zEXRi&&58%z0PCYb@~E64+$8tA;h~YYGsPMB{T!ep0I4O5NlfPW zUk`Cim!7mcbvB2Co(6dL<$V8c*Rrmv6nXK!C*$Nr-bn5XXqawy{g%l@aBKjc3*#BB z=oVDmpJ|@sOE2k-w{EC($v96(WIpjQ5FQ#_+g4cN#f60MZOf-hboW7kyk~)&9mMx0 z-aw|Bg@aA+i-hs%(?s%X=})do+(s4xaqKJEgN3+A#?-KRDod`*P`n(5btvqt|70s{D}W; zcY*6WjScPwTx85WMmX5D;yAbuMNbSc}E2m5^6Nj-z3m^F|Y8GQLvwfCDm}_b%%HeFb4M; z_hC{i;7|KaH|UfWr1S8Qx(hS9i4o+;d6*TAo^7Yag2hcKD+zu#rON2R7AdWr?H`C?eInpeHc$*(zcnD~K*tx6R+ zoIl5kpoT+cB2v`{G%fF$g?RQTh}z$gjDAB+N0l^UMaY^SHc7<_ySG*<+eK~X(oE{s zC!-}5>=4;_3j4ftMrt+ppnOdPS5UBYTi&2vb;t`SEJk9t-s45dfs0Bk)y>7e1+}Y` zoq(H8%X>c@b*m@-x_Bo9Pzt`;Ji~YMV?p3__BD;JBbhn?yF9gfDfHnY{Udt15v*d{ z@Plbe2yDkGks0tGwoOBWrWiG_Q3dQEbC%aq!cFFF#E7d%+GD z)+D<9<;^}fwTD7~-1%_)GuT?4upD8j{9M3eV)?SY+Cybd*>s7!S(0yaeB=LhO`rI- z&FuLtyM-#u?;be@c6C4~yu^ZTQ+VutarDBiQ>~|7>|RP(rKNqG?;Fz2iZGP<|FLwQ z;cWiz`|sA8t=3*`QG1WrX{#uTqBhZ1%^>!cbfI?b9aVcoYQz?s8lh(F5ql?Q2tL1j zkN^Ksjy%h8C%NDEab4&6dTB6|@E4sHMN+OWlNq^zU z#~=D1B$zc^MY}H%)3-3GB~gh(PMb!jjMn`!G|~f^TE}*PVRi+ zZF3_50qtP)vhy+(wTj@|!kXxy5!*t_jx|!@H2H9PBMC>nG!Tfb}dd-{8}@AJ7TOF7mcY^R>T%Sr?1gr}LIe(MNyhY{^To?)nx zsSkD{M)qH~=29p1 zvmm7p2Ei}z=}p_xX~*UJOKVm3q7|Mw4aqU*cT5a)nLm3_jB9@)N6~~t<-Qv)ia`aN zcV|_Yg?Q1>1@0R$&F{X&?anllSL$VnQUXT7+@}TOSPU1OnA6cR(*(2-)Jrxr`Hr%z zifz7U<%HnLsHtgq;PL_Agak{mh^bb}3q}2O|EWx;zoTXbOK{{Ek}=rV%GQ2;j4&7A zNicBf7ZO*@aF`aSRe#4$+eY_>vetFp!FZ#7PzXlPKPa>L4m^iSf&OPTMrp*brgTCTs``cdEt8w45rs15quMdutLY5ggh9cb{?Bv)(T4pn zomp?>z)`oXp(H?gPUfKW_s~XVY(RfBC zB$4PTtV`1m6@Ro0+jH%(;((u!4}xA25zG7ZevCu!Vy_;E(c&PLe}}uDN+|;QIBmYR zW>S}AzlplC?U`bY0bK8Ti=^Z-$T*2Fn*F#jW?2aBRahee@bafe~y49f(DL&={ADfaZ7>NJ4oQ8~5?$^iiQQma5R(^t!PrpM8) zk670OGbLvc4EvL|X3UqP(+xi^e4V9z>>wEstrgL-sNN73Vb7=$M-`?7gZhJ+)r)|) zWzxoVSXWNMipgWCPuGn@_Hw+L`q}G_yL=QhIx@hwjWaHvG^~%*ejLrIjdfDb38W1A zYY*RmQ#Fk79rB!+AZ5m;iKeP3izEa-{O(nv#oSKXhZyWG{cAT`_nHcXNxafY{pk0O z;E%ua(sfSBV}85n8}yA@Ut*FnN;eeW+o_$sgUXD96<(z)3cUeNc*$=B3pTb_y)r?L z4XalRw&`Xxa7x`ap)wjqvT1Vqi)P76?Z35j{T}k(zr4z5l=YrlC29H#fIm^z79xflLU8OU}s( zkxq=mdoeG~-_Ra!uRRLRV{jnLxYUfkB5(HHJo{pviGj;r-c|y}r_SuC3n04JfFXYN zLqF&e(`*YYKpKjbG4=<-aBgPIb@Gn z%Z(e?>uV8pe@NdQ-|0*^(hQ4rMnf*O!HvFd)tDBQ3DTTnc2m%vl8;K_m()5} zC~6tbtm&4#AoaTRSbAgJy^fQPo593zIG&i*b6hN3mVS3!TVkg57nL?2m#8o0jok#l zi_Ln6p+5y@aK{xF^J}M&@8%09DIw%SIAKj3#<~P^pt(sB>l_}U#|iwD;I5Yev|3pY zjM-MjzY(4TQtqfoIl%Doem4ihJ!Q&fG|8y`iVJ5z`XwEhIB6|&&Uw3B^8^fdU*j9oN(31e>&l7j;O_>h2peWw9Q zbwOEIohB;!X^zLSs+_`NsaYQ`U zq2F3yaeRwhx14l}h#D=32dNgrKaw+EqYWBTcyK3h2E=F@=}Ho(vWmI>!yTlFuf+Rl zccn1Wx1?|$(1ORvpupC|xBzzyI3~Z}2vs$<(lfkTGV2p?xeB3oT$pB+9u^;5BDYiU zUHyJ0-I{Fl=ueG$qcYp)&7IxK{e1l~=p-Cks?nHmQGrPWY`~KaI-z}9p|0*_4l|D)o7SG?e2`@YQU6=ZJyiXiri9VWxGvZJr6g08 z{e1<>PbzmB)0aQ_49t{%KOFmXq%LmTJ+JaX)w32d8nIn=MG0m~;Ab3=nr{fEIPqu} zRT)mbLS>ZR9@{GXf&_*N9}rx)%U6wE{c*qQ*esYgXGWU)7EWB?k~6M^o>Qls%al)z zX_52J$;?TN0?nI3aeB+XRbizF`b!C>&z@?~OlQwb)p5w1SnLb20g&oP8~ zwtCzpR`$GTg;;o^M{V{BQyqla5YpDbC+8sEl-@4;=IenvlKp~bQXMIv5&8XklGNR> zEk^5j?o9d9qRgr3dQ4Jgh4xO?n8&?lr`LGByH|sNloU!V2E}ZD4O`^Eb*FllUYgUO z@%o^ePp@;{&FDh*z_*jvV1X0$tL6sEWh!PbWBPW6Mw?{p!JPE-O0g&4msIcLc8%D5 z@(1rw%qu%cy0`*a|L#Q@Ogh|VE|)keRPfJ&k_TNZ4ewG|wzqX9s|z=c`a05RuV>wP z(Je3|D`qLeRtuOvk9f800XNRe`J%0H01q6kdtF1$Qp=hd&&&R-8P|t{lQNd?BsXN3 zhco1X=s1KLDUxv&I%P`ih$;5EC>LrVAuo5!J9n?BhsQ3xH1#hx)&6w7BU)?&KZ|Iz z6ic1;DrNfb+N0_W9k^}ZYGVNQT^&p^w(F&}r+5tHYoJl=yw{ruBa<`3oaa4|!*Zu> zTxd$+)a7sO5To6Lu)oX+ujnV)Y5a+c!D3diE8n?jHskT(5*= z?4{#`uVfsj6C|Q*1<4=Z2o{rEYeJr^)`ksE`;&14CG6Z8{Z7>FmTD;)0YyjmzQ$8V z4f9VgM;r`23JQ#$*Q=URU3)zrmT%((WJZYyPD&?8r$|x@!{#u7%s|>Ir|B^*PUJmLD-u(D}QKC6!3>j@w^__HzNIV6gz;OuI} zD2}EY{ysKeItKo^M z!vV6BnCbJunn5MtppiZhx$77bN;ViTFJ;ngYx{Z#+pq?IJxc&Ad>B-A#L{twIX6Jl z8w-Da)V%#vhb!dCbT+yr)q7706xS(~8pI1h!Gd7`iuy-?pIFf|HaDx-c4oWN$rYNJ zmB+BX9ivP8AE&!0FJfl5vL?4k_Nn!;g9CF-a=aDYu83w$yL>bqto?^gLT8oq=>HnQ z-wNDy2Id9p4((KoqO83F_5G!`_iB7v$N=?y@%`tY=QMHJU+nGBR+&LkU!q1K_S4&i zo5YW^im}-AqULSug2LJe{#OGbSCEiJp6#8>}(%ouIHl7%| zzKe}rHEZ|y5g3tb)r$lPPRCYFcbsN$1)!-|mN56Uh~}B4Rb!`)gj*TS4h#Q|vcu*d zj9hVULcK85(Vw+x!9~MY{EiL1Le!ajpg@x!P7ULOHT{KCRm|AX4Mf1FM} zox=ctd0B#3e7X4UKlnJZY^uXPm)SL~yu5%^qNjyioRfrv1yn11VVP~+Ibt}ND!jJ* zN8h94>OjTfa$&_sBivzGuxr9HYsjvW$j3G5Qw7NS@(-(6dLfG*$%^P%(|}9#md|vw zFbVG`Gp2o)eBFGnJblJ6^h%jf`Iin6#QPe@ubo_NeyoAjp!m|Ieq=rCCp>ZBc=k}e z_uHTv!)`kATbVabX~QV>^mj-^tYN4>4VV;ddhvt2OM2e#w!qM2#!%F6X?FV~FceKp ze|^NPGDNoz`9#8C@1XDej|{No;b8qp2~>eh=2@dUf%RU4dz&{@2o9`04x0IUZbq7AoA_>TB^{;ab*ID*pZPe}I3z z(^St`b2BlGutgHhk3-S5rA+Tfe=K^I6m5i~*R5wg_oSZ3(p*-kNIP*|Kaw-XDD{^v z8s%|60kRV5K;zG_#}=iV8Ito_pF9*3tc$WAq3>^IKUAVBQbnp)TFz=j`nXnbIbAH0 zWhUA0h}t;$T`|P8P;k#*n+q_U2I}3F8uYTPq<5Y}sVR1Z2w({H%Hl75x4jm*a2qPE zi9hW;p?DkZT1~XR17NFD89%>{w{D#7f*PnjLPu!3l1dR6 zKd-{k1MALm_epoN0_s_f{OPD;>0$!FrtmPk&Fu#JrCGy7)g>XI2n-esFy6a|9FE0= zHkB^@y{IFHBmw~}+Y$P94L5>I2u=OP>PC7HE!#ZpU)>PM|2zWxVJOCl5s;N^eu?ZP zA@zR}NRp`}`R2tec>D_Upi3;A=WtJoCegBJGd)^FFG4hEJM^IJgOZqyUNbtQvz7|% zgw~0YqwdJ*x+Z)8{K3O`(!V;b(E)ff%G-QMcjB7aj6a~8$oBMTmm#a|2lqH%ysEuV z{CK;%%39&dx@oxxBjSAP&x~y1@YGas^4?3yId{;rI=QL9)&?KB_d;p|& zdW-RD*Dj`0oo?P&BNKxEs1BRGK=vrT>H28tXi)qpw{#SicCL40I6oli>E-SNg2@F# zWV=FGr-bta+8)nu2RhCb1gh0XUeR&Qg4`zx_W!&Z`Xr%(PnTX%a8Y1=6EIbry z#OKuPgVCCUYmoHj!)3i4vY`!uKJQtL^Dui(8edGA5XqZYk`(1p{YvAa`#Zfs1;FyH zI4mo__C+^)`5LuK^A-~&DXF6R3T3yqJ@i#(vxj@4xLRw)^L!%g$swc%LhTp1R2acC zrX)|Z+BXl(5O%*YdwJU>Na?bSX9V4Ej{~!n%A1Bfdo^>hy`gj6M(2fZNo9=6hfFMx z^!#c_L981i$UJT{x|g^z`}9DlQZB+ni@{{zh&v)*ItK()DJ;4Wo;YfuCqk(ZDmbd| zAIp5id7-FdojNPeMcY=rwBJACtQjsI5(6Fa-`d}9)_C|wv&KqVpKWOboRdyG$Jsg; zsO?a8vjb%`Ac~~1MD8l}G|$LlLHDTwzXpNpiO7NK-Dj6a(IBd%!3_&Yy#e{mFDgUTFUwUA_U${_v}S~kLuv6UUkIWH2j`nM=`6nf z59DZjRFaO7JI4erZQy;KlxdT}^gGv;)%^L$Txv0*UMJTB-f@)Na*dyL;On0Kv61w5 zA6J9tJN5tHYxlzEeUVT2XGt<8l{3|pHZ)k~eGsaIs0rnV4o-I`_i^eyUV43=em2v= zMI#d|gj3J<2P1lcAFlXIXtbJ5skSpc?VPQp56{X z(x{sgO+z@~ju<}sq-K0K$dTNtd1SFk<<|}_{lpan*Y!vG;<>_tZjz*e02yjzGC)~M zf<~3c&wDZ({d9M=r;n8dmWoGHP}^e!I<_qnMzqSw;Px_AN`_BkNKE zHW4yFl{M?Cra0t9l^n%H%KJEf(wHVyn<&ql*R*$~+XkYu=BJirj`^nU)h*h@H?ewD zDPGffbp1=?uk9Bfy-1-6%CH_=$Uyd#IHoo4d#cv*LzzR|?;YigR<6+QL>VH9(H)0)d1S@kUo zX|wXD4h8{9yQWB?=KIHdzg@_1McI=5o8os zpmcWk&wm*`Q+K0&bKGd-uo{;gJUF1sXi5#K)Y0iepx(3*?nLKr2c%zy&O2~hlB4yU z0$;VoXj4DVPBOHVnAW6u{rM{^7QQ9ZyX>vClouMsG+c%Ug4yXFDsBDiKygtK1R=?VF0tr&yqaY8II8R3bgs?s5!l}oY0 zS5!pkwt8JXSZ>+WMA37ie$I2rC$4xBmTQ*hOkp!ol`H(JMCP74VR-*a!&u_IT1#@iMR@upqs;Rs`&lx^()0d2h<7ZNMY&FBn*PJP ze&OrfXPUFJd`-}im3)gUC58?va)7{M)jHB{6%>K?ak^lH_7dkW1P>6M@EP!K0?uAP zj#wRAvkcBTeQ;bJ0WeD3YtD*~Egp)9_Y*L5htBUAEc?I>44Pb)r1O$ z#`2Apj~RRLYBa|`+wuKeX2FsdgF^pGbs4z(WxRs+xE>mZs2LoN2U*R$m^CT2++=ioANMAr?^|(MfA-A{fX~jTdDr7(K8E#6>j&Ce zQlnMm(B_nX48?bl3<;p;xEK+VZ8ilqS<4!gVI&x=tOjc~R3=9oJ`NB~=f!jqZ zRHvG*Nm#BQ>AHa6N_HC_2*bb-{-GYAq>s#Pn?R+sSurX%BF3Bjw{^vsQ-nV}YBrOB zRoaUNBspoGk_SeT{%HOUQYfEcZ4R|i3NfD`h&3EmLqwH~yz$B8GT(AlVI%sqGeLHU z$|aYAT7Iq0{a7M`v-hA@M7nv%hPz``vV-I;+9p?IINA)Bd3GHSsNTY&$9T*=AnT=+IrVM2ex}7jb8cDZEnW z-`{`$liV)|y*PdCq%P+n3WYYTcYdUcu9UBVMS#CWm7>u0&=V@I4u%1zEAaz{6vqp2 zenWliPDrMZdn;0TeAiV5@#3Ork`EQYkJoY|etk6t5a{yZ4hQ5#>CHzs`DzhLlK9fMdPOfju?^UQ6xJ%Tahxf)8iV#sif&XT zz1G0_0P;giO|;x0!)%7FV!z|%8MIzEzE%lEI}&@y<}~7{5*U}}t$i@jGPiC&!=PtOOemN)Q$VyCbKi{cs^T~F{f?dY9d2FTR2(f7tIv#W9}1zrxPymG z?e66@ZD`uh#R%2?Q+nk+$LCpm_{g)%gB8*#SGEUN40T*`UeY4t7nYukpcAENZ|KLecL5AR4pYPoi@_tM( zQ{l$14#wWA8_NS1n;sOR?98^38{;KD)!9V3A{;&tj+b`@x_H-)6}Xe$#}o4n8>8dT ztO^2>vj|jLsM=Wi?k3N_h>a$D8+Vs=kpZX~*L*oll^FbM!BL_qdE-;ub#7&$5JE}_ zrl#V=;$AxQJACPUgQuCzvejUd4WDfuY%!DBQpLDI%reeNBSpD0*Ec&ZUI zS4sw?HIy7UQT3agW>qGegpAxzGV_IQk!neUVkFGGx(AmqZckeKyI?P*@mm0A5+i(qRFF@ddZb#|uo&f;2qEL*RQjdVakBDCNAUN6}_ z!NC2aqulH4cdcHaKih}-n;c>`{DJcQc4)RE9j}(S?G$js^o!aWA&e`^dMDcH&94uQ z1wtkG{aA!|Go$jzb)m<`=U6F(pHpC#$v_kfw@udgreS>IyX1kh^RZQ3*UVGh?o3uo z6~0PGZX->JNn>fy!}?HP5jK}7dbw?@+R$pR;iF^W7K!6RunJ%8AC%2O75}1JdoDDhaN6cTOaTcUtdK!|7!|BxUcrI z24S!qLgk^}jo&5z91jZRZqtaGc5zsnSFT3sA0qZ!7ueOPC1rnAy+PK6dc2D`<+{Ep z>2SqZ%QO(_R&jL{+h|eo)xy)~q$FUxXso&(F#xwt&-bNmoiHp~ug}sd4@~NFyyC5J zEZck15XtM?-Il_Q^3#j8A;_#pn)m2^G3a-v;T9NL1kb3j6K`Ob7DCBe;9dW)0m*e` z%{8Po9@k!d&h?Qq$5pT4L&&DZwlsFBQ0JSJz6 z+6|m22M~wqfMBQZdcn&uTB2;1`LYtap_2u&AC>oI3O~FTpF~=J;P8B`14uT!G0*uIKEFINmyp>K3b1qw2tkV)m zBMbRL+Mj%-XvEJd-k`tgm>J~;@hgo%ISEFw(bad4sQ_k(XFS}rD{f%*zVY|be}cPo zi@)h8N{H;{g(rEoN2Il{)*OtDCuRAJ@w^UOJ^n=ndGerqe$HKoK8=Z`AYAtPp-Yc- z0D`uZYHmlJ)6U@ruHzu6^Gce$MIYx9;m($jn*BHY-TlyW^Erd4w|1ZfDmu@|PRY~6 z%-EDDPpuGf*upt&Nn?~}FvYj3k~Hea2rl;WCcUt8#_Q!PI#3A8h!IWZ71FgsY^xg~ z%`vxMEGyQdv=?M}%-(<$pKHB1gG2Z2XF5OP0FdrdV@@^W|+4 zYE{j+z4xFeoo0cY)T&H=DDmCOjHFPZX*Jia>3lSm+(d!%8nt(DeP+6R?D<&`-H6a8 z@O3)ce`MPcuUUs;wvCQpUusi4_Qu4ra=AKUP#Yk2JlR9Hlg#!y8ECj|#A`u+X3J^n zy?0Sf>Cv{@JD7Qi043|Fs|4)zdX+vJ+2#H!-QF!>yx<%T$9>`Un#neNV}|xo1P@1O znsLbs$O8miF|eE4*7#Ur<-`V|`pX%%3OZ~~*0_gIw_*#5FV<;0mT7ug>DSU$o9;5;^ep;n z)S-|nE^BfRdh$XgHll5qrW=i^kzxn8-w@X6ZZ&I9KpBxggE;(8qayve8N>tvSP~ghiMW{$S zk&<1ei=pxi_s;l({#c=ALGwmepre5ES#^qNw9_#<6>z_~I^&bEK_Rh3hSM`>jza60 z?g!_?+Ob_7OeI|gToIdY+3B(_xLpgeu^y`4@)VOgEwiJ4$LE6eV9QyZ?#)iCNk4#0 zCUm#pL#}2U{yNH9Y*j?Eq>QOhUg#16L5U8r3qk<6@wxI`^_ z??0hnCz){i#_JDCW*Qs)Ac74Oxst|_TkulM!>|b{kj5+*SCecIaG4aIYw%}_UzCaC zCMO$tm~!h%rXHVp2BSHyrMNOPQN)Q|1G8p-p6Ox=C_MR^%=N@BZd}_%p09u{iaKIL zg~{fMK^N5x^qg+uqH=#kzW)iVZa-vKdn4#2s3nj;q{Fl92=+qwj&B*?BxduSaoWi8 z*8R-%@GrB1y|O4`4k0xQeKfKL5HPZuSgxjaM6i3eTZLo1g=T%?x?CG#pUy#qVJLIf zw@asJ+xUKVW~t=ZTVjRlok^Ry4P^%=ftvEE%~olg+e~u_6$_7-vG=r|6I`0|jBl++ z>yE7S;T?07G>3xXcmJq<>Yq_xdv4V4nwZAwCU`>Mb*Jlq7N`=#8DW6$Coe+qeD5-C4SxK2Wxg&wQAJg1%@aXw6zJrCxxXv?%e}rZf-&a3D0Zd z$2wM{>$dmJ|GP$WM8(01Q%`XXd^lZ&Fpztrn8+RIrD4pNdFb5s5~VG#yrB0qFL~a( z27B8q42lBv>zckW-Zu$);Sr5nv+!|zGL!jbJ|8u*S9mK=be3Ghtm!cFE>_P+cn7k} zhte#$8+Pzv`gWmf;0<@ov;DvC@SDTCs{zKlv7fzl^s6`;#Wu~!l*ilN{ol_%kQE#u z-rdm}mG(+*$DG6VERQ5|g_vZ7U%I?;a%dBLS4F#DNJzW=W2W?Gbb z%Tq8w57yhWZ@zbA>TepqduDkeL*HMh5SO{ymwaVk@%a+N8i&*|*TM!ORcr9c%{KVL zH>1^QpU4%j_ssTt>l2N;>g^oH9sNIrhhHl!%OihYXfOL8lUBz?p9$5s_-Jl!g3j=4 z%eRq{M}9lzwg8{4hY6>pb8R*s3_uu{e;aK$B=7^T?dZR?3kY5itKS%RH1i|3PU%c{ z_R6SN4=)5VxE|}P{4$gEST7oWw>i0=WTR;pdLWi|a(bi5{)!0_?reKdIL;Fl+I@G^ zGPS|Wv40^F6hx39Q9{te5g7;O&FQFTMjHq|Ly+U+k1gA5Yg?ZB<;{Swux#pR zHa^t^j29_DZ->*P(_mYNO+^&1p0mW#ZmB*G@^e!$G>sWBgGDs6EoFBrLc$rjUt@n8 zt_4*L&PBfudQA)jd_l>+1x)K4YCPVoMd_FerA!-+Lti4oV#TWS%V6B_xAkq5C@L~5 z&|l?!8zcbq&i!Cl?i?%d_xiVJbkY;bpHK!ih9R_km%!rg?&#)o_5t*>G$pN?OB1>B z-_Pu)1C8H7*}_r4YTrS3^L(G%H}^)bBc(o_zhzgvy*rUJ=FNXZOq&ZGHf!*W64@^g zDk5Z?KlcXFPQd;&X+uBUcPp>r1 z)#D2sPl|;fElkaH8g?a1#J*X}@+ASm)8^G-{R#DyQlKth!hXkur?iV-wip9go7kMQ zT~-S5PKyyO_1fb6rrifOFsAClYVj=#km7+1gLABYR5sKX6*jKe0TB=*S^( zUm5z9SlD_l)~N&NZLSU7l4S?v2VD{#o+vcn_kLp=lrX$?iV@dO)fC1`M`P>G;u!+u zBJ@wWB$ddUs}}^`tOVf%_2Ib5bes$w9cVf^-gGX7C%G$_DfpMBBUhX!l`AL@VY|i2 zP&+0azN@u7aLaY()YCGt>fVc~Jdfdld|hLAkbQR0J;IGHPu_2`K@)#ZkVa9$Hg1rV z`Fhyh3!y4}BHCjw-4zqD-z2t3cK$M3_E3x0Ovs7EeErjC+u z%)DQJ7lNGBT=yoAnk0-^ivPeh_|*}=Am@<*ML##C}(y`zPOZ=$^snZmN; zCxi6^E(Mu?6tWUaXW62k1`IYf_Ij? z$YW0c!HJjH(t4!+bNw>&Q0seq2bb2Gk|IH}$6UqyFWOGtT5IFUICq?p(b(Q;xiH8g zydBft#Aa}W*i*;!kf}g{)w!JaOx3qAiae&NvgCW)6aJ;2)tF*c zZcpH8zbp&ds8DFNV*2x=I-e_e_0O!cR$RJl@)1j6+-fZi_NOxcb#6*+SfKPUq|w)^ zJ&TLLu&rZf4-{kG-q$^$x*y5l2$0=R9P4Xs$ydD8Ux_W20Ua9G{!veMd|(tvR{uG@ z3#w>*s(XKYiZNN5Cp(}N7RV7r!&Am>#C`*uG=3#&+JvFW%T_p+S-Vmu#`@#H*?*@0 z4(L(0UQUxNzkPA9+Z4cp2D6P%p+C-o79zzbUoB}bWRp{FsyK}L`{bh-KjMAt`SqI=G z`IjGi56dqLZCqo8r#GpT*`I2LVUzu3Cs!xWoF!w-Am{VVpZuJVh-U{b*xrh;QZJ0A zQZ!D0aemfcR^k$;cs}Nft<-*EJljvAV)@o$v?zzYhpr%xJP`-TQx{ zb+^Egz1WU_!O8z14GE#{+lJ3iuIQ^JwSEV`bbYR@?ojuDM{~)6N-Jo4s)4pHzxJ!L z0(X%UmvnR=Up{Yi?c_L$=GA^u{VVAii)UC-%*n5Lt1^H7u;!bLw^K~xkVv`|2p4}? z)W~m5TrKdRy^pIydWutz!K$Qi&x@$1^4(y5=ovzCv%%@iXS<_rKjID#IbtC;S;pi{ z)$ylTR7|DycJ$Z%v^rmoq9(X9>zvmd@HB<4C zWqwyZr$}Y8M}TEt`$lazujCLZgTH|`t)Q|OM_Q=XzKXTEw-op>JU^imaARcV)JNZK zK!N@3<9J6UZO;=6iB;2%HrI@z`V6ngg3axO3lBPMy7$SiKiv(W#U6PYN6%pdH%-xJ){g~e;(hi8*FJ!M((Tsd+Wzn;E-1E zqh?s~2ed~i^yRUx!p>KL;c~v5N7oWS8sx9TStHGzk9Ikp-viEAOPcpSS_pqsd;+7G zas9Bq_0WrBY|Mx8rZ!CxnFG62sZR&dx}$gNf#U;?mlyk4q53pxV5jp)j+bZYa*tN; z6VgSTVJJQqRRfnA!a*GTsBx8GJ7IAud;etT`L7o@ba2{8pzqYq?m1@~LvbPT3<@z3YpGSkhu`pc@^t7j&19dmMGXMWzhA6rI8kc#=eMS>HqIdrd);FxT zDmKZm+p+w>FCHe!HD{*Q=9-q*kPKtC_J3eUbyshoBZom`^>5uw!RE4)82xKSEE$O) zi}Pu;9rYrR&@qcJb5Yri@DoMgycJ-M z#rW^&++<0;;Ln&jJstJB8BfDo2AtZ0AO|<|R_~u&2u#TK=5cQ+gzZ23koxbWVCu!Q z3b*Ny)4g3RSx@nq%bv=K{<87yLNIPSGX4`|@yQDPfvam9sE?7IvrQ$a*sf> zRVAD0PUMmm569-HrRq|kQ5DKsfvl}0l{@fo+WuQ6i4+}*@sN7T`Cos)cU7c&t}S4O z1LD%1p8=`Nt4CpZ)>?8DMbc*E4f-eJaT(PHbuxH`Wq0$1s`CP|2Ise@k8vc{4Y(F>Ws&B{h$7DfY-$< zs|U;WvSm13dtw==OZU|>6;}nx!;lFVsU7zsKhpsAcLL1XQAMOVq2V=^mn+HU0i~hx zoJsi*T4E|^mY|3%outt$jBi%kJKv#Tk(g8AAS?x6ga zE=@Fst6gOGhA^W?tM!M}qt${&nw?MH)jW5kyOn-i7@}L2>vD1d`@2&7O}Bb6nFIx{ z_(Ey_<#ArG8acjG6SL6W;MEWk%G1lwfjbM8Q~XK5Kplt+?eotr(}9k~(lbS_+@lat z+KI=zk249@`3n>mHU$?!kk9C+6V(V{yN}d`(pb<7(KM>r;3&;o*sA+C_EKMBxY8;B z;xCOnznH3K7QXmE#1>pUA3b_JPnX5}bzXg3gx>L@*30g` z^lz7(xKLb%rXl7dnNwP%b?CzXh_jL>KACW7=2kcqhY?+<_eSy8tiI(Ok&ErfW~g5b#JbVMGDp zUG}3L;TdD`QmYpq&#jiLRqW>v2EtipGF{&WObmB)i|Ynh906h&#lLz>*KP!~>?jgq z#JGZ3XnZ{iaP2Q3p^((i3RrhS$I@UDA+Sx-V$Q|eNb&V9sF!R8|L@wD7JHqS%zI5t zOO4S$4I?Mz;#>GEzIjl9;|6niMk0Lu^Cq37dnHb zaK{aPTpb{;TKuQ>Lyh{;MTxm5+ACkx;tok&-aoVIDD!A?o?iho8#WjDiJBS=t(k9?|JprY;`TV=0Kne7og3C~f2f+Aa0}?;1#*+*nFKhzAdm z{hKS+Q~Rw@iD4j_K}83i7f+z(u772 z=gB*Db$1bQq3cjSgnx4eSVCSrygKZJ3)PXW55pR4eV^{J%yb6}^^%=Hz|d*B4r}J= zsf`5TsCy3uYqT!G`}>SrBDj5u`L18H!YT2c1^{&y0}bHlAWQQWjo7CR1W%_cULMQnO29KbW z9tep=I?s?Q#g;K|YCiQZ*>7ckR%%?hV=Cps*JsJq-e3jja4B7BZ}BZI*Ir_)@}ut} z=M&#GK^aC0a(u}Huipa`I{~}M@UB1$pp7d;IX0;+*z6;0dcPO3Temhk(Y>1sX=-*{ zZ~_O0K=w{b@a7m!bF*|ui(;9_E(5s`%$7scrzNM1V{rt(dQ}qDl(JaeoVI=)*87We z2XiaCzW93{S9OX#T=TS1k;APl0lTczw(gEh}Uo_ zaejwOcML6wUrB$}STAuto_&4ou-n%I$?jF&(P?hJ)!-GkJ3CjJA_8lKVBpEH3qRyu z&w*09F=dO`05i7u0yyHnG$g6r==Ha+*!6k&GrAif=|*$qTxD?e@P#r5BBFa)WOUOi zDRKI8rWWU4r{tNGa%|CtJsE;!d<5y2C7>q05Cb($WP9B4;yqhE|wb@_Kde(b_ zOiGAwydQk|?e{W|c=wpwKIbOU)v*kYY>54*@$wW_?M?kSKty%Ry|d9FZ`KY@P5C=j zF_hWW-tyi7QpIbjwd!)8E+-qyHxsrL^4D4<`-AyX|9Z%mW82NEYbPGe0M3&hV=)rY z$$6F(Q_4l3kGKZRKFt*B=6W&g8jWh5RHA<#WBIhg;(l2-uJh%u`j z=gjh5niO3V-kvBkbHJ0I%mw96kQq>N$-3>8@P!2K$59q-x3W&Hi|<^NNuwVf?uK7s z`w1X{|10>r@l@skxBzY)UTmvNQ#(_Zz4w;jM(i~eO= z2p-2?6LV_D_qW6Fu^U?hE$Earo8xkgCD$-ORFI}Ds>oHM)Q(44Xe{y8nPXVu z)$;BN_#{&6cJ)BNuf*b0BwBWhF5mm3ctr`a%0jBY|4=a11QJ2#*POO;0+nkRw-rX5 z`h7YopJ@&F)f5%3uNo|rKv?)b(|YwxM;8;+FA(mS%fZ-?eP>(2^;ap6Xk)5}GL1SD zg8)FiJi$6*FD7bK?EBLSQ!7X9{m5-bXN;r0w{I;aX5nVO6{;p?n8nDasH`nt241nQ zK9h7NQ|8kUYIn^h-v`d0_mFYvv}z>5-@TSY0V{(WV(iN4Z<=*B+G)Z9gO{zq-N21= zqecxb|1Vu0#@&X6dwV1iv#rI0AoVAnGszsbB1{)tag%;w-P68dzb}u5&mu1qJnoc(RnR*kW=XJ}`uqo!kn}@-}@S~L^ z)5}@TareTz7lPdk?hH;adY$vCA*hV`?GeEHm;h|jl&s9%n7!j2E{>=FU5haEl!XSl zgXA4%L~{j0ekk3v)=d8I+VzW}oIVp05Ccb+Tfsj0sS9u?oJM8EY8?jZF<6>AQF&pS zld29mQKQx!rA|JwrM!hHu9KE~yP%|{mZ=2I@gsg$o+cwlbuC=3!l1aHaejDnUi>u4 z)!VH=;|FqAIV(e#l-s4GO1QDz2`Ckx;_Paj=?YkHC;fK~*p__CWN>?NHI+bKQJ=Vt z25~P5Aam;Ho__mMJN>6g%HF-?;&J*sSNg~Ay#8M9lS;-+mkCR{Gi(H7D+?M(nfXC5 z?cU%CjXn!vEyk~^I#FKVEIlTyphxyhcD>oZcBcsb_@6LJk;dsxH1yv-o0PrK|8aEQ z@ocwm8`f&8rRq_&N2*q9*4}j4Ma|f$En>wU!PBa}ilTOF6QTBsXlvC7wGv{--mydQ zy!pL<`Y%4YbAOZTJg(!!H6m@RwM6TsTs5th5snJ5y2g?CiU(TW2wl2|n;1#D<8Wjn zTKAhS{3S2+yXS9YJYFp35?Vy8Wbq{h@zrI#pxNILnnyjd(H3?$-M;b>+m{GtGbtx! zgh-l|sT)*g&;LgOEg+0{!QoxJ_j~wbhk0}VnvU0WchY{W$-52bRy=hfxQ}EZH8Eysjc=esVe}D zYroiXIr9b`d*?culjOz&jz(eAgJ!d@JwsSBOcIzV)5h9qje45dl#A)7USZiY_iwZS zvxsTG*-k%-oKV`I?yDG(@@5~`I1t=4$kpCjyp5JYSt>3U`1*ue#$~j}o74R>&c^ch z1j8g0#yXsQuySgL!ha87g!3%6hV=zh#f>+F%Em6$=wf##5qY83J_DF;%;!1vfi2d% zzgTKyu{#S((ed9=5j^@W@+pe;vItTPW^;&O=HdaHhsnF zLnivxNc*uI=)?05kxb3dxtTtxP+kgx3sQBXYOr@6GQME6h67J0$NQ{=_?6lWaxf*- zy-y%NhD(Ws>}!Vs?rCy8swQK+9i~@H=h51?yl`vqvJoF%nKM(gSJ~G|lr7ODl-Z_0 z8)-d_(|Z8v{f`11K7H1m{h&rR=2Ee8w$CfbM<)HlS+NzEIcb&@QqB+i<)$NlS;j3yt&R6=;x}}>x(9%6CA0#3aU*bF7&Fs#M z$gjb-3@lcp{vXrFaTG|l@HblDH ztCU8Nl>HkEvk+l+Qw<6g%Im-ipyZvNd|6o);8)X5GV~6qZ@C`-Byh1htLRkqQeiGq zZ~+v21P^Itaz`Hpvu(gss~RL=3%(O+KK4Cq-3ofyJzwwG9+EJCe+RZ6YDvmiLVuo? zt2`^iA>50v>2nQX&!W-yX9=2>8b@V~Tw;aZcCv}{r5nE|l;iOIaz zN4zjE71z(t7F@JK{MIxj3aib3eiofPHzAjc=9DzV{6QOj*D_)C`W5AJQ(aO0(TQrF zdYywT2Q^Jap2k@l$v7!TV?d4KMJglc>)D2@$FDZ%I~&+YL;2h{*Oqm&YH0)pl+i(gZ$loO zv@X&@kLj2!tnT32dl!|3ifD|cCk++6{K)m?Q6+HNIF4*pNBF3qcTHiEcu-j;qUz))( zR99mt*Q+?Gh_H|oy(tOn#w2C1S^n|=kAj{8$lcFrom9}1|4*g?!HrKpHRq*WAlgp9 za%Ma1M(VKQpYeBNQyLGa2GMw>qmg3M(xpssRcX5y9A~R4LpG`4wPa z_>YBHQRjoyOBsxq%`jdo5h>Xs(rWA_o|5~S%BB>BA%Yi|2;055(ulRjZs2qEQO&`I z7NHTq{vAMMm}i%~2PMz4mHz{|f_eKwcyA_;wh}zm$B1Z|n>Xv5+IXt)W8x}bAgyyN z5ESoc{|){8dfWa^3)-l6+@`xfm->RPd!Zh1$;+0G#qHm2>*scq=M>^!IDJi+PkWqt z)NLik=kL_1caf*F<9xz~ojK4*BwBWXaLywwPPn-n%8-iYruwmeXGg0QoI8T6!ng>4 zNCW#EQ}de-B+@mE4#@0xyS&VwzjKVsw`o-?RU3Ix_7`a+L!C9Rit?A-S2Mi}ugL{B zJtMQt>9NO*Sk=CTC>-!Icq5~Zkuzv5hi>=7(hN9V1SSjF2{1UZfCSZizJ}|sv` zmzr#p{f|NumHL+8L*`Fn8|}<9=I}X4n{J1g!S}Xk?F*Xgj!ij{&wh7W2f9~$+VrvCG zi}Y>^R$GtR4|DJH@$PMPeP<%5-jIXT%a%`f4Gdb!sLiVh{d2OI=IjFNq8g9`{x;BBY8KrcKlKV0%a4xG1jf)>O3zYOtCJtm2eq3#(XMz zJ#ZT}#*@6Y?j|ZkYnog8upO!^JySLtT0uDLWxAFpY-y8QgNGEt69Wr&#R(6W*4;rm z>c8`bV^m85_q+6Q0>;Epe9NAF07TYyO|9TdO)!b)XZSzIopC5motz*Z$1II3<}!f;#lB1~BrOrj`!EOT9qOk`ld;hnh{|Z+jBCx2N33sQKw$**!ZtoV` znP);leE|-Je*OAIb(nLky3iVV947g$agrC(lj0QfS%PlR=C&KkR}c>7409G0Ene31 z>Mnbx=sj3x{h)W;DC$&#Cq>^|^6i8h`Av2|El3X)8j*sWH^5J5xvA-fLLs9&dn$7- zsg&uxF17gBGK)kNUV3tG*JlljQvfA|aQT){m92Yj+7=n^yIy@e=$YR;6;KBdDN^0P zgtlWX@{qlMglp=WT*+ux9!^m9(1O&@ddB!ZlcKe;4Dv3O2tKQo5NjAHV^d%ZS9_g$R8rw=#H2m&&p3xgun% z0V_fW5w8E&cJ@evt%i^QwJBv5JJrv3JAIzzS(mA-#ZeQ1;?(+&;%?_@SQT0NN*#=E zJf{0}p%;JDN8vQ=tq!%?j}3R}5YTY4^lmnMO6riWkvmY`rK*CEP=oFIR^&ayT?>8s zsIs-ulDDQzsXBO-=Y^i+(jB4%%-d!WYQqdBgQ{6|kWq%0y# z+y(Wt$qcu3*GbvXl$9R^9F@u$gqMiV)Ws^8#={<9Pn10rV;oYkU@AdKU6P}qg4P_@ zFcp2Q&5lv3O2yrmSw3aIfoMcI*nixjad7?RCH6EE|q(fvVwrE;U_NVpD){k~WDsxTQCrR6^ zyvOj3B#H9RtoGGo^V7BWE!t43Qi)NF62s3MuzN-R?)p@BVb6Gcy1BStvTNKsZ)3=B z9Mqtetgov+THtimqP%02yIfH|dw*|k3>D6rP!Urgb-i3Eu4!YSird{amQH5Cxfpn~ zq{_|w5J)ovJX8^|AgcGIJIr}$P%A_F7EF%|Pl}!D5F#@PMk9JybwHD6>p$B>1Qm7Froty;{wi)?aUwG9w+qVHDW5 zJe(sACJ=7y>$SCb{`0oUKfI+r8UEnpV&43>yvJ=(Z7^!zG%P3yFYNz}bX2z!ZQ}~e z7oSi;GyD;;C++B4xK9kShdXa>w<{^e`CT2v0^g4H4Rt-#R<+>uCCvS3Xy$S}Ml#iu zBp92dEN#tAb>cvT`0l3DgfW|bEC;^Xw=+gIpT5=zDv;$p$56refg<_0S7_lfGxL$} zhzXi6uO<~;u?3R!dm}v>kVV5Nx#U?SCjju$Ki?I zx}`Z;nS*L4oDj6gZVsqTHWRTr-FIeuR=B2dVEr=*a2%>aIjouh{9yF)Fl%4)q~buv zp0hMK>BB)Y$u7WCxawJM?W43ysIHFT^XUr5giCZn+#v}b)k#jVfA-O7Krbe+bb#pH z@cQGE1)s-Ve}wV~Tn1=#KQSj9k(DgcI`U%TT9Ir)Lm-{BSQZzZ8M!(R212)gapGFzNnEu+$@8!M`R;{7~Koc zq)axw_%*Ai4A0Mj91{wl-uO*7i>+-pgM4H9kC2GEMuh}48CxKIS>=(6J0v!pLAi84 zDJ!#>rYz1Dif+a6TWNhIcXq%d@EK)znzFo{{>J3iW$EbZKoqHu+1>M2Qqw`Mq*KLQ zJ27g>&8;upolEw|zE1f(-$&7$lA3)5ou_+{$=@qPVU-3j-=WgQd4^!~0sq2~d(SZS z)bw5udvw}=6g7sL2Sl4W_rd*vaTOqP?(*|ZeS=+CM)`0?X9>=Uwe6rH#mMKsn72Gql~9c0D> zOE+fcWYg^F=0L9R735~R8Q60oR;PQ;G~WK*myO-KCG#IeYi<0;IZ55D;sX=x^e*sE zZS+3!X6A|;Vj-UrP zM0)mlrnlEvz*-(n*Afj#;eYQ_*bCLJY>J0+my&nR^|M06USjX$+!Eg`$0Zg1Dz^Xn zw*choj%c20cC|XhXQ_27}KXG1qv6S?g-6? z%6BA#f=Gk0@^6&ucXhz7ZMWRR!$~u(VO#mV@$8_+)`>_`uGZU_sK#9tjr(?{O5-&+ zx3oMM)FVhLBWIb0UWWnSUOTqya+>z`zy_m9dw0CR==v@)gCV^$*OroPoVxG}GaY`M zs2=w3$(<~FH>vV$(z~nG|7mzUwJCH0i^h1!r{tqZR|AZ23o4YRk&85-u%}!V{uzGvQb9R$(agd^y;e_G0RHUz) zR5>EQ;>}D$G@ccxUppjIOBhxh-&?nQnyEV;lvead)#4W4+>B)fS#~kU!y)yr@Arf- z_C(v{Gi<$=zLirR-$WQg-Qm*J$z_K=Y|Q*8in9qah&}QwT{TW_e?hHO@Zh&cb!SlE zY~*&_vnD3`hG@gd9AD?X@5hD38o$B`8oEq03vu(J;Noe{j?eaK7}T+kK#arT^3`On zbJ|}vqS*C4$`UR3rTKv&{2Yq-Dv^7_c-DA=ouS@rbD3d-@+3*x(A^LJgHowEQpt($ zTya*_ynYiP>mDw4>Yv+^T+{-<#8&{{B$%6DA1)D{IPk^D&g3ovA}Y7gvL6MsoiG%s zBbrVjqlZxi`N1E_>X#h0L_j3sta-ntbVDIKv_Z#_d8P&h{vRV$I542hHP=Y{@>3?= z0QZioB8#PIUd?`vd)w87^2Uu(TsSx)v|KjxrgwQDntxNtK<+<^44LN%52kN^QNI>P z4Ti1jM>pF&!=`cC8I)~qug+-v5BIzGB>Pa;1N37$S#(Y=fHK0WuU9M{qk0Rbz$Pu> zO<8w@_G88Z-pBgRNe8^WRE!%raQ@H`(!sE!ke+Li-hG)K=AYe1Zo0@Z&MWyl|EZ!f zb`qFubc8*vCN?@AXmk&Tcs{C)^03f5S*d#p`YQ8sH^1@18ow~@^Ai(xuLXkUn)Hxi z_=l2D7goPC5(%KKacfjN^XCA6d-^bie9U2KOFfo7ch$($=S(qfdRm z3#ku6t~IzxTri8YrIDTvnP)4WJET_e$M!#KMsvV`ULDSrg0}I~y_e%&yC8WY<*70u zxqE@uB8d6#W*xXw(MtU#SbjwMSR_FLG&K!oa?jyZ;EOCBxj-YGP-RhsmRx07>L#ea z>&U*wp92|5+StlU16>{CagdMj!|Nw4B<0S%s%1H+op81cNXh3!MO`cV=gPSTx4+>Ga=g?I2RWx8~H#{gv;Qn$h8;D<(x@%pRw7uDO z(_0;EZ+0mHUPJ%yPs#~4DH5Rm&P1d798Wkrv9+({_ARDC57h>-^UsH||50Gd7n^g; z{81gAqG-B-vV?I2-rZwkem-n(Ow_~&Q7*z5?ifI;46XcTb=x1N4s#ozR(# zR}!7Q^}_Fkco_?0+A?dchKi+Fd<#u`29oR!`j0|boUo^e(W_k=snqR>MehZGoywJsp~O{Zek1qxtV zGNRvM0E0)xF5~}7TFZV^q7+#}u)XQ?@goAMsUr{vdv9R9Hp=-)QWw!=$njP#P z1LG}eOyd$ttBR`&d_z0#zY!APg8NP9Ll2ynPU2lWdH<>WVe>s0I3h6YyF(reK{m)fFoccK5i3M(4GkQmQQLT2ohrrO|4Ag`uCj{u($icxLyZh(8-dr0R3i z!ilr=2+{6u56iOW2_h3|`LtQ{=hH1+U#_>l6DN7hy=c!OAKaNbrxMbgKh|^LR;Hvx)o|T%ZvQPz-I#z5e>~Js=U{HVRPY}qDX_K zISrcwz1j!ui-n^b*$MB|-1)vZX`~J6#(e9&pY)xD(dsS{m)e?~xdR0X+EJU3ef5IaOx|%nXzpmv=^uAL z>4DX05^vvz866B>-^;-d>eF`&Cp!wqKRYj^{KRN{KyHxX@%&S12G_}`3Ic^i4~O4I zi3S!d>UZma=mS;XT@PXln_KJS)^|p&7~|INiL6Y|-|Quahw>fheA|JU!d9fP ziDt`K`AU(HRPplQP};VK%fcj^sSP$==&*fzbNxtJXu0h2(HTCVSJ~bK=}G?uujKZ@mj=0M=mUPS54Rure$OUy{j@gEDE zz(1fLv2Ujx_zoY(xY-%4l90KVijIQC+bv#*RAmTRsWh#>OvdeYV2bu-b5?wa2_<_D z2AePiiAYfkm(?Nerv|IV`4{z5fb)mY+8`P4 zv%pk^hgR57?mk1rl6QJa|D)(m{f+U~g7Tz{_*jI=U46N9BwLZXAeF97;xiU?dsIWL zJexL?jN0@DZLRyZlWfp;ZEhQ?j{7*cF;N~L*t0r>weT$vqH^yBnvmSDM=fM~w%Mh} z8MD4{_9SW6_;A3Wl#8P83ZX32O^_?7l_oqVGZ4G>!eN-6#--DWy^uG;RUzy3~h zMvpn8+*qn?F8D7Mu9LdcT{^z|LM(bIF`vDQgX6)c0}xOeZ>h_+a>sE*`W#M@YOF3h z(C=Cv&*vp<-r52KYsR*EU^ND@fdD{GfcD#`;ina^ z&gB4sCLz0~ER1nY4hBDKl#cZ5@ekn7)9qq^m@P+GTyThZE_Kdx4)v!Mlz8DvPI|v1 zJXV{UZ?*?a+I!OO4phYhc%+QSWTlGO(PEN$LEuZHqp=Ud9v{*gIRxhM48DhbB3#GB&|Ta3VnYNMCvoz zV|kA}7v00Mx#bIv@(3ONL0v)U`T#VdN?^hmNh1-NlXXK-!zU@d@!p}X&d>}UxyLs% z>m0jO6R+}^Fd*gMd{p^N=;L~$8s0P3VkDm1p}jpFTXADVdh4w72Qapw9n7}K*dpA` zzcj*+JnQSEfaw!(ziPyGknPqp0YV=AHARW84>J<2E-C{Plvei|eG+ND43D-1Foq5G zSVR>-R>+mU@W;J#>v1?j=P%I1z%pIPprR!2U5W18_dw;4qFHkrt@|mRIrq5#<)n2- z-&5q|_?uP-p33RMMW3p))2`%{y5v9wQXw<_ z^DIPaxts0s>);36Gmm*nA!BenlXy!dR7>P?BqCqu<$$iui02bPQ{Jmh5x1h5`%04b zanUxDDkBPA_v7;urWZ{!atj=47483N$dwTi=zVTs?y?W%re|c2y*}}CvI3?~YPWYC z>4&;iU6Q`q)*&6QzBr@e7QS;_3y)t4l%lkb>M%-UiDybXZYJC3e z>`pMoCV4R@qKYOq)3stbn^bi~6EWZwFIECJNzcu(6zyAQv6!s&vw2dwkhABn{X+lj zoWD5c-W@ursb%VR&GOZDT?GmB8L$J!y2E(lE-0cmx0Lnz8Os`S#G1f(_Q{iNTi?m$ zsNJRJjXtXxGV*PKxLl8mL?5}A`5XKJ6~YJqycX_s3~@?+O_^o#drrfwV|+UIPTql- zVNws{F)2EY^OfOX2%e6qi3e2wCU}np-(LPLPHLtR$a!0z!fZiRFp5*CV9U?3cuNMg z+~Ld;sNyOYSP>9>O~qFThOt(bOswWmW;CQyJ=RXSs zuX8@zDH{5<_O&Y{L3F;iHOcVROGDN8M;JK{A6iEx&Q?xJD<#`} zx~$z5&0Bv}b?ZMvFb%dzfo2`WR{iq73w$xQznvq}h0X@H-BWF{?h^4Erg{}*wWV=C$ z;=1oEheBHtqFu7CUSkO9VBE^Tl&j_VxmnVDAXi zD8S!D;v_1fQ;SUI#mF&|ddO6zulVtLd{-G;ytzhMj)uPy-^!K{l>NOp8e+3WQ}(8P zgzLoaiJ{b@Z;#;tQ$|~Q=gMv+OJ-OH^n*;6I_O^+MKZJWnGS(we&$f@Q_rWRE&01*?uDuHdAR0L1g$BzfYk1D>spNSO-dwk?N-h--T*)Xt zGi!?n>_}TUI zwHz>QMdw*|eIFrp#DI)3&FhDg`gUkKRy27zu79UiHTG^>Rq;P zMoxqQa1B``qsJmA@cFxOn{KCb9PV;A8<(R8VoicfSbBuy|6O)X?~@*y{&QlR&T7JO zD$TjG;LtSRx0i6uXbSqryhk9z(IgE21L?eMHirHdy)G_y?BH6FG@8!ZKO(~~D{8%jb(}H(T&^qqk%{<--Vn@}IKV5K%@xn^-?C(b#pji8UFG4hU}u|Bz`szJx&-OCcio zRoiWfvCUl-h~;yx1}x_J00f`B66l7r0w&ZwC$nZ9c1rOZ+WB~R@6i132BeVV>6QQ8 zDaU~OBy7g15)SGC=0+(UC^gwwBi}k@J1$cxLh=s36Hef|zNV1=55KvBE`ZhtRKInX z*fAaA=R*ryy()W^iLebPx6cP!J~mJIIYnODHlEba?g9Pk1y z5|KXO9a#BtTDqxyq+&2v;IHM}Q~1$l^E}tVG4%JmZeof#kZNB&ILwSkc_6#`>40jZ z#Q7^vo4mb@%#*20a*s^CaC_ttwo6V^Pf*)rd1yQ$VM`^@sIlrB4u-JipN9iw6Jf$_ z>OWpTqwZ6BaN9{vyoRKbz5$|tV(p`rw8o*b+HY$UhKv%sRED2-s2d;!+D0#v7ocC3 z*)pR>OpcT^mir>Am2NCsGxy;H-I1f7+^vp!vO8WYfC1Fh!9s%6%E3tFNxb3=xG-OW zclxO?kD~cKPW1q;#>Ft+QEn_uHN;Z_-p8x^YdzN(aJ$p79rTGj9&o!fc+eW;>lbZ} zNqksk+Uj)c<~@Nm&cF-cI?OtH@W-V_+WJ@I>k?CjJQlT={U(0)j;va$e(J+ojZS|O zbsyDK*+f^vLYXmb$FiSi-!?Tr>(I1Mf{c{rLn4~AO5e|Ext=7728Id1H>dd<-~} zWun&Hw`q36pm^&Q{TtjM2?y)ZBF8W(x$}1FRSj0OTcYJ&lDaOh?&_Z^_=0?~{(ReK zgh4`|?sRS(?WV}ouHX6A8N_tw za5^(7E*PU48zwYO?CTNYPenNhe$eU_GVC% z>%^0NCd*%Lfn|$cSp6Q4%POfW+{gf?_?2c%=0tkxQseLO0tYdK;=U4T40V!V0w z&q&jm{p_hD^u6PdpyV8h>g8=9Lh9=+_M%i4;{XB1o-K>K`8qf!GJ2NM(uV8r9(O&B zpQL8z9DhBWwUN~9yyj=i_ev7QErVCF11fxOwyS1ha0CPq2JyoP0@ff& zCkW6#Y%ZvO|5DEBtCrtk`ih7vB>z$D=c?z`JAMcrgPu9oUOlmF#R3Bu+f`9Rcnk(| zpDgg6pJn{K46TmtQ@z(P!hw@Zy#@U2wbg=#J+25^L>oALSV?k_XAc3k!sxH6PAoYy z+KS!%0J?i&8#Q)Gw)d*Fx7R|xNXqG{jQoRga_(N3S^(Bfu<0sKe(#stf=Iq4@YgI^ ziao)Pd1eyh4nT&1p7_0Zd^vWo#d^ImUmgKIo>R3{m3S#};b5XKR$^e2CTQ-+hB{#d zaBe3NENVBO+@Db3JetLEE`vGIq2O>rbk{}xYMNg2{SXYSfI^DVJ^sEcU86U$v_?G% z>~La==JFwrY(R{G9%paT)4!JT^k18-w^gU{r&n29+?~#5rC#QQf^^7W30LNl&SXnt zB9mS>)Z!tLO0BgGT>PV1@=pNMiS(#2%IBkDaLu3144|R!GOM)TIY4xZTm;?uIY`Dx zqB%6Hy66q@UKQjm;>o#d(25=EBNLm)=bU%1sgsa#Ba_#>8}nRmb$u(T%A_X$Ag5C!YHpS4X6UJU*!D&Hlohj2l2#f+lj~CYy z;u&Il^^=5jHkVhT$u8kb7^6QB^W0bEwtvXgdhBsH-LIn&2t8=&7NwPEtf~un)Gu;s z0_F@kskz-Txi6hOZ)K&qo4;1MSh#0T1WLah^VAgLX!MCo))e9*S9ahS3^6o80)rOI z()thQx4BF5@o$^oPv%-e+yUu=6!7hBD@LISGKeBm`lLiZHa8$n$(=tBHYzr6Q+$RH zqu#EE$XweK6ilhQ2YH#}2EI8LAlzWe9Z8{LgG=W6+9Tg%|MK*A`k1(Ttp5?Ot9hLk zhjid2ndH#X4c6#1$?34A7BLGr*lt;Regk^QQulyp=3UP$MRr$wrXp)R2n)Yr2zB$J z{%pHa$y8=wd*A21iQ^xvj=Fo?LRj1~N_1UaIvKi@L`bS2&ySh~e9j~qC{GnL`xi;>w*^|dyyD9_-VhblBf zl47BvngQX3TS4aq58wY#+3yh@JW)

XDIoexAwvPx*<6v3|F*)K4e#%t4znzd+@+ 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 { testConfig('./configs/LegacyPathToTarkovV4'); }); + it('should validate the LegacyPathToTarkovV5 config', () => { + testConfig('./configs/LegacyPathToTarkovV5'); + }); + it('should validate the LinearPath config', () => { testConfig('./configs/LinearPath'); }); - it('should validate the NarcoticsConfig config', () => { - testConfig('./configs/NarcoticsConfig'); + it('should validate the OriginalNarcoticsConfig config', () => { + testConfig('./configs/OriginalNarcoticsConfig'); }); it('should validate the PathToTarkovReloaded config', () => { From 5c26cea068ff84e7fe54fc3f8c89f1b5d0f6b856 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:07:43 +0100 Subject: [PATCH 023/203] fix(config): integration with Legs trader --- configs/Default/config.json | 2 +- configs/OriginalNarcoticsConfig/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 86b91d71..e977ab15 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -476,7 +476,7 @@ }, "access_via": ["Outskirts"] }, - "Legs": { + "6748edbcb936f1098d4303e4": { "// mod integration for Legs the Trader": true, "// Gunsmith is available after extracting from Tunnel (shoreline map) or Lighthouse Tunnel (lighthouse map)": true, "disable_warning": true, diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index 710a2fb9..c8d4f1ee 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -475,7 +475,7 @@ }, "access_via": ["Outskirts"] }, - "Legs": { + "6748edbcb936f1098d4303e4": { "// mod integration for Legs the Trader": true, "// Gunsmith is available after extracting from Tunnel (shoreline map) or Lighthouse Tunnel (lighthouse map)": true, "disable_warning": true, From 15dba97d613dafd0bf066da8deeb3563d03fbfd5 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:10:51 +0100 Subject: [PATCH 024/203] fix(config): integration with Priscilu trader --- configs/Default/config.json | 2 +- configs/OriginalNarcoticsConfig/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index e977ab15..fa354adb 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -453,7 +453,7 @@ }, "heal_always_enabled": true }, - "Priscilu": { + "6748adca5c70634464b214a8": { "// mod integration for Priscilu": true, "// Priscilu is available after extracting from Outskirts (woods map)": true, "disable_warning": true, diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index c8d4f1ee..c722f71b 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -452,7 +452,7 @@ }, "heal_always_enabled": true }, - "Priscilu": { + "6748adca5c70634464b214a8": { "// mod integration for Priscilu": true, "// Priscilu is available after extracting from Outskirts (woods map)": true, "disable_warning": true, From e52bc4ceabc8ec382f9fc006e2b116161bd75a8b Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:18:31 +0100 Subject: [PATCH 025/203] style: apply prettier to utils.test.ts --- tests/utils.test.ts | 64 ++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 248ef2bc..40cc158f 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -1,32 +1,32 @@ -import { getPTTMongoId, isValidMongoId } from '../src/utils'; - -describe('PTT utils', () => { - describe('getPTTMongoId', () => { - it('should get a string of length 24', () => { - expect(getPTTMongoId('').length).toBe(24); - expect(getPTTMongoId('test').length).toBe(24); - }); - - it('should get a valid mongo id', () => { - const mongoId = getPTTMongoId('test'); - expect(isValidMongoId(mongoId)).toBe(true); - }); - - it('should check that ids are not equals for 2 different inputs data', () => { - const mongoId1 = getPTTMongoId('test1'); - const mongoId2 = getPTTMongoId('test2'); - expect(mongoId1).not.toBe(mongoId2); - }); - - it('should check that the function is pure', () => { - expect(getPTTMongoId('test')).toBe(getPTTMongoId('test')); - expect(getPTTMongoId('test1')).toBe(getPTTMongoId('test1')); - expect(getPTTMongoId('test2')).toBe(getPTTMongoId('test2')); - expect(getPTTMongoId('test3')).toBe(getPTTMongoId('test3')); - }); - - it('should check that the id start with "PTT" preefix', () => { - expect(getPTTMongoId('test').startsWith('deadbeef')).toBe(true); - }); - }); -}); +import { getPTTMongoId, isValidMongoId } from '../src/utils'; + +describe('PTT utils', () => { + describe('getPTTMongoId', () => { + it('should get a string of length 24', () => { + expect(getPTTMongoId('').length).toBe(24); + expect(getPTTMongoId('test').length).toBe(24); + }); + + it('should get a valid mongo id', () => { + const mongoId = getPTTMongoId('test'); + expect(isValidMongoId(mongoId)).toBe(true); + }); + + it('should check that ids are not equals for 2 different inputs data', () => { + const mongoId1 = getPTTMongoId('test1'); + const mongoId2 = getPTTMongoId('test2'); + expect(mongoId1).not.toBe(mongoId2); + }); + + it('should check that the function is pure', () => { + expect(getPTTMongoId('test')).toBe(getPTTMongoId('test')); + expect(getPTTMongoId('test1')).toBe(getPTTMongoId('test1')); + expect(getPTTMongoId('test2')).toBe(getPTTMongoId('test2')); + expect(getPTTMongoId('test3')).toBe(getPTTMongoId('test3')); + }); + + it('should check that the id start with "PTT" preefix', () => { + expect(getPTTMongoId('test').startsWith('deadbeef')).toBe(true); + }); + }); +}); From 18b22f81c473204cee06457d97bad3754d271db2 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:31:16 +0100 Subject: [PATCH 026/203] 6.0.0-rc.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 83c5a484..b180b820 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "path-to-tarkov", - "version": "5.3.3", + "version": "6.0.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "path-to-tarkov", - "version": "5.3.3", + "version": "6.0.0-rc.1", "license": "MIT", "devDependencies": { "@mermaid-js/mermaid-cli": "^9.1.7", diff --git a/package.json b/package.json index 9508cd8f..ac25771d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "path-to-tarkov", "displayName": "Path To Tarkov", "fullName": "Trap-PathToTarkov", - "version": "5.3.3", + "version": "6.0.0-rc.1", "main": "src/mod.js", "license": "MIT", "author": "Trap", From ec06d7b830358ebea0de75f5301e39e9816d1132 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:35:30 +0100 Subject: [PATCH 027/203] docs: get rid of mermaid --- package.json | 4 +- paths/default.drawio | 281 ------------------------------------------- paths/default.md | 44 ------- paths/linear.md | 35 ------ 4 files changed, 1 insertion(+), 363 deletions(-) delete mode 100644 paths/default.drawio delete mode 100644 paths/default.md delete mode 100644 paths/linear.md diff --git a/package.json b/package.json index ac25771d..df79afa3 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,8 @@ "dev:install": "npm run build && npm run build:client && npm run prepare:files && node scripts/install-files.js", "git:check:status": "bash scripts/check-git-status.sh", "gather:external:resources": "bash scripts/gather-external-resources.sh && npm run prettier", - "build:doc:mermaid": "mmdc --width 1600 --height 1200 -t dark -b transparent -i paths/default.md -o configs/Default/PathToTarkov.png", "build:doc:all-exfils": "node scripts/generate-all-exfils > ALL_EXFILS.md", - "build:doc": "npm run build:doc:all-exfils && npm run build:doc:mermaid", + "build:doc": "npm run build:doc:all-exfils", "zip:files": "cd dist && bestzip ../mod.zip user BepInEx && cd .. && node scripts/rename-zip.js", "prepare:files": "node scripts/prepare-files.js", "build:release": "npm run rebuild:all && npm run prepare:files && npm run zip:files && npm run git:check:status", @@ -35,7 +34,6 @@ "test:ci": "npm run build && npm run test && npm run lint:all && npm run build:doc:all-exfils" }, "devDependencies": { - "@mermaid-js/mermaid-cli": "^9.1.7", "@types/i18n": "^0.13.5", "@types/jest": "^29.5.12", "@types/node": "^20.14.11", diff --git a/paths/default.drawio b/paths/default.drawio deleted file mode 100644 index fe222446..00000000 --- a/paths/default.drawio +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/paths/default.md b/paths/default.md deleted file mode 100644 index fc9a8049..00000000 --- a/paths/default.md +++ /dev/null @@ -1,44 +0,0 @@ -```mermaid -flowchart TD - Lab{Laboratory} - GZ{Ground Zero} - Streets{Streets of Tarkov} - I{Interchange} - C{Customs} - F{Factory} - W{Woods} - R{Military reserve} - L{Lighthouse} - Shoreline{Shoreline} - - Prapor[[Prapor's stash]] - Therapist[["Therapist's stash"]] - Mechanic[["Mechanic's stash (home)"]] - Ragman[[Ragman's stash]] - Skier[[Skier's stash]] - Peacekeeper[[Peacekeeper's stash]] - Jaeger[[Jaeger's stash]] - MilitaryLighthouseStash[[a stash near the military reserve]] - ReserveInterchangeBunkerStash[[an underground stash in a bunker]] - ShorelineWoodsStash[[a stash between shoreline and woods]] - - %% The normal default path - Lab <--Any--> Prapor - GZ <--Car--> Prapor - Streets <--Car--> Prapor - Streets <--Collapsed crane--> Therapist <--Railroad to tarkov--> C - C <--Railroad to military base--> Skier <--Scav lands--> R - R <--Checkpoint fence--> MilitaryLighthouseStash <--Road to military base--> L - L <--Southern road--> Peacekeeper <--Tunnel--> Shoreline - C <--Old gas station gate--> Ragman <--Railway exfil--> I - C <--Factory far corner--> Mechanic <--Gate 3--> F - F <--Office window--> Jaeger <--Factory gate--> W - - %% Additional shortcuts - Therapist <--Scav checkpoint--> GZ - I <--Safe room--> ReserveInterchangeBunkerStash <--"D-2"--> R - Shoreline <--Car--> ShorelineWoodsStash <--Car--> W - - Shoreline <--Old bunker--> ReserveInterchangeBunkerStash - I <--Car--> Prapor -``` diff --git a/paths/linear.md b/paths/linear.md deleted file mode 100644 index 25616edf..00000000 --- a/paths/linear.md +++ /dev/null @@ -1,35 +0,0 @@ -```mermaid -flowchart TD - Lab{Laboratory} - GZ{Ground Zero} - Streets{Streets of Tarkov} - I{Interchange} - C{Customs} - F{Factory} - W{Woods} - R{Military reserve} - L{Lighthouse} - Shoreline{Shoreline} - - Prapor[[Prapor's stash]] - Therapist[["Therapist's stash"]] - Mechanic[["Mechanic's stash (home)"]] - Ragman[[Ragman's stash]] - Skier[[Skier's stash]] - Peacekeeper[[Peacekeeper's stash]] - Jaeger[[Jaeger's stash]] - MilitaryLighthouseStash[[a stash near the military reserve]] - - %% The normal default path - Lab <--Any--> Prapor - GZ <--Car--> Prapor - Streets <--Car--> Prapor - Streets <--Collapsed crane--> Therapist <--Railroad to tarkov--> C - C <--Railroad to military base--> Skier <--Scav lands--> R - R <--Checkpoint fence--> MilitaryLighthouseStash <--Road to military base--> L - L <--Southern road--> Peacekeeper <--Tunnel--> Shoreline - C <--Old gas station gate--> Ragman <--Railway exfil--> I - C <--Factory far corner--> Mechanic <--Gate 3--> F - F <--Office window--> Jaeger <--Factory gate--> W - -``` From 6f857cea0c407db16a67c289839c9d033dc85866 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:35:53 +0100 Subject: [PATCH 028/203] docs: update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed6822c2..a49ae385 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ New spawn points can be added in `player_spawnpoints.json` ## The Default configuration -![PathToTarkov mermaid image](./configs/Default/PathToTarkov.png) +![PathToTarkov config image](./configs/Default/TarkovMapV2.jpg) By default, you are on `MechanicStash` offraid position. It means you can spawn on Customs or Factory maps only. From 4e064d16c12ae8f123fa6cdfd90e66ccb499ae08 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 1 Dec 2024 21:48:30 +0100 Subject: [PATCH 029/203] chore: update lockfile --- package-lock.json | 560 ---------------------------------------------- 1 file changed, 560 deletions(-) diff --git a/package-lock.json b/package-lock.json index b180b820..4910a9ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "6.0.0-rc.1", "license": "MIT", "devDependencies": { - "@mermaid-js/mermaid-cli": "^9.1.7", "@types/i18n": "^0.13.5", "@types/jest": "^29.5.12", "@types/node": "^20.14.11", @@ -1107,35 +1106,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@mermaid-js/mermaid-cli": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/@mermaid-js/mermaid-cli/-/mermaid-cli-9.1.7.tgz", - "integrity": "sha512-m7sAmOHhG6bmY1IEy+rSvyrQrKA/XIM6PFWP7w+3uW/C+uanPrIt0ieLL2NJfvfzLMkvEin1ClYE+pA6Y7Jwnw==", - "dev": true, - "dependencies": { - "chalk": "^5.0.1", - "commander": "^9.0.0", - "puppeteer": "^18.0.5" - }, - "bin": { - "mmdc": "src/cli.js" - }, - "engines": { - "node": ">=14.1.0" - } - }, - "node_modules/@mermaid-js/mermaid-cli/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1334,16 +1304,6 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", @@ -1580,18 +1540,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2129,12 +2077,6 @@ "node": ">=10" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -2228,15 +2170,6 @@ "text-hex": "1.0.x" } }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, "node_modules/compress-commons": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", @@ -2359,15 +2292,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dev": true, - "dependencies": { - "node-fetch": "2.6.7" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2443,12 +2367,6 @@ "node": ">=8" } }, - "node_modules/devtools-protocol": { - "version": "0.0.1045489", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz", - "integrity": "sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ==", - "dev": true - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -2787,26 +2705,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2877,15 +2775,6 @@ "bser": "2.1.1" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", @@ -3050,21 +2939,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3171,19 +3045,6 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -4462,12 +4323,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4480,26 +4335,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4689,12 +4524,6 @@ "node": ">=8" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -4842,15 +4671,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -4864,22 +4684,6 @@ "node": ">= 6" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4889,44 +4693,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-18.2.1.tgz", - "integrity": "sha512-7+UhmYa7wxPh2oMRwA++k8UGVDxh3YdWFB52r9C3tM81T6BU7cuusUSxImz0GEYSOYUKk/YzIhkQ6+vc0gHbxQ==", - "deprecated": "< 22.6.4 is no longer supported", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "puppeteer-core": "18.2.1" - }, - "engines": { - "node": ">=14.1.0" - } - }, - "node_modules/puppeteer-core": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-18.2.1.tgz", - "integrity": "sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==", - "dev": true, - "dependencies": { - "cross-fetch": "3.1.5", - "debug": "4.3.4", - "devtools-protocol": "0.0.1045489", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.1", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.9.0" - }, - "engines": { - "node": ">=14.1.0" - } - }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -5356,18 +5122,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -5410,12 +5164,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -5443,12 +5191,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "node_modules/triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", @@ -5588,16 +5330,6 @@ "node": ">=14.17" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -5672,22 +5404,6 @@ "makeerror": "1.0.12" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5783,27 +5499,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -5846,16 +5541,6 @@ "node": ">=10" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -6701,25 +6386,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@mermaid-js/mermaid-cli": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/@mermaid-js/mermaid-cli/-/mermaid-cli-9.1.7.tgz", - "integrity": "sha512-m7sAmOHhG6bmY1IEy+rSvyrQrKA/XIM6PFWP7w+3uW/C+uanPrIt0ieLL2NJfvfzLMkvEin1ClYE+pA6Y7Jwnw==", - "dev": true, - "requires": { - "chalk": "^5.0.1", - "commander": "^9.0.0", - "puppeteer": "^18.0.5" - }, - "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - } - } - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6908,16 +6574,6 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, - "@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, "@typescript-eslint/eslint-plugin": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", @@ -7053,15 +6709,6 @@ "dev": true, "requires": {} }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -7448,12 +7095,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -7534,12 +7175,6 @@ "text-hex": "1.0.x" } }, - "commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true - }, "compress-commons": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", @@ -7633,15 +7268,6 @@ "prompts": "^2.0.1" } }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dev": true, - "requires": { - "node-fetch": "2.6.7" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7695,12 +7321,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "devtools-protocol": { - "version": "0.0.1045489", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz", - "integrity": "sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ==", - "dev": true - }, "diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -7949,18 +7569,6 @@ "jest-util": "^29.7.0" } }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -8027,15 +7635,6 @@ "bser": "2.1.1" } }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, "fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", @@ -8165,15 +7764,6 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8253,16 +7843,6 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -9244,12 +8824,6 @@ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -9262,15 +8836,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -9412,12 +8977,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -9521,12 +9080,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -9537,58 +9090,12 @@ "sisteransi": "^1.0.5" } }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, - "puppeteer": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-18.2.1.tgz", - "integrity": "sha512-7+UhmYa7wxPh2oMRwA++k8UGVDxh3YdWFB52r9C3tM81T6BU7cuusUSxImz0GEYSOYUKk/YzIhkQ6+vc0gHbxQ==", - "dev": true, - "requires": { - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "puppeteer-core": "18.2.1" - } - }, - "puppeteer-core": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-18.2.1.tgz", - "integrity": "sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==", - "dev": true, - "requires": { - "cross-fetch": "3.1.5", - "debug": "4.3.4", - "devtools-protocol": "0.0.1045489", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.1", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.9.0" - } - }, "pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -9874,18 +9381,6 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -9922,12 +9417,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -9949,12 +9438,6 @@ "is-number": "^7.0.0" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", @@ -10035,16 +9518,6 @@ "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -10096,22 +9569,6 @@ "makeerror": "1.0.12" } }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -10183,13 +9640,6 @@ "signal-exit": "^3.0.7" } }, - "ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", - "dev": true, - "requires": {} - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -10223,16 +9673,6 @@ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", From fd9bd20a80dd4e937df47d27081743cb9b978a7d Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 2 Dec 2024 20:46:29 +0100 Subject: [PATCH 030/203] fix: re-enable hideout areas restrictions --- src/path-to-tarkov-controller.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 5d711776..8a47690b 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -383,17 +383,6 @@ export class PathToTarkovController { { frequency: 'Always' }, ); - // this.container.afterResolution( - // 'LocationCallbacks', - // (_t, result): void => { - // const locationCallbacks = Array.isArray(result) ? result[0] : result; - - // const originalGet = locationCallbacks.getLocationData.bind(locationCallbacks); - // locationCallbacks.getLocationData = this.createGetLocationData(originalGet); - // }, - // { frequency: 'Always' }, - // ); - this.container.afterResolution( 'DataCallbacks', (_t, result): void => { @@ -404,8 +393,8 @@ export class PathToTarkovController { dataCallbacks.getTemplateItems = this.createGetTemplateItems(originalGetTemplateItems); // override getHideoutAreas - // const originalGetHideoutAreas = dataCallbacks.getHideoutAreas.bind(dataCallbacks); - // dataCallbacks.getHideoutAreas = this.createGetHideoutAreas(originalGetHideoutAreas); + const originalGetHideoutAreas = dataCallbacks.getHideoutAreas.bind(dataCallbacks); + dataCallbacks.getHideoutAreas = this.createGetHideoutAreas(originalGetHideoutAreas); // override getGlobals const originalGetGlobals = dataCallbacks.getGlobals.bind(dataCallbacks); From 17265de392b67603df5563088e95d29ed324f511 Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 2 Dec 2024 22:43:30 +0100 Subject: [PATCH 031/203] fix(config-analysis): misleading error message formatting --- src/config-analysis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 8c40d15a..fac9d68f 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -107,7 +107,7 @@ const getErrorsForOffraidPositions = (config: Config): string[] => { const offraidPosition = offraidByExfil[extractName]; if (!config.infiltrations[offraidPosition]) { errors.push( - `wrong offraidPosition: "${offraidPosition}" in infiltrations.${mapName}.${extractName}`, + `wrong offraidPosition: "${offraidPosition}" in exfiltrations.${mapName}.${extractName}`, ); } }); From 7f45de8a1855c84f63c1372ccdc39adc4fdddcb6 Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 3 Dec 2024 00:32:10 +0100 Subject: [PATCH 032/203] chore: re-use isLocationBaseAvailable everytime locationBase is handled --- src/path-to-tarkov-controller.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 8a47690b..ab6e0b2d 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -422,6 +422,10 @@ export class PathToTarkovController { offraidPosition: string, sessionId: string, ): void { + if (!this.isLocationBaseAvailable(locationBase)) { + return; + } + const mapName = resolveMapNameFromLocation(locationBase.Id); const infiltrations = this.getConfig(sessionId).infiltrations; @@ -460,6 +464,7 @@ export class PathToTarkovController { } } + // this will ignore unavailable maps (like terminal) private isLocationBaseAvailable(locationBase: ILocationBase): boolean { if (locationBase.Scene.path && locationBase.Scene.rcid) { return true; @@ -475,7 +480,11 @@ export class PathToTarkovController { return; } - const transits = locationBase.transits ?? []; // fallback on empty array because the type can lie (for `terminal` map) + if (!this.isLocationBaseAvailable(locationBase)) { + return; + } + + const transits = locationBase.transits ?? []; let nbTransitsWiped = 0; transits.forEach(transit => { @@ -495,7 +504,6 @@ export class PathToTarkovController { return; } - // this will ignore unavailable maps (like terminal) if (!this.isLocationBaseAvailable(locationBase)) { return; } From dbfb201e1ada8b315a6452fc53c930ebe356afda Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 3 Dec 2024 21:01:00 +0100 Subject: [PATCH 033/203] feat: support of vanilla transits --- configs/Default/config.json | 2 +- src/config.ts | 2 +- src/helpers.ts | 4 +++ src/path-to-tarkov-controller.ts | 60 ++++++++++++++++++++------------ 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index fa354adb..a28610f2 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -8,7 +8,7 @@ "vanilla_exfils_requirements": true, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, - "bypass_transits_override": false, + "disable_all_transits": false, "bypass_keep_found_in_raid_tweak": false, "bypass_uninstall_procedure": false, "restrictions_in_raid": { diff --git a/src/config.ts b/src/config.ts index 59e7041d..a201f82e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -151,7 +151,7 @@ type RawConfig = { workbench_always_enabled: boolean; vanilla_exfils_requirements?: boolean; bypass_exfils_override?: boolean; - bypass_transits_override?: boolean; + disable_all_transits?: boolean; bypass_uninstall_procedure: boolean; enable_run_through?: boolean; enable_legacy_ptt_api?: boolean; diff --git a/src/helpers.ts b/src/helpers.ts index ad9672fd..a9f03d96 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -24,6 +24,10 @@ const getPosition = (pos: SpawnPoint['Position']): PositionXYZ => { export const PTT_INFILTRATION = 'PTT_INFILTRATION'; +export const isPlayerSpawnPoint = (spawnPoint: ISpawnPointParam): boolean => { + return Boolean(spawnPoint.Categories.find(cat => cat === 'Player')); +}; + export const createSpawnPoint = ( pos: SpawnPoint['Position'], rot: number, diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index ab6e0b2d..4be4030f 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -14,6 +14,7 @@ import { createExitPoint, createSpawnPoint, isIgnoredArea, + isPlayerSpawnPoint, PTT_INFILTRATION, } from './helpers'; @@ -156,8 +157,8 @@ export class PathToTarkovController { * Warning: this function will mutate the given locationBase */ syncLocationBase(locationBase: ILocationBase, sessionId: string): void { - const offraidPosition = this.getOffraidPosition(sessionId); - this.updateSpawnPoints(locationBase, offraidPosition, sessionId); + this.updateInfiltrationForPlayerSpawnPoints(locationBase); + this.updateSpawnPoints(locationBase, sessionId); this.updateLocationBaseExits(locationBase, sessionId); this.updateLocationBaseTransits(locationBase, sessionId); } @@ -406,28 +407,18 @@ export class PathToTarkovController { private removePlayerSpawnsForLocation(locationBase: ILocationBase): void { locationBase.SpawnPointParams = locationBase.SpawnPointParams.filter(params => { - const playerCategoryFound = params.Categories.find(cat => cat === 'Player'); - - // remove the spawn point if Category is related to player - if (playerCategoryFound) { - return false; - } - - return true; + return !isPlayerSpawnPoint(params); }); } - private updateSpawnPoints( - locationBase: ILocationBase, - offraidPosition: string, - sessionId: string, - ): void { + private updateSpawnPoints(locationBase: ILocationBase, sessionId: string): void { if (!this.isLocationBaseAvailable(locationBase)) { return; } const mapName = resolveMapNameFromLocation(locationBase.Id); const infiltrations = this.getConfig(sessionId).infiltrations; + const offraidPosition = this.getOffraidPosition(sessionId); if (!infiltrations[offraidPosition]) { this.debug( @@ -464,6 +455,22 @@ export class PathToTarkovController { } } + /** + * The purpose of this function is to set the PTT Infiltration field for all player spawnpoints + * It will allow exfils to be available even when player took a transit + */ + private updateInfiltrationForPlayerSpawnPoints(locationBase: ILocationBase): void { + if (!this.isLocationBaseAvailable(locationBase)) { + return; + } + + locationBase.SpawnPointParams.forEach(spawnPoint => { + if (isPlayerSpawnPoint(spawnPoint)) { + spawnPoint.Infiltration = PTT_INFILTRATION; + } + }); + } + // this will ignore unavailable maps (like terminal) private isLocationBaseAvailable(locationBase: ILocationBase): boolean { if (locationBase.Scene.path && locationBase.Scene.rcid) { @@ -473,17 +480,26 @@ export class PathToTarkovController { return false; } + /** + * Disable transits if specified by the config + */ private updateLocationBaseTransits(locationBase: ILocationBase, sessionId: string): void { + if (!this.isLocationBaseAvailable(locationBase)) { + return; + } + const config = this.getConfig(sessionId); - if (config.bypass_exfils_override || config.bypass_transits_override) { + if (!config.disable_all_transits) { return; } - if (!this.isLocationBaseAvailable(locationBase)) { - return; + if (config.disable_all_transits) { + this.updateLocationDisableAllTransits(locationBase); } + } + private updateLocationDisableAllTransits(locationBase: ILocationBase): void { const transits = locationBase.transits ?? []; let nbTransitsWiped = 0; @@ -498,13 +514,13 @@ export class PathToTarkovController { } private updateLocationBaseExits(locationBase: ILocationBase, sessionId: string): void { - const config = this.getConfig(sessionId); - - if (config.bypass_exfils_override) { + if (!this.isLocationBaseAvailable(locationBase)) { return; } - if (!this.isLocationBaseAvailable(locationBase)) { + const config = this.getConfig(sessionId); + + if (config.bypass_exfils_override) { return; } From cf492846dc114f34ccb160a561ce1d55b913bad4 Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 3 Dec 2024 22:28:32 +0100 Subject: [PATCH 034/203] fix: rewrite FoundInRaid tweak --- src/end-of-raid-controller.ts | 5 +- src/event-watcher.ts | 16 +++--- src/keep-fir-tweak.ts | 88 +++++++++++++++++++++----------- src/mod.ts | 7 --- src/path-to-tarkov-controller.ts | 22 +++++++- 5 files changed, 87 insertions(+), 51 deletions(-) diff --git a/src/end-of-raid-controller.ts b/src/end-of-raid-controller.ts index ed9253d9..89bfc8e7 100644 --- a/src/end-of-raid-controller.ts +++ b/src/end-of-raid-controller.ts @@ -48,11 +48,12 @@ export class EndOfRaidController { return; } - const newOffraidPosition = this.ptt.pathToTarkovController.onPlayerExtracts( + const newOffraidPosition = this.ptt.pathToTarkovController.onPlayerExtracts({ sessionId, mapName, exitName, - ); + isPlayerScav, + }); if (newOffraidPosition) { this.ptt.debug(`end of raid: new offraid position ${newOffraidPosition}`); diff --git a/src/event-watcher.ts b/src/event-watcher.ts index 7df0ddff..55c8595d 100644 --- a/src/event-watcher.ts +++ b/src/event-watcher.ts @@ -23,7 +23,6 @@ const createInitialRaidCache = (sessionId: string): RaidCache => ({ currentLocationName: null, exitName: undefined, isPlayerScav: null, - // TODO: add the exitStatus }); export class EventWatcher { @@ -97,8 +96,8 @@ export class EventWatcher { const originalStartLocalRaid = matchController.startLocalRaid.bind(matchController); matchController.startLocalRaid = (sessionId: string, data: IStartLocalRaidRequestData) => { - const originalResult = deepClone(originalStartLocalRaid(sessionId, data)); - const locationBase: ILocationBase = originalResult.locationLoot; + const result = deepClone(originalStartLocalRaid(sessionId, data)); + const locationBase: ILocationBase = result.locationLoot; this.ptt.pathToTarkovController.syncLocationBase(locationBase, sessionId); this.initRaidCache(sessionId); @@ -106,7 +105,7 @@ export class EventWatcher { if (!raidCache) { this.ptt.logger.error(`no PTT raid cache found when starting the raid`); - return originalResult; + return result; } // void data.mode; // => "PVE_OFFLINE" @@ -118,7 +117,7 @@ export class EventWatcher { `offline raid started on location '${data.location}' with sessionId '${sessionId}'`, ); - return originalResult; + return result; }; }, { frequency: 'Always' }, @@ -137,13 +136,12 @@ export class EventWatcher { data: IEndLocalRaidRequestData, sessionId: string, ) => { - const originalResult = originalEndLocalRaid(url, data, sessionId); + const result = originalEndLocalRaid(url, data, sessionId); const raidCache = this.getRaidCache(sessionId); - if (!raidCache) { this.ptt.logger.error(`no PTT raid cache found`); - return originalResult; + return result; } raidCache.sessionId = sessionId; @@ -156,7 +154,7 @@ export class EventWatcher { ); this.runEndOfRaidCallback(sessionId); - return originalResult; + return result; }; }, { frequency: 'Always' }, diff --git a/src/keep-fir-tweak.ts b/src/keep-fir-tweak.ts index df26a805..243fc0f7 100644 --- a/src/keep-fir-tweak.ts +++ b/src/keep-fir-tweak.ts @@ -1,31 +1,57 @@ -import type { DependencyContainer } from 'tsyringe'; -import type { ConfigServer } from '@spt/servers/ConfigServer'; -import type { ConfigTypes } from '@spt/models/enums/ConfigTypes'; -import type { IInRaidConfig } from '@spt/models/spt/config/IInRaidConfig'; - -// TODO: filter to get only items that are in the player equipment (need to use "equipment" field as a parentId) -// const setSpawnedInSessionOnAllItems = (items: IItem[]): number => { -// let counter = 0; - -// items.forEach(item => { -// if (item.upd) { -// if (!item.upd.SpawnedInSession) { -// item.upd.SpawnedInSession = true; -// counter = counter + 1; -// } -// } else { -// item.upd = { SpawnedInSession: true }; -// counter = counter + 1; -// } -// }); - -// return counter; -// }; - -export const applyKeepFoundInRaidTweak = (container: DependencyContainer): void => { - const configServer = container.resolve('ConfigServer'); - const inRaidConfig = configServer.getConfig('spt-inraid' as ConfigTypes.IN_RAID); - - // this does not work - inRaidConfig.alwaysKeepFoundInRaidonRaidEnd = true; -}; +import type { SaveServer } from '@spt/servers/SaveServer'; +import type { IItem } from '@spt/models/eft/common/tables/IItem'; + +export class KeepFoundInRaidTweak { + constructor(private saveServer: SaveServer) {} + + public setFoundInRaidOnEquipment(sessionId: string, isPlayerScav: boolean): number { + const profile = this.saveServer.getProfile(sessionId); + const characterData = profile.characters[isPlayerScav ? 'scav' : 'pmc']; + const inventory = characterData.Inventory; + const allEquipmentItems = KeepFoundInRaidTweak.getItemsContainedIn( + inventory.items, + inventory.equipment, + ); + + const nbImpactedItems = KeepFoundInRaidTweak.setSpawnedInSessionOnItems(allEquipmentItems); + this.saveServer.saveProfile(sessionId); + + return nbImpactedItems; + } + + private static getItemsContainedIn(items: IItem[], parentId: string): IItem[] { + const resultItems: IItem[] = []; + + items.forEach(item => { + if (!item._id || !item.parentId) { + return; + } + + if (item.parentId === parentId) { + resultItems.push(item); + const deeperItems = this.getItemsContainedIn(items, item._id); + resultItems.push(...deeperItems); + } + }); + + return resultItems; + } + + private static setSpawnedInSessionOnItems(items: IItem[]): number { + let counter = 0; + + items.forEach(item => { + if (item.upd) { + if (!item.upd.SpawnedInSession) { + item.upd.SpawnedInSession = true; + counter = counter + 1; + } + } else { + item.upd = { SpawnedInSession: true }; + counter = counter + 1; + } + }); + + return counter; + } +} diff --git a/src/mod.ts b/src/mod.ts index d6c1dc84..b4df54f5 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -32,7 +32,6 @@ import { pathToTarkovReloadedTooltipsConfigCompat } from './pttr-tooltips'; import path from 'path'; import { analyzeConfig } from './config-analysis'; import { TradersAvailabilityService } from './services/TradersAvailabilityService'; -import { applyKeepFoundInRaidTweak } from './keep-fir-tweak'; const getTooltipsConfig = ( userConfig: UserConfig, @@ -162,12 +161,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { return; } - if (!this.config.bypass_keep_found_in_raid_tweak) { - applyKeepFoundInRaidTweak(container); - // this.debug('keep FIR tweak applied'); - this.logger.warning('keep FIR tweak does not work on this verison'); - } - this.pathToTarkovController.tradersAvailabilityService.init(quests); if (this.tooltipsConfig) { diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 4be4030f..104fd7f4 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -36,6 +36,7 @@ import type { IHideoutArea } from '@spt/models/eft/hideout/IHideoutArea'; import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBodyResponseData'; import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; +import { KeepFoundInRaidTweak } from './keep-fir-tweak'; // import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; type IndexedLocations = Record; @@ -140,9 +141,26 @@ export class PathToTarkovController { } // returns the new offraid position (or null if not found) - onPlayerExtracts(sessionId: string, mapName: MapName, exitName: string): string | null { - const extractsConf = this.getConfig(sessionId).exfiltrations[mapName]; + onPlayerExtracts(params: { + sessionId: string; + mapName: MapName; + exitName: string; + isPlayerScav: boolean; + }): string | null { + const { sessionId, mapName, exitName, isPlayerScav } = params; + const config = this.getConfig(sessionId); + + if (config.bypass_keep_found_in_raid_tweak) { + this.debug(`[${sessionId}] FIR tweak disabled`); + } else { + const firTweak = new KeepFoundInRaidTweak(this.saveServer); + const nbImpactedItems = firTweak.setFoundInRaidOnEquipment(sessionId, isPlayerScav); + this.debug( + `[${sessionId}] FIR tweak added SpawnedInSession on ${nbImpactedItems} item${nbImpactedItems > 1 ? 's' : ''}`, + ); + } + const extractsConf = config.exfiltrations[mapName]; const newOffraidPosition = extractsConf && exitName && extractsConf[exitName]; if (newOffraidPosition) { From 2c13371fa412c730679c4d6396e3c6c1aeaabe17 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 4 Dec 2024 18:52:46 +0100 Subject: [PATCH 035/203] fix: add missing factory exfils --- src/all-exfils.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/all-exfils.ts b/src/all-exfils.ts index bf34b2b0..0134eabe 100644 --- a/src/all-exfils.ts +++ b/src/all-exfils.ts @@ -27,7 +27,15 @@ const ALL_DUMPED_EXFILS_FROM_SCRIPT = { 'Administration Gate', 'Factory Far Corner', ], - factory: ['Cellars', 'Gate 3', 'Gate 0', 'Gate m', 'Office Window', 'Camera Bunker Door'], + factory: [ + 'Cellars', + 'Gate 3', + 'Gate 0', + 'Gate m', + 'Gate_o', + 'Office Window', + 'Camera Bunker Door', + ], interchange: [ 'NW Exfil', 'SE Exfil', @@ -45,6 +53,7 @@ const ALL_DUMPED_EXFILS_FROM_SCRIPT = { 'South V-Ex', 'Factory Gate', 'un-sec', + 'wood_sniper_exit', 'East Gate', 'Outskirts Water', 'Mountain Stash', From 6c0121c203bea7b47244ee4033d6d86a493ed34a Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 4 Dec 2024 18:53:25 +0100 Subject: [PATCH 036/203] 6.0.0-rc.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4910a9ae..94546d30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "path-to-tarkov", - "version": "6.0.0-rc.1", + "version": "6.0.0-rc.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "path-to-tarkov", - "version": "6.0.0-rc.1", + "version": "6.0.0-rc.2", "license": "MIT", "devDependencies": { "@types/i18n": "^0.13.5", diff --git a/package.json b/package.json index df79afa3..d2a54dd1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "path-to-tarkov", "displayName": "Path To Tarkov", "fullName": "Trap-PathToTarkov", - "version": "6.0.0-rc.1", + "version": "6.0.0-rc.2", "main": "src/mod.js", "license": "MIT", "author": "Trap", From cac2340b6594c553814e01467aafbb34ef1d3252 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 4 Dec 2024 20:59:11 +0100 Subject: [PATCH 037/203] fix: new factory spawnpoints thanks to GorillaSoup --- ALL_EXFILS.md | 1 - configs/Default/config.json | 8 +-- configs/Default/player_spawnpoints.json | 91 +++++++++++++------------ external-resources/scavs_exfils.json | 2 +- 4 files changed, 54 insertions(+), 48 deletions(-) diff --git a/ALL_EXFILS.md b/ALL_EXFILS.md index 1a67bbe7..f51abdb7 100644 --- a/ALL_EXFILS.md +++ b/ALL_EXFILS.md @@ -36,7 +36,6 @@ | "Gate 0" | Gate 0 | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25057) | | "Gate m" | Med Tent Gate | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=88025) | | "Gate_o" | Courtyard Gate | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=403860) | -| "Office Window" | Office Window | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25060) | | "Camera Bunker Door" | Camera Bunker Door | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25058) | ## Interchange diff --git a/configs/Default/config.json b/configs/Default/config.json index a28610f2..5495d457 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -691,7 +691,7 @@ "Cellars": "FactoryZB-013", "Camera Bunker Door": "MechanicHideout", "Gate 0": "FactoryZB-1011", - "Office Window": "GasGate" + "Gate_o": "GasGate" }, "factory4_night": { "Gate 3": "FactoryZB-016", @@ -699,7 +699,7 @@ "Cellars": "FactoryZB-013", "Camera Bunker Door": "MechanicHideout", "Gate 0": "FactoryZB-1011", - "Office Window": "GasGate" + "Gate_o": "GasGate" }, "bigmap": { "Military Checkpoint": "ScavCP", @@ -883,8 +883,8 @@ "GasGate": { "bigmap": ["Old Gas Scav"], "woods": ["Factory Gate"], - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"] + "factory4_day": ["Courtyard"], + "factory4_night": ["Courtyard"] }, "TarkovRR": { "bigmap": ["RR to Tarkov"], diff --git a/configs/Default/player_spawnpoints.json b/configs/Default/player_spawnpoints.json index d3b9a5fb..58929e56 100644 --- a/configs/Default/player_spawnpoints.json +++ b/configs/Default/player_spawnpoints.json @@ -1,58 +1,73 @@ { - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", + "Comment": "Example rotation values -> N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "factory4_day": { - "Gate 0": { - "Position": [-52.5704842, 1.25745475, 55.06734], - "Rotation": 93.18849 - }, "Gate 3": { - "Position": [58.67002, 0.233123064, 57.4049568], - "Rotation": 129.412323 + "Position": [57.89, 0.3, 49.57], + "Rotation": 238.056732 + }, + "Courtyard": { + "Position": [24.91, 1.18, 53.76], + "Rotation": 238.056732 + }, + "Gate 0": { + "Position": [-51.44, 1.31, 55.24], + "Rotation": 238.056732 }, "Med tent gates": { - "Position": [-18.9917545, 0.229607314, -46.5803642], - "Rotation": 19.03057 + "Position": [-18.21, 0.3, -43.48], + "Rotation": 238.056732 }, - "Cellars": { - "Position": [66.78813, -2.63332653, -30.9360619], - "Rotation": 231.811646 + "Transit to Customs": { + "Position": [15.94, -0.29, -44.01], + "Rotation": 238.056732 + }, + "Transit to Labs": { + "Position": [-26.71, -4.75, -35.46], + "Rotation": 238.056732 }, "Camera Bunker Door": { - "Position": [-20.8695526, -2.63423038, 34.9322433], - "Rotation": 0.891350448 + "Position": [-15.17, -2.61, 39.17], + "Rotation": 238.056732 }, - "Office Window": { - "Position": [17.66614, 8.210876, 40.92688], - "Rotation": 158.9888 + "Cellars": { + "Position": [65.02, -2.63, -31.82], + "Rotation": 238.056732 } }, "factory4_night": { - "Gate 0": { - "Position": [-52.5704842, 1.25745475, 55.06734], - "Rotation": 93.18849 - }, "Gate 3": { - "Position": [58.67002, 0.233123064, 57.4049568], - "Rotation": 129.412323 + "Position": [57.89, 0.3, 49.57], + "Rotation": 238.056732 + }, + "Courtyard": { + "Position": [24.91, 1.18, 53.76], + "Rotation": 238.056732 + }, + "Gate 0": { + "Position": [-51.44, 1.31, 55.24], + "Rotation": 238.056732 }, "Med tent gates": { - "Position": [-18.9917545, 0.229607314, -46.5803642], - "Rotation": 19.03057 + "Position": [-18.21, 0.3, -43.48], + "Rotation": 238.056732 }, - "Cellars": { - "Position": [66.78813, -2.63332653, -30.9360619], - "Rotation": 231.811646 + "Transit Factory to Customs": { + "Position": [15.94, -0.29, -44.01], + "Rotation": 238.056732 + }, + "Transit Factory to Labs": { + "Position": [-26.71, -4.75, -35.46], + "Rotation": 238.056732 }, "Camera Bunker Door": { - "Position": [-20.8695526, -2.63423038, 34.9322433], - "Rotation": 0.891350448 + "Position": [-15.17, -2.61, 39.17], + "Rotation": 238.056732 }, - "Office Window": { - "Position": [17.66614, 8.210876, 40.92688], - "Rotation": 158.9888 + "Cellars": { + "Position": [65.02, -2.63, -31.82], + "Rotation": 238.056732 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "bigmap": { "Military Base CP": { "Position": [674.5625, 5.60742664, 123.641823], @@ -127,7 +142,6 @@ "Rotation": 307.1494 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "woods": { "Northern UN Roadblock": { "Position": [-555.2336, 9.391193, -76.86284], @@ -190,7 +204,6 @@ "Rotation": 104.772415 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "rezervbase": { "Scav lands": { "Position": [-120.954071, -6.94097, -129.4829], @@ -238,7 +251,6 @@ "Rotation": 128.773651 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "interchange": { "Interchange Vehicle Extract": { "Position": [-242.849625, 21.32544, -372.680878], @@ -269,7 +281,6 @@ "Rotation": 344.7888 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "shoreline": { "North Fence Passage": { "Position": [-510.430939, -11.9056053, -373.174316], @@ -324,7 +335,6 @@ "Rotation": 335.1047 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "lighthouse": { "Path to Shoreline": { "Position": [-284.0998, 14.4007835, -161.669266], @@ -375,7 +385,6 @@ "Rotation": 77.76075 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "tarkovstreets": { "Streets Vehicle Extract": { "Position": [-8.757395, 2.31632733, 458.126923], @@ -446,7 +455,6 @@ "Rotation": 15.33 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "laboratory": { "Cargo Elevator": { "Position": [-114.2475, 4.101831, -408.6356], @@ -477,7 +485,6 @@ "Rotation": 14.0038671 } }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "sandbox": { "Nakatani Basement Stairs": { "Position": [5.295958, 22.73891, 331.8584], diff --git a/external-resources/scavs_exfils.json b/external-resources/scavs_exfils.json index 1c36af3e..14133063 100644 --- a/external-resources/scavs_exfils.json +++ b/external-resources/scavs_exfils.json @@ -16,7 +16,7 @@ "Administration Gate", "Factory Far Corner" ], - "factory": ["Office Window", "Camera Bunker Door"], + "factory": ["Camera Bunker Door"], "interchange": [], "woods": [ "East Gate", From 9a35f3f8a7bb2c3aa02d013a736049e6dc7ed3d9 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 13:23:03 +0100 Subject: [PATCH 038/203] fix!: labs worldevent exfils and train exfils BREAKING CHANGE: vanilla_exfils_requirements is no longer supported --- src/helpers.ts | 80 +++++++++++++++++++++++++++----- src/path-to-tarkov-controller.ts | 52 ++++++++------------- 2 files changed, 88 insertions(+), 44 deletions(-) diff --git a/src/helpers.ts b/src/helpers.ts index a9f03d96..7895d068 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -57,19 +57,75 @@ export const createSpawnPoint = ( }; }; -export const createExitPoint = (name: string): IExit => { - const Chance = 100; - const Count = 0; - const ExfiltrationTime = 10; - const MinTime = 0; - const MaxTime = 0; - const PlayersCount = 0; - const ExfiltrationType = 'Individual'; - const PassageRequirement = 'None'; - const RequirementTip = ''; +type ExitProps = { + Id: string; + PassageRequirement: string; + ExfiltrationType: string; + RequirementTip: string; + Count: number; + MaxTime: number; + MinTime: number; + PlayersCount: number; + Chance: number; + ExfiltrationTime: number; +}; + +// TODO: default_exfiltration_time_seconds field in config ? +const DEFAULT_EXFILTRATION_TIME_IN_SECONDS = 10; + +const getDefaultExitProps = (): ExitProps => ({ + Id: '', + PassageRequirement: 'None', + ExfiltrationType: 'Individual', + RequirementTip: '', + Count: 0, + MinTime: 0, + MaxTime: 0, + PlayersCount: 0, + Chance: 100, + ExfiltrationTime: DEFAULT_EXFILTRATION_TIME_IN_SECONDS, +}); + +const getExitProps = (originalExit: IExit | undefined): ExitProps => { + const newExitProps = getDefaultExitProps(); + + if (!originalExit) { + return newExitProps; + } + + if (originalExit.PassageRequirement === 'WorldEvent') { + newExitProps.PassageRequirement = originalExit.PassageRequirement; + newExitProps.ExfiltrationType = originalExit.ExfiltrationType; + newExitProps.RequirementTip = originalExit.RequirementTip; + } else if (originalExit.PassageRequirement === 'Train') { + newExitProps.PassageRequirement = originalExit.PassageRequirement; + newExitProps.ExfiltrationType = originalExit.ExfiltrationType; + newExitProps.RequirementTip = originalExit.RequirementTip; + newExitProps.Id = originalExit.Id; + newExitProps.Count = originalExit.Count; + newExitProps.MinTime = originalExit.MinTime; + newExitProps.MaxTime = originalExit.MaxTime; + } + + return newExitProps; +}; + +export const createExitPoint = (name: string, originalExit: IExit | undefined): IExit => { + const { + Id, + Count, + MinTime, + MaxTime, + ExfiltrationType, + PassageRequirement, + RequirementTip, + PlayersCount, + Chance, + ExfiltrationTime, + } = getExitProps(originalExit); return { - Id: '', + Id, Name: name, EntryPoints: PTT_INFILTRATION, Chance, @@ -81,7 +137,7 @@ export const createExitPoint = (name: string): IExit => { ExfiltrationType, PassageRequirement, RequirementTip, - EventAvailable: true, + EventAvailable: false, ChancePVE: Chance, CountPVE: Count, ExfiltrationTimePVE: ExfiltrationTime, diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 104fd7f4..8ac98474 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -1,5 +1,5 @@ import type { IBodyHealth, IGlobals } from '@spt/models/eft/common/IGlobals'; -import type { ILocationBase } from '@spt/models/eft/common/ILocationBase'; +import type { IExit, ILocationBase } from '@spt/models/eft/common/ILocationBase'; import type { ILogger } from '@spt/models/spt/utils/ILogger'; import type { ConfigServer } from '@spt/servers/ConfigServer'; import type { DatabaseServer } from '@spt/servers/DatabaseServer'; @@ -547,43 +547,31 @@ export class PathToTarkovController { if (extractPoints.length === 0) { this.logger.error(`Path To Tarkov: no exfils found for map '${mapName}'!`); - return; } + // TODO: move this into config-analysis if (config.vanilla_exfils_requirements) { - const usedExitNames = new Set(); - - // filter all exits and keep vanilla requirements (except for ScavCooperation requirements) - locationBase.exits = locationBase.exits - .filter(exit => { - return extractPoints.includes(exit.Name); - }) - .map(exit => { - usedExitNames.add(exit.Name); - - if (exit.PassageRequirement === 'ScavCooperation') { - return createExitPoint(exit.Name); - } - - exit.EntryPoints = PTT_INFILTRATION; - exit.ExfiltrationTime = 10; - exit.Chance = 100; + this.logger.error('Path To Tarkov: "vanilla_exfils_requirements" is no longer supported'); + return; + } - return exit; - }); + // TODO(refactor): implement an indexBy util + const indexedExits = locationBase.exits.reduce>( + (indexed, exit) => { + return { + ...indexed, + [exit.Name]: exit, + }; + }, + {}, + ); - // add missing extractPoints (potentially scav extracts) - extractPoints.forEach(extractName => { - if (!usedExitNames.has(extractName)) { - const exitPoint = createExitPoint(extractName); - locationBase.exits.push(exitPoint); - } - }); - } else { - // erase all exits and create custom exit points without requirements - locationBase.exits = extractPoints.map(createExitPoint); - } + // erase all exits and create custom exit points without requirements + locationBase.exits = extractPoints.map(exitName => { + const originalExit = indexedExits[exitName]; + return createExitPoint(exitName, originalExit); + }); } private getInitialOffraidPosition = (sessionId: string): string => { From 95bf8edb7b9f235814286052a40c9a4a35bab792 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 17:56:24 +0100 Subject: [PATCH 039/203] fix(config): change HarryHideout id trader --- configs/Default/config.json | 94 ++++++++++----------- configs/OriginalNarcoticsConfig/config.json | 2 +- configs/PathToTarkovReloaded/config.json | 2 +- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 5495d457..fc691858 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -499,7 +499,7 @@ }, "access_via": ["LegsHideout"] }, - "HarryHideout": { + "67419e9d0d4541ce671543bb": { "// mod integration for HarryHideout": true, "// HarryHideout is available at PlayerHideout": true, "disable_warning": true, @@ -568,6 +568,52 @@ }, "access_via": ["RuinedHouse"] }, + "6688d464bc40c867f60e7d7e": { + "// mod integration for Scorpion": true, + "// Scorpion is available at ReserveZB-014": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Woods/Reserve", + "cz": "Woods/Reserve", + "en": "Woods/Reserve", + "es-mx": "Woods/Reserve", + "es": "Woods/Reserve", + "fr": "Woods/Reserve", + "ge": "Woods/Reserve", + "hu": "Woods/Reserve", + "it": "Woods/Reserve", + "jp": "Woods/Reserve", + "kr": "Woods/Reserve", + "pl": "Woods/Reserve", + "po": "Woods/Reserve", + "ru": "Woods/Reserve" + }, + "access_via": ["ReserveZB-014"] + }, + "668aaff35fd574b6dcc4a686": { + "// mod integration for PAINTER": true, + "// PAINTERSHOP is available at Car": false, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Customs/Streets/Interchange", + "cz": "Customs/Streets/Interchange", + "en": "Customs/Streets/Interchange", + "es-mx": "Customs/Streets/Interchange", + "es": "Customs/Streets/Interchange", + "fr": "Customs/Streets/Interchange", + "ge": "Customs/Streets/Interchange", + "hu": "Customs/Streets/Interchange", + "it": "Customs/Streets/Interchange", + "jp": "Customs/Streets/Interchange", + "kr": "Customs/Streets/Interchange", + "pl": "Customs/Streets/Interchange", + "po": "Customs/Streets/Interchange", + "ru": "Customs/Streets/Interchange" + }, + "access_via": ["TarkovRR", "CrashSite", "Railway"] + }, "lotus": { "// mod integration for lotus": true, "// lotus is available at Emercom": true, @@ -614,29 +660,6 @@ }, "access_via": ["BasementDescent"] }, - "6688d464bc40c867f60e7d7e": { - "// mod integration for Scorpion": true, - "// Scorpion is available at ReserveZB-014": true, - "disable_warning": true, - "override_description": true, - "location_description": { - "ch": "Woods/Reserve", - "cz": "Woods/Reserve", - "en": "Woods/Reserve", - "es-mx": "Woods/Reserve", - "es": "Woods/Reserve", - "fr": "Woods/Reserve", - "ge": "Woods/Reserve", - "hu": "Woods/Reserve", - "it": "Woods/Reserve", - "jp": "Woods/Reserve", - "kr": "Woods/Reserve", - "pl": "Woods/Reserve", - "po": "Woods/Reserve", - "ru": "Woods/Reserve" - }, - "access_via": ["ReserveZB-014"] - }, "Sally": { "// mod integration for Sally": true, "// Sally is available at Manhole": true, @@ -659,29 +682,6 @@ "ru": "Reserve/Streets" }, "access_via": ["Manhole"] - }, - "668aaff35fd574b6dcc4a686": { - "// mod integration for PAINTER": true, - "// PAINTERSHOP is available at Car": false, - "disable_warning": true, - "override_description": true, - "location_description": { - "ch": "Customs/Streets/Interchange", - "cz": "Customs/Streets/Interchange", - "en": "Customs/Streets/Interchange", - "es-mx": "Customs/Streets/Interchange", - "es": "Customs/Streets/Interchange", - "fr": "Customs/Streets/Interchange", - "ge": "Customs/Streets/Interchange", - "hu": "Customs/Streets/Interchange", - "it": "Customs/Streets/Interchange", - "jp": "Customs/Streets/Interchange", - "kr": "Customs/Streets/Interchange", - "pl": "Customs/Streets/Interchange", - "po": "Customs/Streets/Interchange", - "ru": "Customs/Streets/Interchange" - }, - "access_via": ["TarkovRR", "CrashSite", "Railway"] } }, "exfiltrations": { diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index c722f71b..289c3a0a 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -498,7 +498,7 @@ }, "access_via": ["LegsHideout"] }, - "HarryHideout": { + "67419e9d0d4541ce671543bb": { "// mod integration for HarryHideout": true, "// HarryHideout is available at PlayerHideout": true, "disable_warning": true, diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index 7aa2841e..4fcce643 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -402,7 +402,7 @@ }, "access_via": ["ShorelineLighthouseTunnel"] }, - "HarryHideout": { + "67419e9d0d4541ce671543bb": { "// mod integration for HarryHideout": true, "// HarryHideout is available at PlayerHideout": true, "disable_warning": true, From 3f2f7fbce978c10d625e05188954271f41955896 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 18:08:09 +0100 Subject: [PATCH 040/203] fix(config): change Artem trader id --- configs/Default/config.json | 2 +- configs/DevilFlippy/config.json | 2 +- configs/OriginalNarcoticsConfig/config.json | 2 +- configs/PathToTarkovReloaded/config.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index fc691858..6079ddc0 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -522,7 +522,7 @@ }, "access_via": ["FactoryZB-1011"] }, - "ArtemTrader": { + "66bf757f27d0b097db0acea5": { "// mod integration for ArtemTrader": true, "// ArtemTrader is available at ArtemHideout": true, "disable_warning": true, diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index 39e32921..ccb20348 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -374,7 +374,7 @@ }, "heal_always_enabled": false }, - "ArtemTrader": { + "66bf757f27d0b097db0acea5": { "// mod integration for ArtemTrader": true, "// ArtemTrader is available at ArtemHideout": true, "disable_warning": false, diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index 289c3a0a..13bc7887 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -521,7 +521,7 @@ }, "access_via": ["FactoryZB-1011"] }, - "ArtemTrader": { + "66bf757f27d0b097db0acea5": { "// mod integration for ArtemTrader": true, "// ArtemTrader is available at ArtemHideout": true, "disable_warning": true, diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index 4fcce643..7d65fd74 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -425,7 +425,7 @@ }, "access_via": ["PlayerHideout"] }, - "ArtemTrader": { + "66bf757f27d0b097db0acea5": { "// mod integration for ArtemTrader": true, "// ArtemTrader is available at Boat": true, "disable_warning": true, From e86e2040db89459531f9deeffe586a510d069160 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 18:11:21 +0100 Subject: [PATCH 041/203] fix: main stash should not be available from therapist --- configs/Default/config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 6079ddc0..d6ee990e 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -46,8 +46,7 @@ "FactoryZB-1011", "FactoryZB-1012", "FactoryZB-013", - "FactoryZB-016", - "TherapistHideout" + "FactoryZB-016" ], "hideout_secondary_stashes": [ { From e542c32274dfbc47442e16adf4118491f785cea5 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 18:13:58 +0100 Subject: [PATCH 042/203] fix: add Therapist stash --- configs/Default/config.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configs/Default/config.json b/configs/Default/config.json index d6ee990e..f7e1b3aa 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -223,6 +223,11 @@ "id": "PathToTarkov_Catacombs_stash", "size": 16, "access_via": ["Catacombs"] + }, + { + "id": "PathToTarkov_Therapist_stash", + "size": 16, + "access_via": ["TherapistHideout"] } ], "traders_config": { From 4a4272338c20395da5c5612b1975e0efd3d3ee5a Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 19:07:41 +0100 Subject: [PATCH 043/203] chore: cleanup outdated comments in default config --- configs/Default/config.json | 55 +++++++++++++++---------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index f7e1b3aa..8a6d0741 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -437,7 +437,6 @@ }, "579dc571d53a0658a154fbec": { "// Trader name": "Fence", - "// Fence is accessible everywhere": true, "access_via": "*", "insurance_always_enabled": true, "insurance_config": { @@ -459,7 +458,6 @@ }, "6748adca5c70634464b214a8": { "// mod integration for Priscilu": true, - "// Priscilu is available after extracting from Outskirts (woods map)": true, "disable_warning": true, "override_description": true, "location_description": { @@ -482,7 +480,6 @@ }, "6748edbcb936f1098d4303e4": { "// mod integration for Legs the Trader": true, - "// Gunsmith is available after extracting from Tunnel (shoreline map) or Lighthouse Tunnel (lighthouse map)": true, "disable_warning": true, "override_description": true, "location_description": { @@ -505,7 +502,6 @@ }, "67419e9d0d4541ce671543bb": { "// mod integration for HarryHideout": true, - "// HarryHideout is available at PlayerHideout": true, "disable_warning": true, "override_description": true, "location_description": { @@ -528,7 +524,6 @@ }, "66bf757f27d0b097db0acea5": { "// mod integration for ArtemTrader": true, - "// ArtemTrader is available at ArtemHideout": true, "disable_warning": true, "override_description": true, "location_description": { @@ -549,32 +544,8 @@ }, "access_via": ["ArtemHideout"] }, - "hephaestus_alxk": { - "// mod integration for Hephaestus": true, - "// Hephaestus is available at Streets": true, - "disable_warning": true, - "override_description": true, - "location_description": { - "ch": "Streets", - "cz": "Streets", - "en": "Streets", - "es-mx": "Streets", - "es": "Streets", - "fr": "Streets", - "ge": "Streets", - "hu": "Streets", - "it": "Streets", - "jp": "Streets", - "kr": "Streets", - "pl": "Streets", - "po": "Streets", - "ru": "Streets" - }, - "access_via": ["RuinedHouse"] - }, "6688d464bc40c867f60e7d7e": { "// mod integration for Scorpion": true, - "// Scorpion is available at ReserveZB-014": true, "disable_warning": true, "override_description": true, "location_description": { @@ -597,7 +568,6 @@ }, "668aaff35fd574b6dcc4a686": { "// mod integration for PAINTER": true, - "// PAINTERSHOP is available at Car": false, "disable_warning": true, "override_description": true, "location_description": { @@ -620,7 +590,6 @@ }, "lotus": { "// mod integration for lotus": true, - "// lotus is available at Emercom": true, "disable_warning": true, "override_description": true, "location_description": { @@ -643,7 +612,6 @@ }, "Coyote": { "// mod integration for Coyote": true, - "// Coyote is available at BasementDescent": true, "disable_warning": true, "override_description": true, "location_description": { @@ -664,9 +632,30 @@ }, "access_via": ["BasementDescent"] }, + "hephaestus_alxk": { + "// mod integration for Hephaestus": true, + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "Streets", + "cz": "Streets", + "en": "Streets", + "es-mx": "Streets", + "es": "Streets", + "fr": "Streets", + "ge": "Streets", + "hu": "Streets", + "it": "Streets", + "jp": "Streets", + "kr": "Streets", + "pl": "Streets", + "po": "Streets", + "ru": "Streets" + }, + "access_via": ["RuinedHouse"] + }, "Sally": { "// mod integration for Sally": true, - "// Sally is available at Manhole": true, "disable_warning": true, "override_description": true, "location_description": { From 6bbc4463b7c3d6744c27b1600f0fceae7d2a301d Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 19:25:56 +0100 Subject: [PATCH 044/203] fix(config): more balanced HarryHideout access_via (having available at the player hideout is cheaty) --- configs/Default/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 8a6d0741..43233588 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -520,7 +520,7 @@ "po": "Hideout", "ru": "Hideout" }, - "access_via": ["FactoryZB-1011"] + "access_via": ["BasementDescent"] }, "66bf757f27d0b097db0acea5": { "// mod integration for ArtemTrader": true, From 27d41689cd2fe8eeebe0fd5aae4a2831b3daf7fc Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 20:39:34 +0100 Subject: [PATCH 045/203] fix(config): update traders descriptions + french translation --- configs/Default/config.json | 518 ++++++++++++++++++------------------ 1 file changed, 259 insertions(+), 259 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 43233588..b9794e24 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -244,20 +244,20 @@ }, "override_description": true, "location_description": { - "ch": "Woods", - "cz": "Woods", - "en": "Woods", - "es-mx": "Woods", - "es": "Woods", - "fr": "Woods", - "ge": "Woods", - "hu": "Woods", - "it": "Woods", - "jp": "Woods", - "kr": "Woods", - "pl": "Woods", - "po": "Woods", - "ru": "Woods" + "ch": "Scav Bunker in woods", + "cz": "Scav Bunker in woods", + "en": "Scav Bunker in woods", + "es-mx": "Scav Bunker in woods", + "es": "Scav Bunker in woods", + "fr": "Bunker Scav dans les bois", + "ge": "Scav Bunker in woods", + "hu": "Scav Bunker in woods", + "it": "Scav Bunker in woods", + "jp": "Scav Bunker in woods", + "kr": "Scav Bunker in woods", + "pl": "Scav Bunker in woods", + "po": "Scav Bunker in woods", + "ru": "Scav Bunker in woods" }, "access_via": ["PraporHideout"] }, @@ -274,62 +274,41 @@ }, "override_description": true, "location_description": { - "ch": "Ground Zero", - "cz": "Ground Zero", - "en": "Ground Zero", - "es-mx": "Ground Zero", - "es": "Ground Zero", - "fr": "Ground Zero", - "ge": "Ground Zero", - "hu": "Ground Zero", - "it": "Ground Zero", - "jp": "Ground Zero", - "kr": "Ground Zero", - "pl": "Ground Zero", - "po": "Ground Zero", - "ru": "Ground Zero" + "ch": "Emercom checkpoint on Ground Zero", + "cz": "Emercom checkpoint on Ground Zero", + "en": "Emercom checkpoint on Ground Zero", + "es-mx": "Emercom checkpoint on Ground Zero", + "es": "Emercom checkpoint on Ground Zero", + "fr": "Point de contrôle Emercom à Ground Zero", + "ge": "Emercom checkpoint on Ground Zero", + "hu": "Emercom checkpoint on Ground Zero", + "it": "Emercom checkpoint on Ground Zero", + "jp": "Emercom checkpoint on Ground Zero", + "kr": "Emercom checkpoint on Ground Zero", + "pl": "Emercom checkpoint on Ground Zero", + "po": "Emercom checkpoint on Ground Zero", + "ru": "Emercom checkpoint on Ground Zero" }, "access_via": ["TherapistHideout"] }, - "6617beeaa9cfa777ca915b7c": { - "// Trader name": "Ref", - "override_description": true, - "location_description": { - "ch": "Shoreline/Customs", - "cz": "Shoreline/Customs", - "en": "Shoreline/Customs", - "es-mx": "Shoreline/Customs", - "es": "Shoreline/Customs", - "fr": "Shoreline/Customs", - "ge": "Shoreline/Customs", - "hu": "Shoreline/Customs", - "it": "Shoreline/Customs", - "jp": "Shoreline/Customs", - "kr": "Shoreline/Customs", - "pl": "Shoreline/Customs", - "po": "Shoreline/Customs", - "ru": "Shoreline/Customs" - }, - "access_via": ["RailwayBridge", "PortRR"] - }, "5a7c2eca46aef81a7ca2145d": { "// Trader name": "Mechanic", "override_description": true, "location_description": { - "ch": "Factory", - "cz": "Factory", - "en": "Factory", - "es-mx": "Factory", - "es": "Factory", - "fr": "Factory", - "ge": "Factory", - "hu": "Factory", - "it": "Factory", - "jp": "Factory", - "kr": "Factory", - "pl": "Factory", - "po": "Factory", - "ru": "Factory" + "ch": "Bunker in Factory", + "cz": "Bunker in Factory", + "en": "Bunker in Factory", + "es-mx": "Bunker in Factory", + "es": "Bunker in Factory", + "fr": "Bunker dans l'usine", + "ge": "Bunker in Factory", + "hu": "Bunker in Factory", + "it": "Bunker in Factory", + "jp": "Bunker in Factory", + "kr": "Bunker in Factory", + "pl": "Bunker in Factory", + "po": "Bunker in Factory", + "ru": "Bunker in Factory" }, "access_via": ["MechanicHideout"] }, @@ -346,20 +325,20 @@ }, "override_description": true, "location_description": { - "ch": "Customs", - "cz": "Customs", - "en": "Customs", - "es-mx": "Customs", - "es": "Customs", - "fr": "Customs", - "ge": "Customs", - "hu": "Customs", - "it": "Customs", - "jp": "Customs", - "kr": "Customs", - "pl": "Customs", - "po": "Customs", - "ru": "Customs" + "ch": "Warehouse 17 at Customs", + "cz": "Warehouse 17 at Customs", + "en": "Warehouse 17 at Customs", + "es-mx": "Warehouse 17 at Customs", + "es": "Warehouse 17 at Customs", + "fr": "Entrepôt 17 à la douane", + "ge": "Warehouse 17 at Customs", + "hu": "Warehouse 17 at Customs", + "it": "Warehouse 17 at Customs", + "jp": "Warehouse 17 at Customs", + "kr": "Warehouse 17 at Customs", + "pl": "Warehouse 17 at Customs", + "po": "Warehouse 17 at Customs", + "ru": "Warehouse 17 at Customs" }, "access_via": ["SkierHideout"] }, @@ -376,20 +355,20 @@ }, "override_description": true, "location_description": { - "ch": "Interchange/Customs", - "cz": "Interchange/Customs", - "en": "Interchange/Customs", - "es-mx": "Interchange/Customs", - "es": "Interchange/Customs", - "fr": "Interchange/Customs", - "ge": "Interchange/Customs", - "hu": "Interchange/Customs", - "it": "Interchange/Customs", - "jp": "Interchange/Customs", - "kr": "Interchange/Customs", - "pl": "Interchange/Customs", - "po": "Interchange/Customs", - "ru": "Interchange/Customs" + "ch": "Somewhere between Interchange and Customs", + "cz": "Somewhere between Interchange and Customs", + "en": "Somewhere between Interchange and Customs", + "es-mx": "Somewhere between Interchange and Customs", + "es": "Somewhere between Interchange and Customs", + "fr": "Quelque part entre l'échangeur et les douanes", + "ge": "Somewhere between Interchange and Customs", + "hu": "Somewhere between Interchange and Customs", + "it": "Somewhere between Interchange and Customs", + "jp": "Somewhere between Interchange and Customs", + "kr": "Somewhere between Interchange and Customs", + "pl": "Somewhere between Interchange and Customs", + "po": "Somewhere between Interchange and Customs", + "ru": "Somewhere between Interchange and Customs" }, "access_via": ["TrailerPark", "ScavCamp"] }, @@ -397,20 +376,20 @@ "// Trader name": "Jaeger", "override_description": true, "location_description": { - "ch": "Woods", - "cz": "Woods", - "en": "Woods", - "es-mx": "Woods", - "es": "Woods", - "fr": "Woods", - "ge": "Woods", - "hu": "Woods", - "it": "Woods", - "jp": "Woods", - "kr": "Woods", - "pl": "Woods", - "po": "Woods", - "ru": "Woods" + "ch": "Mountain stash in Woods", + "cz": "Mountain stash in Woods", + "en": "Mountain stash in Woods", + "es-mx": "Mountain stash in Woods", + "es": "Mountain stash in Woods", + "fr": "Cachette de la montagne dans les bois", + "ge": "Mountain stash in Woods", + "hu": "Mountain stash in Woods", + "it": "Mountain stash in Woods", + "jp": "Mountain stash in Woods", + "kr": "Mountain stash in Woods", + "pl": "Mountain stash in Woods", + "po": "Mountain stash in Woods", + "ru": "Mountain stash in Woods" }, "access_via": ["JaegerHideout"] }, @@ -418,20 +397,20 @@ "// Trader name": "Peacekeeper", "override_description": true, "location_description": { - "ch": "Shoreline/Reserve", - "cz": "Shoreline/Reserve", - "en": "Shoreline/Reserve", - "es-mx": "Shoreline/Reserve", - "es": "Shoreline/Reserve", - "fr": "Shoreline/Reserve", - "ge": "Shoreline/Reserve", - "hu": "Shoreline/Reserve", - "it": "Shoreline/Reserve", - "jp": "Shoreline/Reserve", - "kr": "Shoreline/Reserve", - "pl": "Shoreline/Reserve", - "po": "Shoreline/Reserve", - "ru": "Shoreline/Reserve" + "ch": "In D2 bunker between military reserve and shoreline", + "cz": "In D2 bunker between military reserve and shoreline", + "en": "In D2 bunker between military reserve and shoreline", + "es-mx": "In D2 bunker between military reserve and shoreline", + "es": "In D2 bunker between military reserve and shoreline", + "fr": "Dans le bunker D2 entre la réserve militaire et le littoral", + "ge": "In D2 bunker between military reserve and shoreline", + "hu": "In D2 bunker between military reserve and shoreline", + "it": "In D2 bunker between military reserve and shoreline", + "jp": "In D2 bunker between military reserve and shoreline", + "kr": "In D2 bunker between military reserve and shoreline", + "pl": "In D2 bunker between military reserve and shoreline", + "po": "In D2 bunker between military reserve and shoreline", + "ru": "In D2 bunker between military reserve and shoreline" }, "access_via": ["PeacekeeperHideout"] }, @@ -456,25 +435,46 @@ }, "heal_always_enabled": true }, + "6617beeaa9cfa777ca915b7c": { + "// Trader name": "Ref", + "override_description": true, + "location_description": { + "ch": "Along the railroad line between shoreline and customs", + "cz": "Along the railroad line between shoreline and customs", + "en": "Along the railroad line between shoreline and customs", + "es-mx": "Along the railroad line between shoreline and customs", + "es": "Along the railroad line between shoreline and customs", + "fr": "Le long de la voie ferrée entre le littoral et les douanes", + "ge": "Along the railroad line between shoreline and customs", + "hu": "Along the railroad line between shoreline and customs", + "it": "Along the railroad line between shoreline and customs", + "jp": "Along the railroad line between shoreline and customs", + "kr": "Along the railroad line between shoreline and customs", + "pl": "Along the railroad line between shoreline and customs", + "po": "Along the railroad line between shoreline and customs", + "ru": "Along the railroad line between shoreline and customs" + }, + "access_via": ["RailwayBridge", "PortRR"] + }, "6748adca5c70634464b214a8": { "// mod integration for Priscilu": true, "disable_warning": true, "override_description": true, "location_description": { - "ch": "Woods", - "cz": "Woods", - "en": "Woods", - "es-mx": "Woods", - "es": "Woods", - "fr": "Woods", - "ge": "Woods", - "hu": "Woods", - "it": "Woods", - "jp": "Woods", - "kr": "Woods", - "pl": "Woods", - "po": "Woods", - "ru": "Woods" + "ch": "Somewhere outskirts in woods", + "cz": "Somewhere outskirts in woods", + "en": "Somewhere outskirts in woods", + "es-mx": "Somewhere outskirts in woods", + "es": "Somewhere outskirts in woods", + "fr": "Quelque part en périphérie dans les bois", + "ge": "Somewhere outskirts in woods", + "hu": "Somewhere outskirts in woods", + "it": "Somewhere outskirts in woods", + "jp": "Somewhere outskirts in woods", + "kr": "Somewhere outskirts in woods", + "pl": "Somewhere outskirts in woods", + "po": "Somewhere outskirts in woods", + "ru": "Somewhere outskirts in woods" }, "access_via": ["Outskirts"] }, @@ -483,20 +483,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Customs", - "cz": "Customs", - "en": "Customs", - "es-mx": "Customs", - "es": "Customs", - "fr": "Customs", - "ge": "Customs", - "hu": "Customs", - "it": "Customs", - "jp": "Customs", - "kr": "Customs", - "pl": "Customs", - "po": "Customs", - "ru": "Customs" + "ch": "Trailer Park Workers Shack", + "cz": "Trailer Park Workers Shack", + "en": "Trailer Park Workers Shack", + "es-mx": "Trailer Park Workers Shack", + "es": "Trailer Park Workers Shack", + "fr": "Cabane des travailleurs du parc à remorques aux douanes", + "ge": "Trailer Park Workers Shack", + "hu": "Trailer Park Workers Shack", + "it": "Trailer Park Workers Shack", + "jp": "Trailer Park Workers Shack", + "kr": "Trailer Park Workers Shack", + "pl": "Trailer Park Workers Shack", + "po": "Trailer Park Workers Shack", + "ru": "Trailer Park Workers Shack" }, "access_via": ["LegsHideout"] }, @@ -505,20 +505,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Hideout", - "cz": "Hideout", - "en": "Hideout", - "es-mx": "Hideout", - "es": "Hideout", - "fr": "Hideout", - "ge": "Hideout", - "hu": "Hideout", - "it": "Hideout", - "jp": "Hideout", - "kr": "Hideout", - "pl": "Hideout", - "po": "Hideout", - "ru": "Hideout" + "ch": "Basement in town between streets and ground zero", + "cz": "Basement in town between streets and ground zero", + "en": "Basement in town between streets and ground zero", + "es-mx": "Basement in town between streets and ground zero", + "es": "Basement in town between streets and ground zero", + "fr": "Sous-sol en ville entre les rues et le point zéro", + "ge": "Basement in town between streets and ground zero", + "hu": "Basement in town between streets and ground zero", + "it": "Basement in town between streets and ground zero", + "jp": "Basement in town between streets and ground zero", + "kr": "Basement in town between streets and ground zero", + "pl": "Basement in town between streets and ground zero", + "po": "Basement in town between streets and ground zero", + "ru": "Basement in town between streets and ground zero" }, "access_via": ["BasementDescent"] }, @@ -527,20 +527,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Lighthouse", - "cz": "Lighthouse", - "en": "Lighthouse", - "es-mx": "Lighthouse", - "es": "Lighthouse", - "fr": "Lighthouse", - "ge": "Lighthouse", - "hu": "Lighthouse", - "it": "Lighthouse", - "jp": "Lighthouse", - "kr": "Lighthouse", - "pl": "Lighthouse", - "po": "Lighthouse", - "ru": "Lighthouse" + "ch": "Scav Hideout at the Grotto around lighthouse", + "cz": "Scav Hideout at the Grotto around lighthouse", + "en": "Scav Hideout at the Grotto around lighthouse", + "es-mx": "Scav Hideout at the Grotto around lighthouse", + "es": "Scav Hideout at the Grotto around lighthouse", + "fr": "Cachette Scav à la Grotte vers le phare", + "ge": "Scav Hideout at the Grotto around lighthouse", + "hu": "Scav Hideout at the Grotto around lighthouse", + "it": "Scav Hideout at the Grotto around lighthouse", + "jp": "Scav Hideout at the Grotto around lighthouse", + "kr": "Scav Hideout at the Grotto around lighthouse", + "pl": "Scav Hideout at the Grotto around lighthouse", + "po": "Scav Hideout at the Grotto around lighthouse", + "ru": "Scav Hideout at the Grotto around lighthouse" }, "access_via": ["ArtemHideout"] }, @@ -549,20 +549,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Woods/Reserve", - "cz": "Woods/Reserve", - "en": "Woods/Reserve", - "es-mx": "Woods/Reserve", - "es": "Woods/Reserve", - "fr": "Woods/Reserve", - "ge": "Woods/Reserve", - "hu": "Woods/Reserve", - "it": "Woods/Reserve", - "jp": "Woods/Reserve", - "kr": "Woods/Reserve", - "pl": "Woods/Reserve", - "po": "Woods/Reserve", - "ru": "Woods/Reserve" + "ch": "In ZB-14 bunker (Woods/Reserve)", + "cz": "In ZB-14 bunker (Woods/Reserve)", + "en": "In ZB-14 bunker (Woods/Reserve)", + "es-mx": "In ZB-14 bunker (Woods/Reserve)", + "es": "In ZB-14 bunker (Woods/Reserve)", + "fr": "Dans le bunker ZB-14 (Bois/Réserve militaire)", + "ge": "In ZB-14 bunker (Woods/Reserve)", + "hu": "In ZB-14 bunker (Woods/Reserve)", + "it": "In ZB-14 bunker (Woods/Reserve)", + "jp": "In ZB-14 bunker (Woods/Reserve)", + "kr": "In ZB-14 bunker (Woods/Reserve)", + "pl": "In ZB-14 bunker (Woods/Reserve)", + "po": "In ZB-14 bunker (Woods/Reserve)", + "ru": "In ZB-14 bunker (Woods/Reserve)" }, "access_via": ["ReserveZB-014"] }, @@ -571,20 +571,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Customs/Streets/Interchange", - "cz": "Customs/Streets/Interchange", - "en": "Customs/Streets/Interchange", - "es-mx": "Customs/Streets/Interchange", - "es": "Customs/Streets/Interchange", - "fr": "Customs/Streets/Interchange", - "ge": "Customs/Streets/Interchange", - "hu": "Customs/Streets/Interchange", - "it": "Customs/Streets/Interchange", - "jp": "Customs/Streets/Interchange", - "kr": "Customs/Streets/Interchange", - "pl": "Customs/Streets/Interchange", - "po": "Customs/Streets/Interchange", - "ru": "Customs/Streets/Interchange" + "ch": "Along the railroad line between customs streets and interchange", + "cz": "Along the railroad line between customs streets and interchange", + "en": "Along the railroad line between customs streets and interchange", + "es-mx": "Along the railroad line between customs streets and interchange", + "es": "Along the railroad line between customs streets and interchange", + "fr": "Le long de la ligne de chemin de fer entre les douanes, les rues et l'échangeur", + "ge": "Along the railroad line between customs streets and interchange", + "hu": "Along the railroad line between customs streets and interchange", + "it": "Along the railroad line between customs streets and interchange", + "jp": "Along the railroad line between customs streets and interchange", + "kr": "Along the railroad line between customs streets and interchange", + "pl": "Along the railroad line between customs streets and interchange", + "po": "Along the railroad line between customs streets and interchange", + "ru": "Along the railroad line between customs streets and interchange" }, "access_via": ["TarkovRR", "CrashSite", "Railway"] }, @@ -593,20 +593,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Interchange/Customs", - "cz": "Interchange/Customs", - "en": "Interchange/Customs", - "es-mx": "Interchange/Customs", - "es": "Interchange/Customs", - "fr": "Interchange/Customs", - "ge": "Interchange/Customs", - "hu": "Interchange/Customs", - "it": "Interchange/Customs", - "jp": "Interchange/Customs", - "kr": "Interchange/Customs", - "pl": "Interchange/Customs", - "po": "Interchange/Customs", - "ru": "Interchange/Customs" + "ch": "at Emercom Checkpoint between Interchange and Customs", + "cz": "at Emercom Checkpoint between Interchange and Customs", + "en": "at Emercom Checkpoint between Interchange and Customs", + "es-mx": "at Emercom Checkpoint between Interchange and Customs", + "es": "at Emercom Checkpoint between Interchange and Customs", + "fr": "au poste de contrôle Emercom, entre l'échangeur et les douanes", + "ge": "at Emercom Checkpoint between Interchange and Customs", + "hu": "at Emercom Checkpoint between Interchange and Customs", + "it": "at Emercom Checkpoint between Interchange and Customs", + "jp": "at Emercom Checkpoint between Interchange and Customs", + "kr": "at Emercom Checkpoint between Interchange and Customs", + "pl": "at Emercom Checkpoint between Interchange and Customs", + "po": "at Emercom Checkpoint between Interchange and Customs", + "ru": "at Emercom Checkpoint between Interchange and Customs" }, "access_via": ["Emercom", "Crossroads"] }, @@ -615,20 +615,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Ground Zero/Labs/Streets", - "cz": "Ground Zero/Labs/Streets", - "en": "Ground Zero/Labs/Streets", - "es-mx": "Ground Zero/Labs/Streets", - "es": "Ground Zero/Labs/Streets", - "fr": "Ground Zero/Labs/Streets", - "ge": "Ground Zero/Labs/Streets", - "hu": "Ground Zero/Labs/Streets", - "it": "Ground Zero/Labs/Streets", - "jp": "Ground Zero/Labs/Streets", - "kr": "Ground Zero/Labs/Streets", - "pl": "Ground Zero/Labs/Streets", - "po": "Ground Zero/Labs/Streets", - "ru": "Ground Zero/Labs/Streets" + "ch": "Basement in town between streets and ground zero", + "cz": "Basement in town between streets and ground zero", + "en": "Basement in town between streets and ground zero", + "es-mx": "Basement in town between streets and ground zero", + "es": "Basement in town between streets and ground zero", + "fr": "Sous-sol en ville entre les rues et le point zéro", + "ge": "Basement in town between streets and ground zero", + "hu": "Basement in town between streets and ground zero", + "it": "Basement in town between streets and ground zero", + "jp": "Basement in town between streets and ground zero", + "kr": "Basement in town between streets and ground zero", + "pl": "Basement in town between streets and ground zero", + "po": "Basement in town between streets and ground zero", + "ru": "Basement in town between streets and ground zero" }, "access_via": ["BasementDescent"] }, @@ -637,20 +637,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Streets", - "cz": "Streets", - "en": "Streets", - "es-mx": "Streets", - "es": "Streets", - "fr": "Streets", - "ge": "Streets", - "hu": "Streets", - "it": "Streets", - "jp": "Streets", - "kr": "Streets", - "pl": "Streets", - "po": "Streets", - "ru": "Streets" + "ch": "Ruined house in the streets", + "cz": "Ruined house in the streets", + "en": "Ruined house in the streets", + "es-mx": "Ruined house in the streets", + "es": "Ruined house in the streets", + "fr": "Maison en ruine dans les rues", + "ge": "Ruined house in the streets", + "hu": "Ruined house in the streets", + "it": "Ruined house in the streets", + "jp": "Ruined house in the streets", + "kr": "Ruined house in the streets", + "pl": "Ruined house in the streets", + "po": "Ruined house in the streets", + "ru": "Ruined house in the streets" }, "access_via": ["RuinedHouse"] }, @@ -659,20 +659,20 @@ "disable_warning": true, "override_description": true, "location_description": { - "ch": "Reserve/Streets", - "cz": "Reserve/Streets", - "en": "Reserve/Streets", - "es-mx": "Reserve/Streets", - "es": "Reserve/Streets", - "fr": "Reserve/Streets", - "ge": "Reserve/Streets", - "hu": "Reserve/Streets", - "it": "Reserve/Streets", - "jp": "Reserve/Streets", - "kr": "Reserve/Streets", - "pl": "Reserve/Streets", - "po": "Reserve/Streets", - "ru": "Reserve/Streets" + "ch": "Sewer between Reserve and Streets", + "cz": "Sewer between Reserve and Streets", + "en": "Sewer between Reserve and Streets", + "es-mx": "Sewer between Reserve and Streets", + "es": "Sewer between Reserve and Streets", + "fr": "Égout entre la réserve militaire et les rues", + "ge": "Sewer between Reserve and Streets", + "hu": "Sewer between Reserve and Streets", + "it": "Sewer between Reserve and Streets", + "jp": "Sewer between Reserve and Streets", + "kr": "Sewer between Reserve and Streets", + "pl": "Sewer between Reserve and Streets", + "po": "Sewer between Reserve and Streets", + "ru": "Sewer between Reserve and Streets" }, "access_via": ["Manhole"] } From ef745c45ca4c1536649b119bf92691610250b57e Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 21:19:09 +0100 Subject: [PATCH 046/203] fix: use traders location instead of traders description --- src/traders-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traders-controller.ts b/src/traders-controller.ts index 50889d80..2f36ad0e 100644 --- a/src/traders-controller.ts +++ b/src/traders-controller.ts @@ -57,7 +57,7 @@ export class TradersController { if (desc) { const globalLocale = locales?.global?.[locale]; - const localeId = `${traderId} Description`; + const localeId = `${traderId} Location`; if (globalLocale && globalLocale[localeId]) { globalLocale[localeId] = desc; From 8a489012e7fb168caa504cfb864660b142c6f83a Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 21:30:47 +0100 Subject: [PATCH 047/203] fix: remove unused vanilla_exfils_requirements in all configs --- configs/Default/config.json | 1 - configs/DevilFlippy/config.json | 1 - configs/ExampleOverrideByProfiles/config.json | 1 - configs/LegacyPathToTarkovV4/config.json | 1 - configs/LegacyPathToTarkovV5/config.json | 1 - configs/LinearPath/config.json | 1 - configs/OriginalNarcoticsConfig/config.json | 1 - configs/PathToTarkovReloaded/config.json | 1 - 8 files changed, 8 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index b9794e24..02b12231 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -5,7 +5,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": true, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "disable_all_transits": false, diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index ccb20348..1b6abc74 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -7,7 +7,6 @@ "flea_access_restriction": true, "flea_access_level": 1, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, diff --git a/configs/ExampleOverrideByProfiles/config.json b/configs/ExampleOverrideByProfiles/config.json index e1ac15e8..f1ac2aab 100644 --- a/configs/ExampleOverrideByProfiles/config.json +++ b/configs/ExampleOverrideByProfiles/config.json @@ -13,7 +13,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, diff --git a/configs/LegacyPathToTarkovV4/config.json b/configs/LegacyPathToTarkovV4/config.json index 152b36bf..1eddd726 100644 --- a/configs/LegacyPathToTarkovV4/config.json +++ b/configs/LegacyPathToTarkovV4/config.json @@ -5,7 +5,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, diff --git a/configs/LegacyPathToTarkovV5/config.json b/configs/LegacyPathToTarkovV5/config.json index bc6c7b35..105a054a 100644 --- a/configs/LegacyPathToTarkovV5/config.json +++ b/configs/LegacyPathToTarkovV5/config.json @@ -7,7 +7,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, diff --git a/configs/LinearPath/config.json b/configs/LinearPath/config.json index 4015445e..72c4fe87 100644 --- a/configs/LinearPath/config.json +++ b/configs/LinearPath/config.json @@ -5,7 +5,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index 13bc7887..7ac69fac 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -5,7 +5,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": true, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index 7d65fd74..c6a28fb0 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -5,7 +5,6 @@ "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, - "vanilla_exfils_requirements": false, "player_scav_move_offraid_position": false, "workbench_always_enabled": true, "bypass_keep_found_in_raid_tweak": false, From 12585423c3440e4254a6490796a9db4b5976c0b7 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 5 Dec 2024 21:43:02 +0100 Subject: [PATCH 048/203] feat: more exfils for laboratory --- configs/Default/config.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 02b12231..4ce812ca 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -779,9 +779,11 @@ }, "laboratory": { "lab_Hangar_Gate": "Catacombs", + "lab_Parking_Gate": "BasementDescent", "lab_Under_Storage_Collector": "SewerRiver", "lab_Elevator_Main": "SylobateElevator", "lab_Elevator_Cargo": "BasementDescent", + "lab_Elevator_Med": "BasementDescent", "lab_Vent": "VentShaft" }, "sandbox": { @@ -1058,7 +1060,7 @@ "BasementDescent": { "sandbox": ["Nakatani Basement Stairs"], "tarkovstreets": ["Basement Descent"], - "laboratory": ["Cargo Elevator"] + "laboratory": ["Cargo Elevator", "Parking Gate", "Med Block Elevator"] }, "RuinedHouse": { "tarkovstreets": ["Streets Ruined House"] From 276386dce7f59abf5b936cb45dc7df72846b4c34 Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 6 Dec 2024 13:25:35 +0100 Subject: [PATCH 049/203] refactor: split PTT-Extracts into several BepInEx patches --- PTT-Extracts/PTTExtracts.csproj | 4 ++-- .../InitAllExfiltrationPointsPatch.cs} | 19 +++--------------- .../Patches/ScavExfiltrationPointPatch.cs | 20 +++++++++++++++++++ PTT-Extracts/Plugin.cs | 4 ++-- 4 files changed, 27 insertions(+), 20 deletions(-) rename PTT-Extracts/{Patch.cs => Patches/InitAllExfiltrationPointsPatch.cs} (91%) create mode 100644 PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs diff --git a/PTT-Extracts/PTTExtracts.csproj b/PTT-Extracts/PTTExtracts.csproj index 08b1918e..4e8a77b3 100644 --- a/PTT-Extracts/PTTExtracts.csproj +++ b/PTT-Extracts/PTTExtracts.csproj @@ -3,8 +3,8 @@ netstandard2.0 PTTExtracts - Unlock scavs exfiltrations for PMCs (Patches for Path to Tarkov) - 1.0.1 + Extract Patches for Path to Tarkov + 1.0.2 true latest diff --git a/PTT-Extracts/Patch.cs b/PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs similarity index 91% rename from PTT-Extracts/Patch.cs rename to PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs index 53c8ae62..d3352b62 100644 --- a/PTT-Extracts/Patch.cs +++ b/PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs @@ -6,23 +6,8 @@ using EFT.Interactive; using HarmonyLib; -namespace PTTExtracts +namespace PTT.Extracts { - public class ScavExfiltrationPointPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return typeof(ScavExfiltrationPoint).GetMethod("InfiltrationMatch", BindingFlags.Public | BindingFlags.Instance); - } - - [PatchPrefix] - private static bool Prefix(ref bool __result) - { - __result = true; - return false; - } - } - public class InitAllExfiltrationPointsPatch : ModulePatch { public static bool NameMatches(LocationExitClass x) @@ -119,4 +104,6 @@ private static bool PatchPrefix(ref ExfiltrationControllerClass __instance, Loca return false; } } + } + diff --git a/PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs b/PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs new file mode 100644 index 00000000..bca812c4 --- /dev/null +++ b/PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using SPT.Reflection.Patching; +using EFT.Interactive; + +namespace PTT.Extracts +{ + public class ScavExfiltrationPointPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return typeof(ScavExfiltrationPoint).GetMethod("InfiltrationMatch", BindingFlags.Public | BindingFlags.Instance); + } + [PatchPrefix] + private static bool Prefix(ref bool __result) + { + __result = true; + return false; + } + } +} \ No newline at end of file diff --git a/PTT-Extracts/Plugin.cs b/PTT-Extracts/Plugin.cs index ea887d0f..bcfdc7e4 100644 --- a/PTT-Extracts/Plugin.cs +++ b/PTT-Extracts/Plugin.cs @@ -7,8 +7,8 @@ public class Plugin : BaseUnityPlugin { public void Awake() { - new InitAllExfiltrationPointsPatch().Enable(); - new ScavExfiltrationPointPatch().Enable(); + new PTT.Extracts.InitAllExfiltrationPointsPatch().Enable(); + new PTT.Extracts.ScavExfiltrationPointPatch().Enable(); Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); } From 67cdcf4e6903f319352e50a46a3569d88bd86075 Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 6 Dec 2024 20:42:11 +0100 Subject: [PATCH 050/203] feat(client): hide locked traders --- PTT-Extracts/PTTExtracts.csproj | 3 ++ PTT-Extracts/Patches/TraderLockPatch.cs | 40 +++++++++++++++++++++++++ PTT-Extracts/Plugin.cs | 2 ++ 3 files changed, 45 insertions(+) create mode 100644 PTT-Extracts/Patches/TraderLockPatch.cs diff --git a/PTT-Extracts/PTTExtracts.csproj b/PTT-Extracts/PTTExtracts.csproj index 4e8a77b3..aaeacabc 100644 --- a/PTT-Extracts/PTTExtracts.csproj +++ b/PTT-Extracts/PTTExtracts.csproj @@ -18,6 +18,9 @@ ..\..\..\..\BepInEx\plugins\spt\spt-reflection.dll + + ..\..\..\..\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll + ..\..\..\..\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll diff --git a/PTT-Extracts/Patches/TraderLockPatch.cs b/PTT-Extracts/Patches/TraderLockPatch.cs new file mode 100644 index 00000000..cb4f14e5 --- /dev/null +++ b/PTT-Extracts/Patches/TraderLockPatch.cs @@ -0,0 +1,40 @@ +using System.Reflection; +using SPT.Reflection.Patching; +using EFT; +using EFT.UI; + +namespace PTT.Traders +{ + // old way of doing it + internal class LockTraderPanelPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() => + typeof(TraderPanel).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public); + [PatchPostfix] + private static void Postfix(TraderCard __instance, ref Profile.TraderInfo trader) + { + if (trader.Unlocked) + { + return; + } + __instance.HideGameObject(); // Lock the trader if not unlocked + } + } + + // new way of doing it + internal class LockTraderCardPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() => + typeof(TraderCard).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public); + [PatchPostfix] + private static void Postfix(TraderCard __instance, ref Profile.TraderInfo trader) + { + if (trader.Unlocked) + { + return; + } + __instance.HideGameObject(); // Lock the trader if not unlocked + } + } + +} \ No newline at end of file diff --git a/PTT-Extracts/Plugin.cs b/PTT-Extracts/Plugin.cs index bcfdc7e4..c549e975 100644 --- a/PTT-Extracts/Plugin.cs +++ b/PTT-Extracts/Plugin.cs @@ -9,6 +9,8 @@ public void Awake() { new PTT.Extracts.InitAllExfiltrationPointsPatch().Enable(); new PTT.Extracts.ScavExfiltrationPointPatch().Enable(); + new PTT.Traders.LockTraderCardPatch().Enable(); + new PTT.Traders.LockTraderPanelPatch().Enable(); Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); } From 4c64e083545c47f6d8b4240305cc50b5d9b5835c Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 6 Dec 2024 21:06:46 +0100 Subject: [PATCH 051/203] refactor: rename PTTExtracts.dll into Trap.PathToTarkov.dll --- .gitignore | 4 +- .prettierignore | 2 +- {PTT-Extracts => PTT-BepInEx}/.gitattributes | 0 {PTT-Extracts => PTT-BepInEx}/.gitignore | 0 PTT-BepInEx/ConfigurationManagerAttributes.cs | 103 +++++++++++++++++ {PTT-Extracts => PTT-BepInEx}/NuGet.Config | 0 .../PTT.csproj | 6 +- .../PTTExtracts.sln => PTT-BepInEx/PTT.sln | 2 +- PTT-BepInEx/Patches/HideLockedTraderPatch.cs | 39 +++++++ .../Patches/InitAllExfiltrationPointsPatch.cs | 107 +++++++++++++++++ .../Patches/ScavExfiltrationPointPatch.cs | 20 ++++ PTT-BepInEx/Plugin.cs | 19 +++ PTT-Extracts/License.txt | 64 ---------- .../Patches/InitAllExfiltrationPointsPatch.cs | 109 ------------------ .../Patches/ScavExfiltrationPointPatch.cs | 20 ---- PTT-Extracts/Patches/TraderLockPatch.cs | 40 ------- PTT-Extracts/Plugin.cs | 18 --- package.json | 4 +- scripts/install-files.js | 2 +- scripts/prepare-files.js | 5 +- 20 files changed, 302 insertions(+), 262 deletions(-) rename {PTT-Extracts => PTT-BepInEx}/.gitattributes (100%) rename {PTT-Extracts => PTT-BepInEx}/.gitignore (100%) create mode 100644 PTT-BepInEx/ConfigurationManagerAttributes.cs rename {PTT-Extracts => PTT-BepInEx}/NuGet.Config (100%) rename PTT-Extracts/PTTExtracts.csproj => PTT-BepInEx/PTT.csproj (90%) rename PTT-Extracts/PTTExtracts.sln => PTT-BepInEx/PTT.sln (88%) create mode 100644 PTT-BepInEx/Patches/HideLockedTraderPatch.cs create mode 100644 PTT-BepInEx/Patches/InitAllExfiltrationPointsPatch.cs create mode 100644 PTT-BepInEx/Patches/ScavExfiltrationPointPatch.cs create mode 100644 PTT-BepInEx/Plugin.cs delete mode 100644 PTT-Extracts/License.txt delete mode 100644 PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs delete mode 100644 PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs delete mode 100644 PTT-Extracts/Patches/TraderLockPatch.cs delete mode 100644 PTT-Extracts/Plugin.cs diff --git a/.gitignore b/.gitignore index 8f5cb5e0..ebe00112 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ /mod.zip /configs/UserConfig.json -/PTT-Extracts/bin -/PTT-Extracts/obj +/PTT-BepInEx/bin +/PTT-BepInEx/obj diff --git a/.prettierignore b/.prettierignore index 0f4651c8..0edb48c0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,6 +3,6 @@ /dist/ /src/*.js /Trap-PathToTarkov-* -/PTT-Extracts/ +/PTT-BepInEx/ *.md package-lock.json diff --git a/PTT-Extracts/.gitattributes b/PTT-BepInEx/.gitattributes similarity index 100% rename from PTT-Extracts/.gitattributes rename to PTT-BepInEx/.gitattributes diff --git a/PTT-Extracts/.gitignore b/PTT-BepInEx/.gitignore similarity index 100% rename from PTT-Extracts/.gitignore rename to PTT-BepInEx/.gitignore diff --git a/PTT-BepInEx/ConfigurationManagerAttributes.cs b/PTT-BepInEx/ConfigurationManagerAttributes.cs new file mode 100644 index 00000000..13a35116 --- /dev/null +++ b/PTT-BepInEx/ConfigurationManagerAttributes.cs @@ -0,0 +1,103 @@ +///

+/// Class that specifies how a setting should be displayed inside the ConfigurationManager settings window. +/// +/// Usage: +/// This class template has to be copied inside the plugin's project and referenced by its code directly. +/// make a new instance, assign any fields that you want to override, and pass it as a tag for your setting. +/// +/// If a field is null (default), it will be ignored and won't change how the setting is displayed. +/// If a field is non-null (you assigned a value to it), it will override default behavior. +/// +/// +/// +/// Here's an example of overriding order of settings and marking one of the settings as advanced: +/// +/// // Override IsAdvanced and Order +/// Config.AddSetting("X", "1", 1, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true, Order = 3 })); +/// // Override only Order, IsAdvanced stays as the default value assigned by ConfigManager +/// Config.AddSetting("X", "2", 2, new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 1 })); +/// Config.AddSetting("X", "3", 3, new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 2 })); +/// +/// +/// +/// +/// You can read more and see examples in the readme at https://github.com/BepInEx/BepInEx.ConfigurationManager +/// You can optionally remove fields that you won't use from this class, it's the same as leaving them null. +/// +#pragma warning disable 0169, 0414, 0649 +internal sealed class ConfigurationManagerAttributes +{ + /// + /// Should the setting be shown as a percentage (only use with value range settings). + /// + public bool? ShowRangeAsPercent; + + /// + /// Custom setting editor (OnGUI code that replaces the default editor provided by ConfigurationManager). + /// See below for a deeper explanation. Using a custom drawer will cause many of the other fields to do nothing. + /// + public System.Action CustomDrawer; + + /// + /// Show this setting in the settings screen at all? If false, don't show. + /// + public bool? Browsable; + + /// + /// Category the setting is under. Null to be directly under the plugin. + /// + public string Category; + + /// + /// If set, a "Default" button will be shown next to the setting to allow resetting to default. + /// + public object DefaultValue; + + /// + /// Force the "Reset" button to not be displayed, even if a valid DefaultValue is available. + /// + public bool? HideDefaultButton; + + /// + /// Force the setting name to not be displayed. Should only be used with a to get more space. + /// Can be used together with to gain even more space. + /// + public bool? HideSettingName; + + /// + /// Optional description shown when hovering over the setting. + /// Not recommended, provide the description when creating the setting instead. + /// + public string Description; + + /// + /// Name of the setting. + /// + public string DispName; + + /// + /// Order of the setting on the settings list relative to other settings in a category. + /// 0 by default, higher number is higher on the list. + /// + public int? Order; + + /// + /// Only show the value, don't allow editing it. + /// + public bool? ReadOnly; + + /// + /// If true, don't show the setting by default. User has to turn on showing advanced settings or search for it. + /// + public bool? IsAdvanced; + + /// + /// Custom converter from setting type to string for the built-in editor textboxes. + /// + public System.Func ObjToStr; + + /// + /// Custom converter from string to setting type for the built-in editor textboxes. + /// + public System.Func StrToObj; +} \ No newline at end of file diff --git a/PTT-Extracts/NuGet.Config b/PTT-BepInEx/NuGet.Config similarity index 100% rename from PTT-Extracts/NuGet.Config rename to PTT-BepInEx/NuGet.Config diff --git a/PTT-Extracts/PTTExtracts.csproj b/PTT-BepInEx/PTT.csproj similarity index 90% rename from PTT-Extracts/PTTExtracts.csproj rename to PTT-BepInEx/PTT.csproj index aaeacabc..24420e99 100644 --- a/PTT-Extracts/PTTExtracts.csproj +++ b/PTT-BepInEx/PTT.csproj @@ -2,9 +2,9 @@ netstandard2.0 - PTTExtracts - Extract Patches for Path to Tarkov - 1.0.2 + Trap.PathToTarkov + Client patches for Path to Tarkov + 1.1.0 true latest diff --git a/PTT-Extracts/PTTExtracts.sln b/PTT-BepInEx/PTT.sln similarity index 88% rename from PTT-Extracts/PTTExtracts.sln rename to PTT-BepInEx/PTT.sln index 186d6876..4331e11b 100644 --- a/PTT-Extracts/PTTExtracts.sln +++ b/PTT-BepInEx/PTT.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.32106.194 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PTTExtracts", "PTTExtracts.csproj", "{C1DE1108-5182-4676-AF15-8802E053494E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PTT", "PTT.csproj", "{C1DE1108-5182-4676-AF15-8802E053494E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/PTT-BepInEx/Patches/HideLockedTraderPatch.cs b/PTT-BepInEx/Patches/HideLockedTraderPatch.cs new file mode 100644 index 00000000..a7f50dd0 --- /dev/null +++ b/PTT-BepInEx/Patches/HideLockedTraderPatch.cs @@ -0,0 +1,39 @@ +using System.Reflection; +using SPT.Reflection.Patching; +using EFT; +using EFT.UI; + +namespace PTT.Patches; + +// old +internal class HideLockedTraderPanelPatch : ModulePatch +{ + protected override MethodBase GetTargetMethod() => + typeof(TraderPanel).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public); + + [PatchPostfix] + protected static void Postfix(TraderPanel __instance, ref Profile.TraderInfo trader) + { + if (!trader.Unlocked) + { + __instance.HideGameObject(); + } + } +} + +// new +internal class HideLockedTraderCardPatch : ModulePatch +{ + protected override MethodBase GetTargetMethod() => + typeof(TraderCard).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public); + + [PatchPostfix] + protected static void Postfix(TraderCard __instance, ref Profile.TraderInfo trader) + { + if (!trader.Unlocked) + { + __instance.HideGameObject(); + } + } +} + diff --git a/PTT-BepInEx/Patches/InitAllExfiltrationPointsPatch.cs b/PTT-BepInEx/Patches/InitAllExfiltrationPointsPatch.cs new file mode 100644 index 00000000..db637e75 --- /dev/null +++ b/PTT-BepInEx/Patches/InitAllExfiltrationPointsPatch.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using SPT.Reflection.Patching; +using EFT.Interactive; +using HarmonyLib; + +namespace PTT.Patches; + +internal class InitAllExfiltrationPointsPatch : ModulePatch +{ + private static bool NameMatches(LocationExitClass x) + { + return exitName == x.Name; + } + + private static string exitName; + + private static bool RandomRange(ExfiltrationPoint trigger) + { + return UnityEngine.Random.Range(0f, 100f) <= trigger.Settings.Chance; + } + + private static bool IsNotScavExfil(ExfiltrationPoint x) + { + return x is not ScavExfiltrationPoint || x is SharedExfiltrationPoint; + } + + private static bool IsScavExfil(ExfiltrationPoint x) + { + return x is ScavExfiltrationPoint; + } + + protected override MethodBase GetTargetMethod() + { + return typeof(ExfiltrationControllerClass).GetMethod("InitAllExfiltrationPoints", BindingFlags.Public | BindingFlags.Instance); + } + + [PatchPrefix] + protected static bool PatchPrefix(ref ExfiltrationControllerClass __instance, LocationExitClass[] settings, bool justLoadSettings = false, bool giveAuthority = true) + { + ExfiltrationPoint[] source = LocationScene.GetAllObjects(false).ToArray(); + ExfiltrationPoint[] scavExfilArr = source.Where(new Func(IsScavExfil)).ToArray(); + ExfiltrationPoint[] pmcExfilArr = source.Where(new Func(IsNotScavExfil)).ToArray(); + + List pmcExfilList = pmcExfilArr.ToList(); + + foreach (ExfiltrationPoint scavExfil in scavExfilArr) + { + if (!pmcExfilList.Any(k => k.Settings.Name == scavExfil.Settings.Name)) + { + pmcExfilList.Add(scavExfil); + } + } + + AccessTools.Property(typeof(ExfiltrationControllerClass), "ExfiltrationPoints").SetValue(__instance, pmcExfilList.ToArray()); + + AccessTools.Property(typeof(ExfiltrationControllerClass), "ScavExfiltrationPoints").SetValue(__instance, source.Where(new Func(IsScavExfil)).Cast().ToArray()); + + AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").SetValue(__instance, new List(__instance.ScavExfiltrationPoints.Length)); + AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").SetValue(__instance, new List()); + + List list_0 = (List)AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").GetValue(__instance); + List list_1 = (List)AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").GetValue(__instance); + + foreach (ScavExfiltrationPoint scavExfiltrationPoint in __instance.ScavExfiltrationPoints) + { + Logger.LogWarning("Scav Exfil name = " + scavExfiltrationPoint.Settings.Name); + SharedExfiltrationPoint sharedExfiltrationPoint = scavExfiltrationPoint as SharedExfiltrationPoint; + if (sharedExfiltrationPoint != null && sharedExfiltrationPoint.IsMandatoryForScavs) + { + list_1.Add(scavExfiltrationPoint); + } + else + { + list_0.Add(scavExfiltrationPoint); + } + } + AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").SetValue(__instance, list_0); + AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").SetValue(__instance, list_1); + + UnityEngine.Random.InitState((int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()); + + foreach (ExfiltrationPoint exfiltrationPoint in __instance.ExfiltrationPoints) + { + Logger.LogWarning("PMC Exfil name = " + exfiltrationPoint.Settings.Name); + exitName = exfiltrationPoint.Settings.Name; + LocationExitClass locationExit = settings.FirstOrDefault(new Func(NameMatches)); + if (locationExit != null) + { + exfiltrationPoint.LoadSettings(exfiltrationPoint.Id, locationExit, giveAuthority); + if (!justLoadSettings && !RandomRange(exfiltrationPoint)) + { + exfiltrationPoint.SetStatusLogged(EExfiltrationStatus.NotPresent, "ExfiltrationController.InitAllExfiltrationPoints-2"); + } + } + else + { + exfiltrationPoint.SetStatusLogged(EExfiltrationStatus.NotPresent, "ExfiltrationController.InitAllExfiltrationPoints-3"); + } + } + + return false; + } +} + diff --git a/PTT-BepInEx/Patches/ScavExfiltrationPointPatch.cs b/PTT-BepInEx/Patches/ScavExfiltrationPointPatch.cs new file mode 100644 index 00000000..d5fc6846 --- /dev/null +++ b/PTT-BepInEx/Patches/ScavExfiltrationPointPatch.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using SPT.Reflection.Patching; +using EFT.Interactive; + +namespace PTT.Patches; + +internal class ScavExfiltrationPointPatch : ModulePatch +{ + protected override MethodBase GetTargetMethod() + { + return typeof(ScavExfiltrationPoint).GetMethod("InfiltrationMatch", BindingFlags.Public | BindingFlags.Instance); + } + + [PatchPrefix] + protected static bool Prefix(ref bool __result) + { + __result = true; + return false; + } +} diff --git a/PTT-BepInEx/Plugin.cs b/PTT-BepInEx/Plugin.cs new file mode 100644 index 00000000..ad8b4850 --- /dev/null +++ b/PTT-BepInEx/Plugin.cs @@ -0,0 +1,19 @@ +using BepInEx; + +namespace PTT; + +[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] +public class Plugin : BaseUnityPlugin +{ + public void Awake() + { + Settings.Config.Init(Config); + + new Patches.HideLockedTraderCardPatch().Enable(); + new Patches.HideLockedTraderPanelPatch().Enable(); + new Patches.InitAllExfiltrationPointsPatch().Enable(); + new Patches.ScavExfiltrationPointPatch().Enable(); + + Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); + } +} diff --git a/PTT-Extracts/License.txt b/PTT-Extracts/License.txt deleted file mode 100644 index d5f95ad5..00000000 --- a/PTT-Extracts/License.txt +++ /dev/null @@ -1,64 +0,0 @@ -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. -License -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. - -1. Definitions - -"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. -"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(g) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. -"Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. -"License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, Noncommercial, ShareAlike. -"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. -"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. -"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. -"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. -"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. -"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. -2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. - -3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: - -to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; -to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; -to Distribute and Publicly Perform the Work including as incorporated in Collections; and, -to Distribute and Publicly Perform Adaptations. -The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights described in Section 4(e). - -4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: - -You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(d), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(d), as requested. -You may Distribute or Publicly Perform an Adaptation only under: (i) the terms of this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-NonCommercial-ShareAlike 3.0 US) ("Applicable License"). You must include a copy of, or the URI, for Applicable License with every copy of each Adaptation You Distribute or Publicly Perform. You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License. You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License. -You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in con-nection with the exchange of copyrighted works. -If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(d) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. -For the avoidance of doubt: - -Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; -Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and, -Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c). -Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. -5. Representations, Warranties and Disclaimer - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING AND TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THIS EXCLUSION MAY NOT APPLY TO YOU. - -6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. Termination - -This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. -Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. -8. Miscellaneous - -Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. -Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. -If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. -No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. -This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. -The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. -Creative Commons Notice -Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License. - -Creative Commons may be contacted at https://creativecommons.org/. \ No newline at end of file diff --git a/PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs b/PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs deleted file mode 100644 index d3352b62..00000000 --- a/PTT-Extracts/Patches/InitAllExfiltrationPointsPatch.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using SPT.Reflection.Patching; -using EFT.Interactive; -using HarmonyLib; - -namespace PTT.Extracts -{ - public class InitAllExfiltrationPointsPatch : ModulePatch - { - public static bool NameMatches(LocationExitClass x) - { - return exitName == x.Name; - } - - public static string exitName; - - public static bool RandomRange(ExfiltrationPoint trigger) - { - return UnityEngine.Random.Range(0f, 100f) <= trigger.Settings.Chance; - } - - public static bool IsNotScavExfil(ExfiltrationPoint x) - { - return x is not ScavExfiltrationPoint || x is SharedExfiltrationPoint; - } - - public static bool IsScavExfil(ExfiltrationPoint x) - { - return x is ScavExfiltrationPoint; - } - - protected override MethodBase GetTargetMethod() - { - return typeof(ExfiltrationControllerClass).GetMethod("InitAllExfiltrationPoints", BindingFlags.Public | BindingFlags.Instance); - } - - [PatchPrefix] - private static bool PatchPrefix(ref ExfiltrationControllerClass __instance, LocationExitClass[] settings, bool justLoadSettings = false, bool giveAuthority = true) - { - ExfiltrationPoint[] source = LocationScene.GetAllObjects(false).ToArray(); - ExfiltrationPoint[] scavExfilArr = source.Where(new Func(IsScavExfil)).ToArray(); - ExfiltrationPoint[] pmcExfilArr = source.Where(new Func(IsNotScavExfil)).ToArray(); - - List pmcExfilList = pmcExfilArr.ToList(); - - foreach (ExfiltrationPoint scavExfil in scavExfilArr) - { - if (!pmcExfilList.Any(k => k.Settings.Name == scavExfil.Settings.Name)) - { - pmcExfilList.Add(scavExfil); - } - } - - AccessTools.Property(typeof(ExfiltrationControllerClass), "ExfiltrationPoints").SetValue(__instance, pmcExfilList.ToArray()); - - AccessTools.Property(typeof(ExfiltrationControllerClass), "ScavExfiltrationPoints").SetValue(__instance, source.Where(new Func(IsScavExfil)).Cast().ToArray()); - - AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").SetValue(__instance, new List(__instance.ScavExfiltrationPoints.Length)); - AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").SetValue(__instance, new List()); - - List list_0 = (List)AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").GetValue(__instance); - List list_1 = (List)AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").GetValue(__instance); - - foreach (ScavExfiltrationPoint scavExfiltrationPoint in __instance.ScavExfiltrationPoints) - { - Logger.LogWarning("Scav Exfil name = " + scavExfiltrationPoint.Settings.Name); - SharedExfiltrationPoint sharedExfiltrationPoint; - if ((sharedExfiltrationPoint = (scavExfiltrationPoint as SharedExfiltrationPoint)) != null && sharedExfiltrationPoint.IsMandatoryForScavs) - { - list_1.Add(scavExfiltrationPoint); - } - else - { - list_0.Add(scavExfiltrationPoint); - } - } - AccessTools.Field(typeof(ExfiltrationControllerClass), "list_0").SetValue(__instance, list_0); - AccessTools.Field(typeof(ExfiltrationControllerClass), "list_1").SetValue(__instance, list_1); - - UnityEngine.Random.InitState((int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()); - - foreach (ExfiltrationPoint exfiltrationPoint in __instance.ExfiltrationPoints) - { - Logger.LogWarning("PMC Exfil name = " + exfiltrationPoint.Settings.Name); - exitName = exfiltrationPoint.Settings.Name; - LocationExitClass gclass = settings.FirstOrDefault(new Func(NameMatches)); - if (gclass != null) - { - exfiltrationPoint.LoadSettings(exfiltrationPoint.Id, gclass, giveAuthority); - if (!justLoadSettings && !RandomRange(exfiltrationPoint)) - { - exfiltrationPoint.SetStatusLogged(EExfiltrationStatus.NotPresent, "ExfiltrationController.InitAllExfiltrationPoints-2"); - } - } - else - { - exfiltrationPoint.SetStatusLogged(EExfiltrationStatus.NotPresent, "ExfiltrationController.InitAllExfiltrationPoints-3"); - } - } - - return false; - } - } - -} - diff --git a/PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs b/PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs deleted file mode 100644 index bca812c4..00000000 --- a/PTT-Extracts/Patches/ScavExfiltrationPointPatch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Reflection; -using SPT.Reflection.Patching; -using EFT.Interactive; - -namespace PTT.Extracts -{ - public class ScavExfiltrationPointPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return typeof(ScavExfiltrationPoint).GetMethod("InfiltrationMatch", BindingFlags.Public | BindingFlags.Instance); - } - [PatchPrefix] - private static bool Prefix(ref bool __result) - { - __result = true; - return false; - } - } -} \ No newline at end of file diff --git a/PTT-Extracts/Patches/TraderLockPatch.cs b/PTT-Extracts/Patches/TraderLockPatch.cs deleted file mode 100644 index cb4f14e5..00000000 --- a/PTT-Extracts/Patches/TraderLockPatch.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Reflection; -using SPT.Reflection.Patching; -using EFT; -using EFT.UI; - -namespace PTT.Traders -{ - // old way of doing it - internal class LockTraderPanelPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() => - typeof(TraderPanel).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public); - [PatchPostfix] - private static void Postfix(TraderCard __instance, ref Profile.TraderInfo trader) - { - if (trader.Unlocked) - { - return; - } - __instance.HideGameObject(); // Lock the trader if not unlocked - } - } - - // new way of doing it - internal class LockTraderCardPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() => - typeof(TraderCard).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public); - [PatchPostfix] - private static void Postfix(TraderCard __instance, ref Profile.TraderInfo trader) - { - if (trader.Unlocked) - { - return; - } - __instance.HideGameObject(); // Lock the trader if not unlocked - } - } - -} \ No newline at end of file diff --git a/PTT-Extracts/Plugin.cs b/PTT-Extracts/Plugin.cs deleted file mode 100644 index c549e975..00000000 --- a/PTT-Extracts/Plugin.cs +++ /dev/null @@ -1,18 +0,0 @@ -using BepInEx; - -namespace PTTExtracts -{ - [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] - public class Plugin : BaseUnityPlugin - { - public void Awake() - { - new PTT.Extracts.InitAllExfiltrationPointsPatch().Enable(); - new PTT.Extracts.ScavExfiltrationPointPatch().Enable(); - new PTT.Traders.LockTraderCardPatch().Enable(); - new PTT.Traders.LockTraderPanelPatch().Enable(); - - Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); - } - } -} diff --git a/package.json b/package.json index d2a54dd1..c82d9536 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "rebuild": "npm run clean && npm run build", "build": "tsc", "build:all": "npm run build:doc && npm run build && npm run build:client", - "build:client": "cd PTT-Extracts && dotnet.exe build", - "clean:client": "cd PTT-Extracts && dotnet.exe clean && rimraf bin obj", + "build:client": "cd PTT-BepInEx && dotnet.exe build", + "clean:client": "cd PTT-BepInEx && dotnet.exe clean && rimraf bin obj", "test:all": "npm run lint:all && npm run test && npm run build:release", "test": "npx jest --verbose", "test:watch": "npx jest --watch", diff --git a/scripts/install-files.js b/scripts/install-files.js index 22020ea9..1d2d50ce 100644 --- a/scripts/install-files.js +++ b/scripts/install-files.js @@ -3,7 +3,7 @@ const { execSync } = require('child_process'); // eslint-disable-next-line @typescript-eslint/no-var-requires const packageJson = require('../package.json'); -const dllFileName = 'PTTExtracts.dll'; +const dllFileName = 'Trap.PathToTarkov.dll'; const cprFlags = '--overwrite'; const main = async modName => { diff --git a/scripts/prepare-files.js b/scripts/prepare-files.js index 7b046390..db5c064f 100644 --- a/scripts/prepare-files.js +++ b/scripts/prepare-files.js @@ -7,13 +7,16 @@ const { mkdirp } = require('mkdirp'); // // eslint-disable-next-line @typescript-eslint/no-var-requires // const cpr = require('cpr'); +const PTTClientDir = 'PTT-BepInEx' +const dllFileName = 'Trap.PathToTarkov.dll'; + const main = async modName => { [ 'rimraf dist/user', 'rimraf dist/BepInEx', () => mkdirp.sync(`./dist/user/mods/${modName}`), () => mkdirp.sync('./dist/BepInEx/plugins'), - 'cpr ./PTT-Extracts/bin/Debug/netstandard2.0/PTTExtracts.dll ./dist/BepInEx/plugins/PTTExtracts.dll -o', + `cpr ./${PTTClientDir}/bin/Debug/netstandard2.0/${dllFileName} ./dist/BepInEx/plugins/${dllFileName} -o`, `cpr package.json ./dist/user/mods/${modName}/package.json -o`, `cpr dist/src ./dist/user/mods/${modName}/src -o`, `cpr configs ./dist/user/mods/${modName}/configs -o`, From 0a1b0fe937570291b9258f58167feffc980f6601 Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 6 Dec 2024 23:12:27 +0100 Subject: [PATCH 052/203] feat(client): add BepInEx config for showing hidden traders --- PTT-BepInEx/ConfigurationManagerAttributes.cs | 103 ------------------ PTT-BepInEx/Patches/HideLockedTraderPatch.cs | 4 +- PTT-BepInEx/Settings/Config.cs | 18 +++ PTT-BepInEx/Utils/Trader.cs | 14 +++ 4 files changed, 34 insertions(+), 105 deletions(-) delete mode 100644 PTT-BepInEx/ConfigurationManagerAttributes.cs create mode 100644 PTT-BepInEx/Settings/Config.cs create mode 100644 PTT-BepInEx/Utils/Trader.cs diff --git a/PTT-BepInEx/ConfigurationManagerAttributes.cs b/PTT-BepInEx/ConfigurationManagerAttributes.cs deleted file mode 100644 index 13a35116..00000000 --- a/PTT-BepInEx/ConfigurationManagerAttributes.cs +++ /dev/null @@ -1,103 +0,0 @@ -/// -/// Class that specifies how a setting should be displayed inside the ConfigurationManager settings window. -/// -/// Usage: -/// This class template has to be copied inside the plugin's project and referenced by its code directly. -/// make a new instance, assign any fields that you want to override, and pass it as a tag for your setting. -/// -/// If a field is null (default), it will be ignored and won't change how the setting is displayed. -/// If a field is non-null (you assigned a value to it), it will override default behavior. -/// -/// -/// -/// Here's an example of overriding order of settings and marking one of the settings as advanced: -/// -/// // Override IsAdvanced and Order -/// Config.AddSetting("X", "1", 1, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true, Order = 3 })); -/// // Override only Order, IsAdvanced stays as the default value assigned by ConfigManager -/// Config.AddSetting("X", "2", 2, new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 1 })); -/// Config.AddSetting("X", "3", 3, new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 2 })); -/// -/// -/// -/// -/// You can read more and see examples in the readme at https://github.com/BepInEx/BepInEx.ConfigurationManager -/// You can optionally remove fields that you won't use from this class, it's the same as leaving them null. -/// -#pragma warning disable 0169, 0414, 0649 -internal sealed class ConfigurationManagerAttributes -{ - /// - /// Should the setting be shown as a percentage (only use with value range settings). - /// - public bool? ShowRangeAsPercent; - - /// - /// Custom setting editor (OnGUI code that replaces the default editor provided by ConfigurationManager). - /// See below for a deeper explanation. Using a custom drawer will cause many of the other fields to do nothing. - /// - public System.Action CustomDrawer; - - /// - /// Show this setting in the settings screen at all? If false, don't show. - /// - public bool? Browsable; - - /// - /// Category the setting is under. Null to be directly under the plugin. - /// - public string Category; - - /// - /// If set, a "Default" button will be shown next to the setting to allow resetting to default. - /// - public object DefaultValue; - - /// - /// Force the "Reset" button to not be displayed, even if a valid DefaultValue is available. - /// - public bool? HideDefaultButton; - - /// - /// Force the setting name to not be displayed. Should only be used with a to get more space. - /// Can be used together with to gain even more space. - /// - public bool? HideSettingName; - - /// - /// Optional description shown when hovering over the setting. - /// Not recommended, provide the description when creating the setting instead. - /// - public string Description; - - /// - /// Name of the setting. - /// - public string DispName; - - /// - /// Order of the setting on the settings list relative to other settings in a category. - /// 0 by default, higher number is higher on the list. - /// - public int? Order; - - /// - /// Only show the value, don't allow editing it. - /// - public bool? ReadOnly; - - /// - /// If true, don't show the setting by default. User has to turn on showing advanced settings or search for it. - /// - public bool? IsAdvanced; - - /// - /// Custom converter from setting type to string for the built-in editor textboxes. - /// - public System.Func ObjToStr; - - /// - /// Custom converter from string to setting type for the built-in editor textboxes. - /// - public System.Func StrToObj; -} \ No newline at end of file diff --git a/PTT-BepInEx/Patches/HideLockedTraderPatch.cs b/PTT-BepInEx/Patches/HideLockedTraderPatch.cs index a7f50dd0..e345f0a7 100644 --- a/PTT-BepInEx/Patches/HideLockedTraderPatch.cs +++ b/PTT-BepInEx/Patches/HideLockedTraderPatch.cs @@ -14,7 +14,7 @@ protected override MethodBase GetTargetMethod() => [PatchPostfix] protected static void Postfix(TraderPanel __instance, ref Profile.TraderInfo trader) { - if (!trader.Unlocked) + if (Utils.Trader.IsHidden(ref trader)) { __instance.HideGameObject(); } @@ -30,7 +30,7 @@ protected override MethodBase GetTargetMethod() => [PatchPostfix] protected static void Postfix(TraderCard __instance, ref Profile.TraderInfo trader) { - if (!trader.Unlocked) + if (Utils.Trader.IsHidden(ref trader)) { __instance.HideGameObject(); } diff --git a/PTT-BepInEx/Settings/Config.cs b/PTT-BepInEx/Settings/Config.cs new file mode 100644 index 00000000..c5495697 --- /dev/null +++ b/PTT-BepInEx/Settings/Config.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using BepInEx.Configuration; + +namespace PTT.Settings; + +internal class Config +{ + private static readonly List ConfigEntries = []; + private const string TradersSection = "Traders"; + + internal static ConfigEntry ShowLockedTraders { get; set; } + + internal static void Init(ConfigFile config) + { + ShowLockedTraders = config.Bind(TradersSection, "Show locked traders", false, "Please reload the traders page when you toggle this option."); + ConfigEntries.Add(ShowLockedTraders); + } +} diff --git a/PTT-BepInEx/Utils/Trader.cs b/PTT-BepInEx/Utils/Trader.cs new file mode 100644 index 00000000..f81646f9 --- /dev/null +++ b/PTT-BepInEx/Utils/Trader.cs @@ -0,0 +1,14 @@ +using EFT; + +namespace PTT.Utils; + +internal class Trader +{ + internal static bool IsHidden(ref Profile.TraderInfo trader) + { + bool traderIsLocked = !trader.Unlocked; + bool shouldHideLockedTrader = !Settings.Config.ShowLockedTraders.Value; + + return shouldHideLockedTrader && traderIsLocked; + } +} \ No newline at end of file From c089e372c2896f38fa94674a8d5c891b12730bb0 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 16:53:22 +0100 Subject: [PATCH 053/203] chore: update types for 3.10.2 --- types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- types/generators/RagfairOfferGenerator.d.ts | 4 +- types/helpers/ProfileHelper.d.ts | 6 + types/helpers/QuestHelper.d.ts | 19 +- types/helpers/RagfairOfferHelper.d.ts | 27 ++- types/helpers/TraderAssortHelper.d.ts | 14 +- types/models/eft/common/tables/IBotBase.d.ts | 2 +- types/models/eft/health/IWorkoutData.d.ts | 1 - types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + types/models/spt/config/IHideoutConfig.d.ts | 21 ++- types/models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + types/services/CircleOfCultistService.d.ts | 100 +++++++--- types/services/ProfileFixerService.d.ts | 24 ++- types/services/SeasonalEventService.d.ts | 6 + types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- 18 files changed, 328 insertions(+), 97 deletions(-) create mode 100644 types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 types/models/spt/hideout/ICircleCraftDetails.d.ts diff --git a/types/controllers/ProfileController.d.ts b/types/controllers/ProfileController.d.ts index 71fd9e6e..dd20b5d7 100644 --- a/types/controllers/ProfileController.d.ts +++ b/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/types/generators/BotEquipmentModGenerator.d.ts b/types/generators/BotEquipmentModGenerator.d.ts index 40c361f0..29aa5cd3 100644 --- a/types/generators/BotEquipmentModGenerator.d.ts +++ b/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/types/generators/RagfairOfferGenerator.d.ts b/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d1..324df2e1 100644 --- a/types/generators/RagfairOfferGenerator.d.ts +++ b/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/types/helpers/ProfileHelper.d.ts b/types/helpers/ProfileHelper.d.ts index ce9af111..c2871b44 100644 --- a/types/helpers/ProfileHelper.d.ts +++ b/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/types/helpers/QuestHelper.d.ts b/types/helpers/QuestHelper.d.ts index cfb1be48..414cc0a5 100644 --- a/types/helpers/QuestHelper.d.ts +++ b/types/helpers/QuestHelper.d.ts @@ -10,6 +10,7 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { Common, IQuestStatus } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IQuest, IQuestCondition, IQuestReward } from "@spt/models/eft/common/tables/IQuest"; +import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; import { IAcceptQuestRequestData } from "@spt/models/eft/quests/IAcceptQuestRequestData"; import { ICompleteQuestRequestData } from "@spt/models/eft/quests/ICompleteQuestRequestData"; @@ -280,6 +281,13 @@ export declare class QuestHelper { * @param response Response to send back to client */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; + /** + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft + */ + getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** * Get players money reward bonus from profile * @param pmcData player profile @@ -324,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/types/helpers/RagfairOfferHelper.d.ts b/types/helpers/RagfairOfferHelper.d.ts index 66a146d1..9dd5be3d 100644 --- a/types/helpers/RagfairOfferHelper.d.ts +++ b/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/types/helpers/TraderAssortHelper.d.ts b/types/helpers/TraderAssortHelper.d.ts index a50b5894..70946a2f 100644 --- a/types/helpers/TraderAssortHelper.d.ts +++ b/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/types/models/eft/common/tables/IBotBase.d.ts b/types/models/eft/common/tables/IBotBase.d.ts index 5becac2c..d3fd87e8 100644 --- a/types/models/eft/common/tables/IBotBase.d.ts +++ b/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/types/models/eft/health/IWorkoutData.d.ts b/types/models/eft/health/IWorkoutData.d.ts index d958b743..ee142061 100644 --- a/types/models/eft/health/IWorkoutData.d.ts +++ b/types/models/eft/health/IWorkoutData.d.ts @@ -1,6 +1,5 @@ export interface IWorkoutData extends Record { skills: IWorkoutSkills; - effects: IWorkoutEffects; } export interface IWorkoutSkills { Common: IWorkoutSkillCommon[]; diff --git a/types/models/eft/profile/ISptProfile.d.ts b/types/models/eft/profile/ISptProfile.d.ts index 8290b1c4..aba539b4 100644 --- a/types/models/eft/profile/ISptProfile.d.ts +++ b/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/types/models/enums/hideout/CircleRewardType.d.ts b/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 00000000..71e83a2e --- /dev/null +++ b/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/types/models/spt/config/IHideoutConfig.d.ts b/types/models/spt/config/IHideoutConfig.d.ts index 52577772..a2483a9e 100644 --- a/types/models/spt/config/IHideoutConfig.d.ts +++ b/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/types/models/spt/config/ITraderConfig.d.ts b/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a68..2835a0d2 100644 --- a/types/models/spt/config/ITraderConfig.d.ts +++ b/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/types/models/spt/hideout/ICircleCraftDetails.d.ts b/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 00000000..991e349c --- /dev/null +++ b/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/types/services/CircleOfCultistService.d.ts b/types/services/CircleOfCultistService.d.ts index e4d34108..e8046178 100644 --- a/types/services/CircleOfCultistService.d.ts +++ b/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object + */ + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/types/services/ProfileFixerService.d.ts b/types/services/ProfileFixerService.d.ts index 6ffda1b9..4a3a5ff6 100644 --- a/types/services/ProfileFixerService.d.ts +++ b/types/services/ProfileFixerService.d.ts @@ -2,9 +2,11 @@ import { HideoutHelper } from "@spt/helpers/HideoutHelper"; import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBonus, IHideoutSlot } from "@spt/models/eft/common/tables/IBotBase"; +import { IQuest, IQuestReward } from "@spt/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest, IRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { IStageBonus } from "@spt/models/eft/hideout/IHideoutArea"; @@ -36,9 +38,10 @@ export declare class ProfileFixerService { protected hashUtil: HashUtil; protected configServer: ConfigServer; protected cloner: ICloner; + protected questHelper: QuestHelper; protected coreConfig: ICoreConfig; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, watermark: Watermark, databaseService: DatabaseService, hideoutHelper: HideoutHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, profileHelper: ProfileHelper, itemHelper: ItemHelper, localisationService: LocalisationService, timeUtil: TimeUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, watermark: Watermark, databaseService: DatabaseService, hideoutHelper: HideoutHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, profileHelper: ProfileHelper, itemHelper: ItemHelper, localisationService: LocalisationService, timeUtil: TimeUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, configServer: ConfigServer, cloner: ICloner, questHelper: QuestHelper); /** * Find issues in the pmc profile data that may cause issues and fix them * @param pmcProfile profile to check and fix @@ -71,6 +74,25 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to remove dead quests from */ protected removeOrphanedQuests(pmcProfile: IPmcData): void; + /** + * Verify that all quest production unlocks have been applied to the PMC Profile + * @param pmcProfile The profile to validate quest productions for + */ + protected verifyQuestProductionUnlocks(pmcProfile: IPmcData): void; + /** + * Validate that the given profile has the given quest reward production scheme unlocked, and add it if not + * @param pmcProfile Profile to check + * @param productionUnlockReward The quest reward to validate + * @param questDetails The quest the reward belongs to + * @returns + */ + protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/types/services/SeasonalEventService.d.ts b/types/services/SeasonalEventService.d.ts index d239ee97..446ccccb 100644 --- a/types/services/SeasonalEventService.d.ts +++ b/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/types/utils/RandomUtil.d.ts b/types/utils/RandomUtil.d.ts index 0da184f6..601300cc 100644 --- a/types/utils/RandomUtil.d.ts +++ b/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ 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 + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } From dcec6a4996666f07c4a6693d14cdf5b0e6194d0a Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 16:54:19 +0100 Subject: [PATCH 054/203] style: apply prettier on prepare-files.js --- scripts/prepare-files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prepare-files.js b/scripts/prepare-files.js index db5c064f..4b77a1bc 100644 --- a/scripts/prepare-files.js +++ b/scripts/prepare-files.js @@ -7,7 +7,7 @@ const { mkdirp } = require('mkdirp'); // // eslint-disable-next-line @typescript-eslint/no-var-requires // const cpr = require('cpr'); -const PTTClientDir = 'PTT-BepInEx' +const PTTClientDir = 'PTT-BepInEx'; const dllFileName = 'Trap.PathToTarkov.dll'; const main = async modName => { From 3d3cd7809f3be8306b821b59731907914fafa5ea Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 17:03:17 +0100 Subject: [PATCH 055/203] chore: gather allExtracts.json --- .../maps/customs_allExtracts.json | 600 ++++++++++++++++++ .../maps/factory_allExtracts.json | 186 ++++++ .../maps/groundzero_allExtracts.json | 163 +++++ .../maps/interchange_allExtracts.json | 186 ++++++ .../maps/laboratory_allExtracts.json | 232 +++++++ .../maps/lighthouse_allExtracts.json | 278 ++++++++ .../maps/reserve_allExtracts.json | 232 +++++++ .../maps/shoreline_allExtracts.json | 324 ++++++++++ .../maps/streets_allExtracts.json | 423 ++++++++++++ .../maps/woods_allExtracts.json | 462 ++++++++++++++ scripts/gather-external-resources.sh | 24 + 11 files changed, 3110 insertions(+) create mode 100644 external-resources/maps/customs_allExtracts.json create mode 100644 external-resources/maps/factory_allExtracts.json create mode 100644 external-resources/maps/groundzero_allExtracts.json create mode 100644 external-resources/maps/interchange_allExtracts.json create mode 100644 external-resources/maps/laboratory_allExtracts.json create mode 100644 external-resources/maps/lighthouse_allExtracts.json create mode 100644 external-resources/maps/reserve_allExtracts.json create mode 100644 external-resources/maps/shoreline_allExtracts.json create mode 100644 external-resources/maps/streets_allExtracts.json create mode 100644 external-resources/maps/woods_allExtracts.json diff --git a/external-resources/maps/customs_allExtracts.json b/external-resources/maps/customs_allExtracts.json new file mode 100644 index 00000000..a6053d79 --- /dev/null +++ b/external-resources/maps/customs_allExtracts.json @@ -0,0 +1,600 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Customs,Boiler Tanks", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "EXFIL_ZB013", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "Customs,Boiler Tanks", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Dorms V-Ex", + "PassageRequirement": "TransferItem", + "PlayersCount": 4, + "PlayersCountPVE": 4, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Customs", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "ZB-1011", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Boiler Tanks", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Crossroads", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Customs", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Old Gas Station", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Boiler Tanks", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Trailer Park", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Boiler Tanks", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "RUAF Roadblock", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Boiler Tanks", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Smuggler's Boat", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Customs", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "ZB-1012", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Shack", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Beyond Fuel Tank", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Railroad To Military Base", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Old Road Gate", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Sniper Roadblock", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Railroad To Port", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Crossroads", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Trailer Park Workers Shack", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Railroad To Tarkov", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "RUAF Roadblock_scav", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Warehouse 17", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Factory Shacks", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Warehouse 4", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Old Azs Gate", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Factory Far Corner", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Administration Gate", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Military Checkpoint", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/factory_allExtracts.json b/external-resources/maps/factory_allExtracts.json new file mode 100644 index 00000000..26dfea0c --- /dev/null +++ b/external-resources/maps/factory_allExtracts.json @@ -0,0 +1,186 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Factory", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Cellars", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Factory", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Gate 3", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Factory", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Gate 0", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Factory", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Gate m", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Factory", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Gate_o", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Gate 3", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Camera Bunker Door", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Office Window", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/groundzero_allExtracts.json b/external-resources/maps/groundzero_allExtracts.json new file mode 100644 index 00000000..84163d11 --- /dev/null +++ b/external-resources/maps/groundzero_allExtracts.json @@ -0,0 +1,163 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "west,east", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Sandbox_VExit", + "PassageRequirement": "TransferItem", + "PlayersCount": 4, + "PlayersCountPVE": 4, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "east", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Unity_free_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "west,east", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav_coop_exit", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "west", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Nakatani_stairs_free_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "west,east", + "EventAvailable": false, + "ExfiltrationTime": 6.0, + "ExfiltrationTimePVE": 6.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Sniper_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "east", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Unity_free_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "west", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Nakatani_stairs_free_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/interchange_allExtracts.json b/external-resources/maps/interchange_allExtracts.json new file mode 100644 index 00000000..a83c2344 --- /dev/null +++ b/external-resources/maps/interchange_allExtracts.json @@ -0,0 +1,186 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "MallNW", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "SE Exfil", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "MallSE", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "NW Exfil", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "MallSE,MallNW", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "PP Exfil", + "PassageRequirement": "TransferItem", + "PlayersCount": 4, + "PlayersCountPVE": 4, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "MallSE,MallNW", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Interchange Cooperation", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "MallSE,MallNW", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Hole Exfill", + "PassageRequirement": "Empty", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "Backpack", + "RequirementTip": "EXFIL_INTERCHANGE_HOLE_TIP", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "MallSE,MallNW", + "EventAvailable": false, + "ExfiltrationTime": 3.0, + "ExfiltrationTimePVE": 3.0, + "ExfiltrationType": "Manual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Saferoom Exfil", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_INTERCHANGE_SAFEROOM_TIP", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "SE Exfil", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "NW Exfil", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/laboratory_allExtracts.json b/external-resources/maps/laboratory_allExtracts.json new file mode 100644 index 00000000..c843cb4d --- /dev/null +++ b/external-resources/maps/laboratory_allExtracts.json @@ -0,0 +1,232 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Manual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Elevator_Cargo", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 5.0, + "ExfiltrationTimePVE": 5.0, + "ExfiltrationType": "Manual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Elevator_Main", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 15.0, + "ExfiltrationTimePVE": 15.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Vent", + "PassageRequirement": "Empty", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "Backpack", + "RequirementTip": "EXFIL_tip_backpack", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 5.0, + "ExfiltrationTimePVE": 5.0, + "ExfiltrationType": "Manual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Elevator_Med", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Under_Storage_Collector", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 60.0, + "ChancePVE": 60.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Parking_Gate", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 60.0, + "ChancePVE": 60.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Hangar_Gate", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 0.0, + "ChancePVE": 0.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Elevator_Cargo", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 0.0, + "ChancePVE": 0.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Elevator_Main", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 0.0, + "ChancePVE": 0.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "lab_Elevator_Med", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/lighthouse_allExtracts.json b/external-resources/maps/lighthouse_allExtracts.json new file mode 100644 index 00000000..c2bdc43c --- /dev/null +++ b/external-resources/maps/lighthouse_allExtracts.json @@ -0,0 +1,278 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 400, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 5.0, + "ExfiltrationTimePVE": 5.0, + "ExfiltrationType": "SharedTimer", + "Id": "0", + "MinTime": 1200.0, + "MinTimePVE": 1200.0, + "MaxTime": 1500.0, + "MaxTimePVE": 1500.0, + "Name": "EXFIL_Train", + "PassageRequirement": "Train", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "TIP IS HARDCODED", + "Side": "Coop" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": " V-Ex_light", + "PassageRequirement": "TransferItem", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "tunnel_shared", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "Alpinist", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Alpinist_light", + "PassageRequirement": "Reference", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Shorl_free", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Nothern_Checkpoint", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Coastal_South_Road", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Shorl_free_scav", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav_Coastal_South", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav_Underboat_Hideout", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav_Hideout_at_the_grotto", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Tunnel,North", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav_Industrial_zone", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/reserve_allExtracts.json b/external-resources/maps/reserve_allExtracts.json new file mode 100644 index 00000000..12c1f163 --- /dev/null +++ b/external-resources/maps/reserve_allExtracts.json @@ -0,0 +1,232 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 400, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 5.0, + "ExfiltrationTimePVE": 5.0, + "ExfiltrationType": "SharedTimer", + "Id": "0", + "MinTime": 1450.0, + "MinTimePVE": 1450.0, + "MaxTime": 1700.0, + "MaxTimePVE": 1700.0, + "Name": "EXFIL_Train", + "PassageRequirement": "Train", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "TIP IS HARDCODED", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "EXFIL_Bunker_D2", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 18.0, + "ExfiltrationTimePVE": 18.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "EXFIL_Bunker", + "PassageRequirement": "WorldEvent", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_BUNKER_POWER", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "Alpinist", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Alpinist", + "PassageRequirement": "Reference", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "EXFIL_ScavCooperation", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Common", + "EventAvailable": false, + "ExfiltrationTime": 10.0, + "ExfiltrationTimePVE": 10.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "EXFIL_vent", + "PassageRequirement": "Empty", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "Backpack", + "RequirementTip": "EXFIL_tip_backpack", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Exit1", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Exit2", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Exit3", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Exit4", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/shoreline_allExtracts.json b/external-resources/maps/shoreline_allExtracts.json new file mode 100644 index 00000000..972732bc --- /dev/null +++ b/external-resources/maps/shoreline_allExtracts.json @@ -0,0 +1,324 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "Riverside,Village", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Shorl_V-Ex", + "PassageRequirement": "TransferItem", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Village", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Road to Customs", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Village", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Road_at_railbridge", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Riverside", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Tunnel", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Riverside,Village", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Lighthouse_pass", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Riverside,Village", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Smugglers_Trail_coop", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Riverside,Village", + "EventAvailable": false, + "ExfiltrationTime": 30.0, + "ExfiltrationTimePVE": 30.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Pier Boat", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Riverside,Village", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "Alpinist", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "RedRebel_alp", + "PassageRequirement": "Reference", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav Road to Customs", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Lighthouse", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Wrecked Road", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "South Fence Passage", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "RWing Gym Entrance", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Adm Basement", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/streets_allExtracts.json b/external-resources/maps/streets_allExtracts.json new file mode 100644 index 00000000..860c9b24 --- /dev/null +++ b/external-resources/maps/streets_allExtracts.json @@ -0,0 +1,423 @@ +[ + { + "Chance": 40.0, + "ChancePVE": 40.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E8_yard", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 50.0, + "ChancePVE": 50.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E7_car", + "PassageRequirement": "TransferItem", + "PlayersCount": 4, + "PlayersCountPVE": 4, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E6_1,E1_2", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E1", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E4_5,E3_4", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E4", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E2_3,E1_2", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E2", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E2_3,E3_4", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E3", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E4_5,E5_6", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E5", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 0.0, + "ChancePVE": 0.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E6_1,E5_6", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E6", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 6.0, + "ExfiltrationTimePVE": 6.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E9_sniper", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Exit_E10_coop", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E6_1,E5_6", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "E7", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e1", + "_Name": "Basement Descent", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e2", + "_Name": "Entrance to Catacombs", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e3", + "_Name": "Ventilation Shaft", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e4", + "_Name": "Sewer Manhole", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e5", + "_Name": "Near Kamchatskaya Arch", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e7", + "_name": "Cardinal Apartment Complex Parking", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "E1_2,E6_1,E2_3,E3_4,E4_5,E5_6,E6_1", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "scav_e8", + "_name": "Klimov Shopping Mall Exfil", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/external-resources/maps/woods_allExtracts.json b/external-resources/maps/woods_allExtracts.json new file mode 100644 index 00000000..69d44d66 --- /dev/null +++ b/external-resources/maps/woods_allExtracts.json @@ -0,0 +1,462 @@ +[ + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "House,Old Station", + "EventAvailable": false, + "ExfiltrationTime": 20.0, + "ExfiltrationTimePVE": 20.0, + "ExfiltrationType": "SharedTimer", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Factory Gate", + "PassageRequirement": "ScavCooperation", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Cooperate", + "Side": "Coop" + }, + { + "Chance": 66.0, + "ChancePVE": 66.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "House", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "RUAF Gate", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 66.0, + "ChancePVE": 66.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "House", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "ZB-016", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 66.0, + "ChancePVE": 66.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Old Station", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "ZB-014", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "House", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "UN Roadblock", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 5000, + "CountPve": 0, + "EntryPoints": "House,Old Station", + "EventAvailable": false, + "ExfiltrationTime": 60.0, + "ExfiltrationTimePVE": 60.0, + "ExfiltrationType": "SharedTimer", + "Id": "5449016a4bdc2d6f028b456f", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "South V-Ex", + "PassageRequirement": "TransferItem", + "PlayersCount": 4, + "PlayersCountPVE": 4, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "EXFIL_Item", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "Old Station", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Outskirts", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "House", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "un-sec", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "House,Old Station", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "wood_sniper_exit", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Pmc" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Outskirts", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Outskirts Water", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Dead Man's Place", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "The Boat", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Scav House", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "East Gate", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Mountain Stash", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "West Border", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "Old Station", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "UN Roadblock", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + }, + { + "Chance": 100.0, + "ChancePVE": 100.0, + "Count": 0, + "CountPve": 0, + "EntryPoints": "", + "EventAvailable": false, + "ExfiltrationTime": 8.0, + "ExfiltrationTimePVE": 8.0, + "ExfiltrationType": "Individual", + "Id": "", + "MinTime": 0.0, + "MinTimePVE": 0.0, + "MaxTime": 0.0, + "MaxTimePVE": 0.0, + "Name": "RUAF Roadblock", + "PassageRequirement": "None", + "PlayersCount": 0, + "PlayersCountPVE": 0, + "RequiredSlot": "FirstPrimaryWeapon", + "RequirementTip": "", + "Side": "Scav" + } +] diff --git a/scripts/gather-external-resources.sh b/scripts/gather-external-resources.sh index f73c3818..35280bc3 100644 --- a/scripts/gather-external-resources.sh +++ b/scripts/gather-external-resources.sh @@ -8,16 +8,40 @@ ls $DB_PATH 2>&1 > /dev/null || exit 1 mkdir -p $TARGET_PATH mkdir -p $TARGET_PATH/maps +## EN locales + cp $DB_PATH/locales/global/en.json $TARGET_PATH/locales_global_en.json +# Maps and extracts + cp $DB_PATH/locations/bigmap/base.json $TARGET_PATH/maps/customs.json +cp $DB_PATH/locations/bigmap/allExtracts.json $TARGET_PATH/maps/customs_allExtracts.json + cp $DB_PATH/locations/factory4_day/base.json $TARGET_PATH/maps/factory.json +cp $DB_PATH/locations/factory4_day/allExtracts.json $TARGET_PATH/maps/factory_allExtracts.json + cp $DB_PATH/locations/interchange/base.json $TARGET_PATH/maps/interchange.json +cp $DB_PATH/locations/interchange/allExtracts.json $TARGET_PATH/maps/interchange_allExtracts.json + cp $DB_PATH/locations/laboratory/base.json $TARGET_PATH/maps/laboratory.json +cp $DB_PATH/locations/laboratory/allExtracts.json $TARGET_PATH/maps/laboratory_allExtracts.json + cp $DB_PATH/locations/lighthouse/base.json $TARGET_PATH/maps/lighthouse.json +cp $DB_PATH/locations/lighthouse/allExtracts.json $TARGET_PATH/maps/lighthouse_allExtracts.json + cp $DB_PATH/locations/rezervbase/base.json $TARGET_PATH/maps/reserve.json +cp $DB_PATH/locations/rezervbase/allExtracts.json $TARGET_PATH/maps/reserve_allExtracts.json + cp $DB_PATH/locations/shoreline/base.json $TARGET_PATH/maps/shoreline.json +cp $DB_PATH/locations/shoreline/allExtracts.json $TARGET_PATH/maps/shoreline_allExtracts.json + cp $DB_PATH/locations/woods/base.json $TARGET_PATH/maps/woods.json +cp $DB_PATH/locations/woods/allExtracts.json $TARGET_PATH/maps/woods_allExtracts.json + cp $DB_PATH/locations/tarkovstreets/base.json $TARGET_PATH/maps/streets.json +cp $DB_PATH/locations/tarkovstreets/allExtracts.json $TARGET_PATH/maps/streets_allExtracts.json + cp $DB_PATH/locations/sandbox/base.json $TARGET_PATH/maps/groundzero.json +cp $DB_PATH/locations/sandbox/allExtracts.json $TARGET_PATH/maps/groundzero_allExtracts.json + From c261a89baddac26602019d0aeeeaaffb62770e2e Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 17:18:08 +0100 Subject: [PATCH 056/203] refactor: get rid of scav_exfils.json + reorder exfils --- ALL_EXFILS.md | 115 +++++++++-------- external-resources/location_name_mapping.json | 15 ++- external-resources/mapgenie_locations.json | 4 + external-resources/scavs_exfils.json | 59 --------- scripts/generate-all-exfils.js | 34 +---- src/all-exfils.ts | 116 +++++++++--------- 6 files changed, 130 insertions(+), 213 deletions(-) delete mode 100644 external-resources/scavs_exfils.json diff --git a/ALL_EXFILS.md b/ALL_EXFILS.md index f51abdb7..bf36e19c 100644 --- a/ALL_EXFILS.md +++ b/ALL_EXFILS.md @@ -3,30 +3,31 @@ ## Customs |identifier|description|mapgenie.io| |----------|-----------|-----------| +| "EXFIL_ZB013" | ZB-013 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=43360) | +| "Dorms V-Ex" | Dorms V-Ex | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29982) | +| "ZB-1011" | ZB-1011 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=30116) | | "Crossroads" | Crossroads | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29969) | -| "Smuggler's Boat" | Smuggler's Boat | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29968) | +| "Old Gas Station" | Old Gas Station | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29974) | +| "Trailer Park" | Trailer Park | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29970) | | "RUAF Roadblock" | RUAF Roadblock | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29973) | +| "Smuggler's Boat" | Smuggler's Boat | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29968) | | "ZB-1012" | ZB-1012 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=30117) | -| "ZB-1011" | ZB-1011 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=30116) | -| "Trailer Park" | Trailer Park | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29970) | -| "Old Gas Station" | Old Gas Station | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29974) | -| "Dorms V-Ex" | Dorms V-Ex | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29982) | -| "EXFIL_ZB013" | ZB-013 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=43360) | -| "Railroad To Tarkov" | Railroad to Tarkov | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29971) | -| "Railroad To Port" | Railroad to Port | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29967) | +| "Shack" | Military Base CP | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29978) | +| "Beyond Fuel Tank" | Passage Between Rocks | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29979) | | "Railroad To Military Base" | Railroad to Military Base | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29980) | -| "Trailer Park Workers Shack" | Trailer Park Workers' Shack | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29972) | +| "Old Road Gate" | Old Road Gate | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29981) | | "Sniper Roadblock" | Sniper Roadblock | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29983) | +| "Railroad To Port" | Railroad to Port | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29967) | +| "Trailer Park Workers Shack" | Trailer Park Workers' Shack | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29972) | +| "Railroad To Tarkov" | Railroad to Tarkov | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29971) | +| "RUAF Roadblock_scav" | RUAF Roadblock | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29973) | | "Warehouse 17" | Warehouse 17 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29985) | | "Factory Shacks" | Factory Shacks | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29984) | -| "Old Road Gate" | Old Road Gate | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29981) | | "Warehouse 4" | Warehouse 4 | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=30162) | | "Old Azs Gate" | Old Gas Station Gate | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=59684) | -| "Beyond Fuel Tank" | Passage Between Rocks | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29979) | -| "Shack" | Military Base CP | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29978) | -| "Military Checkpoint" | Scav Checkpoint | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29977) | -| "Administration Gate" | Administration Gate | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29976) | | "Factory Far Corner" | Factory Far Corner | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29975) | +| "Administration Gate" | Administration Gate | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29976) | +| "Military Checkpoint" | Scav Checkpoint | [link](https://mapgenie.io/tarkov/maps/customs?locationIds=29977) | ## Factory |identifier|description|mapgenie.io| @@ -37,68 +38,67 @@ | "Gate m" | Med Tent Gate | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=88025) | | "Gate_o" | Courtyard Gate | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=403860) | | "Camera Bunker Door" | Camera Bunker Door | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25058) | +| "Office Window" | Office Window | [link](https://mapgenie.io/tarkov/maps/factory?locationIds=25060) | ## Interchange |identifier|description|mapgenie.io| |----------|-----------|-----------| -| "NW Exfil" | Railway Exfil | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28341) | | "SE Exfil" | Emercom Checkpoint | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28340) | +| "NW Exfil" | Railway Exfil | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28341) | | "PP Exfil" | Power Station V-Ex | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28339) | -| "Saferoom Exfil" | Saferoom Exfil | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28342) | -| "Hole Exfill" | Hole in the Fence | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28349) | | "Interchange Cooperation" | Scav Camp (Co-Op) | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28343) | +| "Hole Exfill" | Hole in the Fence | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28349) | +| "Saferoom Exfil" | Saferoom Exfil | [link](https://mapgenie.io/tarkov/maps/interchange?locationIds=28342) | ## Woods |identifier|description|mapgenie.io| |----------|-----------|-----------| -| "ZB-016" | ZB-016 | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24858) | -| "Outskirts" | Outskirts | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24866) | -| "UN Roadblock" | UN Roadblock | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24855) | +| "Factory Gate" | Friendship Bridge (Co-Op) | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24856) | | "RUAF Gate" | RUAF Gate | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24857) | +| "ZB-016" | ZB-016 | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24858) | | "ZB-014" | ZB-014 | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24862) | +| "UN Roadblock" | UN Roadblock | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24855) | | "South V-Ex" | Bridge V-Ex | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65037) | -| "Factory Gate" | Friendship Bridge (Co-Op) | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24856) | +| "Outskirts" | Outskirts | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24866) | | "un-sec" | Northern UN Roadblock | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65038) | | "wood_sniper_exit" | Power Line Passage | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=410432) | -| "East Gate" | Scav Bunker | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65036) | | "Outskirts Water" | Scav Bridge | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65035) | +| "Dead Man's Place" | Dead Man's Place | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24868) | +| "The Boat" | Boat | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24869) | +| "Scav House" | Scav House | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24870) | +| "East Gate" | Scav Bunker | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=65036) | | "Mountain Stash" | Mountain Stash | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24859) | | "West Border" | Eastern Rocks | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24666) | | "Old Station" | Old Railway Depot | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24854) | -| "Scav House" | Scav House | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24870) | -| "The Boat" | Boat | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24869) | -| "Dead Man's Place" | Dead Man's Place | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24868) | +| "RUAF Roadblock" | RUAF Roadblock | [link](https://mapgenie.io/tarkov/maps/woods?locationIds=24857) | ## Shoreline |identifier|description|mapgenie.io| |----------|-----------|-----------| -| "Tunnel" | Tunnel | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26116) | -| "Rock Passage" | Rock Passage | no link | -| "Pier Boat" | Pier Boat | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26124) | -| "CCP Temporary" | CCP Temporary | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26122) | +| "Shorl_V-Ex" | Road to North V-Ex | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317032) | | "Road to Customs" | Road to Customs | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26121) | -| "Lighthouse_pass" | Path to Lighthouse | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=151041) | | "Road_at_railbridge" | Railway Bridge | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=151043) | -| "Shorl_V-Ex" | Road to North V-Ex | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317032) | -| "RedRebel_alp" | Climber's Trail | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317034) | +| "Tunnel" | Tunnel | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26116) | +| "Lighthouse_pass" | Path to Lighthouse | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=151041) | | "Smugglers_Trail_coop" | Smuggler's Path (Co-op) | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317040) | -| "Adm Basement" | Admin Basement | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=28239) | -| "RWing Gym Entrance" | East Wing Gym Entrance | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=28240) | -| "South Fence Passage" | Old Bunker | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317033) | -| "Ruined House Fence" | Ruined House Fence | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26118) | -| "Svetliy Dead End" | Svetliy Dead End | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26117) | -| "Wrecked Road" | Ruined Road | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26323) | +| "Pier Boat" | Pier Boat | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26124) | +| "RedRebel_alp" | Climber's Trail | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317034) | +| "Scav Road to Customs" | Road to Customs | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26121) | | "Lighthouse" | Lighthouse | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26123) | +| "Wrecked Road" | Ruined Road | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=26323) | +| "South Fence Passage" | Old Bunker | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=317033) | +| "RWing Gym Entrance" | East Wing Gym Entrance | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=28240) | +| "Adm Basement" | Admin Basement | [link](https://mapgenie.io/tarkov/maps/shoreline?locationIds=28239) | ## Military Reserve |identifier|description|mapgenie.io| |----------|-----------|-----------| | "EXFIL_Train" | Armored Train | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39352) | +| "EXFIL_Bunker_D2" | D-2 | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39424) | +| "EXFIL_Bunker" | Bunker Hermetic Door | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39336) | | "Alpinist" | Cliff Descent | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39196) | | "EXFIL_ScavCooperation" | Scav Lands (Co-Op) | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39211) | -| "EXFIL_Bunker" | Bunker Hermetic Door | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39336) | | "EXFIL_vent" | Sewer Manhole | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39212) | -| "EXFIL_Bunker_D2" | D-2 | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39424) | | "Exit1" | Hole in the Wall by the Mountains | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39194) | | "Exit2" | Heating Pipe | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39193) | | "Exit3" | Depot Hermetic Door | [link](https://mapgenie.io/tarkov/maps/reserve?locationIds=39299) | @@ -108,58 +108,57 @@ |identifier|description|mapgenie.io| |----------|-----------|-----------| | "EXFIL_Train" | Armored Train | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152316) | -| "Alpinist_light" | Mountain Pass | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152323) | +| " V-Ex_light" | Road to Military Base V-Ex | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152319) | | "tunnel_shared" | Side Tunnel (Co-Op) | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152326) | +| "Alpinist_light" | Mountain Pass | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152323) | +| "Shorl_free" | Path to Shoreline | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152322) | | "Nothern_Checkpoint" | Northern Checkpoint | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152315) | | "Coastal_South_Road" | Southern Road | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152328) | -| "Shorl_free" | Path to Shoreline | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152322) | -| " V-Ex_light" | Road to Military Base V-Ex | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152319) | -| "SCAV_Industrial_Zone" | Industrial Zone Gates | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152317) | -| "Scav_Hideout_at_the_grotto" | Scav Hideout at the Grotto | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152321) | -| "SCAV_Underboat_Hideout" | Hideout Under the Landing Stage | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152325) | +| "Shorl_free_scav" | Path to Shoreline | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152322) | | "Scav_Coastal_South" | Southern Road Landslide | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152329) | +| "Scav_Underboat_Hideout" | Hideout Under the Landing Stage | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152325) | +| "Scav_Hideout_at_the_grotto" | Scav Hideout at the Grotto | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152321) | +| "Scav_Industrial_zone" | Industrial Zone Gates | [link](https://mapgenie.io/tarkov/maps/lighthouse?locationIds=152317) | ## Streets of Tarkov |identifier|description|mapgenie.io| |----------|-----------|-----------| +| "E8_yard" | Courtyard | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247836) | +| "E7_car" | Primorsky Ave Taxi V-Ex | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247835) | | "E1" | Stylobate Building Elevator | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300388) | +| "E4" | Crash Site | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300385) | | "E2" | Sewer River | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247839) | | "E3" | Damaged House | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247837) | -| "E4" | Crash Site | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300385) | | "E5" | Collapsed Crane | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247831) | | "E6" | Scav Checkpoint | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247830) | -| "E7_car" | Primorsky Ave Taxi V-Ex | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247835) | -| "E8_yard" | Courtyard | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247836) | | "E9_sniper" | Klimov Street | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247827) | | "Exit_E10_coop" | Pinewood Basement (Co-Op) | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300387) | | "E7" | Expo Checkpoint | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300382) | -| "E8" | Cardinal Apartment Complex | no link | | "scav_e1" | Basement Descent | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247829) | | "scav_e2" | Entrance to Catacombs | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247838) | | "scav_e3" | Ventilation Shaft | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247834) | | "scav_e4" | Sewer Manhole | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=247832) | | "scav_e5" | Near Kamchatskaya Arch | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300386) | -| "scav_e6" | Basement Entrance | no link | | "scav_e7" | Cardinal Apartment Complex Parking | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300400) | | "scav_e8" | Klimov Shopping Mall Exfil | [link](https://mapgenie.io/tarkov/maps/streets?locationIds=300384) | ## Laboratory |identifier|description|mapgenie.io| |----------|-----------|-----------| -| "lab_Parking_Gate" | Parking Gate | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=32101) | -| "lab_Hangar_Gate" | Hangar Gate | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31570) | -| "lab_Elevator_Med" | Medical Block Elevator | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31549) | -| "lab_Under_Storage_Collector" | Sewage Conduit | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31540) | +| "lab_Elevator_Cargo" | Cargo Elevator | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31571) | | "lab_Elevator_Main" | Main Elevator | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31542) | | "lab_Vent" | Ventilation Shaft | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31543) | -| "lab_Elevator_Cargo" | Cargo Elevator | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31571) | +| "lab_Elevator_Med" | Medical Block Elevator | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31549) | +| "lab_Under_Storage_Collector" | Sewage Conduit | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31540) | +| "lab_Parking_Gate" | Parking Gate | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=32101) | +| "lab_Hangar_Gate" | Hangar Gate | [link](https://mapgenie.io/tarkov/maps/lab?locationIds=31570) | ## Ground Zero |identifier|description|mapgenie.io| |----------|-----------|-----------| -| "Unity_free_exit" | Emercom Checkpoint | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314855) | | "Sandbox_VExit" | Police Cordon V-Ex | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314851) | -| "Sniper_exit" | Mira Ave | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314853) | +| "Unity_free_exit" | Emercom Checkpoint | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314855) | | "Scav_coop_exit" | Scav Checkpoint (Co-op) | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314852) | | "Nakatani_stairs_free_exit" | Nakatani Basement Stairs | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314854) | +| "Sniper_exit" | Mira Ave | [link](https://mapgenie.io/tarkov/maps/groundzero?locationIds=314853) | diff --git a/external-resources/location_name_mapping.json b/external-resources/location_name_mapping.json index 43e9e213..1591e62a 100644 --- a/external-resources/location_name_mapping.json +++ b/external-resources/location_name_mapping.json @@ -1,13 +1,12 @@ { - "streets": "Streets of Tarkov", - "reserve": "Military Reserve", - "woods": "Woods", - "factory": "Factory", "customs": "Customs", - "lighthouse": "Lighthouse", - "shoreline": "Shoreline", + "factory": "Factory", "interchange": "Interchange", + "woods": "Woods", + "shoreline": "Shoreline", + "reserve": "Military Reserve", + "lighthouse": "Lighthouse", + "streets": "Streets of Tarkov", "laboratory": "Laboratory", - "groundzero": "Ground Zero", - "yolo": "TODO: check this" + "groundzero": "Ground Zero" } diff --git a/external-resources/mapgenie_locations.json b/external-resources/mapgenie_locations.json index a9a0eb8a..761693ec 100644 --- a/external-resources/mapgenie_locations.json +++ b/external-resources/mapgenie_locations.json @@ -452,6 +452,10 @@ "id": 24857, "description": "RUAF Gate" }, + { + "id": 24857, + "description": "RUAF Roadblock" + }, { "id": 24858, "description": "ZB-016" diff --git a/external-resources/scavs_exfils.json b/external-resources/scavs_exfils.json deleted file mode 100644 index 14133063..00000000 --- a/external-resources/scavs_exfils.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "customs": [ - "Railroad To Tarkov", - "Railroad To Port", - "Railroad To Military Base", - "Trailer Park Workers Shack", - "Sniper Roadblock", - "Warehouse 17", - "Factory Shacks", - "Old Road Gate", - "Warehouse 4", - "Old Azs Gate", - "Beyond Fuel Tank", - "Shack", - "Military Checkpoint", - "Administration Gate", - "Factory Far Corner" - ], - "factory": ["Camera Bunker Door"], - "interchange": [], - "woods": [ - "East Gate", - "Outskirts Water", - "Mountain Stash", - "West Border", - "Old Station", - "Scav House", - "The Boat", - "Dead Man's Place" - ], - "shoreline": [ - "Adm Basement", - "RWing Gym Entrance", - "South Fence Passage", - "Ruined House Fence", - "Svetliy Dead End", - "Wrecked Road", - "Lighthouse" - ], - "reserve": ["Exit1", "Exit2", "Exit3", "Exit4"], - "lighthouse": [ - "SCAV_Industrial_Zone", - "Scav_Hideout_at_the_grotto", - "SCAV_Underboat_Hideout", - "Scav_Coastal_South" - ], - "streets": [ - "scav_e1", - "scav_e2", - "scav_e3", - "scav_e4", - "scav_e5", - "scav_e6", - "scav_e7", - "scav_e8" - ], - "laboratory": [], - "groundzero": [] -} diff --git a/scripts/generate-all-exfils.js b/scripts/generate-all-exfils.js index 8ed70975..2c61c2f9 100644 --- a/scripts/generate-all-exfils.js +++ b/scripts/generate-all-exfils.js @@ -4,7 +4,6 @@ const fs = require('node:fs/promises'); const EXTERNAL_RESOURCES_DIR = 'external-resources'; const LOCATION_NAME_MAPPING_FILENAME = 'location_name_mapping.json'; const LOCALES_FILENAME = 'locales_global_en.json'; -const SCAVS_EXFILS_FILENAME = 'scavs_exfils.json'; const MAPGENIE_LOCATIONS_FILENAME = 'mapgenie_locations.json'; const MAPS_DIR = 'maps'; @@ -43,11 +42,11 @@ const LOCALES = lowerLocaleKeys( require(`../${EXTERNAL_RESOURCES_DIR}/${LOCALES_FILENAME}`), ); // eslint-disable-next-line @typescript-eslint/no-var-requires -const SCAVS_EXFILS = require(`../${EXTERNAL_RESOURCES_DIR}/${SCAVS_EXFILS_FILENAME}`); +// const SCAVS_EXFILS = require(`../${EXTERNAL_RESOURCES_DIR}/${SCAVS_EXFILS_FILENAME}`); // eslint-disable-next-line @typescript-eslint/no-var-requires const MAPGENIE_LOCATIONS = require(`../${EXTERNAL_RESOURCES_DIR}/${MAPGENIE_LOCATIONS_FILENAME}`); -const getMapJsonFilePath = mapName => `${EXTERNAL_RESOURCES_DIR}/${MAPS_DIR}/${mapName}.json`; +const getMapJsonFilePath = mapName => `${EXTERNAL_RESOURCES_DIR}/${MAPS_DIR}/${mapName}_allExtracts.json`; const getMapGenieMapName = mapName => { if (MAPGENIE_REMAPPING[mapName]) { @@ -93,16 +92,6 @@ class ConfigError extends Error { const resolveMapDisplayName = mapName => LOCATION_NAME_MAPPING[mapName]; -const assertValidMapNames = mapNames => { - mapNames.forEach(mapName => { - if (!LOCATION_NAME_MAPPING[mapName]) { - throw new ConfigError( - `Invalid map name '${mapName}' found in ${SCAVS_EXFILS_FILENAME} file!`, - ); - } - }); -}; - const resolveLocale = localeId => { const value = LOCALES[localeId.toLowerCase()]; @@ -118,7 +107,7 @@ const loadMapExits = async mapName => { try { const fileContent = await fs.readFile(filePath, 'utf-8'); - return JSON.parse(fileContent).exits.map(exit => exit.Name); + return JSON.parse(fileContent).map(exit => exit.Name); } catch (err) { throw new ConfigError(`cannot load '${filePath}, reason=${err.toString()}'`); } @@ -163,7 +152,6 @@ const mergeMapsExits = (mapsExitsLeft, mapsExitsRight) => { const formatMapsExits = mapsExits => { const allMapNames = Object.keys(mapsExits); - assertValidMapNames(allMapNames); return allMapNames .reduce((output, mapName) => { @@ -185,22 +173,10 @@ const formatMapsExits = mapsExits => { }; const main = async () => { - const allMapNames = Object.keys(SCAVS_EXFILS); - assertValidMapNames(allMapNames); + const allMapNames = Object.keys(LOCATION_NAME_MAPPING); const mapsExits = await loadMapsExits(allMapNames); - const allMapsExits = mergeMapsExits(mapsExits, SCAVS_EXFILS); - - // const allFlattenedExfils = {}; - // Object.keys(allMapsExits).forEach(mapName => { - // const exfils = allMapsExits[mapName]; - // exfils.forEach(exfilName => { - // if (allFlattenedExfils[exfilName]) { - // throw new Error(`Duplicate exfilName "${exfilName}" found for map "${mapName}"`); - // } - // allFlattenedExfils[exfilName] = true; - // }); - // }); + const allMapsExits = mergeMapsExits(mapsExits, {}); process.stderr.write(JSON.stringify(allMapsExits, undefined, 2)); process.stderr.write('\n'); diff --git a/src/all-exfils.ts b/src/all-exfils.ts index 0134eabe..cc24a1a8 100644 --- a/src/all-exfils.ts +++ b/src/all-exfils.ts @@ -2,30 +2,31 @@ // This is copy-pasted from the output (stderr) of the 'generate-all-exfils.js' script const ALL_DUMPED_EXFILS_FROM_SCRIPT = { customs: [ + 'EXFIL_ZB013', + 'Dorms V-Ex', + 'ZB-1011', 'Crossroads', - "Smuggler's Boat", + 'Old Gas Station', + 'Trailer Park', 'RUAF Roadblock', + "Smuggler's Boat", 'ZB-1012', - 'ZB-1011', - 'Trailer Park', - 'Old Gas Station', - 'Dorms V-Ex', - 'EXFIL_ZB013', - 'Railroad To Tarkov', - 'Railroad To Port', + 'Shack', + 'Beyond Fuel Tank', 'Railroad To Military Base', - 'Trailer Park Workers Shack', + 'Old Road Gate', 'Sniper Roadblock', + 'Railroad To Port', + 'Trailer Park Workers Shack', + 'Railroad To Tarkov', + 'RUAF Roadblock_scav', 'Warehouse 17', 'Factory Shacks', - 'Old Road Gate', 'Warehouse 4', 'Old Azs Gate', - 'Beyond Fuel Tank', - 'Shack', - 'Military Checkpoint', - 'Administration Gate', 'Factory Far Corner', + 'Administration Gate', + 'Military Checkpoint', ], factory: [ 'Cellars', @@ -33,62 +34,60 @@ const ALL_DUMPED_EXFILS_FROM_SCRIPT = { 'Gate 0', 'Gate m', 'Gate_o', - 'Office Window', 'Camera Bunker Door', + 'Office Window', ], interchange: [ - 'NW Exfil', 'SE Exfil', + 'NW Exfil', 'PP Exfil', - 'Saferoom Exfil', - 'Hole Exfill', 'Interchange Cooperation', + 'Hole Exfill', + 'Saferoom Exfil', ], woods: [ - 'ZB-016', - 'Outskirts', - 'UN Roadblock', + 'Factory Gate', 'RUAF Gate', + 'ZB-016', 'ZB-014', + 'UN Roadblock', 'South V-Ex', - 'Factory Gate', + 'Outskirts', 'un-sec', 'wood_sniper_exit', - 'East Gate', 'Outskirts Water', + "Dead Man's Place", + 'The Boat', + 'Scav House', + 'East Gate', 'Mountain Stash', 'West Border', 'Old Station', - 'Scav House', - 'The Boat', - "Dead Man's Place", + 'RUAF Roadblock', ], shoreline: [ - 'Tunnel', - 'Rock Passage', - 'Pier Boat', - 'CCP Temporary', + 'Shorl_V-Ex', 'Road to Customs', - 'Lighthouse_pass', 'Road_at_railbridge', - 'Shorl_V-Ex', - 'RedRebel_alp', + 'Tunnel', + 'Lighthouse_pass', 'Smugglers_Trail_coop', - 'Adm Basement', - 'RWing Gym Entrance', - 'South Fence Passage', - 'Ruined House Fence', - 'Svetliy Dead End', - 'Wrecked Road', + 'Pier Boat', + 'RedRebel_alp', + 'Scav Road to Customs', 'Lighthouse', + 'Wrecked Road', + 'South Fence Passage', + 'RWing Gym Entrance', + 'Adm Basement', ], reserve: [ 'EXFIL_Train', + 'EXFIL_Bunker_D2', + 'EXFIL_Bunker', 'Alpinist', 'EXFIL_ScavCooperation', - 'EXFIL_Bunker', 'EXFIL_vent', - 'EXFIL_Bunker_D2', 'Exit1', 'Exit2', 'Exit3', @@ -96,54 +95,53 @@ const ALL_DUMPED_EXFILS_FROM_SCRIPT = { ], lighthouse: [ 'EXFIL_Train', - 'Alpinist_light', + ' V-Ex_light', 'tunnel_shared', + 'Alpinist_light', + 'Shorl_free', 'Nothern_Checkpoint', 'Coastal_South_Road', - 'Shorl_free', - ' V-Ex_light', - 'SCAV_Industrial_Zone', - 'Scav_Hideout_at_the_grotto', - 'SCAV_Underboat_Hideout', + 'Shorl_free_scav', 'Scav_Coastal_South', + 'Scav_Underboat_Hideout', + 'Scav_Hideout_at_the_grotto', + 'Scav_Industrial_zone', ], streets: [ + 'E8_yard', + 'E7_car', 'E1', + 'E4', 'E2', 'E3', - 'E4', 'E5', 'E6', - 'E7_car', - 'E8_yard', 'E9_sniper', 'Exit_E10_coop', 'E7', - 'E8', 'scav_e1', 'scav_e2', 'scav_e3', 'scav_e4', 'scav_e5', - 'scav_e6', 'scav_e7', 'scav_e8', ], laboratory: [ - 'lab_Parking_Gate', - 'lab_Hangar_Gate', - 'lab_Elevator_Med', - 'lab_Under_Storage_Collector', + 'lab_Elevator_Cargo', 'lab_Elevator_Main', 'lab_Vent', - 'lab_Elevator_Cargo', + 'lab_Elevator_Med', + 'lab_Under_Storage_Collector', + 'lab_Parking_Gate', + 'lab_Hangar_Gate', ], groundzero: [ - 'Unity_free_exit', 'Sandbox_VExit', - 'Sniper_exit', + 'Unity_free_exit', 'Scav_coop_exit', 'Nakatani_stairs_free_exit', + 'Sniper_exit', ], }; From 95624c2e05ca57b994d25c8bee53899ba3db7aae Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 17:20:56 +0100 Subject: [PATCH 057/203] fix: broken DevilFlippy config because "E8" extract does not exist anymore --- configs/DevilFlippy/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index 1b6abc74..6870dc32 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -640,7 +640,7 @@ "E4": "LotusHideout", "E7": "ExpoCPFlea", "E7_car": "StreetsCarToLabs", - "E8": "PainterHideout", + "E8_yard": "PainterHideout", "E9_sniper": "KlimovStreet", "scav_e1": "BasementDescent", "scav_e5": "RequisitionsHideout" From c1b6a56a4699514afe3a94b3e9dcbc92d6b194b0 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 17:23:38 +0100 Subject: [PATCH 058/203] 6.0.0-rc.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 94546d30..32d0dac5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "path-to-tarkov", - "version": "6.0.0-rc.2", + "version": "6.0.0-rc.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "path-to-tarkov", - "version": "6.0.0-rc.2", + "version": "6.0.0-rc.3", "license": "MIT", "devDependencies": { "@types/i18n": "^0.13.5", diff --git a/package.json b/package.json index c82d9536..9022ffe4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "path-to-tarkov", "displayName": "Path To Tarkov", "fullName": "Trap-PathToTarkov", - "version": "6.0.0-rc.2", + "version": "6.0.0-rc.3", "main": "src/mod.js", "license": "MIT", "author": "Trap", From 442d4ed9ca40aefcee51085f216fccc27c55710c Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 17:26:35 +0100 Subject: [PATCH 059/203] chore: apply prettier --- scripts/generate-all-exfils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/generate-all-exfils.js b/scripts/generate-all-exfils.js index 2c61c2f9..03c2a232 100644 --- a/scripts/generate-all-exfils.js +++ b/scripts/generate-all-exfils.js @@ -46,7 +46,8 @@ const LOCALES = lowerLocaleKeys( // eslint-disable-next-line @typescript-eslint/no-var-requires const MAPGENIE_LOCATIONS = require(`../${EXTERNAL_RESOURCES_DIR}/${MAPGENIE_LOCATIONS_FILENAME}`); -const getMapJsonFilePath = mapName => `${EXTERNAL_RESOURCES_DIR}/${MAPS_DIR}/${mapName}_allExtracts.json`; +const getMapJsonFilePath = mapName => + `${EXTERNAL_RESOURCES_DIR}/${MAPS_DIR}/${mapName}_allExtracts.json`; const getMapGenieMapName = mapName => { if (MAPGENIE_REMAPPING[mapName]) { From 0e7fb206f69a768f0a6089bc98048abbe69f2126 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 22:00:18 +0100 Subject: [PATCH 060/203] feat!: unify player spawnpoints --- .../Customs_TarkovDev/Customs_TarkovDev.jsonc | 0 .../Factory_TarkovDev/Factory_TarkovDev.jsonc | 0 .../GroundZero_TarkovDev.jsonc | 0 .../Interchange_TarkovDev.jsonc | 0 .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 0 .../Lighthouse_TarkovData.jsonc | 0 .../Reserve_TarkovData.jsonc | 0 .../Shoreline_TarkovData.jsonc | 0 .../Streets_TarkovData.jsonc | 0 .../Woods_TarkovData/Woods_TarkovData.jsonc | 0 .../Instructions.txt | 0 configs/Default/config.json | 90 +++- configs/DevilFlippy/config.json | 29 +- configs/DevilFlippy/player_spawnpoints.json | 491 ----------------- configs/ExampleOverrideByProfiles/config.json | 26 +- .../player_spawnpoints.json | 374 ------------- configs/LegacyPathToTarkovV4/config.json | 24 +- .../player_spawnpoints.json | 310 ----------- configs/LegacyPathToTarkovV5/config.json | 26 +- .../player_spawnpoints.json | 374 ------------- configs/LinearPath/config.json | 18 +- configs/LinearPath/player_spawnpoints.json | 370 ------------- configs/OriginalNarcoticsConfig/config.json | 8 +- .../player_spawnpoints.json | 503 ------------------ configs/PathToTarkovReloaded/config.json | 50 +- .../player_spawnpoints.json | 382 ------------- ...ts.json => shared_player_spawnpoints.json} | 17 +- src/config-analysis.ts | 20 + src/config.ts | 59 +- src/mod.ts | 3 +- tests/configs.test.ts | 6 +- 31 files changed, 261 insertions(+), 2919 deletions(-) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc (100%) rename configs/Default/{DynamicMaps compatibility => DynamicMaps optional tooltips}/Instructions.txt (100%) delete mode 100644 configs/DevilFlippy/player_spawnpoints.json delete mode 100644 configs/ExampleOverrideByProfiles/player_spawnpoints.json delete mode 100644 configs/LegacyPathToTarkovV4/player_spawnpoints.json delete mode 100644 configs/LegacyPathToTarkovV5/player_spawnpoints.json delete mode 100644 configs/LinearPath/player_spawnpoints.json delete mode 100644 configs/OriginalNarcoticsConfig/player_spawnpoints.json delete mode 100644 configs/PathToTarkovReloaded/player_spawnpoints.json rename configs/{Default/player_spawnpoints.json => shared_player_spawnpoints.json} (95%) diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc diff --git a/configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc similarity index 100% rename from configs/Default/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc rename to configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc diff --git a/configs/Default/DynamicMaps compatibility/Instructions.txt b/configs/Default/DynamicMaps optional tooltips/Instructions.txt similarity index 100% rename from configs/Default/DynamicMaps compatibility/Instructions.txt rename to configs/Default/DynamicMaps optional tooltips/Instructions.txt diff --git a/configs/Default/config.json b/configs/Default/config.json index 4ce812ca..7f628691 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -256,7 +256,10 @@ "kr": "Scav Bunker in woods", "pl": "Scav Bunker in woods", "po": "Scav Bunker in woods", - "ru": "Scav Bunker in woods" + "ro": "Scav Bunker in woods", + "ru": "Scav Bunker in woods", + "rk": "Scav Bunker in woods", + "tu": "Scav Bunker in woods" }, "access_via": ["PraporHideout"] }, @@ -286,7 +289,10 @@ "kr": "Emercom checkpoint on Ground Zero", "pl": "Emercom checkpoint on Ground Zero", "po": "Emercom checkpoint on Ground Zero", - "ru": "Emercom checkpoint on Ground Zero" + "ro": "Emercom checkpoint on Ground Zero", + "ru": "Emercom checkpoint on Ground Zero", + "sk": "Emercom checkpoint on Ground Zero", + "tu": "Emercom checkpoint on Ground Zero" }, "access_via": ["TherapistHideout"] }, @@ -307,7 +313,10 @@ "kr": "Bunker in Factory", "pl": "Bunker in Factory", "po": "Bunker in Factory", - "ru": "Bunker in Factory" + "ro": "Bunker in Factory", + "ru": "Bunker in Factory", + "sk": "Bunker in Factory", + "tu": "Bunker in Factory" }, "access_via": ["MechanicHideout"] }, @@ -337,7 +346,10 @@ "kr": "Warehouse 17 at Customs", "pl": "Warehouse 17 at Customs", "po": "Warehouse 17 at Customs", - "ru": "Warehouse 17 at Customs" + "ro": "Warehouse 17 at Customs", + "ru": "Warehouse 17 at Customs", + "sk": "Warehouse 17 at Customs", + "tu": "Warehouse 17 at Customs" }, "access_via": ["SkierHideout"] }, @@ -367,7 +379,10 @@ "kr": "Somewhere between Interchange and Customs", "pl": "Somewhere between Interchange and Customs", "po": "Somewhere between Interchange and Customs", - "ru": "Somewhere between Interchange and Customs" + "ro": "Somewhere between Interchange and Customs", + "ru": "Somewhere between Interchange and Customs", + "sk": "Somewhere between Interchange and Customs", + "tu": "Somewhere between Interchange and Customs" }, "access_via": ["TrailerPark", "ScavCamp"] }, @@ -388,7 +403,10 @@ "kr": "Mountain stash in Woods", "pl": "Mountain stash in Woods", "po": "Mountain stash in Woods", - "ru": "Mountain stash in Woods" + "ro": "Mountain stash in Woods", + "ru": "Mountain stash in Woods", + "sk": "Mountain stash in Woods", + "tu": "Mountain stash in Woods" }, "access_via": ["JaegerHideout"] }, @@ -409,7 +427,10 @@ "kr": "In D2 bunker between military reserve and shoreline", "pl": "In D2 bunker between military reserve and shoreline", "po": "In D2 bunker between military reserve and shoreline", - "ru": "In D2 bunker between military reserve and shoreline" + "ro": "In D2 bunker between military reserve and shoreline", + "ru": "In D2 bunker between military reserve and shoreline", + "sk": "In D2 bunker between military reserve and shoreline", + "tu": "In D2 bunker between military reserve and shoreline" }, "access_via": ["PeacekeeperHideout"] }, @@ -451,7 +472,10 @@ "kr": "Along the railroad line between shoreline and customs", "pl": "Along the railroad line between shoreline and customs", "po": "Along the railroad line between shoreline and customs", - "ru": "Along the railroad line between shoreline and customs" + "ro": "Along the railroad line between shoreline and customs", + "ru": "Along the railroad line between shoreline and customs", + "sk": "Along the railroad line between shoreline and customs", + "tu": "Along the railroad line between shoreline and customs" }, "access_via": ["RailwayBridge", "PortRR"] }, @@ -473,7 +497,10 @@ "kr": "Somewhere outskirts in woods", "pl": "Somewhere outskirts in woods", "po": "Somewhere outskirts in woods", - "ru": "Somewhere outskirts in woods" + "ro": "Somewhere outskirts in woods", + "ru": "Somewhere outskirts in woods", + "sk": "Somewhere outskirts in woods", + "tu": "Somewhere outskirts in woods" }, "access_via": ["Outskirts"] }, @@ -495,7 +522,10 @@ "kr": "Trailer Park Workers Shack", "pl": "Trailer Park Workers Shack", "po": "Trailer Park Workers Shack", - "ru": "Trailer Park Workers Shack" + "ro": "Trailer Park Workers Shack", + "ru": "Trailer Park Workers Shack", + "sk": "Trailer Park Workers Shack", + "tu": "Trailer Park Workers Shack" }, "access_via": ["LegsHideout"] }, @@ -517,7 +547,10 @@ "kr": "Basement in town between streets and ground zero", "pl": "Basement in town between streets and ground zero", "po": "Basement in town between streets and ground zero", - "ru": "Basement in town between streets and ground zero" + "ru": "Basement in town between streets and ground zero", + "ro": "Basement in town between streets and ground zero", + "sk": "Basement in town between streets and ground zero", + "tu": "Basement in town between streets and ground zero" }, "access_via": ["BasementDescent"] }, @@ -539,7 +572,10 @@ "kr": "Scav Hideout at the Grotto around lighthouse", "pl": "Scav Hideout at the Grotto around lighthouse", "po": "Scav Hideout at the Grotto around lighthouse", - "ru": "Scav Hideout at the Grotto around lighthouse" + "ro": "Scav Hideout at the Grotto around lighthouse", + "ru": "Scav Hideout at the Grotto around lighthouse", + "sk": "Scav Hideout at the Grotto around lighthouse", + "tu": "Scav Hideout at the Grotto around lighthouse" }, "access_via": ["ArtemHideout"] }, @@ -561,7 +597,10 @@ "kr": "In ZB-14 bunker (Woods/Reserve)", "pl": "In ZB-14 bunker (Woods/Reserve)", "po": "In ZB-14 bunker (Woods/Reserve)", - "ru": "In ZB-14 bunker (Woods/Reserve)" + "ro": "In ZB-14 bunker (Woods/Reserve)", + "ru": "In ZB-14 bunker (Woods/Reserve)", + "sk": "In ZB-14 bunker (Woods/Reserve)", + "tu": "In ZB-14 bunker (Woods/Reserve)" }, "access_via": ["ReserveZB-014"] }, @@ -583,7 +622,10 @@ "kr": "Along the railroad line between customs streets and interchange", "pl": "Along the railroad line between customs streets and interchange", "po": "Along the railroad line between customs streets and interchange", - "ru": "Along the railroad line between customs streets and interchange" + "ro": "Along the railroad line between customs streets and interchange", + "ru": "Along the railroad line between customs streets and interchange", + "sk": "Along the railroad line between customs streets and interchange", + "tu": "Along the railroad line between customs streets and interchange" }, "access_via": ["TarkovRR", "CrashSite", "Railway"] }, @@ -605,7 +647,10 @@ "kr": "at Emercom Checkpoint between Interchange and Customs", "pl": "at Emercom Checkpoint between Interchange and Customs", "po": "at Emercom Checkpoint between Interchange and Customs", - "ru": "at Emercom Checkpoint between Interchange and Customs" + "ro": "at Emercom Checkpoint between Interchange and Customs", + "ru": "at Emercom Checkpoint between Interchange and Customs", + "sk": "at Emercom Checkpoint between Interchange and Customs", + "tu": "at Emercom Checkpoint between Interchange and Customs" }, "access_via": ["Emercom", "Crossroads"] }, @@ -627,7 +672,10 @@ "kr": "Basement in town between streets and ground zero", "pl": "Basement in town between streets and ground zero", "po": "Basement in town between streets and ground zero", - "ru": "Basement in town between streets and ground zero" + "ro": "Basement in town between streets and ground zero", + "ru": "Basement in town between streets and ground zero", + "sk": "Basement in town between streets and ground zero", + "tu": "Basement in town between streets and ground zero" }, "access_via": ["BasementDescent"] }, @@ -649,7 +697,10 @@ "kr": "Ruined house in the streets", "pl": "Ruined house in the streets", "po": "Ruined house in the streets", - "ru": "Ruined house in the streets" + "ro": "Ruined house in the streets", + "ru": "Ruined house in the streets", + "sk": "Ruined house in the streets", + "tu": "Ruined house in the streets" }, "access_via": ["RuinedHouse"] }, @@ -671,7 +722,10 @@ "kr": "Sewer between Reserve and Streets", "pl": "Sewer between Reserve and Streets", "po": "Sewer between Reserve and Streets", - "ru": "Sewer between Reserve and Streets" + "ro": "Sewer between Reserve and Streets", + "ru": "Sewer between Reserve and Streets", + "sk": "Sewer between Reserve and Streets", + "tu": "Sewer between Reserve and Streets" }, "access_via": ["Manhole"] } diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index 6870dc32..3b09215e 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -684,7 +684,7 @@ }, "RagmanHideout": { "bigmap": ["Crossroads"], - "interchange": ["EmercomMall"] + "interchange": ["Emercom"] }, "TherapistHideout": { "sandbox": ["EmercomGZ"] @@ -710,7 +710,7 @@ "interchange": ["Railway"] }, "ScorpionHideout": { - "tarkovstreets": ["Stylobate Building Elevator"], + "tarkovstreets": ["Sylobate Elevator"], "laboratory": ["Main Elevator"] }, "DormsCar": { @@ -718,7 +718,7 @@ "shoreline": ["North Fence Passage"] }, "NorthCar": { - "interchange": ["Car at Power Station"], + "interchange": ["Interchange Vehicle Extract"], "sandbox": ["Police Car"], "woods": ["Woods Vehicle Extract"] }, @@ -727,7 +727,7 @@ "lighthouse": ["Lighthouse Vehicle Extract"] }, "Boat": { - "bigmap": ["Smuggler's Boat"], + "bigmap": ["Smugglers Boat"], "shoreline": ["Pier Boat"], "woods": ["ScavVillage"], "lighthouse": ["Lighthouse Docks Boat"] @@ -775,7 +775,7 @@ }, "WoodsLighthouse": { "woods": ["Outskirts"], - "lighthouse": ["NorthernRoad"] + "lighthouse": ["Northern CP"] }, "ZB-014Stash": { "woods": ["ZB-014"] @@ -785,8 +785,8 @@ "tarkovstreets": ["Streets Ruined House"] }, "ShorelineLighthouseTunnel": { - "shoreline": ["Tunnel"], - "lighthouse": ["Lighthouse tunnel"] + "shoreline": ["Shoreline Tunnel"], + "lighthouse": ["Lighthouse Tunnel"] }, "ShorelineLighthousePath": { "shoreline": ["Path to Lighthouse"], @@ -805,7 +805,7 @@ "laboratory": ["Lab Sewage Conduit"] }, "StreetsCarToLabs": { - "tarkovstreets": ["Primorsky Vehicle Extract"], + "tarkovstreets": ["Streets Vehicle Extract"], "laboratory": ["Parking Gate"] }, "Catacombs": { @@ -821,9 +821,20 @@ "tarkovstreets": ["Klimov Street"] }, "BasementDescent": { - "sandbox": ["Nakatani Basement"], + "sandbox": ["Nakatani Basement Stairs"], "tarkovstreets": ["Basement Descent"], "laboratory": ["Cargo Elevator"] } + }, + "infiltrations_config": { + "additional_player_spawnpoints": { + "woods": { + "ScavVillage": { + "Description": "Scav Village in the north end", + "Position": [-58.53, 7.66, -757.22], + "Rotation": 180 + } + } + } } } diff --git a/configs/DevilFlippy/player_spawnpoints.json b/configs/DevilFlippy/player_spawnpoints.json deleted file mode 100644 index 0296cad3..00000000 --- a/configs/DevilFlippy/player_spawnpoints.json +++ /dev/null @@ -1,491 +0,0 @@ -{ - "factory4_day": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - }, - "Camera Bunker Door": { - "Position": [-20.8695526, -2.63423038, 34.9322433], - "Rotation": 0.891350448 - } - }, - "factory4_night": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - }, - "Camera Bunker Door": { - "Position": [-20.8695526, -2.63423038, 34.9322433], - "Rotation": 0.891350448 - } - }, - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smuggler's Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 - }, - "Old Gas Scav": { - "Position": [302.545, 2.91025, -185.017761], - "Rotation": 202.349335 - }, - "MallTrain": { - "Position": [-154.6799, 2.266766, -221.5874], - "Rotation": 327.8281 - }, - "PraveenGasoline": { - "Position": [354.8507, 1.106263, -191.5768], - "Rotation": 23.4955 - }, - "OfficePath": { - "Position": [655.933, 1.098399, -166.3037], - "rotation": 302.8839 - }, - "RUAFAdmin": { - "Position": [667.3405, 1.064447, -58.31626], - "rotation": 287.2482 - }, - "Warehouse 17": { - "Position": [48.11184, 1.10045552, -84.83577], - "Rotation": 155.8685 - }, - "Scav CP": { - "Position": [647.141, -0.3182248, -25.9616776], - "Rotation": 307.1494 - }, - "Trailer Park": { - "Position": [-310.01, 0.89, -215.43], - "Rotation": 31.98688 - } - }, - "woods": { - "UN Roadblock": { - "Position": [-521.465332, -1.258715, 288.813171], - "Rotation": 76.4774246 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], - "Rotation": 285.467377 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Bridge Car": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "RUAFRoadblock": { - "Position": [-129.7272, -1.194496, 415.476], - "Rotation": 146.2519 - }, - "Mountain Stash": { - "Position": [-215.205872, 31.7007847, -209.631348], - "Rotation": 335.046753 - }, - "Woods Vehicle Extract": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "ScavVillage": { - "Comment": "Scav Village in the north end", - "Position": [-58.53, 7.66, -757.22], - "Rotation": 180 - }, - "ZB-016": { - "Position": [-388.16, 3.25, 20.05], - "Rotation": 115.467377 - }, - "RUAF Gate": { - "Position": [-146.51947, 1.22620764, 425.6336], - "Rotation": 162.779083 - }, - "Northern UN Roadblock": { - "Position": [-555.2336, 9.391193, -76.86284], - "Rotation": 138.160156 - }, - "ZB-014": { - "Position": [447.93, -14.25, 67.26], - "Rotation": 285.467377 - } - }, - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "CP Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 - }, - "Bunker Hermetic": { - "Position": [64.5668, -6.95917463, -190.306641], - "Rotation": 280.9828 - }, - "Depot Hermetic": { - "Position": [118.866768, -12.2845945, -119.324211], - "Rotation": 299.889923 - }, - "Hole In Wall": { - "Position": [-262.3644, -6.20308161, 47.7328873], - "Rotation": 89.65134 - }, - "Train Station": { - "Position": [166.653687, -5.19410563, -144.143341], - "Rotation": 191.8541 - }, - "Checkpoint Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [56.2388641, -6.94445145, 90.22048], - "Rotation": 287.982239 - } - }, - "interchange": { - "Car at Power Station": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - }, - "EmercomMall": { - "Position": [-313.2805, 21.32544, 254.3763], - "Rotation": 105.2137 - }, - "Fence Gap": { - "Position": [-220.849625, 21.35, -40.680878], - "Rotation": 52.06011 - } - }, - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - }, - "Ruined Road": { - "Position": [350.51, -59.67, 324.86], - "Rotation": 55.0321 - }, - "Railway Bridge": { - "Position": [-1023.37292, -60.67251, 314.364075], - "Rotation": 24.1157665 - } - }, - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - }, - "Grotto": { - "Position": [194.516525, -0.48209092, -491.773224], - "Rotation": 182.743759 - }, - "Armored Train LH": { - "Position": [10.0, 11.97, -870.85], - "Rotation": 180.236305 - }, - "NorthernRoad": { - "Position": [108.83, 4.61, -982.84], - "Rotation": 360.5 - }, - "Southern Road": { - "Position": [-215.268738, 5.94645643, 419.227417], - "Rotation": 77.76075 - }, - "Mountain Pass": { - "Position": [-147.143173, 30.5996075, -4.088336], - "Rotation": 74.17951 - } - }, - "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 - }, - "Near Kamchatskaya Arch": { - "Position": [260.6, -4.5, 49.6], - "Rotation": 304.3322 - }, - "Cardinal Appartments Parking": { - "Position": [103.6, -1.9, -155.3], - "Rotation": 304.3322 - }, - "Crash Site": { - "Position": [269.3, 3.4, 427.25], - "Rotation": 87.62667 - }, - "Stylobate Building Elevator": { - "Position": [-45.63, 9.6, -64.12], - "Rotation": 200 - }, - "Expo Checkpoint": { - "Position": [215, -1.93, -88.75], - "Rotation": 304.3322 - } - }, - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "sandbox": { - "Nakatani Basement": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "Mira Ave": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "GZ Scav checkpoint": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - }, - "EmercomGZ": { - "Position": [152.5, 24.1, -89.4], - "Rotation": 0.85 - }, - "Police Car": { - "Position": [-12.97, 22.6, 116.99], - "Rotation": 90.0 - }, - "Scav Hideout": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - } - } -} diff --git a/configs/ExampleOverrideByProfiles/config.json b/configs/ExampleOverrideByProfiles/config.json index f1ac2aab..ff9fc27c 100644 --- a/configs/ExampleOverrideByProfiles/config.json +++ b/configs/ExampleOverrideByProfiles/config.json @@ -316,11 +316,11 @@ "exfiltrations": { "factory4_day": { "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate_o": "JaegerStash" }, "factory4_night": { "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate_o": "JaegerStash" }, "bigmap": { "Railroad To Tarkov": "TherapistStash", @@ -373,11 +373,11 @@ "infiltrations": { "TherapistStash": { "bigmap": ["Crossroads"], - "sandbox": ["GZ Scav checkpoint"], + "sandbox": ["Scav Hideout"], "tarkovstreets": ["Zmeevsky Alley"] }, "PraporStash": { - "tarkovstreets": ["Primorsky Vehicle Extract"], + "tarkovstreets": ["Streets Vehicle Extract"], "sandbox": ["Police Car"], "laboratory": [ "Cargo Elevator", @@ -388,7 +388,7 @@ "Med Block Elevator", "Parking Gate" ], - "interchange": ["Car at Power Station"] + "interchange": ["Interchange Vehicle Extract"] }, "MechanicStash": { "factory4_day": ["Gate 3"], @@ -400,21 +400,21 @@ "interchange": ["Railway"] }, "SkierStash": { - "bigmap": ["Railroad To Military Base"], + "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] }, "PeacekeeperStash": { - "lighthouse": ["Lighthouse tunnel"], - "shoreline": ["Tunnel"] + "lighthouse": ["Lighthouse Tunnel"], + "shoreline": ["Shoreline Tunnel"] }, "JaegerStash": { - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"], - "woods": ["Factory Gate", "RUAFRoadblock", "UN Roadblock"] + "factory4_day": ["Courtyard"], + "factory4_night": ["Courtyard"], + "woods": ["Factory Gate", "RUAF Gate", "UN Roadblock"] }, "MilitaryLighthouseStash": { "lighthouse": ["Lighthouse Vehicle Extract"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "ReserveBunkerStash": { "rezervbase": ["D-2"], @@ -423,7 +423,7 @@ }, "ShorelineWoodsStash": { "shoreline": ["Road to Customs"], - "woods": ["Bridge Car"] + "woods": ["Woods Vehicle Extract"] }, "KlimovStash": { "tarkovstreets": ["Klimov Street"] diff --git a/configs/ExampleOverrideByProfiles/player_spawnpoints.json b/configs/ExampleOverrideByProfiles/player_spawnpoints.json deleted file mode 100644 index cffa610a..00000000 --- a/configs/ExampleOverrideByProfiles/player_spawnpoints.json +++ /dev/null @@ -1,374 +0,0 @@ -{ - "factory4_day": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "factory4_night": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smuggler's Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 - }, - "Old Gas Scav": { - "Position": [302.545, 2.91025, -185.017761], - "Rotation": 202.349335 - }, - "MallTrain": { - "Position": [-154.6799, 2.266766, -221.5874], - "Rotation": 327.8281 - }, - "PraveenGasoline": { - "Position": [354.8507, 1.106263, -191.5768], - "Rotation": 23.4955 - }, - "OfficePath": { - "Position": [655.933, 1.098399, -166.3037], - "rotation": 302.8839 - }, - "RUAFAdmin": { - "Position": [667.3405, 1.064447, -58.31626], - "rotation": 287.2482 - } - }, - "woods": { - "UN Roadblock": { - "Comment": "UN Roadblock", - "Position": [-543.3435, 9.776281, -78.09744], - "Rotation": 228.816986 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], - "Rotation": 285.467377 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Bridge Car": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "RUAFRoadblock": { - "Position": [-129.7272, -1.194496, 415.476], - "Rotation": 146.2519 - } - }, - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "CP Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 - }, - "Depot Hermetic": { - "Position": [118.866768, -12.2845945, -119.324211], - "Rotation": 299.889923 - }, - "Hole In Wall": { - "Position": [-262.3644, -6.20308161, 47.7328873], - "Rotation": 89.65134 - }, - "Train Station": { - "Position": [166.653687, -5.19410563, -144.143341], - "Rotation": 191.8541 - } - }, - "interchange": { - "Car at Power Station": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - }, - "EmercomMall": { - "Position": [-313.2805, 21.32544, 254.3763], - "Rotation": 105.2137 - } - }, - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - } - }, - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - } - }, - "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 - } - }, - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "sandbox": { - "Nakatani Basement": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "Mira Ave": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "GZ Scav checkpoint": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - }, - "Police Car": { - "Position": [-12.97, 22.6, 116.99], - "Rotation": 90.0 - } - } -} diff --git a/configs/LegacyPathToTarkovV4/config.json b/configs/LegacyPathToTarkovV4/config.json index 1eddd726..0cadbf06 100644 --- a/configs/LegacyPathToTarkovV4/config.json +++ b/configs/LegacyPathToTarkovV4/config.json @@ -528,7 +528,7 @@ "Gate m": "FactoryZB-1012", "Cellars": "FactoryZB-1011", "Camera Bunker Door": "FactoryZB-1011", - "Office Window": "WoodsFactoryGate", + "Gate_o": "WoodsFactoryGate", "Gate 0": "WoodsFactoryGate" }, "factory4_night": { @@ -536,7 +536,7 @@ "Gate m": "FactoryZB-1012", "Cellars": "FactoryZB-1011", "Camera Bunker Door": "FactoryZB-1011", - "Office Window": "WoodsFactoryGate", + "Gate_o": "WoodsFactoryGate", "Gate 0": "WoodsFactoryGate" }, "bigmap": { @@ -609,11 +609,11 @@ "ShorelineLighthousePath": { "shoreline": ["Path to Lighthouse"], "lighthouse": ["Path to Shoreline"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "ShorelineLighthouseTunnel": { - "shoreline": ["Tunnel"], - "lighthouse": ["Lighthouse tunnel"] + "shoreline": ["Shoreline Tunnel"], + "lighthouse": ["Lighthouse Tunnel"] }, "ShorelineNorthMoutains": { "rezervbase": ["Cliff"], @@ -621,7 +621,7 @@ }, "WoodsReserveShoreline": { "woods": ["Outskirts"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "InterchangeCustoms": { "bigmap": ["Crossroads"], @@ -632,7 +632,7 @@ "bigmap": ["RUAF Roadblock"] }, "Boat": { - "bigmap": ["Smuggler's Boat"], + "bigmap": ["Smugglers Boat"], "woods": ["The Boat"], "shoreline": ["Pier Boat"], "lighthouse": ["Lighthouse Docks Boat"] @@ -643,10 +643,10 @@ }, "Car": { "bigmap": ["Dorms Car"], - "interchange": ["Car at Power Station"], - "woods": ["Bridge Car"], + "interchange": ["Interchange Vehicle Extract"], + "woods": ["Woods Vehicle Extract"], "lighthouse": ["Lighthouse Vehicle Extract"], - "tarkovstreets": ["Primorsky Vehicle Extract"], + "tarkovstreets": ["Streets Vehicle Extract"], "sandbox": ["Mira Ave"], "laboratory": [ "Cargo Elevator", @@ -663,12 +663,12 @@ "rezervbase": ["Scav lands"] }, "MilitaryBaseRail": { - "bigmap": ["Railroad To Military Base"], + "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] }, "FactoryZB-1013": { "bigmap": ["ZB-1013"], - "woods": ["ZB-1014"], + "woods": ["ZB-014"], "factory4_day": ["Gate 3"], "factory4_night": ["Gate 3"] }, diff --git a/configs/LegacyPathToTarkovV4/player_spawnpoints.json b/configs/LegacyPathToTarkovV4/player_spawnpoints.json deleted file mode 100644 index 5953a507..00000000 --- a/configs/LegacyPathToTarkovV4/player_spawnpoints.json +++ /dev/null @@ -1,310 +0,0 @@ -{ - "factory4_day": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - } - }, - "factory4_night": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - } - }, - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smuggler's Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 - } - }, - "woods": { - "UN Roadblock": { - "Comment": "UN Roadblock", - "Position": [-543.3435, 9.776281, -78.09744], - "Rotation": 228.816986 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], - "Rotation": 285.467377 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Bridge Car": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - } - }, - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "CP Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - } - }, - "interchange": { - "Car at Power Station": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - } - }, - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - } - }, - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - } - }, - "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 - } - }, - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "sandbox": { - "Nakatani Basement": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "Mira Ave": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "GZ Scav checkpoint": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - } - } -} diff --git a/configs/LegacyPathToTarkovV5/config.json b/configs/LegacyPathToTarkovV5/config.json index 105a054a..4f92b0de 100644 --- a/configs/LegacyPathToTarkovV5/config.json +++ b/configs/LegacyPathToTarkovV5/config.json @@ -310,11 +310,11 @@ "exfiltrations": { "factory4_day": { "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate_o": "JaegerStash" }, "factory4_night": { "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate_o": "JaegerStash" }, "bigmap": { "Railroad To Tarkov": "TherapistStash", @@ -367,11 +367,11 @@ "infiltrations": { "TherapistStash": { "bigmap": ["Crossroads"], - "sandbox": ["GZ Scav checkpoint"], + "sandbox": ["Scav Hideout"], "tarkovstreets": ["Zmeevsky Alley"] }, "PraporStash": { - "tarkovstreets": ["Primorsky Vehicle Extract"], + "tarkovstreets": ["Streets Vehicle Extract"], "sandbox": ["Police Car"], "laboratory": [ "Cargo Elevator", @@ -382,7 +382,7 @@ "Med Block Elevator", "Parking Gate" ], - "interchange": ["Car at Power Station"] + "interchange": ["Interchange Vehicle Extract"] }, "MechanicStash": { "factory4_day": ["Gate 3"], @@ -394,21 +394,21 @@ "interchange": ["Railway"] }, "SkierStash": { - "bigmap": ["Railroad To Military Base"], + "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] }, "PeacekeeperStash": { - "lighthouse": ["Lighthouse tunnel"], - "shoreline": ["Tunnel"] + "lighthouse": ["Lighthouse Tunnel"], + "shoreline": ["Shoreline Tunnel"] }, "JaegerStash": { - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"], - "woods": ["Factory Gate", "RUAFRoadblock", "UN Roadblock"] + "factory4_day": ["Courtyard"], + "factory4_night": ["Courtyard"], + "woods": ["Factory Gate", "RUAF Gate", "UN Roadblock"] }, "MilitaryLighthouseStash": { "lighthouse": ["Lighthouse Vehicle Extract"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "ReserveBunkerStash": { "rezervbase": ["D-2"], @@ -417,7 +417,7 @@ }, "ShorelineWoodsStash": { "shoreline": ["Road to Customs"], - "woods": ["Bridge Car"] + "woods": ["Woods Vehicle Extract"] }, "KlimovStash": { "tarkovstreets": ["Klimov Street"] diff --git a/configs/LegacyPathToTarkovV5/player_spawnpoints.json b/configs/LegacyPathToTarkovV5/player_spawnpoints.json deleted file mode 100644 index cffa610a..00000000 --- a/configs/LegacyPathToTarkovV5/player_spawnpoints.json +++ /dev/null @@ -1,374 +0,0 @@ -{ - "factory4_day": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "factory4_night": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smuggler's Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 - }, - "Old Gas Scav": { - "Position": [302.545, 2.91025, -185.017761], - "Rotation": 202.349335 - }, - "MallTrain": { - "Position": [-154.6799, 2.266766, -221.5874], - "Rotation": 327.8281 - }, - "PraveenGasoline": { - "Position": [354.8507, 1.106263, -191.5768], - "Rotation": 23.4955 - }, - "OfficePath": { - "Position": [655.933, 1.098399, -166.3037], - "rotation": 302.8839 - }, - "RUAFAdmin": { - "Position": [667.3405, 1.064447, -58.31626], - "rotation": 287.2482 - } - }, - "woods": { - "UN Roadblock": { - "Comment": "UN Roadblock", - "Position": [-543.3435, 9.776281, -78.09744], - "Rotation": 228.816986 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], - "Rotation": 285.467377 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Bridge Car": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "RUAFRoadblock": { - "Position": [-129.7272, -1.194496, 415.476], - "Rotation": 146.2519 - } - }, - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "CP Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 - }, - "Depot Hermetic": { - "Position": [118.866768, -12.2845945, -119.324211], - "Rotation": 299.889923 - }, - "Hole In Wall": { - "Position": [-262.3644, -6.20308161, 47.7328873], - "Rotation": 89.65134 - }, - "Train Station": { - "Position": [166.653687, -5.19410563, -144.143341], - "Rotation": 191.8541 - } - }, - "interchange": { - "Car at Power Station": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - }, - "EmercomMall": { - "Position": [-313.2805, 21.32544, 254.3763], - "Rotation": 105.2137 - } - }, - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - } - }, - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - } - }, - "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 - } - }, - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "sandbox": { - "Nakatani Basement": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "Mira Ave": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "GZ Scav checkpoint": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - }, - "Police Car": { - "Position": [-12.97, 22.6, 116.99], - "Rotation": 90.0 - } - } -} diff --git a/configs/LinearPath/config.json b/configs/LinearPath/config.json index 72c4fe87..0bc5de69 100644 --- a/configs/LinearPath/config.json +++ b/configs/LinearPath/config.json @@ -276,11 +276,11 @@ "exfiltrations": { "factory4_day": { "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate_o": "JaegerStash" }, "factory4_night": { "Gate 3": "MechanicStash", - "Office Window": "JaegerStash" + "Gate_o": "JaegerStash" }, "bigmap": { "Railroad To Tarkov": "TherapistStash", @@ -351,21 +351,21 @@ "interchange": ["Railway"] }, "SkierStash": { - "bigmap": ["Railroad To Military Base"], + "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] }, "PeacekeeperStash": { - "lighthouse": ["Lighthouse tunnel"], - "shoreline": ["Tunnel"] + "lighthouse": ["Lighthouse Tunnel"], + "shoreline": ["Shoreline Tunnel"] }, "JaegerStash": { - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"], - "woods": ["Factory Gate", "RUAFRoadblock", "UN Roadblock"] + "factory4_day": ["Courtyard"], + "factory4_night": ["Courtyard"], + "woods": ["Factory Gate", "RUAF Gate", "UN Roadblock"] }, "MilitaryLighthouseStash": { "lighthouse": ["Lighthouse Vehicle Extract"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "KlimovStash": { "tarkovstreets": ["Klimov Street"] diff --git a/configs/LinearPath/player_spawnpoints.json b/configs/LinearPath/player_spawnpoints.json deleted file mode 100644 index a126e9e3..00000000 --- a/configs/LinearPath/player_spawnpoints.json +++ /dev/null @@ -1,370 +0,0 @@ -{ - "factory4_day": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "factory4_night": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smuggler's Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 - }, - "Old Gas Scav": { - "Position": [302.545, 2.91025, -185.017761], - "Rotation": 202.349335 - }, - "MallTrain": { - "Position": [-154.6799, 2.266766, -221.5874], - "Rotation": 327.8281 - }, - "PraveenGasoline": { - "Position": [354.8507, 1.106263, -191.5768], - "Rotation": 23.4955 - }, - "OfficePath": { - "Position": [655.933, 1.098399, -166.3037], - "rotation": 302.8839 - }, - "RUAFAdmin": { - "Position": [667.3405, 1.064447, -58.31626], - "rotation": 287.2482 - } - }, - "woods": { - "UN Roadblock": { - "Comment": "UN Roadblock", - "Position": [-543.3435, 9.776281, -78.09744], - "Rotation": 228.816986 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], - "Rotation": 285.467377 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Bridge Car": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "RUAFRoadblock": { - "Position": [-129.7272, -1.194496, 415.476], - "Rotation": 146.2519 - } - }, - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "CP Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 - }, - "Depot Hermetic": { - "Position": [118.866768, -12.2845945, -119.324211], - "Rotation": 299.889923 - }, - "Hole In Wall": { - "Position": [-262.3644, -6.20308161, 47.7328873], - "Rotation": 89.65134 - }, - "Train Station": { - "Position": [166.653687, -5.19410563, -144.143341], - "Rotation": 191.8541 - } - }, - "interchange": { - "Car at Power Station": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - }, - "EmercomMall": { - "Position": [-313.2805, 21.32544, 254.3763], - "Rotation": 105.2137 - } - }, - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - } - }, - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - } - }, - "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 - } - }, - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "sandbox": { - "Nakatani Basement": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "Mira Ave": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "GZ Scav checkpoint": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - } - } -} diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index 7ac69fac..4155a9c1 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -689,7 +689,7 @@ "Cellars": "FactoryZB-013", "Camera Bunker Door": "MechanicHideout", "Gate 0": "FactoryZB-1011", - "Office Window": "GasGate" + "Gate_o": "GasGate" }, "factory4_night": { "Gate 3": "FactoryZB-016", @@ -697,7 +697,7 @@ "Cellars": "FactoryZB-013", "Camera Bunker Door": "MechanicHideout", "Gate 0": "FactoryZB-1011", - "Office Window": "GasGate" + "Gate_o": "GasGate" }, "bigmap": { "Military Checkpoint": "ScavCP", @@ -881,8 +881,8 @@ "GasGate": { "bigmap": ["Old Gas Scav"], "woods": ["Factory Gate"], - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"] + "factory4_day": ["Courtyard"], + "factory4_night": ["Courtyard"] }, "TarkovRR": { "bigmap": ["RR to Tarkov"], diff --git a/configs/OriginalNarcoticsConfig/player_spawnpoints.json b/configs/OriginalNarcoticsConfig/player_spawnpoints.json deleted file mode 100644 index d3b9a5fb..00000000 --- a/configs/OriginalNarcoticsConfig/player_spawnpoints.json +++ /dev/null @@ -1,503 +0,0 @@ -{ - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "factory4_day": { - "Gate 0": { - "Position": [-52.5704842, 1.25745475, 55.06734], - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": [58.67002, 0.233123064, 57.4049568], - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": [-18.9917545, 0.229607314, -46.5803642], - "Rotation": 19.03057 - }, - "Cellars": { - "Position": [66.78813, -2.63332653, -30.9360619], - "Rotation": 231.811646 - }, - "Camera Bunker Door": { - "Position": [-20.8695526, -2.63423038, 34.9322433], - "Rotation": 0.891350448 - }, - "Office Window": { - "Position": [17.66614, 8.210876, 40.92688], - "Rotation": 158.9888 - } - }, - "factory4_night": { - "Gate 0": { - "Position": [-52.5704842, 1.25745475, 55.06734], - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": [58.67002, 0.233123064, 57.4049568], - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": [-18.9917545, 0.229607314, -46.5803642], - "Rotation": 19.03057 - }, - "Cellars": { - "Position": [66.78813, -2.63332653, -30.9360619], - "Rotation": 231.811646 - }, - "Camera Bunker Door": { - "Position": [-20.8695526, -2.63423038, 34.9322433], - "Rotation": 0.891350448 - }, - "Office Window": { - "Position": [17.66614, 8.210876, 40.92688], - "Rotation": 158.9888 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "Trailer Park": { - "Position": [-310.01, 0.89, -215.43], - "Rotation": 31.98688 - }, - "Trailer Park Workers Shack": { - "Position": [-251.01, 0.89, -227.43], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smugglers Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Factory Far Corner": { - "Position": [647.2151, 1.12474906, -150.711029], - "Rotation": 331.2538 - }, - "Old Gas Scav": { - "Position": [302.545, 2.91025, -185.017761], - "Rotation": 202.349335 - }, - "RR to Military Base": { - "Position": [458.392639, 4.95283127, 181.01564], - "Rotation": 256.057983 - }, - "RR to Port": { - "Position": [-150.3853, 2.62803984, 23.7549515], - "Rotation": 1.93337643 - }, - "RR to Tarkov": { - "Position": [-165.420151, 3.40357137, -200.949509], - "Rotation": 6.05172825 - }, - "Warehouse 17": { - "Position": [48.11184, 1.10045552, -84.83577], - "Rotation": 155.8685 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.0221 - }, - "Scav CP": { - "Position": [647.141, -0.3182248, -25.9616776], - "Rotation": 307.1494 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "woods": { - "Northern UN Roadblock": { - "Position": [-555.2336, 9.391193, -76.86284], - "Rotation": 138.160156 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "RUAF Gate": { - "Position": [-146.51947, 1.22620764, 425.6336], - "Rotation": 162.779083 - }, - "ZB-014": { - "Position": [447.93, -14.25, 67.26], - "Rotation": 285.467377 - }, - "ZB-016": { - "Position": [-388.16, 3.25, 20.05], - "Rotation": 115.467377 - }, - "Sawmill River": { - "Position": [-649.91, 8.61, -272.75], - "Rotation": 138.160156 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Mountain Stash": { - "Position": [-215.205872, 31.7007847, -209.631348], - "Rotation": 335.046753 - }, - "Sniper Rock Bunker": { - "Position": [-155.286, 50.95411, -277.7933], - "Rotation": 345.938324 - }, - "UN Roadblock": { - "Position": [-521.465332, -1.258715, 288.813171], - "Rotation": 76.4774246 - }, - "Scav Bridge": { - "Position": [98.54763, 16.67556, -843.773254], - "Rotation": -843.773254 - }, - "Woods Vehicle Extract": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "Old Station": { - "Position": [-504.468628, 7.252748, 151.354584], - "Rotation": 134.066681 - }, - "Scav Bunker": { - "Position": [224.07019, 20.14909, -708.5178], - "Rotation": 104.772415 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "Checkpoint Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [56.2388641, -6.94445145, 90.22048], - "Rotation": 287.982239 - }, - "Bunker Hermetic": { - "Position": [64.5668, -6.95917463, -190.306641], - "Rotation": 280.9828 - }, - "Depot Hermetic": { - "Position": [118.866768, -12.2845945, -119.324211], - "Rotation": 299.889923 - }, - "Heating Pipe": { - "Position": [-9.3644, -5.60308161, -186.8873], - "Rotation": 330.65134 - }, - "Hole In Wall": { - "Position": [-262.3644, -6.20308161, 47.7328873], - "Rotation": 89.65134 - }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 - }, - "Train Station": { - "Position": [166.653687, -5.19410563, -144.143341], - "Rotation": 191.8541 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "interchange": { - "Interchange Vehicle Extract": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Fence Gap": { - "Position": [-220.849625, 21.35, -40.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Emercom": { - "Position": [-328.429871, 21.3254356, 260.571655], - "Rotation": 73.0782242 - }, - "Scav Camp": { - "Position": [283.740051, 21.3254337, -34.4532776], - "Rotation": 138.160156 - }, - "FromCrossroads": { - "Position": [283.740051, 21.3254337, 265.4532776], - "Rotation": 100.086945 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Old Bunker": { - "Position": [-390.330939, -5.4056053, -374.74316], - "Rotation": 41.4962769 - }, - "Climbers Trail": { - "Position": [-198.30939, -11.2056053, -360.54316], - "Rotation": 56.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Shoreline Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Ruined Road": { - "Position": [350.51, -59.67, 324.86], - "Rotation": 55.0321 - }, - "Admin Basement": { - "Position": [-252.256073, -7.096292, -145.4518], - "Rotation": 359.0387 - }, - "CCP Temporary": { - "Position": [-967.462463, -59.678566, 375.060669], - "Rotation": 166.59436 - }, - "Shoreline Northern Cliffs": { - "Position": [-174.818451, -11.1724739, -364.436646], - "Rotation": 330.086456 - }, - "Railway Bridge": { - "Position": [-1023.37292, -60.67251, 314.364075], - "Rotation": 24.1157665 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - }, - "Smugglers Path": { - "Position": [-700.538428, -25.45863, -242.9271], - "Rotation": 335.1047 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Industrial Gates": { - "Position": [-155.70462, 14.1516333, -789.0004], - "Rotation": 347.57063 - }, - "Lighthouse Tunnel": { - "Position": [-54.28882, 5.95763159, 327.053345], - "Rotation": 106.236305 - }, - "Armored Train LH": { - "Position": [10.0, 11.97, -870.85], - "Rotation": 180.236305 - }, - "Northeast Mountains": { - "Position": [-362.13, 26.1, -535.54], - "Rotation": 85.936305 - }, - "Southern Road Water": { - "Position": [-225.77, 0.02, 442.06], - "Rotation": 120.936305 - }, - "Grotto": { - "Position": [194.516525, -0.48209092, -491.773224], - "Rotation": 182.743759 - }, - "Northern CP": { - "Position": [115.480957, 4.61967325, -980.5756], - "Rotation": 347.679443 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - }, - "Mountain Pass": { - "Position": [-147.143173, 30.5996075, -4.088336], - "Rotation": 74.17951 - }, - "Southern Road": { - "Position": [-215.268738, 5.94645643, 419.227417], - "Rotation": 77.76075 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "tarkovstreets": { - "Streets Vehicle Extract": { - "Position": [-8.757395, 2.31632733, 458.126923], - "Rotation": 177.1993 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Expo Checkpoint": { - "Position": [215, -1.93, -88.75], - "Rotation": 304.3322 - }, - "Cardinal Appartments Parking": { - "Position": [103.6, -1.9, -155.3], - "Rotation": 304.3322 - }, - "Cardinal Appartments": { - "Position": [82.8, 3.97, -175.4], - "Rotation": 304.3322 - }, - "Crash Site": { - "Position": [269.3, 3.4, 427.25], - "Rotation": 87.62667 - }, - "Kamchatskya Arch": { - "Position": [260.6, -4.5, 49.6], - "Rotation": 304.3322 - }, - "Sylobate Elevator": { - "Position": [-47.23, 9.6, -68.04], - "Rotation": 15.33 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "Comment": "N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", - "sandbox": { - "Nakatani Basement Stairs": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "Mira Ave": { - "Position": [215.1694, 16.01762, 40.5], - "Rotation": 0.7702 - }, - "Police Car": { - "Position": [-12.97, 22.6, 116.99], - "Rotation": 90.0 - }, - "Scav Hideout": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - }, - "EmercomGZ": { - "Position": [152.5, 24.1, -89.4], - "Rotation": 0.85 - } - } -} diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index c6a28fb0..5114bfe1 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -523,7 +523,7 @@ "Gate m": "FactoryZB-1012", "Cellars": "FactoryZB-1011", "Camera Bunker Door": "FactoryZB-1011", - "Office Window": "WoodsFactoryGate", + "Gate_o": "WoodsFactoryGate", "Gate 0": "WoodsFactoryGate" }, "factory4_night": { @@ -531,7 +531,7 @@ "Gate m": "FactoryZB-1012", "Cellars": "FactoryZB-1011", "Camera Bunker Door": "FactoryZB-1011", - "Office Window": "WoodsFactoryGate", + "Gate_o": "WoodsFactoryGate", "Gate 0": "WoodsFactoryGate" }, "bigmap": { @@ -619,11 +619,11 @@ "ShorelineLighthousePath": { "shoreline": ["Path to Lighthouse"], "lighthouse": ["Path to Shoreline"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "ShorelineLighthouseTunnel": { - "shoreline": ["Tunnel"], - "lighthouse": ["Lighthouse tunnel"] + "shoreline": ["Shoreline Tunnel"], + "lighthouse": ["Lighthouse Tunnel"] }, "ShorelineNorthMoutains": { "rezervbase": ["Cliff"], @@ -631,14 +631,14 @@ }, "WoodsReserveShoreline": { "woods": ["Outskirts"], - "rezervbase": ["CP Fence"] + "rezervbase": ["Checkpoint Fence"] }, "InterchangeCustoms": { "bigmap": ["Crossroads"], "interchange": ["Scav Camp"] }, "CustomsTarkovRail": { - "bigmap": ["MallTrain"], + "bigmap": ["RR to Tarkov"], "interchange": ["Railway"] }, "WoodsCustoms": { @@ -646,7 +646,7 @@ "bigmap": ["RUAF Roadblock"] }, "Boat": { - "bigmap": ["Smuggler's Boat"], + "bigmap": ["Smugglers Boat"], "woods": ["The Boat"], "shoreline": ["Pier Boat"], "lighthouse": ["Lighthouse Docks Boat"] @@ -657,11 +657,11 @@ }, "Car": { "bigmap": ["Dorms Car"], - "interchange": ["Car at Power Station"], - "woods": ["Bridge Car"], + "interchange": ["Interchange Vehicle Extract"], + "woods": ["Woods Vehicle Extract"], "lighthouse": ["Lighthouse Vehicle Extract"], - "tarkovstreets": ["Primorsky Vehicle Extract"], - "sandbox": ["hideout_gz"], + "tarkovstreets": ["Streets Vehicle Extract"], + "sandbox": ["Nakatani Basement Stairs"], "laboratory": [ "Cargo Elevator", "Lab Sewage Conduit", @@ -675,16 +675,16 @@ "rezervbase": ["Scav lands"] }, "PilgrimTrail": { - "bigmap": ["PraveenGasoline"], + "bigmap": ["Old Gas Scav"], "tarkovstreets": ["Crane"] }, "MilitaryBaseRail": { - "bigmap": ["Railroad To Military Base"], + "bigmap": ["RR to Military Base"], "rezervbase": ["Train Station"] }, "FactoryZB-1013": { "bigmap": ["ZB-1013"], - "woods": ["ZB-1014"], + "woods": ["ZB-014"], "factory4_day": ["Gate 3"], "factory4_night": ["Gate 3"] }, @@ -699,9 +699,9 @@ "factory4_night": ["Cellars"] }, "ScavWindow": { - "bigmap": ["OfficePath"], - "factory4_day": ["Office Window"], - "factory4_night": ["Office Window"] + "bigmap": ["Factory Far Corner"], + "factory4_day": ["Courtyard"], + "factory4_night": ["Courtyard"] }, "WoodsFactoryGate": { "woods": ["Factory Gate"], @@ -709,25 +709,25 @@ "factory4_night": ["Gate 0"] }, "WoodsMilitaryPath": { - "woods": ["RUAFRoadblock"], - "bigmap": ["RUAFAdmin"] + "woods": ["RUAF Gate"], + "bigmap": ["Administration Gate"] }, "SafeRoom": { "rezervbase": ["D-2"], "interchange": ["Safe Room"] }, "TherapistHideout": { - "sandbox": ["Crow Hideout"] + "sandbox": ["Scav Hideout"] }, "PlayerHideout": { - "sandbox": ["hideout_gz"] + "sandbox": ["Nakatani Basement Stairs"] }, "EmercomToKlimov": { - "sandbox": ["Crow Hideout"], + "sandbox": ["Scav Hideout"], "tarkovstreets": ["Basement Descent"] }, "SniperPath": { - "sandbox": ["From Streets"], + "sandbox": ["Mira Ave"], "tarkovstreets": ["Klimov Street"] }, "UnderpasstoLabs": { @@ -740,7 +740,7 @@ }, "StreetsEvac": { "tarkovstreets": ["Evacuation Zone"], - "interchange": ["EmercomMall"], + "interchange": ["Emercom"], "bigmap": ["Old Gas Scav"] }, "CatacombsHangar": { diff --git a/configs/PathToTarkovReloaded/player_spawnpoints.json b/configs/PathToTarkovReloaded/player_spawnpoints.json deleted file mode 100644 index ffb7eab4..00000000 --- a/configs/PathToTarkovReloaded/player_spawnpoints.json +++ /dev/null @@ -1,382 +0,0 @@ -{ - "factory4_day": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "factory4_night": { - "Gate 0": { - "Position": { - "x": -52.5704842, - "y": 1.25745475, - "z": 55.06734 - }, - "Rotation": 93.18849 - }, - "Gate 3": { - "Position": { - "x": 58.67002, - "y": 0.233123064, - "z": 57.4049568 - }, - "Rotation": 129.412323 - }, - "Med tent gates": { - "Position": { - "x": -18.9917545, - "y": 0.229607314, - "z": -46.5803642 - }, - "Rotation": 19.03057 - }, - "Cellars": { - "Position": { - "x": 66.78813, - "y": -2.63332653, - "z": -30.9360619 - }, - "Rotation": 231.811646 - }, - "Office Window": { - "Position": { - "x": 17.66614, - "y": 8.210876, - "z": 40.92688 - }, - "Rotation": 158.9888 - } - }, - "bigmap": { - "Military Base CP": { - "Position": [674.5625, 5.60742664, 123.641823], - "Rotation": 238.056732 - }, - "Railroad To Military Base": { - "Position": [489.120117, 1.40883172, 207.272552], - "Rotation": 228.254486 - }, - "ZB-1011": { - "Position": [629.4296, -2.77441788, -127.8221], - "Rotation": 97.17987 - }, - "ZB-1012": { - "Position": [464.075, -2.68441629, -112.424088], - "Rotation": 96.69592 - }, - "ZB-1013": { - "Position": [199.2377, -2.81965065, -145.043625], - "Rotation": 341.8522 - }, - "Crossroads": { - "Position": [-324.1054, -0.317715019, -91.3120041], - "Rotation": 31.98688 - }, - "RUAF Roadblock": { - "Position": [-3.56247973, 1.08614612, -132.9248], - "Rotation": 54.44671 - }, - "Smuggler's Boat": { - "Position": [-28.292078, -11.5068331, 109.108429], - "Rotation": 187.815948 - }, - "Sniper Roadblock": { - "Position": [30.446312, -0.259777457, 118.656456], - "Rotation": 327.517334 - }, - "Dorms Car": { - "Position": [191.627884, -2.16589069, 208.912079], - "Rotation": 278.774384 - }, - "Old Gas Scav": { - "Position": [302.545, 2.91025, -185.017761], - "Rotation": 202.349335 - }, - "MallTrain": { - "Position": [-154.6799, 2.266766, -221.5874], - "Rotation": 327.8281 - }, - "PraveenGasoline": { - "Position": [354.8507, 1.106263, -191.5768], - "Rotation": 23.4955 - }, - "OfficePath": { - "Position": [655.933, 1.098399, -166.3037], - "rotation": 302.8839 - }, - "RUAFAdmin": { - "Position": [667.3405, 1.064447, -58.31626], - "rotation": 287.2482 - } - }, - "woods": { - "UN Roadblock": { - "Comment": "UN Roadblock", - "Position": [-543.3435, 9.776281, -78.09744], - "Rotation": 228.816986 - }, - "Factory Gate": { - "Position": [-346.51947, -2.32620764, 353.3336], - "Rotation": 174.779083 - }, - "ZB-1014": { - "Position": [447.4841, -14.2453938, 69.34354], - "Rotation": 285.467377 - }, - "Outskirts": { - "Position": [334.693359, -11.418191, 327.578033], - "Rotation": 160.7393 - }, - "The Boat": { - "Position": [190.682846, -14.9319124, 219.147934], - "Rotation": 227.765961 - }, - "Bridge Car": { - "Position": [-487.348541, 15.0604687, -497.965179], - "Rotation": 24.781599 - }, - "RUAFRoadblock": { - "Position": [-129.7272, -1.194496, 415.476], - "Rotation": 146.2519 - } - }, - "rezervbase": { - "Scav lands": { - "Position": [-120.954071, -6.94097, -129.4829], - "Rotation": 260.069275 - }, - "Scav lands rail": { - "Position": [-196.7502, -5.37225676, -114.267555], - "Rotation": 93.10983 - }, - "Cliff": { - "Position": [-15.9683733, 18.4609661, 195.898743], - "Rotation": 190.4635 - }, - "CP Fence": { - "Comment": "RezervBase_cp_fence (exit4)", - "Position": [53.0388641, -6.82445145, 133.46048], - "Rotation": 263.982239 - }, - "D-2": { - "Position": [-116.999077, -18.3659115, 169.5836], - "Rotation": 128.773651 - }, - "Reserve Manhole": { - "Position": [50.6118279, -6.97395849, 73.78378], - "Rotation": 213.616745 - }, - "Depot Hermetic": { - "Position": [118.866768, -12.2845945, -119.324211], - "Rotation": 299.889923 - }, - "Hole In Wall": { - "Position": [-262.3644, -6.20308161, 47.7328873], - "Rotation": 89.65134 - }, - "Train Station": { - "Position": [166.653687, -5.19410563, -144.143341], - "Rotation": 191.8541 - } - }, - "interchange": { - "Car at Power Station": { - "Position": [-242.849625, 21.32544, -372.680878], - "Rotation": 52.06011 - }, - "Fence Gap": { - "Position": [-220.849625, 21.35, -40.680878], - "Rotation": 52.06011 - }, - "Railway": { - "Position": [473.177979, 18.4533634, -390.7554], - "Rotation": 281.3094 - }, - "Safe Room": { - "Position": [-49.4776039, 21.3254585, 47.4479179], - "Rotation": 344.7888 - }, - "EmercomMall": { - "Position": [-313.2805, 21.32544, 254.3763], - "Rotation": 105.2137 - }, - "Scav Camp": { - "Position": [283.740051, 21.3254337, -34.4532776], - "Rotation": 138.160156 - }, - "FromCrossroads": { - "Position": [283.740051, 21.3254337, 265.4532776], - "Rotation": 100.086945 - } - }, - "shoreline": { - "North Fence Passage": { - "Position": [-510.430939, -11.9056053, -373.174316], - "Rotation": 41.4962769 - }, - "Road to Customs": { - "Position": [-864.0486, -43.44637, 16.5865173], - "Rotation": 18.213295 - }, - "Pier Boat": { - "Position": [-311.829468, -64.56999, 559.7176], - "Rotation": 210.594009 - }, - "Tunnel": { - "Position": [356.304871, -59.9092941, 313.181915], - "Rotation": 274.0321 - }, - "Path to Lighthouse": { - "Position": [362.138428, -54.85863, -181.549271], - "Rotation": 335.1047 - } - }, - "lighthouse": { - "Path to Shoreline": { - "Position": [-284.0998, 14.4007835, -161.669266], - "Rotation": 126.306564 - }, - "Lighthouse Vehicle Extract": { - "Position": [-316.70462, 15.1516333, -784.0004], - "Rotation": 37.57063 - }, - "Lighthouse tunnel": { - "Position": [-65.93657, 5.95763254, 328.924927], - "Rotation": 101.297722 - }, - "Lighthouse Docks Boat": { - "Position": [164.16626, 0.317433029, -163.23497], - "Rotation": 285.558533 - } - }, - "tarkovstreets": { - "Primorsky Vehicle Extract": { - "Position": [-5.0, 3.8, 459.9], - "Rotation": 0.0 - }, - "Basement Descent": { - "Position": [73.63199, -2.13371778, 56.0767555], - "Rotation": 326.0107 - }, - "Catacombs": { - "Position": [-243.837051, 0.6605578, 243.027969], - "Rotation": 124.062996 - }, - "Evacuation Zone": { - "Position": [161.997284, 3.35329342, 419.626373], - "Rotation": 241.142944 - }, - "Klimov Street": { - "Position": [-152.4702, 0.8981548, 76.18395], - "Rotation": 10.636034 - }, - "Sewer River": { - "Position": [-263.4596, -2.58167219, 216.658859], - "Rotation": 151.635468 - }, - "Streets Manhole": { - "Position": [279.991425, 3.43549061, 349.09433], - "Rotation": 268.153534 - }, - "Streets Ruined House": { - "Position": [-244.822723, 6.355562, 344.1349], - "Rotation": 87.62667 - }, - "Streets Vents": { - "Position": [-123.828979, 2.30664325, 432.900574], - "Rotation": 244.029388 - }, - "Underpass": { - "Position": [-2.86661983, -3.73687434, 6.0282855], - "Rotation": 2.20911074 - }, - "Zmeevsky Alley": { - "Position": [176.868683, 0.7778812, 172.814636], - "Rotation": 304.3322 - }, - "Crane": { - "Position": [212.0187, 3.098404, 252.7016], - "Rotation": 270.9422 - } - }, - "laboratory": { - "Cargo Elevator": { - "Position": [-114.2475, 4.101831, -408.6356], - "Rotation": 270.727661 - }, - "Hangar Gate": { - "Position": [-170.346313, 0.07315855, -249.111542], - "Rotation": 208.741516 - }, - "Lab Sewage Conduit": { - "Position": [-123.794968, -4.985455, -260.754242], - "Rotation": 185.730515 - }, - "Lab Vents": { - "Position": [-142.8083, -4.053963, -400.147034], - "Rotation": 38.8127365 - }, - "Main Elevator": { - "Position": [-279.4339, -4.050967, -334.7585], - "Rotation": 73.58874 - }, - "Med Block Elevator": { - "Position": [-114.566971, -4.05397, -343.565735], - "Rotation": 275.983582 - }, - "Parking Gate": { - "Position": [-231.813736, 0.0220247321, -426.099579], - "Rotation": 14.0038671 - } - }, - "sandbox": { - "hideout_gz": { - "Position": [5.295958, 22.73891, 331.8584], - "Rotation": 132.0392 - }, - "From Streets": { - "Position": [233.1694, 16.01762, 56.08633], - "Rotation": 251.7702 - }, - "Crow Hideout": { - "Position": [31.74341, 22.59711, -85.79424], - "Rotation": 43.04764 - } - } -} diff --git a/configs/Default/player_spawnpoints.json b/configs/shared_player_spawnpoints.json similarity index 95% rename from configs/Default/player_spawnpoints.json rename to configs/shared_player_spawnpoints.json index 58929e56..f65df913 100644 --- a/configs/Default/player_spawnpoints.json +++ b/configs/shared_player_spawnpoints.json @@ -1,5 +1,6 @@ { - "Comment": "Example rotation values -> N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", + "Comment": "The player spawnpoints marked in this file are shared between all configs", + "Comment about Rotation": "Example rotation values -> N: 180, NE: 225, E: 270, SE: 315, S: 0, SW: 45, W: 90, NW: 135", "factory4_day": { "Gate 3": { "Position": [57.89, 0.3, 49.57], @@ -140,6 +141,10 @@ "Scav CP": { "Position": [647.141, -0.3182248, -25.9616776], "Rotation": 307.1494 + }, + "Administration Gate": { + "Position": [667.3405, 1.064447, -58.31626], + "rotation": 287.2482 } }, "woods": { @@ -218,7 +223,7 @@ "Rotation": 190.4635 }, "Checkpoint Fence": { - "Comment": "RezervBase_cp_fence (exit4)", + "Description": "RezervBase_cp_fence (exit4)", "Position": [56.2388641, -6.94445145, 90.22048], "Rotation": 287.982239 }, @@ -430,6 +435,14 @@ "Position": [176.868683, 0.7778812, 172.814636], "Rotation": 304.3322 }, + "Crane": { + "Position": [212.0187, 3.098404, 252.7016], + "Rotation": 270.9422 + }, + "Near Kamchatskaya Arch": { + "Position": [260.6, -4.5, 49.6], + "Rotation": 304.3322 + }, "Expo Checkpoint": { "Position": [215, -1.93, -88.75], "Rotation": 304.3322 diff --git a/src/config-analysis.ts b/src/config-analysis.ts index fac9d68f..aa6a528c 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -207,6 +207,23 @@ const getErrorsForInfils = (config: Config, spawnConfig: SpawnConfig): string[] return errors; }; +const getErrorsForAdditionalSpawnpoints = (config: Config): string[] => { + const errors: string[] = []; + + const additionalSpawnConfig = config.infiltrations_config?.additional_player_spawnpoints ?? {}; + + Object.keys(additionalSpawnConfig).forEach(mapName => { + if (!ALLOWED_MAPS.includes(mapName)) { + errors.push( + `${mapName} is now allowed as a map name in "infiltrations_config.additional_player_spawnpoints"`, + ); + return; + } + }); + + return errors; +}; + export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigValidationResult => { const errors: string[] = []; const warnings: string[] = []; @@ -238,6 +255,9 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 7. check for infiltrations maps and spawn points errors.push(...getErrorsForInfils(config, spawnConfig)); + // 8. check for additional spawnpoints + errors.push(...getErrorsForAdditionalSpawnpoints(config)); + return { errors, warnings, diff --git a/src/config.ts b/src/config.ts index a201f82e..9993cba3 100644 --- a/src/config.ts +++ b/src/config.ts @@ -32,7 +32,7 @@ export type PositionXYZ = { export type SpawnPointGenericPosition = [number, number, number] | PositionXYZ; /** - * player_spawnpoints.json + * shared_player_spawnpoints.json */ export type SpawnPoint = { Position: SpawnPointGenericPosition; @@ -75,6 +75,10 @@ type AllLocales = { kr?: T; pl?: T; po?: T; + ro?: T; + ru?: T; + sk?: T; + tu?: T; }; export type LocaleName = keyof AllLocales; @@ -138,6 +142,10 @@ export type OverrideByProfiles = ByProfileId<{ hideout_main_stash_access_via?: AccessVia; }>; +export type InfiltrationsConfig = { + additional_player_spawnpoints?: Partial; +}; + type RawConfig = { enabled: boolean; debug?: boolean; @@ -161,12 +169,14 @@ type RawConfig = { hideout_secondary_stashes: RawStashConfig[]; traders_access_restriction: boolean; traders_config: TradersConfig; + infiltrations_config?: InfiltrationsConfig; exfiltrations: Exfiltrations; infiltrations: Infiltrations; }; -export type Config = Omit & { +export type Config = Omit & { hideout_secondary_stashes: StashConfig[]; + infiltrations_config: InfiltrationsConfig; }; export type PathToTarkovReloadedTooltipsConfig = { @@ -197,7 +207,7 @@ export const CONFIGS_DIR = join(__dirname, '../configs'); export const USER_CONFIG_PATH = join(CONFIGS_DIR, 'UserConfig.json'); export const CONFIG_FILENAME = 'config.json'; -export const SPAWN_CONFIG_FILENAME = 'player_spawnpoints.json'; +export const SPAWN_CONFIG_FILENAME = 'shared_player_spawnpoints.json'; export const PRAPOR_ID = '54cb50c76803fa8b248b4571'; export const FENCE_ID = '579dc571d53a0658a154fbec'; @@ -255,7 +265,7 @@ export const MAPLIST = [ ]; // sandbox_high is a special map for high level players (> 20) -const prepareGroundZeroHigh = (maps: ByMap): ByMap => { +const prepareGroundZeroHighPartial = (maps: Partial>): Partial> => { if (maps.sandbox && !maps.sandbox_high) { return { ...maps, @@ -266,6 +276,10 @@ const prepareGroundZeroHigh = (maps: ByMap): ByMap => { return maps; }; +const prepareGroundZeroHigh = (maps: ByMap): ByMap => { + return prepareGroundZeroHighPartial(maps) as ByMap; +}; + export const processConfig = (originalConfig: RawConfig): Config => { const config = deepClone(originalConfig); @@ -278,15 +292,48 @@ export const processConfig = (originalConfig: RawConfig): Config => { }); const stashConfigs: StashConfig[] = config.hideout_secondary_stashes.map(toStashConfig); + const infiltrationsConfig = config.infiltrations_config ?? {}; return { ...config, hideout_secondary_stashes: stashConfigs, + infiltrations_config: infiltrationsConfig, }; }; -export const processSpawnConfig = (spawnConfig: SpawnConfig): SpawnConfig => { - return prepareGroundZeroHigh(spawnConfig); +const mergeAdditionalSpawnpoints = ( + spawnConfig: SpawnConfig, + additionalSpawnConfig: Partial, +): SpawnConfig => { + const clonedSpawnConfig = deepClone(spawnConfig); + + Object.keys(additionalSpawnConfig).forEach(mapName => { + const infilConfig = additionalSpawnConfig[mapName as MapName]; + const spawnPoints = clonedSpawnConfig[mapName as MapName]; + + if (!infilConfig || !spawnPoints) { + return; + } + + Object.keys(infilConfig).forEach(spawnPointName => { + const spawnPoint = infilConfig[spawnPointName]; + const spawnPoints = clonedSpawnConfig[mapName as MapName]; + + if (spawnPoint) { + spawnPoints[spawnPointName] = spawnPoint; + } + }); + }); + + return clonedSpawnConfig; +}; + +export const processSpawnConfig = (spawnConfig: SpawnConfig, config: Config): SpawnConfig => { + const additionalPlayerSpawnpoints = + config.infiltrations_config?.additional_player_spawnpoints ?? {}; + + const mergedConfig = mergeAdditionalSpawnpoints(spawnConfig, additionalPlayerSpawnpoints); + return prepareGroundZeroHigh(mergedConfig); }; export const getUserConfig = (): UserConfig => { diff --git a/src/mod.ts b/src/mod.ts index b4df54f5..742911c8 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -63,7 +63,8 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { readJsonFile(path.join(CONFIGS_DIR, userConfig.selectedConfig, CONFIG_FILENAME)), ); this.spawnConfig = processSpawnConfig( - readJsonFile(path.join(CONFIGS_DIR, userConfig.selectedConfig, SPAWN_CONFIG_FILENAME)), + readJsonFile(path.join(CONFIGS_DIR, SPAWN_CONFIG_FILENAME)), + this.config, ); this.tooltipsConfig = getTooltipsConfig(userConfig); diff --git a/tests/configs.test.ts b/tests/configs.test.ts index 18bd1c8d..a68d712d 100644 --- a/tests/configs.test.ts +++ b/tests/configs.test.ts @@ -8,8 +8,8 @@ const loadConfig = (dirPath: string): Config => { return processConfig(readJsonFile(path.join(dirPath, 'config.json'))); }; -const loadSpawnConfig = (dirPath: string): SpawnConfig => { - return processSpawnConfig(readJsonFile(path.join(dirPath, 'player_spawnpoints.json'))); +const loadSpawnConfig = (config: Config): SpawnConfig => { + return processSpawnConfig(readJsonFile('./configs/shared_player_spawnpoints.json'), config); }; describe('PTT embedded configs', () => { @@ -25,7 +25,7 @@ describe('PTT embedded configs', () => { const testConfig = (dirPath: string) => { const config = loadConfig(dirPath); - const spawnConfig = loadSpawnConfig(dirPath); + const spawnConfig = loadSpawnConfig(config); const { errors, warnings } = analyzeConfig(config, spawnConfig); From e1a743dfee9c688de271e138b7dd509e7673bae1 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 7 Dec 2024 23:42:04 +0100 Subject: [PATCH 061/203] chore: save script extract-legacy-tooltips --- scripts/extract-legacy-tooltips.js | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 scripts/extract-legacy-tooltips.js diff --git a/scripts/extract-legacy-tooltips.js b/scripts/extract-legacy-tooltips.js new file mode 100644 index 00000000..e8fc1f84 --- /dev/null +++ b/scripts/extract-legacy-tooltips.js @@ -0,0 +1,92 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const Tooltips = require('../configs/Default/Tooltips.json'); + +const localesToChange = Tooltips.localesToChange ?? []; +const additionalLocales = + (Tooltips.additionalLocalesToggle ? Tooltips.localesToChangeAdditional : []) ?? []; +const moddedLocales = (Tooltips.moddedTraderCompat ? Tooltips.moddedTraderExtracts : []) ?? []; +const allLocales = [...localesToChange, ...additionalLocales, ...moddedLocales]; + +const localeMappings = { + english: 'en', + en: 'en', + chinese: 'ch', + ch: 'ch', + czech: 'cz', + cz: 'cz', + french: 'fr', + fr: 'fr', + german: 'ge', + ge: 'ge', + hungarian: 'hu', + hu: 'hu', + italian: 'it', + it: 'it', + japanese: 'jp', + jp: 'jp', + korean: 'kr', + kr: 'kr', + polish: 'pl', + pl: 'pl', + portuguese: 'po', + po: 'po', + slovakian: 'sk', + sk: 'sk', + spanish: 'es', + es: 'es', + turkish: 'tu', + tu: 'tu', + russian: 'ru', + ru: 'ru', + romanian: 'ro', + ro: 'ro', +}; + +const getLang = rawLang => { + return localeMappings[rawLang] ?? rawLang ?? 'en'; +}; + +const createExfilConfig = (rawLang, localeValue) => { + const lang = getLang(rawLang); + + return { + displayName: { + // ch: localeValue, + // cz: localeValue, + // en: localeValue, + // 'es-mx': localeValue, + // es: localeValue, + // fr: localeValue, + // ge: localeValue, + // hu: localeValue, + // it: localeValue, + // jp: localeValue, + // kr: localeValue, + // pl: localeValue, + // po: localeValue, + // ro: localeValue, + // ru: localeValue, + // sk: localeValue, + // tu: localeValue, + [lang]: localeValue, + }, + }; +}; + +const isOdd = n => Boolean(n % 2); +const isEven = n => !isOdd(n); + +const extractExfiltrationsConfigFromLocales = locales => { + const exfiltrationsConfig = {}; + locales.forEach((localeKey, i) => { + if (isEven(i)) { + const localeValue = locales[i + 1]; + exfiltrationsConfig[localeKey] = createExfilConfig(Tooltips.language, localeValue); + } + }); + return exfiltrationsConfig; +}; + +const exfiltrations_config = extractExfiltrationsConfigFromLocales(allLocales); + +console.log(JSON.stringify(exfiltrations_config, undefined, 2)); From c1d728890c20efe771f61db33ce25732286e3eb1 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 8 Dec 2024 16:45:27 +0100 Subject: [PATCH 062/203] fix(config): typo in Stylobate --- .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 2 +- configs/Default/Tooltips.json | 4 ++-- configs/Default/config.json | 12 ++++++------ configs/DevilFlippy/config.json | 2 +- .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 2 +- configs/OriginalNarcoticsConfig/Tooltips.json | 4 ++-- configs/OriginalNarcoticsConfig/config.json | 12 ++++++------ configs/shared_player_spawnpoints.json | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc index afad85d9..b8c48250 100644 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc +++ b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc @@ -64,7 +64,7 @@ "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, }, { - "Text": "Main Elevator (Streets, Sylobate Elevator)", + "Text": "Main Elevator (Streets, Stylobate Elevator)", "ImagePath": "Markers/exit.png", "Position": { "x": -282.304016, "y": -334.896, "z": -3.631999 }, "Category": "Extract", diff --git a/configs/Default/Tooltips.json b/configs/Default/Tooltips.json index c002a68a..297a35c0 100644 --- a/configs/Default/Tooltips.json +++ b/configs/Default/Tooltips.json @@ -147,7 +147,7 @@ "Power Station SUV (Streets/Woods/GZ)", "E1", - "Sylobate Elevator (Labs, Main Elevator)", + "Stylobate Elevator (Labs, Main Elevator)", "E2", "Sewer River (Labs, Sewage Conduit)", "E4", @@ -202,7 +202,7 @@ "lab_Elevator_Cargo", "Cargo Elevator (Streets/Ground Zero)", "lab_Elevator_Main", - "Main Elevator (Streets, Sylobate Elevator)", + "Main Elevator (Streets, Syylobate Elevator)", "lab_Hangar_Gate", "Hangar Gate (Streets, Catacombs)", "lab_Under_Storage_Collector", diff --git a/configs/Default/config.json b/configs/Default/config.json index 7f628691..3e350c8e 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -214,9 +214,9 @@ "access_via": ["SewerRiver"] }, { - "id": "PathToTarkov_SylobateElevator_stash", + "id": "PathToTarkov_StylobateElevator_stash", "size": 4, - "access_via": ["SylobateElevator"] + "access_via": ["StylobateElevator"] }, { "id": "PathToTarkov_Catacombs_stash", @@ -819,7 +819,7 @@ "tunnel_shared": "SideTunnel" }, "tarkovstreets": { - "E1": "SylobateElevator", + "E1": "StylobateElevator", "scav_e3": "VentShaft", "E3": "RuinedHouse", "E4": "CrashSite", @@ -835,7 +835,7 @@ "lab_Hangar_Gate": "Catacombs", "lab_Parking_Gate": "BasementDescent", "lab_Under_Storage_Collector": "SewerRiver", - "lab_Elevator_Main": "SylobateElevator", + "lab_Elevator_Main": "StylobateElevator", "lab_Elevator_Cargo": "BasementDescent", "lab_Elevator_Med": "BasementDescent", "lab_Vent": "VentShaft" @@ -1135,8 +1135,8 @@ "tarkovstreets": ["Sewer River"], "laboratory": ["Lab Sewage Conduit"] }, - "SylobateElevator": { - "tarkovstreets": ["Sylobate Elevator"], + "StylobateElevator": { + "tarkovstreets": ["Stylobate Elevator"], "laboratory": ["Main Elevator"] }, "CrashSite": { diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index 3b09215e..a5a5f586 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -710,7 +710,7 @@ "interchange": ["Railway"] }, "ScorpionHideout": { - "tarkovstreets": ["Sylobate Elevator"], + "tarkovstreets": ["Stylobate Elevator"], "laboratory": ["Main Elevator"] }, "DormsCar": { diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc index afad85d9..b8c48250 100644 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc +++ b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc @@ -64,7 +64,7 @@ "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, }, { - "Text": "Main Elevator (Streets, Sylobate Elevator)", + "Text": "Main Elevator (Streets, Stylobate Elevator)", "ImagePath": "Markers/exit.png", "Position": { "x": -282.304016, "y": -334.896, "z": -3.631999 }, "Category": "Extract", diff --git a/configs/OriginalNarcoticsConfig/Tooltips.json b/configs/OriginalNarcoticsConfig/Tooltips.json index c002a68a..b0d54168 100644 --- a/configs/OriginalNarcoticsConfig/Tooltips.json +++ b/configs/OriginalNarcoticsConfig/Tooltips.json @@ -147,7 +147,7 @@ "Power Station SUV (Streets/Woods/GZ)", "E1", - "Sylobate Elevator (Labs, Main Elevator)", + "Stylobate Elevator (Labs, Main Elevator)", "E2", "Sewer River (Labs, Sewage Conduit)", "E4", @@ -202,7 +202,7 @@ "lab_Elevator_Cargo", "Cargo Elevator (Streets/Ground Zero)", "lab_Elevator_Main", - "Main Elevator (Streets, Sylobate Elevator)", + "Main Elevator (Streets, Stylobate Elevator)", "lab_Hangar_Gate", "Hangar Gate (Streets, Catacombs)", "lab_Under_Storage_Collector", diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index 4155a9c1..dd905382 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -214,9 +214,9 @@ "access_via": ["SewerRiver"] }, { - "id": "PathToTarkov_SylobateElevator_stash", + "id": "PathToTarkov_StylobateElevator_stash", "size": 4, - "access_via": ["SylobateElevator"] + "access_via": ["StylobateElevator"] }, { "id": "PathToTarkov_Catacombs_stash", @@ -771,7 +771,7 @@ "tunnel_shared": "SideTunnel" }, "tarkovstreets": { - "E1": "SylobateElevator", + "E1": "StylobateElevator", "scav_e3": "VentShaft", "E3": "RuinedHouse", "E4": "CrashSite", @@ -786,7 +786,7 @@ "laboratory": { "lab_Hangar_Gate": "Catacombs", "lab_Under_Storage_Collector": "SewerRiver", - "lab_Elevator_Main": "SylobateElevator", + "lab_Elevator_Main": "StylobateElevator", "lab_Elevator_Cargo": "BasementDescent", "lab_Vent": "VentShaft" }, @@ -1085,8 +1085,8 @@ "tarkovstreets": ["Sewer River"], "laboratory": ["Lab Sewage Conduit"] }, - "SylobateElevator": { - "tarkovstreets": ["Sylobate Elevator"], + "StylobateElevator": { + "tarkovstreets": ["Stylobate Elevator"], "laboratory": ["Main Elevator"] }, "CrashSite": { diff --git a/configs/shared_player_spawnpoints.json b/configs/shared_player_spawnpoints.json index f65df913..2e323d94 100644 --- a/configs/shared_player_spawnpoints.json +++ b/configs/shared_player_spawnpoints.json @@ -463,7 +463,7 @@ "Position": [260.6, -4.5, 49.6], "Rotation": 304.3322 }, - "Sylobate Elevator": { + "Stylobate Elevator": { "Position": [-47.23, 9.6, -68.04], "Rotation": 15.33 } From 65dede02cf60138a68102989b1b2c8d86d083ea5 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 8 Dec 2024 17:29:24 +0100 Subject: [PATCH 063/203] chore: add respawn_at field to the default config --- configs/Default/config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/Default/config.json b/configs/Default/config.json index 3e350c8e..7d42777d 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -2,6 +2,7 @@ "enabled": true, "debug": true, "initial_offraid_position": "FactoryZB-1011", + "respawn_at": ["FactoryZB-1011"], "reset_offraid_position_on_player_die": true, "traders_access_restriction": true, "hideout_multistash_enabled": true, From 59b9017c26c69e0f976fd509b449331a62a1b5f6 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 8 Dec 2024 17:47:00 +0100 Subject: [PATCH 064/203] fix(analyze): add config warning when conflicting access_via are found in secondary stashes --- configs/Default/config.json | 1 - configs/DevilFlippy/config.json | 5 ----- configs/PathToTarkovReloaded/config.json | 5 ----- src/config-analysis.ts | 20 +++++++++++++++++++- tests/configs.test.ts | 4 ++-- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 7d42777d..0902007c 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -10,7 +10,6 @@ "workbench_always_enabled": true, "disable_all_transits": false, "bypass_keep_found_in_raid_tweak": false, - "bypass_uninstall_procedure": false, "restrictions_in_raid": { "5449016a4bdc2d6f028b456f": { "// type = roubles": true, diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index a5a5f586..5b1b8364 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -114,11 +114,6 @@ "size": 38, "access_via": ["RefHideout"] }, - { - "id": "WelcomeToTarkov_PainterHideout_stash", - "size": 38, - "access_via": ["PainterHideout"] - }, { "id": "WelcomeToTarkov_Boat_stash", "size": 16, diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index 5114bfe1..f5b047c3 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -165,11 +165,6 @@ "size": 20, "access_via": ["SniperPath"] }, - { - "id": "PathToTarkov_EmercomStreet_stash", - "size": 8, - "access_via": ["EmercomToKlimov"] - }, { "id": "PathToTarkov_sewer_stash", "size": 8, diff --git a/src/config-analysis.ts b/src/config-analysis.ts index aa6a528c..73d69f24 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -171,6 +171,23 @@ const getErrorsSecondaryStashes = (config: Config): string[] => { return errors; }; +const getWarningsSecondaryStahes = (config: Config): string[] => { + const warnings: string[] = []; + const offraidPositions = new Set(); + + config.hideout_secondary_stashes.forEach(stashConfig => { + ensureArray(stashConfig.access_via).forEach(offraidPosition => { + if (offraidPositions.has(offraidPosition)) { + warnings.push(`offraid position is already used by stash "${stashConfig.name}"`); + } else { + offraidPositions.add(offraidPosition); + } + }); + }); + + return warnings; +}; + const getErrorsForInfils = (config: Config, spawnConfig: SpawnConfig): string[] => { const errors: string[] = []; @@ -249,8 +266,9 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 5. checks for exfil maps errors.push(...getErrorsForExfils(config)); - // 6. check for secondary stashes errors + // 6. check for secondary stashes errors.push(...getErrorsSecondaryStashes(config)); + warnings.push(...getWarningsSecondaryStahes(config)); // 7. check for infiltrations maps and spawn points errors.push(...getErrorsForInfils(config, spawnConfig)); diff --git a/tests/configs.test.ts b/tests/configs.test.ts index a68d712d..e21ca33e 100644 --- a/tests/configs.test.ts +++ b/tests/configs.test.ts @@ -13,14 +13,14 @@ const loadSpawnConfig = (config: Config): SpawnConfig => { }; describe('PTT embedded configs', () => { - const jestConsole = console; + const originalConsole = console; beforeEach(() => { global.console = require('console'); }); afterEach(() => { - global.console = jestConsole; + global.console = originalConsole; }); const testConfig = (dirPath: string) => { From 17e44fb5b565d80daee67d7801be8591451d6edc Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 8 Dec 2024 19:48:02 +0100 Subject: [PATCH 065/203] refactor: NarcoticsConfig duplicated offraid positions --- configs/Default/config.json | 194 +++++-------------- configs/OriginalNarcoticsConfig/config.json | 196 +++++--------------- src/config-analysis.ts | 32 ++++ src/config.ts | 2 +- 4 files changed, 130 insertions(+), 294 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 0902007c..fc1c98ca 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -76,12 +76,12 @@ { "id": "PathToTarkov_Ref_stash", "size": 48, - "access_via": ["PortRR", "RailwayBridge"] + "access_via": ["RefHideout"] }, { "id": "PathToTarkov_Lotus_stash", "size": 48, - "access_via": ["Crossroads", "Emercom"] + "access_via": ["Crossroads"] }, { "id": "PathToTarkov_Artem_stash", @@ -121,52 +121,37 @@ { "id": "PathToTarkov_CustomsNorth_stash", "size": 32, - "access_via": [ - "FactoryCorner", - "RUAFWoods", - "GasGate", - "RUAFCustoms", - "UNRoadblock", - "NorthUNRoadblock" - ] + "access_via": ["RUAFWoods", "GasGate", "RUAFCustoms", "UNRoadblock", "NorthUNRoadblock"] }, { "id": "PathToTarkov_CustomsSouth_stash", "size": 32, - "access_via": [ - "MilBaseCP", - "ScavLands", - "MilBaseRR", - "HoleinWall", - "SniperRB", - "SmugglersPath", - "RoadtoCustoms" - ] + "access_via": ["MilBaseCP", "MilBaseRR", "HoleinWall", "SniperRB", "RoadtoCustoms"] }, { "id": "PathToTarkov_CustomsEast_stash", "size": 48, - "access_via": ["TarkovRR", "CrashSite", "Railway", "ScavCamp", "TrailerPark"] + "access_via": ["TarkovRR", "CrashSite", "Railway", "InterchangeScavCamp"] }, { "id": "PathToTarkov_CustomsWest_stash", "size": 32, - "access_via": ["ScavCP", "Outskirts", "NorthernCP"] + "access_via": ["Outskirts"] }, { "id": "PathToTarkov_ShoreLightPath_stash", "size": 16, - "access_via": ["LighthousePath", "ShorelinePath", "MountainPass"] + "access_via": ["LighthouseShorelinePath", "MountainPass"] }, { "id": "PathToTarkov_ShorelineWest_stash", "size": 16, - "access_via": ["Tunnel", "SideTunnel", "RuinedRoad", "SouthernRoad"] + "access_via": ["LighthouseShorelineTunnel", "ShorelineLighthouseRoad"] }, { "id": "PathToTarkov_ShorelineNorth_stash", "size": 16, - "access_via": ["ClimbersTrail", "CliffDescent"] + "access_via": ["CliffDescent"] }, { "id": "PathToTarkov_GZStreets_stash", @@ -176,12 +161,12 @@ { "id": "PathToTarkov_NorthCar_stash", "size": 4, - "access_via": ["WoodsCar", "InterchangeCar", "StreetsCar", "GZCar"] + "access_via": ["CityCar"] }, { "id": "PathToTarkov_SouthCar_stash", "size": 4, - "access_via": ["DormsCar", "ShorelineCar"] + "access_via": ["ShorelineDormsCar"] }, { "id": "PathToTarkov_MilCar_stash", @@ -201,7 +186,7 @@ { "id": "PathToTarkov_ArmoredTrain_stash", "size": 16, - "access_via": ["ReserveTrain", "LighthouseTrain"] + "access_via": ["ArmoredTrain"] }, { "id": "PathToTarkov_VentShaft_stash", @@ -384,7 +369,7 @@ "sk": "Somewhere between Interchange and Customs", "tu": "Somewhere between Interchange and Customs" }, - "access_via": ["TrailerPark", "ScavCamp"] + "access_via": ["InterchangeScavCamp"] }, "5c0647fdd443bc2504c2d371": { "// Trader name": "Jaeger", @@ -477,7 +462,7 @@ "sk": "Along the railroad line between shoreline and customs", "tu": "Along the railroad line between shoreline and customs" }, - "access_via": ["RailwayBridge", "PortRR"] + "access_via": ["RefHideout"] }, "6748adca5c70634464b214a8": { "// mod integration for Priscilu": true, @@ -652,7 +637,7 @@ "sk": "at Emercom Checkpoint between Interchange and Customs", "tu": "at Emercom Checkpoint between Interchange and Customs" }, - "access_via": ["Emercom", "Crossroads"] + "access_via": ["Crossroads"] }, "Coyote": { "// mod integration for Coyote": true, @@ -748,11 +733,11 @@ "Gate_o": "GasGate" }, "bigmap": { - "Military Checkpoint": "ScavCP", + "Military Checkpoint": "Outskirts", "EXFIL_ZB013": "FactoryZB-013", "ZB-1012": "FactoryZB-1012", "ZB-1011": "FactoryZB-1011", - "Dorms V-Ex": "DormsCar", + "Dorms V-Ex": "ShorelineDormsCar", "Sniper Roadblock": "SniperRB", "Smuggler's Boat": "SmugglersBoat", "RUAF Roadblock": "RUAFCustoms", @@ -761,10 +746,10 @@ "Railroad To Tarkov": "TarkovRR", "Shack": "MilBaseCP", "Warehouse 17": "SkierHideout", - "Trailer Park": "TrailerPark", + "Trailer Park": "InterchangeScavCamp", "Railroad To Military Base": "MilBaseRR", - "Railroad To Port": "PortRR", - "Factory Far Corner": "FactoryCorner", + "Railroad To Port": "RefHideout", + "Factory Far Corner": "RUAFWoods", "Trailer Park Workers Shack": "LegsHideout" }, "woods": { @@ -775,13 +760,13 @@ "ZB-014": "ReserveZB-014", "Outskirts": "Outskirts", "UN Roadblock": "UNRoadblock", - "South V-Ex": "WoodsCar", + "South V-Ex": "CityCar", "RUAF Gate": "RUAFWoods", "Mountain Stash": "JaegerHideout" }, "rezervbase": { - "EXFIL_ScavCooperation": "ScavLands", - "EXFIL_Train": "ReserveTrain", + "EXFIL_ScavCooperation": "MilBaseCP", + "EXFIL_Train": "ArmoredTrain", "EXFIL_Bunker": "ReserveZB-014", "Exit1": "HoleinWall", "Exit4": "CPFence", @@ -790,40 +775,40 @@ "EXFIL_vent": "Manhole" }, "interchange": { - "PP Exfil": "InterchangeCar", + "PP Exfil": "CityCar", "Saferoom Exfil": "SafeRoom", "NW Exfil": "Railway", - "SE Exfil": "Emercom", - "Interchange Cooperation": "ScavCamp" + "SE Exfil": "Crossroads", + "Interchange Cooperation": "InterchangeScavCamp" }, "shoreline": { - "RedRebel_alp": "ClimbersTrail", + "RedRebel_alp": "CliffDescent", "Road to Customs": "RoadtoCustoms", "Pier Boat": "PierBoat", - "Tunnel": "Tunnel", - "Wrecked Road": "RuinedRoad", - "Lighthouse_pass": "LighthousePath", - "Smugglers_Trail_coop": "SmugglersPath", + "Tunnel": "LighthouseShorelineTunnel", + "Wrecked Road": "ShorelineLighthouseRoad", + "Lighthouse_pass": "LighthouseShorelinePath", + "Smugglers_Trail_coop": "SniperRB", "South Fence Passage": "PeacekeeperHideout", - "Shorl_V-Ex": "ShorelineCar", - "Road_at_railbridge": "RailwayBridge" + "Shorl_V-Ex": "ShorelineDormsCar", + "Road_at_railbridge": "RefHideout" }, "lighthouse": { " V-Ex_light": "LighthouseCar", - "Shorl_free": "ShorelinePath", - "Coastal_South_Road": "SouthernRoad", + "Shorl_free": "LighthouseShorelinePath", + "Coastal_South_Road": "ShorelineLighthouseRoad", "Scav_Hideout_at_the_grotto": "ArtemHideout", - "EXFIL_Train": "LighthouseTrain", - "Nothern_Checkpoint": "NorthernCP", + "EXFIL_Train": "ArmoredTrain", + "Nothern_Checkpoint": "Outskirts", "Alpinist_light": "MountainPass", - "tunnel_shared": "SideTunnel" + "tunnel_shared": "LighthouseShorelineTunnel" }, "tarkovstreets": { "E1": "StylobateElevator", "scav_e3": "VentShaft", "E3": "RuinedHouse", "E4": "CrashSite", - "E7_car": "StreetsCar", + "E7_car": "CityCar", "E9_sniper": "KlimovStreet", "scav_e1": "BasementDescent", "scav_e2": "Catacombs", @@ -842,7 +827,7 @@ }, "sandbox": { "Unity_free_exit": "TherapistHideout", - "Sandbox_VExit": "GZCar", + "Sandbox_VExit": "CityCar", "Nakatani_stairs_free_exit": "BasementDescent", "Sniper_exit": "KlimovStreet", "Scav_coop_exit": "ExpoCP" @@ -864,11 +849,6 @@ "LegsHideout": { "bigmap": ["Trailer Park Workers Shack"] }, - "Emercom": { - "bigmap": ["Crossroads"], - "interchange": ["Emercom"], - "shoreline": ["Road to Customs"] - }, "TherapistHideout": { "sandbox": ["EmercomGZ"] }, @@ -899,15 +879,6 @@ "factory4_day": ["Gate 0"], "factory4_night": ["Gate 0"] }, - "ScavCP": { - "bigmap": ["Scav CP"], - "lighthouse": ["Northern CP"], - "woods": ["Outskirts"] - }, - "DormsCar": { - "bigmap": ["Dorms Car"], - "shoreline": ["North Fence Passage"] - }, "SniperRB": { "bigmap": ["Sniper Roadblock"], "rezervbase": ["Hole In Wall"], @@ -939,10 +910,6 @@ "interchange": ["Railway"], "tarkovstreets": ["Crash Site"] }, - "PortRR": { - "bigmap": ["RR to Port"], - "shoreline": ["Railway Bridge"] - }, "MilBaseRR": { "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] @@ -951,14 +918,6 @@ "bigmap": ["Military Base CP"], "rezervbase": ["Scav lands"] }, - "TrailerPark": { - "bigmap": ["Trailer Park"], - "interchange": ["Scav Camp"] - }, - "FactoryCorner": { - "bigmap": ["Factory Far Corner"], - "woods": ["RUAF Gate"] - }, "NorthUNRoadblock": { "bigmap": ["RUAF Roadblock"], "woods": ["Northern UN Roadblock"] @@ -977,12 +936,6 @@ "woods": ["UN Roadblock"], "interchange": ["Railway"] }, - "WoodsCar": { - "tarkovstreets": ["Streets Vehicle Extract"], - "interchange": ["Interchange Vehicle Extract"], - "sandbox": ["Police Car"], - "woods": ["Woods Vehicle Extract"] - }, "RUAFWoods": { "bigmap": ["Factory Far Corner"], "woods": ["RUAF Gate"] @@ -990,19 +943,6 @@ "ReserveZB-014": { "woods": ["ZB-014"] }, - "ScavLands": { - "bigmap": ["Military Base CP"], - "rezervbase": ["Scav lands"] - }, - "ReserveTrain": { - "bigmap": ["RR to Military Base"], - "woods": ["Factory Gate"], - "lighthouse": ["Armored Train LH"], - "shoreline": ["Railway Bridge"], - "interchange": ["Railway"], - "rezervbase": ["Train Station"], - "tarkovstreets": ["Crash Site"] - }, "HoleinWall": { "bigmap": ["Dorms Car"], "rezervbase": ["Hole In Wall"] @@ -1019,7 +959,7 @@ "rezervbase": ["Reserve Manhole"], "tarkovstreets": ["Streets Manhole"] }, - "InterchangeCar": { + "CityCar": { "tarkovstreets": ["Streets Vehicle Extract"], "interchange": ["Interchange Vehicle Extract"], "sandbox": ["Police Car"], @@ -1033,14 +973,10 @@ "woods": ["UN Roadblock"], "tarkovstreets": ["Crash Site"] }, - "ScavCamp": { + "InterchangeScavCamp": { "interchange": ["Scav Camp"], "bigmap": ["Trailer Park"] }, - "ClimbersTrail": { - "rezervbase": ["Cliff"], - "shoreline": ["Climbers Trail"] - }, "RoadtoCustoms": { "bigmap": ["Sniper Roadblock"], "shoreline": ["Road to Customs"], @@ -1052,28 +988,15 @@ "lighthouse": ["Southern Road Water"], "woods": ["Sawmill River"] }, - "Tunnel": { - "shoreline": ["Shoreline Tunnel"], - "lighthouse": ["Lighthouse Tunnel"] - }, - "RuinedRoad": { + "ShorelineLighthouseRoad": { "shoreline": ["Ruined Road"], "lighthouse": ["Southern Road"] }, - "ShorelinePath": { - "shoreline": ["Path to Lighthouse"], - "lighthouse": ["Path to Shoreline"] - }, - "SmugglersPath": { - "shoreline": ["Smugglers Path"], - "bigmap": ["Sniper Roadblock"], - "rezervbase": ["Hole In Wall"] - }, - "ShorelineCar": { + "ShorelineDormsCar": { "bigmap": ["Dorms Car"], "shoreline": ["North Fence Passage"] }, - "RailwayBridge": { + "RefHideout": { "bigmap": ["RR to Port"], "shoreline": ["Railway Bridge"] }, @@ -1081,15 +1004,11 @@ "rezervbase": ["Checkpoint Fence"], "lighthouse": ["Lighthouse Vehicle Extract"] }, - "LighthousePath": { + "LighthouseShorelinePath": { "shoreline": ["Path to Lighthouse"], "lighthouse": ["Path to Shoreline"] }, - "SouthernRoad": { - "shoreline": ["Ruined Road"], - "lighthouse": ["Southern Road"] - }, - "LighthouseTrain": { + "ArmoredTrain": { "bigmap": ["RR to Military Base"], "woods": ["Factory Gate"], "lighthouse": ["Armored Train LH"], @@ -1098,16 +1017,11 @@ "rezervbase": ["Train Station"], "tarkovstreets": ["Crash Site"] }, - "NorthernCP": { - "bigmap": ["Scav CP"], - "lighthouse": ["Northern CP"], - "woods": ["Outskirts"] - }, "MountainPass": { "shoreline": ["Path to Lighthouse"], "lighthouse": ["Mountain Pass"] }, - "SideTunnel": { + "LighthouseShorelineTunnel": { "shoreline": ["Shoreline Tunnel"], "lighthouse": ["Lighthouse Tunnel"] }, @@ -1147,18 +1061,6 @@ "Catacombs": { "tarkovstreets": ["Catacombs"], "laboratory": ["Hangar Gate"] - }, - "StreetsCar": { - "tarkovstreets": ["Streets Vehicle Extract"], - "interchange": ["Interchange Vehicle Extract"], - "sandbox": ["Police Car"], - "woods": ["Woods Vehicle Extract"] - }, - "GZCar": { - "tarkovstreets": ["Streets Vehicle Extract"], - "interchange": ["Interchange Vehicle Extract"], - "sandbox": ["Police Car"], - "woods": ["Woods Vehicle Extract"] } } } diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index dd905382..c650223c 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -76,12 +76,12 @@ { "id": "PathToTarkov_Ref_stash", "size": 48, - "access_via": ["PortRR", "RailwayBridge"] + "access_via": ["RefHideout"] }, { "id": "PathToTarkov_Lotus_stash", "size": 48, - "access_via": ["Crossroads", "Emercom"] + "access_via": ["Crossroads"] }, { "id": "PathToTarkov_Artem_stash", @@ -121,52 +121,37 @@ { "id": "PathToTarkov_CustomsNorth_stash", "size": 32, - "access_via": [ - "FactoryCorner", - "RUAFWoods", - "GasGate", - "RUAFCustoms", - "UNRoadblock", - "NorthUNRoadblock" - ] + "access_via": ["RUAFWoods", "GasGate", "RUAFCustoms", "UNRoadblock", "NorthUNRoadblock"] }, { "id": "PathToTarkov_CustomsSouth_stash", "size": 32, - "access_via": [ - "MilBaseCP", - "ScavLands", - "MilBaseRR", - "HoleinWall", - "SniperRB", - "SmugglersPath", - "RoadtoCustoms" - ] + "access_via": ["MilBaseCP", "MilBaseRR", "HoleinWall", "SniperRB", "RoadtoCustoms"] }, { "id": "PathToTarkov_CustomsEast_stash", "size": 48, - "access_via": ["TarkovRR", "CrashSite", "Railway", "ScavCamp", "TrailerPark"] + "access_via": ["TarkovRR", "CrashSite", "Railway", "InterchangeScavCamp"] }, { "id": "PathToTarkov_CustomsWest_stash", "size": 32, - "access_via": ["ScavCP", "Outskirts", "NorthernCP"] + "access_via": ["Outskirts"] }, { "id": "PathToTarkov_ShoreLightPath_stash", "size": 16, - "access_via": ["LighthousePath", "ShorelinePath", "MountainPass"] + "access_via": ["LighthouseShorelinePath", "MountainPass"] }, { "id": "PathToTarkov_ShorelineWest_stash", "size": 16, - "access_via": ["Tunnel", "SideTunnel", "RuinedRoad", "SouthernRoad"] + "access_via": ["LighthouseShorelineTunnel", "ShorelineLighthouseRoad"] }, { "id": "PathToTarkov_ShorelineNorth_stash", "size": 16, - "access_via": ["ClimbersTrail", "CliffDescent"] + "access_via": ["CliffDescent"] }, { "id": "PathToTarkov_GZStreets_stash", @@ -176,12 +161,12 @@ { "id": "PathToTarkov_NorthCar_stash", "size": 4, - "access_via": ["WoodsCar", "InterchangeCar", "StreetsCar", "GZCar"] + "access_via": ["CityCar"] }, { "id": "PathToTarkov_SouthCar_stash", "size": 4, - "access_via": ["DormsCar", "ShorelineCar"] + "access_via": ["ShorelineDormsCar"] }, { "id": "PathToTarkov_MilCar_stash", @@ -201,7 +186,7 @@ { "id": "PathToTarkov_ArmoredTrain_stash", "size": 16, - "access_via": ["ReserveTrain", "LighthouseTrain"] + "access_via": ["ArmoredTrain"] }, { "id": "PathToTarkov_VentShaft_stash", @@ -304,7 +289,7 @@ "po": "Shoreline/Customs", "ru": "Shoreline/Customs" }, - "access_via": ["RailwayBridge", "PortRR"] + "access_via": ["RefHideout"] }, "5a7c2eca46aef81a7ca2145d": { "// Trader name": "Mechanic", @@ -385,7 +370,7 @@ "po": "Interchange/Customs", "ru": "Interchange/Customs" }, - "access_via": ["TrailerPark", "ScavCamp"] + "access_via": ["InterchangeScavCamp"] }, "5c0647fdd443bc2504c2d371": { "// Trader name": "Jaeger", @@ -568,7 +553,7 @@ }, "lotus": { "// mod integration for lotus": true, - "// lotus is available at Emercom": true, + "// lotus is available at Crossroads/Emercom": true, "disable_warning": true, "override_description": true, "location_description": { @@ -587,7 +572,7 @@ "po": "Interchange/Customs", "ru": "Interchange/Customs" }, - "access_via": ["Emercom", "Crossroads"] + "access_via": ["Crossroads"] }, "Coyote": { "// mod integration for Coyote": true, @@ -700,11 +685,11 @@ "Gate_o": "GasGate" }, "bigmap": { - "Military Checkpoint": "ScavCP", + "Military Checkpoint": "Outskirts", "EXFIL_ZB013": "FactoryZB-013", "ZB-1012": "FactoryZB-1012", "ZB-1011": "FactoryZB-1011", - "Dorms V-Ex": "DormsCar", + "Dorms V-Ex": "ShorelineDormsCar", "Sniper Roadblock": "SniperRB", "Smuggler's Boat": "SmugglersBoat", "RUAF Roadblock": "RUAFCustoms", @@ -713,10 +698,10 @@ "Railroad To Tarkov": "TarkovRR", "Shack": "MilBaseCP", "Warehouse 17": "SkierHideout", - "Trailer Park": "TrailerPark", + "Trailer Park": "InterchangeScavCamp", "Railroad To Military Base": "MilBaseRR", - "Railroad To Port": "PortRR", - "Factory Far Corner": "FactoryCorner", + "Railroad To Port": "RefHideout", + "Factory Far Corner": "RUAFWoods", "Trailer Park Workers Shack": "LegsHideout" }, "woods": { @@ -727,13 +712,13 @@ "ZB-014": "ReserveZB-014", "Outskirts": "Outskirts", "UN Roadblock": "UNRoadblock", - "South V-Ex": "WoodsCar", + "South V-Ex": "CityCar", "RUAF Gate": "RUAFWoods", "Mountain Stash": "JaegerHideout" }, "rezervbase": { - "EXFIL_ScavCooperation": "ScavLands", - "EXFIL_Train": "ReserveTrain", + "EXFIL_ScavCooperation": "MilBaseCP", + "EXFIL_Train": "ArmoredTrain", "EXFIL_Bunker": "ReserveZB-014", "Exit1": "HoleinWall", "Exit4": "CPFence", @@ -742,40 +727,40 @@ "EXFIL_vent": "Manhole" }, "interchange": { - "PP Exfil": "InterchangeCar", + "PP Exfil": "CityCar", "Saferoom Exfil": "SafeRoom", "NW Exfil": "Railway", - "SE Exfil": "Emercom", - "Interchange Cooperation": "ScavCamp" + "SE Exfil": "Crossroads", + "Interchange Cooperation": "InterchangeScavCamp" }, "shoreline": { - "RedRebel_alp": "ClimbersTrail", + "RedRebel_alp": "CliffDescent", "Road to Customs": "RoadtoCustoms", "Pier Boat": "PierBoat", - "Tunnel": "Tunnel", - "Wrecked Road": "RuinedRoad", - "Lighthouse_pass": "LighthousePath", - "Smugglers_Trail_coop": "SmugglersPath", + "Tunnel": "LighthouseShorelineTunnel", + "Wrecked Road": "ShorelineLighthouseRoad", + "Lighthouse_pass": "LighthouseShorelinePath", + "Smugglers_Trail_coop": "SniperRB", "South Fence Passage": "PeacekeeperHideout", - "Shorl_V-Ex": "ShorelineCar", - "Road_at_railbridge": "RailwayBridge" + "Shorl_V-Ex": "ShorelineDormsCar", + "Road_at_railbridge": "RefHideout" }, "lighthouse": { " V-Ex_light": "LighthouseCar", - "Shorl_free": "ShorelinePath", - "Coastal_South_Road": "SouthernRoad", + "Shorl_free": "LighthouseShorelinePath", + "Coastal_South_Road": "ShorelineLighthouseRoad", "Scav_Hideout_at_the_grotto": "ArtemHideout", - "EXFIL_Train": "LighthouseTrain", - "Nothern_Checkpoint": "NorthernCP", + "EXFIL_Train": "ArmoredTrain", + "Nothern_Checkpoint": "Outskirts", "Alpinist_light": "MountainPass", - "tunnel_shared": "SideTunnel" + "tunnel_shared": "LighthouseShorelineTunnel" }, "tarkovstreets": { "E1": "StylobateElevator", "scav_e3": "VentShaft", "E3": "RuinedHouse", "E4": "CrashSite", - "E7_car": "StreetsCar", + "E7_car": "CityCar", "E9_sniper": "KlimovStreet", "scav_e1": "BasementDescent", "scav_e2": "Catacombs", @@ -792,7 +777,7 @@ }, "sandbox": { "Unity_free_exit": "TherapistHideout", - "Sandbox_VExit": "GZCar", + "Sandbox_VExit": "CityCar", "Nakatani_stairs_free_exit": "BasementDescent", "Sniper_exit": "KlimovStreet", "Scav_coop_exit": "ExpoCP" @@ -814,11 +799,6 @@ "LegsHideout": { "bigmap": ["Trailer Park Workers Shack"] }, - "Emercom": { - "bigmap": ["Crossroads"], - "interchange": ["Emercom"], - "shoreline": ["Road to Customs"] - }, "TherapistHideout": { "sandbox": ["EmercomGZ"] }, @@ -849,15 +829,6 @@ "factory4_day": ["Gate 0"], "factory4_night": ["Gate 0"] }, - "ScavCP": { - "bigmap": ["Scav CP"], - "lighthouse": ["Northern CP"], - "woods": ["Outskirts"] - }, - "DormsCar": { - "bigmap": ["Dorms Car"], - "shoreline": ["North Fence Passage"] - }, "SniperRB": { "bigmap": ["Sniper Roadblock"], "rezervbase": ["Hole In Wall"], @@ -889,10 +860,6 @@ "interchange": ["Railway"], "tarkovstreets": ["Crash Site"] }, - "PortRR": { - "bigmap": ["RR to Port"], - "shoreline": ["Railway Bridge"] - }, "MilBaseRR": { "bigmap": ["RR to Military Base"], "rezervbase": ["Scav lands rail"] @@ -901,14 +868,6 @@ "bigmap": ["Military Base CP"], "rezervbase": ["Scav lands"] }, - "TrailerPark": { - "bigmap": ["Trailer Park"], - "interchange": ["Scav Camp"] - }, - "FactoryCorner": { - "bigmap": ["Factory Far Corner"], - "woods": ["RUAF Gate"] - }, "NorthUNRoadblock": { "bigmap": ["RUAF Roadblock"], "woods": ["Northern UN Roadblock"] @@ -927,12 +886,6 @@ "woods": ["UN Roadblock"], "interchange": ["Railway"] }, - "WoodsCar": { - "tarkovstreets": ["Streets Vehicle Extract"], - "interchange": ["Interchange Vehicle Extract"], - "sandbox": ["Police Car"], - "woods": ["Woods Vehicle Extract"] - }, "RUAFWoods": { "bigmap": ["Factory Far Corner"], "woods": ["RUAF Gate"] @@ -940,11 +893,7 @@ "ReserveZB-014": { "woods": ["ZB-014"] }, - "ScavLands": { - "bigmap": ["Military Base CP"], - "rezervbase": ["Scav lands"] - }, - "ReserveTrain": { + "ArmoredTrain": { "bigmap": ["RR to Military Base"], "woods": ["Factory Gate"], "lighthouse": ["Armored Train LH"], @@ -969,7 +918,7 @@ "rezervbase": ["Reserve Manhole"], "tarkovstreets": ["Streets Manhole"] }, - "InterchangeCar": { + "CityCar": { "tarkovstreets": ["Streets Vehicle Extract"], "interchange": ["Interchange Vehicle Extract"], "sandbox": ["Police Car"], @@ -983,14 +932,10 @@ "woods": ["UN Roadblock"], "tarkovstreets": ["Crash Site"] }, - "ScavCamp": { + "InterchangeScavCamp": { "interchange": ["Scav Camp"], "bigmap": ["Trailer Park"] }, - "ClimbersTrail": { - "rezervbase": ["Cliff"], - "shoreline": ["Climbers Trail"] - }, "RoadtoCustoms": { "bigmap": ["Sniper Roadblock"], "shoreline": ["Road to Customs"], @@ -1002,28 +947,15 @@ "lighthouse": ["Southern Road Water"], "woods": ["Sawmill River"] }, - "Tunnel": { - "shoreline": ["Shoreline Tunnel"], - "lighthouse": ["Lighthouse Tunnel"] - }, - "RuinedRoad": { - "shoreline": ["Ruined Road"], - "lighthouse": ["Southern Road"] - }, - "ShorelinePath": { + "LighthouseShorelinePath": { "shoreline": ["Path to Lighthouse"], "lighthouse": ["Path to Shoreline"] }, - "SmugglersPath": { - "shoreline": ["Smugglers Path"], - "bigmap": ["Sniper Roadblock"], - "rezervbase": ["Hole In Wall"] - }, - "ShorelineCar": { + "ShorelineDormsCar": { "bigmap": ["Dorms Car"], "shoreline": ["North Fence Passage"] }, - "RailwayBridge": { + "RefHideout": { "bigmap": ["RR to Port"], "shoreline": ["Railway Bridge"] }, @@ -1031,33 +963,15 @@ "rezervbase": ["Checkpoint Fence"], "lighthouse": ["Lighthouse Vehicle Extract"] }, - "LighthousePath": { - "shoreline": ["Path to Lighthouse"], - "lighthouse": ["Path to Shoreline"] - }, - "SouthernRoad": { + "ShorelineLighthouseRoad": { "shoreline": ["Ruined Road"], "lighthouse": ["Southern Road"] }, - "LighthouseTrain": { - "bigmap": ["RR to Military Base"], - "woods": ["Factory Gate"], - "lighthouse": ["Armored Train LH"], - "shoreline": ["Railway Bridge"], - "interchange": ["Railway"], - "rezervbase": ["Train Station"], - "tarkovstreets": ["Crash Site"] - }, - "NorthernCP": { - "bigmap": ["Scav CP"], - "lighthouse": ["Northern CP"], - "woods": ["Outskirts"] - }, "MountainPass": { "shoreline": ["Path to Lighthouse"], "lighthouse": ["Mountain Pass"] }, - "SideTunnel": { + "LighthouseShorelineTunnel": { "shoreline": ["Shoreline Tunnel"], "lighthouse": ["Lighthouse Tunnel"] }, @@ -1097,18 +1011,6 @@ "Catacombs": { "tarkovstreets": ["Catacombs"], "laboratory": ["Hangar Gate"] - }, - "StreetsCar": { - "tarkovstreets": ["Streets Vehicle Extract"], - "interchange": ["Interchange Vehicle Extract"], - "sandbox": ["Police Car"], - "woods": ["Woods Vehicle Extract"] - }, - "GZCar": { - "tarkovstreets": ["Streets Vehicle Extract"], - "interchange": ["Interchange Vehicle Extract"], - "sandbox": ["Police Car"], - "woods": ["Woods Vehicle Extract"] } } } diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 73d69f24..7aae0ff4 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -1,4 +1,5 @@ import { isValidExfilForMap } from './all-exfils'; +import type { ByMap } from './config'; import { EMPTY_STASH, type Config, type MapName, type SpawnConfig } from './config'; import { ensureArray } from './utils'; @@ -116,6 +117,36 @@ const getErrorsForOffraidPositions = (config: Config): string[] => { return errors; }; +const getInfiltrationHash = (spawns: ByMap): string => { + const results = Object.keys(spawns).flatMap(mapName => { + return spawns[mapName as MapName].map(spawnName => { + return `${mapName}.${spawnName}`; + }); + }); + + return results.sort().join('/'); +}; + +const getWarningsForOffraidPositions = (config: Config): string[] => { + const warnings: string[] = []; + const offraidPosByHash: Record = {}; + + Object.keys(config.infiltrations).forEach(offraidPosition => { + const spawnsByMap = config.infiltrations[offraidPosition]; + const hash = getInfiltrationHash(spawnsByMap); + + if (offraidPosByHash[hash]) { + warnings.push( + `offraid position "${offraidPosition}" seems to be a duplicate of "${offraidPosByHash[hash]}"`, + ); + } else { + offraidPosByHash[hash] = offraidPosition; + } + }); + + return warnings; +}; + const getErrorsForExfils = (config: Config): string[] => { const errors: string[] = []; @@ -262,6 +293,7 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 4. check all offraid positions errors.push(...getErrorsForOffraidPositions(config)); + warnings.push(...getWarningsForOffraidPositions(config)); // 5. checks for exfil maps errors.push(...getErrorsForExfils(config)); diff --git a/src/config.ts b/src/config.ts index 9993cba3..289daf98 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,7 @@ import type { ISptProfile } from '@spt/models/eft/profile/ISptProfile'; import { join } from 'path'; import { deepClone, fileExists, getPTTMongoId, readJsonFile, writeJsonFile } from './utils'; -type ByMap = { +export type ByMap = { factory4_day: T; factory4_night: T; bigmap: T; From a516835ad05ec185530892d9fa6e4aa28fcd50bf Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 8 Dec 2024 20:39:08 +0100 Subject: [PATCH 066/203] feat(wip): introduce offraid_positions displayName and exfiltrations_config displayName --- configs/Default/config.json | 297 ++++++++++++++++++++++++++++++++---- 1 file changed, 271 insertions(+), 26 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index fc1c98ca..09f48c62 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -104,7 +104,7 @@ "access_via": ["BasementDescent"] }, { - "id": "PathToTarkov_Hephaestus_stash", + "id": "PathToTarkov_RuinedHouse_stash", "size": 48, "access_via": ["RuinedHouse"] }, @@ -664,31 +664,6 @@ }, "access_via": ["BasementDescent"] }, - "hephaestus_alxk": { - "// mod integration for Hephaestus": true, - "disable_warning": true, - "override_description": true, - "location_description": { - "ch": "Ruined house in the streets", - "cz": "Ruined house in the streets", - "en": "Ruined house in the streets", - "es-mx": "Ruined house in the streets", - "es": "Ruined house in the streets", - "fr": "Maison en ruine dans les rues", - "ge": "Ruined house in the streets", - "hu": "Ruined house in the streets", - "it": "Ruined house in the streets", - "jp": "Ruined house in the streets", - "kr": "Ruined house in the streets", - "pl": "Ruined house in the streets", - "po": "Ruined house in the streets", - "ro": "Ruined house in the streets", - "ru": "Ruined house in the streets", - "sk": "Ruined house in the streets", - "tu": "Ruined house in the streets" - }, - "access_via": ["RuinedHouse"] - }, "Sally": { "// mod integration for Sally": true, "disable_warning": true, @@ -1062,5 +1037,275 @@ "tarkovstreets": ["Catacombs"], "laboratory": ["Hangar Gate"] } + }, + "exfiltrations_tooltips_template": "$exfilDisplayName ($offraidPositionDisplayName)", + "offraid_positions": { + "PraporHideout": { + "displayName": { + "en": "Prapor" + } + }, + "SkierHideout": { + "displayName": { + "en": "Skier" + } + }, + "JaegerHideout": { + "displayName": { + "en": "Jaeger" + } + }, + "PeacekeeperHideout": { + "displayName": { + "en": "Peacekeeper" + } + }, + "LegsHideout": { + "displayName": { + "en": "Legs" + } + }, + "TherapistHideout": { + "displayName": { + "en": "Therapist" + } + }, + "MechanicHideout": { + "displayName": { + "en": "Mechanic" + } + }, + "ArtemHideout": { + "displayName": { + "en": "Artem" + } + }, + "FactoryZB-016": { + "displayName": { + "en": "Woods/Factory" + } + }, + "FactoryZB-013": { + "displayName": { + "en": "Customs/Factory" + } + }, + "FactoryZB-1012": { + "displayName": { + "en": "Customs/Factory" + } + }, + "FactoryZB-1011": { + "displayName": { + "en": "Customs/Factory" + } + }, + "SniperRB": { + "displayName": { + "en": "Customs/Reserve/Shoreline" + } + }, + "SmugglersBoat": { + "displayName": { + "en": "Boat" + } + }, + "RUAFCustoms": { + "displayName": { + "en": "Customs/Woods" + } + }, + "Crossroads": { + "displayName": { + "en": "Customs/Interchange/Shoreline" + } + }, + "GasGate": { + "displayName": { + "en": "Customs/Woods/Factory" + } + }, + "TarkovRR": { + "displayName": { + "en": "Painter + Customs/Interchange/Streets" + } + }, + "MilBaseRR": { + "displayName": { + "en": "Customs/Reserve" + } + }, + "MilBaseCP": { + "displayName": { + "en": "Customs/Reserve" + } + }, + "NorthUNRoadblock": { + "displayName": { + "en": "Customs/Woods" + } + }, + "FactoryGate": { + "displayName": { + "en": "Customs/Woods" + } + }, + "Outskirts": { + "displayName": { + "en": "Priscilu + Customs/Woods/Lighthouse" + } + }, + "UNRoadblock": { + "displayName": { + "en": "Customs/Woods/Interchange" + } + }, + "RUAFWoods": { + "displayName": { + "en": "Customs/Woods" + } + }, + "ReserveZB-014": { + "displayName": { + "en": "Scorpion" + } + }, + "HoleinWall": { + "displayName": { + "en": "Customs/Reserve" + } + }, + "CPFence": { + "displayName": { + "en": "Lighthouse/Reserve" + } + }, + "CliffDescent": { + "displayName": { + "en": "Shoreline/Reserve" + } + }, + "Manhole": { + "displayName": { + "en": "Sally + Streets/Reserve" + } + }, + "CityCar": { + "displayName": { + "en": "Streets/Interchange/Woods/GZ" + } + }, + "SafeRoom": {}, + "Railway": { + "displayName": { + "en": "Painter + Streets/Woods/Interchange" + } + }, + "InterchangeScavCamp": { + "displayName": { + "en": "Customs/Interchange" + } + }, + "RoadtoCustoms": { + "displayName": { + "en": "Customs/Interchange/Shoreline" + } + }, + "PierBoat": { + "displayName": { + "en": "Customs/Shoreline/Lighthouse/Woods" + } + }, + "ShorelineLighthouseRoad": { + "displayName": { + "en": "Shoreline/Lighthouse" + } + }, + "ShorelineDormsCar": { + "displayName": { + "en": "Customs/Shoreline" + } + }, + "RefHideout": { + "displayName": { + "en": "Customs/Shoreline" + } + }, + "LighthouseCar": { + "displayName": { + "en": "Reserve/Lighthouse" + } + }, + "LighthouseShorelinePath": { + "displayName": { + "en": "Shoreline/Lighthouse" + } + }, + "ArmoredTrain": { + "displayName": { + "en": "goes almost everywhere", + "fr": "va presque partout" + } + }, + "MountainPass": { + "displayName": { + "en": "Shoreline/Lighthouse" + } + }, + "LighthouseShorelineTunnel": { + "displayName": { + "en": "Shoreline/Lighthouse" + } + }, + "BasementDescent": { + "displayName": { + "en": "Harry/Coyote" + } + }, + "RuinedHouse": {}, + "ExpoCP": { + "displayName": { + "en": "GZ/Streets" + } + }, + "KlimovStreet": { + "displayName": { + "en": "GZ/Streets" + } + }, + "VentShaft": { + "displayName": { + "en": "Streets/Lab" + } + }, + "SewerRiver": { + "displayName": { + "en": "Streets/Lab" + } + }, + "StylobateElevator": { + "displayName": { + "en": "Streets/Lab" + } + }, + "CrashSite": { + "displayName": { + "en": "Painter + Streets/Interchange/Woods" + } + }, + "Catacombs": { + "displayName": { + "en": "Streets/Lab" + } + } + }, + "exfiltrations_config": { + "Warehouse 17": { + "override_tooltips_template": "$offraidPositionDisplayName $exfilDisplayName", + "displayName": { + "en": "in Warehouse 17", + "fr": "à l'entrepôt 17" + } + } } } From 627fffb6f794b7f7aeee5ee18e9b555d09a4de14 Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 10 Dec 2024 01:35:15 +0100 Subject: [PATCH 067/203] chore: fix typo in configs/Default/Tooltips --- configs/Default/Tooltips.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/Default/Tooltips.json b/configs/Default/Tooltips.json index 297a35c0..b0d54168 100644 --- a/configs/Default/Tooltips.json +++ b/configs/Default/Tooltips.json @@ -202,7 +202,7 @@ "lab_Elevator_Cargo", "Cargo Elevator (Streets/Ground Zero)", "lab_Elevator_Main", - "Main Elevator (Streets, Syylobate Elevator)", + "Main Elevator (Streets, Stylobate Elevator)", "lab_Hangar_Gate", "Hangar Gate (Streets, Catacombs)", "lab_Under_Storage_Collector", From ec81044bb32cc26001dd36f057edad07d43801b5 Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 10 Dec 2024 21:49:58 +0100 Subject: [PATCH 068/203] feat: add Saria next to Peacekeeper in default config --- configs/Default/config.json | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/configs/Default/config.json b/configs/Default/config.json index 09f48c62..e37b81f2 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -614,6 +614,30 @@ }, "access_via": ["TarkovRR", "CrashSite", "Railway"] }, + "66f4db5ca4958508883d700c": { + "// Trader name": "Saria", + "override_description": true, + "location_description": { + "ch": "With Peacekeeper in Bunker D2", + "cz": "With Peacekeeper in Bunker D2", + "en": "With Peacekeeper in Bunker D2", + "es-mx": "With Peacekeeper in Bunker D2", + "es": "With Peacekeeper in Bunker D2", + "fr": "Avec Peacekeeper dans le bunker D2", + "ge": "With Peacekeeper in Bunker D2", + "hu": "With Peacekeeper in Bunker D2", + "it": "With Peacekeeper in Bunker D2", + "jp": "With Peacekeeper in Bunker D2", + "kr": "With Peacekeeper in Bunker D2", + "pl": "With Peacekeeper in Bunker D2", + "po": "With Peacekeeper in Bunker D2", + "ro": "With Peacekeeper in Bunker D2", + "ru": "With Peacekeeper in Bunker D2", + "sk": "With Peacekeeper in Bunker D2", + "tu": "With Peacekeeper in Bunker D2" + }, + "access_via": ["PeacekeeperHideout"] + }, "lotus": { "// mod integration for lotus": true, "disable_warning": true, From 9d4da44e6cd2e32c845ca5b9e0c6dc49013482f4 Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 10 Dec 2024 22:42:11 +0100 Subject: [PATCH 069/203] fix: unsupported vanilla_exfils_requirements (warn instead of errror) --- src/path-to-tarkov-controller.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 8ac98474..4cca2121 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -552,8 +552,7 @@ export class PathToTarkovController { // TODO: move this into config-analysis if (config.vanilla_exfils_requirements) { - this.logger.error('Path To Tarkov: "vanilla_exfils_requirements" is no longer supported'); - return; + this.logger.warning('Path To Tarkov: "vanilla_exfils_requirements" is no longer supported'); } // TODO(refactor): implement an indexBy util From 4abb4265fed540fd8085480007abbefbe334df0b Mon Sep 17 00:00:00 2001 From: Trap Date: Tue, 10 Dec 2024 23:48:08 +0100 Subject: [PATCH 070/203] fix(config): allow user to remove all exfils for a given map (when transits are enabled) --- src/config-analysis.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 7aae0ff4..e5c9b827 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -156,8 +156,11 @@ const getErrorsForExfils = (config: Config): string[] => { errors.push(`${mapName} is now allowed as a map name in "exfiltrations"`); } - // 2. check for map with no exfils - if (Object.keys(config.exfiltrations[mapName as MapName]).length === 0) { + // 2. check for map with no exfils (only when all transits are disabled) + if ( + config.disable_all_transits && + Object.keys(config.exfiltrations[mapName as MapName]).length === 0 + ) { errors.push(`no exfils found for map ${mapName} in "exfiltrations"`); } }); From 12808922f4fb4af7270df59d2988343265a6a0a5 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 00:54:33 +0100 Subject: [PATCH 071/203] chore: cleanup --- src/traders-controller.ts | 5 ++--- tests/utils.test.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/traders-controller.ts b/src/traders-controller.ts index 2f36ad0e..bd0db5d1 100644 --- a/src/traders-controller.ts +++ b/src/traders-controller.ts @@ -47,9 +47,8 @@ export class TradersController { // be able to lock a trader trader.base.unlockedByDefault = false; + // traders description update if (tradersConfig[traderId].override_description) { - // change trader location in descriptions - Object.keys(locales?.global ?? []).forEach(locale => { const locationDescription = tradersConfig[traderId].location_description; @@ -129,7 +128,7 @@ export class TradersController { } } - // offraid pay-to-heal config + // offraid pay-to-heal config update if (tradersConfig[traderId].heal_always_enabled) { trader.base.medic = true; trader.base.loyaltyLevels = trader.base.loyaltyLevels.map((loyaltyLevel, index) => { diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 40cc158f..916c252f 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -25,7 +25,7 @@ describe('PTT utils', () => { expect(getPTTMongoId('test3')).toBe(getPTTMongoId('test3')); }); - it('should check that the id start with "PTT" preefix', () => { + it('should check that the id start with PTT "deadbeef" prefix', () => { expect(getPTTMongoId('test').startsWith('deadbeef')).toBe(true); }); }); From eac591eb0b63aa02b37e6b93e669d438c5b94266 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 20:52:15 +0100 Subject: [PATCH 072/203] feat: exfiltrations tooltips templating --- src/config-analysis.ts | 11 +- src/config.ts | 64 +++++--- src/mod.ts | 1 + src/path-to-tarkov-controller.ts | 22 ++- src/services/ExfilsTooltipsTemplater.ts | 175 +++++++++++++++++++++ src/services/TradersAvailabilityService.ts | 3 +- src/utils.ts | 4 + 7 files changed, 244 insertions(+), 36 deletions(-) create mode 100644 src/services/ExfilsTooltipsTemplater.ts diff --git a/src/config-analysis.ts b/src/config-analysis.ts index e5c9b827..73794904 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -1,7 +1,7 @@ import { isValidExfilForMap } from './all-exfils'; import type { ByMap } from './config'; import { EMPTY_STASH, type Config, type MapName, type SpawnConfig } from './config'; -import { ensureArray } from './utils'; +import { ensureArray, isEmpty } from './utils'; const MIN_NEEDED_MAPS = [ 'laboratory', @@ -157,10 +157,7 @@ const getErrorsForExfils = (config: Config): string[] => { } // 2. check for map with no exfils (only when all transits are disabled) - if ( - config.disable_all_transits && - Object.keys(config.exfiltrations[mapName as MapName]).length === 0 - ) { + if (config.disable_all_transits && isEmpty(config.exfiltrations[mapName as MapName])) { errors.push(`no exfils found for map ${mapName} in "exfiltrations"`); } }); @@ -280,12 +277,12 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV const warnings: string[] = []; // 1. check there is at least one offraid position - if (Object.keys(config.infiltrations).length === 0) { + if (isEmpty(config.infiltrations)) { errors.push('no offraid position found in "infiltrations"'); } // 2. check there is at least one map - if (Object.keys(config.exfiltrations).length === 0) { + if (isEmpty(config.exfiltrations)) { errors.push('no map found found in "exfiltrations"'); } diff --git a/src/config.ts b/src/config.ts index 289daf98..39a76b74 100644 --- a/src/config.ts +++ b/src/config.ts @@ -17,6 +17,26 @@ export type ByMap = { terminal: T; }; +export type ByLocale = { + ch?: T; + cz?: T; + en?: T; + 'es-mx'?: T; + es?: T; + fr?: T; + ge?: T; + hu?: T; + it?: T; + jp?: T; + kr?: T; + pl?: T; + po?: T; + ro?: T; + ru?: T; + sk?: T; + tu?: T; +}; + type ByProfileId = Record; export type MapName = keyof ByMap; @@ -61,27 +81,7 @@ export type RawStashConfig = { access_via: AccessVia; }; -type AllLocales = { - ch?: T; - cz?: T; - en?: T; - 'es-mx'?: T; - es?: T; - fr?: T; - ge?: T; - hu?: T; - it?: T; - jp?: T; - kr?: T; - pl?: T; - po?: T; - ro?: T; - ru?: T; - sk?: T; - tu?: T; -}; - -export type LocaleName = keyof AllLocales; +export type LocaleName = keyof ByLocale; type InsuranceConfig = { insurance_price_coef?: number; @@ -102,7 +102,7 @@ type RepairConfig = { type StaticTraderConfig = { disable_warning?: boolean; override_description?: boolean; - location_description?: AllLocales; + location_description?: ByLocale; insurance_always_enabled?: boolean; insurance_config?: InsuranceConfig; repair_always_enabled?: boolean; @@ -119,15 +119,15 @@ type TraderConfig = StaticTraderConfig & { export type TradersConfig = Record; type SpawnPointName = string; -type OffraidPosition = string; +type OffraidPositionName = string; type ExtractName = string; type Exfiltrations = ByMap<{ - [extractName: ExtractName]: OffraidPosition; + [extractName: ExtractName]: OffraidPositionName; }>; type Infiltrations = { - [offraidPosition: OffraidPosition]: ByMap; + [offraidPosition: OffraidPositionName]: ByMap; }; export type OffraidRegenConfig = { @@ -146,6 +146,15 @@ export type InfiltrationsConfig = { additional_player_spawnpoints?: Partial; }; +export type OffraidPositionDefinition = { + displayName?: ByLocale; +}; + +export type ExfiltrationConfig = { + override_tooltips_template?: string; + displayName?: ByLocale; +}; + type RawConfig = { enabled: boolean; debug?: boolean; @@ -169,9 +178,12 @@ type RawConfig = { hideout_secondary_stashes: RawStashConfig[]; traders_access_restriction: boolean; traders_config: TradersConfig; - infiltrations_config?: InfiltrationsConfig; exfiltrations: Exfiltrations; infiltrations: Infiltrations; + infiltrations_config?: InfiltrationsConfig; + exfiltrations_config?: Record; // TODO: validate in config-analysis + exfiltrations_tooltips_template?: string; // TODO: validate in config-analysis + offraid_positions?: Record; // TODO: validate in config-analysis }; export type Config = Omit & { diff --git a/src/mod.ts b/src/mod.ts index 742911c8..9584f014 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -183,6 +183,7 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { this.executeOnStartAPICallbacks = executeOnStartAPICallbacks; + this.pathToTarkovController.injectTooltipsInLocales(this.config); this.pathToTarkovController.tradersController.initTraders(this.config); const nbAddedTemplates = diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index 4cca2121..d9ccbcb1 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -37,7 +37,7 @@ import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBody import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; import { KeepFoundInRaidTweak } from './keep-fir-tweak'; -// import type { LocationCallbacks } from '@spt/callbacks/LocationCallbacks'; +import { ExfilsTooltipsTemplater } from './services/ExfilsTooltipsTemplater'; type IndexedLocations = Record; @@ -103,6 +103,24 @@ export class PathToTarkovController { this.overrideControllers(); } + // TODO: make it dynamic (aka intercept instead of mutating the db) + injectTooltipsInLocales(config: Config): void { + const allLocales = this.db.getTables()?.locales?.global; + + if (!allLocales) { + throw new Error('Path To Tarkov: no locales found in db'); + } + + const templater = new ExfilsTooltipsTemplater(allLocales); + const partialLocales = templater.computeLocales(config); + const report = ExfilsTooltipsTemplater.mutateLocales(allLocales, partialLocales); + + const nbValuesUpdated = report.nbTotalValuesUpdated / report.nbLocalesImpacted; + this.debug( + `${nbValuesUpdated} extract tooltip values updated for ${report.nbLocalesImpacted} locales (total of ${report.nbTotalValuesUpdated})`, + ); + } + setConfig(config: Config, sessionId: string): void { // TODO: validation ? this.configCache[sessionId] = config; @@ -299,7 +317,7 @@ export class PathToTarkovController { if (gridProps) { gridProps.cellsV = size; } else { - throw new Error('Path To Tarkov: cannot set size for custom stash'); + throw new Error('Path To Tarkov: cannot set size for custom stash'); } }); diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts new file mode 100644 index 00000000..93315d70 --- /dev/null +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -0,0 +1,175 @@ +import type { ByLocale, Config, LocaleName, MapName } from '../config'; +import { deepClone } from '../utils'; + +const EXFIL_DISPLAY_NAME_VARIABLE = '$exfilDisplayName'; +const OFFRAID_POSITION_DISPLAY_NAME_VARIABLE = '$offraidPositionDisplayName'; + +const DEFAULT_FALLBACK_LANGUAGE = 'en'; + +type AllLocalesInDb = Record>; +type PartialLocales = Partial>>; + +export type MinimumConfigForTooltipsTemplater = Pick< + Config, + 'exfiltrations' | 'exfiltrations_config' | 'exfiltrations_tooltips_template' | 'offraid_positions' +>; + +export type LocalesMutationReport = { + nbLocalesImpacted: number; + nbTotalValuesUpdated: number; +}; + +type ComputeLocaleValueParameter = { + locale: LocaleName; + exfilName: string; + offraidPosition: string; +}; + +export class ExfilsTooltipsTemplater { + // this is used to be sure to keep the vanilla locales even after mutations are applied to the database + private readonly snapshotLocales: AllLocalesInDb; + + constructor(allLocales: AllLocalesInDb) { + this.snapshotLocales = deepClone(allLocales); + } + + public computeLocales(config: MinimumConfigForTooltipsTemplater): PartialLocales { + const result: PartialLocales = {}; + + Object.keys(this.snapshotLocales).forEach(locale => { + const localeValues: Record = {}; + result[locale] = localeValues; + + Object.keys(config.exfiltrations).forEach(mapName => { + const exfils = config.exfiltrations[mapName as MapName]; + + Object.keys(exfils).forEach(exfilName => { + const offraidPosition = exfils[exfilName]; + + const computeParams: ComputeLocaleValueParameter = { + locale: locale as LocaleName, + exfilName, + offraidPosition, + }; + + localeValues[exfilName] = this.computeLocaleValue(config, computeParams); + }); + }); + }); + + return result; + } + + public static mutateLocales( + allLocales: AllLocalesInDb, + partialLocales: PartialLocales, + ): LocalesMutationReport { + const report: LocalesMutationReport = { + nbLocalesImpacted: 0, + nbTotalValuesUpdated: 0, + }; + + void Object.keys(allLocales).forEach(localeName => { + if (partialLocales[localeName]) { + const values = allLocales[localeName]; + const newValues = partialLocales[localeName] ?? {}; + const nbNewValues = Object.keys(newValues).length; + + if (nbNewValues > 0) { + void Object.assign(values, newValues); // mutation here + report.nbLocalesImpacted += 1; + report.nbTotalValuesUpdated += nbNewValues; + } + } + }); + + return report; + } + + private computeLocaleValue( + config: MinimumConfigForTooltipsTemplater, + { exfilName, offraidPosition, locale }: ComputeLocaleValueParameter, + ): string { + const exfilDisplayName = this.resolveExfilDisplayName(config, exfilName, locale); + + const offraidPositionDisplayName = ExfilsTooltipsTemplater.resolveOffraidPositionDisplayName( + config, + offraidPosition, + locale, + ); + + const tooltipsTemplate = ExfilsTooltipsTemplater.resolveTooltipsTemplate(config, exfilName); + + const templatedValue = tooltipsTemplate + .replace(EXFIL_DISPLAY_NAME_VARIABLE, exfilDisplayName) + .replace(OFFRAID_POSITION_DISPLAY_NAME_VARIABLE, offraidPositionDisplayName); + + return templatedValue; + } + + private resolveExfilDisplayName( + config: MinimumConfigForTooltipsTemplater, + exfilName: string, + locale: LocaleName, + ): string { + const exfilConfig = config?.exfiltrations_config?.[exfilName]; + const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( + locale, + exfilConfig?.displayName, + ); + + if (resolvedDisplayName) { + return resolvedDisplayName; + } + + const vanillaResolvedValue = this.snapshotLocales[locale][exfilName]; + return vanillaResolvedValue ?? 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; + } + + private static resolveOffraidPositionDisplayName( + config: MinimumConfigForTooltipsTemplater, + offraidPosition: string, + locale: LocaleName, + ): string { + const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; + const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( + locale, + offraidPositionDefinition?.displayName, + ); + + if (resolvedDisplayName) { + return resolvedDisplayName; + } + + return offraidPosition; + } + + private static resolveTooltipsTemplate( + config: MinimumConfigForTooltipsTemplater, + exfilName: string, + ): string { + const exfilConfig = config.exfiltrations_config?.[exfilName]; + + if (exfilConfig?.override_tooltips_template) { + return exfilConfig.override_tooltips_template; + } + + if (config.exfiltrations_tooltips_template) { + return config.exfiltrations_tooltips_template; + } + + // by default, the tooltips template is the name of the exfil itself + return EXFIL_DISPLAY_NAME_VARIABLE; + } + + private static resolveDisplayName = ( + locale: LocaleName, + displayName: ByLocale | undefined, + ): string | undefined => { + if (!displayName) { + return undefined; + } + + return displayName[locale] ?? displayName[DEFAULT_FALLBACK_LANGUAGE]; + }; +} diff --git a/src/services/TradersAvailabilityService.ts b/src/services/TradersAvailabilityService.ts index 9ee47243..c6c3361f 100644 --- a/src/services/TradersAvailabilityService.ts +++ b/src/services/TradersAvailabilityService.ts @@ -1,5 +1,6 @@ import type { IQuestStatus } from '@spt/models/eft/common/tables/IBotBase'; import type { IQuest } from '@spt/models/eft/common/tables/IQuest'; +import { isEmpty } from '../utils'; type Quests = Record; @@ -44,7 +45,7 @@ export class TradersAvailabilityService { const unlockQuests = this.tradersLockedByQuests[traderId]; - if (!unlockQuests || Object.keys(unlockQuests).length === 0) { + if (!unlockQuests || isEmpty(unlockQuests)) { return true; } diff --git a/src/utils.ts b/src/utils.ts index 2426da0e..32da3ae3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -103,6 +103,10 @@ export function shuffle(givenArray: T[]): T[] { // eslint-disable-next-line @typescript-eslint/no-empty-function export function noop(): void {} +export const isEmpty = (obj: object): boolean => { + return Object.keys(obj).length === 0; +}; + export const isEmptyArray = (arr: T[] | undefined): boolean => { return Boolean(arr && arr.length > 0); }; From 26509be14b06e1fd96cde175b10884588ff03d1b Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 21:44:42 +0100 Subject: [PATCH 073/203] chore: cleanup useless dynamic maps compats --- .../Customs_TarkovDev/Customs_TarkovDev.jsonc | 691 ----------- .../Factory_TarkovDev/Factory_TarkovDev.jsonc | 215 ---- .../GroundZero_TarkovDev.jsonc | 207 ---- .../Interchange_TarkovDev.jsonc | 627 ---------- .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 283 ----- .../Lighthouse_TarkovData.jsonc | 320 ----- .../Reserve_TarkovData.jsonc | 556 --------- .../Shoreline_TarkovData.jsonc | 548 --------- .../Streets_TarkovData.jsonc | 1092 ----------------- .../Woods_TarkovData/Woods_TarkovData.jsonc | 216 ---- .../Instructions.txt | 5 - .../Customs_TarkovDev/Customs_TarkovDev.jsonc | 691 ----------- .../Factory_TarkovDev/Factory_TarkovDev.jsonc | 215 ---- .../GroundZero_TarkovDev.jsonc | 207 ---- .../Interchange_TarkovDev.jsonc | 627 ---------- .../Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc | 283 ----- .../Lighthouse_TarkovData.jsonc | 320 ----- .../Reserve_TarkovData.jsonc | 556 --------- .../Shoreline_TarkovData.jsonc | 548 --------- .../Streets_TarkovData.jsonc | 1092 ----------------- .../Woods_TarkovData/Woods_TarkovData.jsonc | 216 ---- .../Instructions.txt | 5 - 22 files changed, 9520 deletions(-) delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc delete mode 100644 configs/Default/DynamicMaps optional tooltips/Instructions.txt delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc delete mode 100644 configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc deleted file mode 100644 index 67f3c3a9..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc +++ /dev/null @@ -1,691 +0,0 @@ -{ - "DisplayName": "Customs (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["bigmap"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "DefaultLevel": 0, - "Layers": { - "Underground": { - "Level": -1, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_-1.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - // zb-1011 - "Min": { "x": 620, "y": -137, "z": -100 }, - "Max": { "x": 635, "y": -125, "z": 0.5 }, - }, - { - // zb-1012 - "Min": { "x": 458, "y": -122, "z": -100 }, - "Max": { "x": 473, "y": -110, "z": 0.5 }, - }, - { - // old gas - "Min": { "x": 308, "y": -184, "z": -100 }, - "Max": { "x": 314, "y": -173, "z": 0.5 }, - }, - { - // switch basement - "Min": { "x": 323, "y": -88, "z": -100 }, - "Max": { "x": 349, "y": -32, "z": 0.5 }, - }, - { - // zb-013 - "Min": { "x": 193, "y": -158, "z": -100 }, - "Max": { "x": 219, "y": -137, "z": 0.5 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_0.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - "Min": { "x": -372, "y": -306, "z": -100 }, - "Max": { "x": 698, "y": 235, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_1.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - // dorms - "Min": { "x": 165, "y": 125, "z": 2.7 }, - "Max": { "x": 243, "y": 190, "z": 5.0 }, - }, - { - // mechanic - "Min": { "x": 72, "y": -170, "z": 2.7 }, - "Max": { "x": 116, "y": -83, "z": 6.5 }, - }, - { - // switch 2nd - "Min": { "x": 341, "y": -84, "z": 2.7 }, - "Max": { "x": 356, "y": -30, "z": 6.5 }, - }, - { - // switch 2nd - "Min": { "x": 321, "y": -59, "z": 2.7 }, - "Max": { "x": 334, "y": -52, "z": 6.5 }, - }, - { - // scav checkpoint - "Min": { "x": 577, "y": -1, "z": 2.7 }, - "Max": { "x": 589, "y": 10, "z": 6.5 }, - }, - { - // dead scav warehouse - "Min": { "x": 532, "y": -134, "z": 2.7 }, - "Max": { "x": 580, "y": -104, "z": 100 }, - }, - { - // pump 2nd - "Min": { "x": 599, "y": -139, "z": 2.7 }, - "Max": { "x": 625, "y": -120, "z": 100 }, - }, - { - // big red 2nd - "Min": { "x": -223, "y": -131, "z": 5.7 }, - "Max": { "x": -199, "y": -90, "z": 100 }, - }, - { - // skeleton - "Min": { "x": 169, "y": -160, "z": 5.7 }, - "Max": { "x": 239, "y": 3, "z": 100 }, - }, - { - // switch sniper - "Min": { "x": 316, "y": -95, "z": 5.7 }, - "Max": { "x": 336, "y": -56, "z": 100 }, - }, - { - // USEC 2nd - "Min": { "x": 556, "y": -92, "z": 5.7 }, - "Max": { "x": 584, "y": -46, "z": 100 }, - }, - { - // construction 2nd - "Min": { "x": 65, "y": -22, "z": 5.7 }, - "Max": { "x": 93, "y": 0, "z": 100 }, - }, - { - // chemical warehouse sniper scav - "Min": { "x": 450, "y": -90, "z": 14 }, - "Max": { "x": 497, "y": -44, "z": 15 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_2.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - // dorms - "Min": { "x": 165, "y": 125, "z": 5.0 }, - "Max": { "x": 234, "y": 190, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - // all of these labels are from Tarkov.dev map data under MIT license - { - "Text": "Big Red", - "Position": { "x": -215, "y": -119, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Dorms", - "Position": { "x": 200, "y": 150, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "New Gas", - "Position": { "x": 404, "y": 31, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Old Gas", - "Position": { "x": 331, "y": -173, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Fortress", - "Position": { "x": 201, "y": -127, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crackhouse", - "Position": { "x": 83, "y": -153, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Streamer House", - "Position": { "x": 567, "y": -67, "z": 0 }, - }, - { - "Text": "Main Bridge", - "Position": { "x": -69, "y": 7, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 6, - }, - { - "Text": "Sniper Hill", - "Position": { "x": 110, "y": 85, "z": 0 }, - }, - { - "Text": "Storage", - "Position": { "x": -288, "y": -134, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Trailer Park", - "Position": { "x": -211, "y": -219, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Junk Bridge", - "Position": { "x": -66, "y": 46, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Repair Shop", - "Position": { "x": 106, "y": -90, "z": 0 }, - }, - { - "Text": "Sniper Ridge", - "Position": { "x": 491, "y": 63, "z": 0 }, - "DegreesRotation": 5, - }, - { - "Text": "Old Construction", - "Position": { "x": 75, "y": -9, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Skeleton", - "Position": { "x": 200, "y": -13, "z": 0 }, - "FontSize": 16, - "DegreesRotation": -9, - }, - { - "Text": "Warehouse 3", - "Position": { "x": 390, "y": -94, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Depot", - "Position": { "x": 472, "y": -67, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Warehouse 7", - "Position": { "x": 555, "y": -118, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Military Checkpoint", - "Position": { "x": 572, "y": 0, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Bus Station", - "Position": { "x": 238, "y": 53, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Warehouse 4", - "Position": { "x": 333, "y": -67, "z": 1 }, - "FontSize": 16, - }, - { - "Text": "Powerline Tower", - "Position": { "x": 497, "y": 110, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Warehouse 17", - "Position": { "x": 46, "y": -59, "z": 0 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "ZB-013 Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": 352.230316, "y": -40.8052826, "z": 2.61458874 }, - "Category": "Switch", - }, - { - "Text": "Military Base CP (Reserve, Scav Lands)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 643.3982, "y": 126.869247, "z": 2.400003 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railroad to Military Base (Reserve, Scav Land rails*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 489.058228, "y": 221.391266, "z": 3.950006 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sniper Roadblock (Reserve*/Shoreline)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 15.3699341, "y": 127.94, "z": 0.139977932 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railroad to Port (Ref/Shoreline)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -142.550232, "y": 46.9100037, "z": -0.629980564 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Trailer Park Workers' Shack (Legs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -248.540222, "y": -232.9901, "z": 2.550012 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railroad to Tarkov (Painter/Streets/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -166.020264, "y": -218.380112, "z": 2.42000723 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Warehouse 17 (Skier)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 45.9998779, "y": -78.43004, "z": 3.61000967 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Old Gas Station Gate (Woods/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 301.639923, "y": -197.940048, "z": 3.469995 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Factory Far Corner (Woods, RUAF Gate)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 654.53, "y": -160.49, "z": 3.19999838 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Scav Checkpoint (Woods/Lighthouse)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 652.24, "y": -27.1200027, "z": 1.00499988 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "ZB-013 (Factory, Cellars)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 200.9755, "y": -153.086456, "z": -1.1484108 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Dorms SUV (Shoreline, North Fence SUV)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 181.08, "y": 213.25, "z": -0.71 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "ZB-1011 (Hideout/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 621.4368, "y": -127.700775, "z": -2.65 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Crossroads (Lotus/Interchange/Shoreline*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -335.120239, "y": -73.98008, "z": -3.97000742 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Trailer Park (Ragman/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -313.720276, "y": -233.2801, "z": -1.72000742 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "RUAF Roadblock (Woods, UN Roadblock)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -14.5001221, "y": -138.450043, "z": 1.92000723 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Smuggler's Boat (Lighthouse*/Shoreline/Woods*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -43.11017, "y": 119.40004, "z": -14.2250118 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "ZB-1012 (Hideout/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 459.427826, "y": -111.042969, "z": -2.31699228 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Tarcone Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -205.499237, "y": -109.994392, "z": 8.110943 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780d0532459777a5108b9a2", - }, - { - "Text": "Portable Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -251.320953, "y": -221.941071, "z": 3.85700083 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780d07a2459777de4559324", - }, - { - "Text": "Trailer Park Portable Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -194.560135, "y": -207.398911, "z": 2.34600019 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5913611c86f77479e0084092", - }, - { - "Text": "Factory Shortcut", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 356.052551, "y": -14.5693512, "z": 2.34000182 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - }, - { - "Text": "Unknown Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 370.014923, "y": -50.08902, "z": 2.15399933 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "593962ca86f774068014d9af", - }, - { - "Text": "Factory Shortcut", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 356.957367, "y": -8.079105, "z": 2.14515162 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - }, - { - "Text": "Dorm 114", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 233.549591, "y": 159.682587, "z": 0.889000237 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59387a4986f77401cc236e62", - }, - { - "Text": "Dorm 206", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 230.641281, "y": 138.671631, "z": 3.86939716 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938603e86f77435642354f4", - }, - { - "Text": "Dorm 105", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 227.877258, "y": 135.61264, "z": 0.8901995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "591382d986f774465a6413a7", - }, - { - "Text": "Dorm 110", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 231.0886, "y": 159.435349, "z": 0.910999358 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59136e1e86f774432f15d133", - }, - { - "Text": "Dorm 104", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 230.101257, "y": 134.913879, "z": 0.8860002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "591383f186f7744a4c5edcf3", - }, - { - "Text": "Dorm Guard Desk", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 225.517273, "y": 138.366241, "z": 0.8858002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59136a4486f774447a1ed172", - }, - { - "Text": "Dorm 204", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 173.379211, "y": 150.356216, "z": 3.83760285 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59148c8a86f774197930e983", - }, - { - "Text": "Dorm 108", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 177.473969, "y": 178.489075, "z": 0.8406372 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5914578086f774123569ffa4", - }, - { - "Text": "Dorm 314 Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 180.671432, "y": 183.722443, "z": 6.84058475 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf7f2459777de4559322", - }, - { - "Text": "Dorm 218", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 190.192383, "y": 175.3542, "z": 3.84178257 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf9e2459777df90dcb73", - }, - { - "Text": "Dorm 118", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 194.794083, "y": 174.546783, "z": 0.830601 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5672c92d4bdc2d180f8b4567", - }, - { - "Text": "Dorm 220", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 193.957886, "y": 174.821625, "z": 3.831203 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cfa52459777dfb276eb1", - }, - { - "Text": "Dorm 308", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 177.4756, "y": 178.488113, "z": 6.850606 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf722459777a5108b9a1", - }, - { - "Text": "Dorm 315", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 179.284683, "y": 174.810455, "z": 6.830814 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf692459777de4559321", - }, - { - "Text": "Dorm 214", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 178.105484, "y": 183.746643, "z": 3.83598375 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf942459777df90dcb72", - }, - { - "Text": "Dorm 203", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 176.041077, "y": 150.26828, "z": 3.83258247 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938504186f7740991483f30", - }, - { - "Text": "Dorm 103", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 175.734467, "y": 149.366577, "z": 0.820169449 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938994586f774523a425196", - }, - { - "Text": "Dorm 306", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 174.544632, "y": 157.45575, "z": 6.828404 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cda02459777b272ede61", - }, - { - "Text": "Dorm 303", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 176.039612, "y": 150.268463, "z": 6.82898426 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "593aa4be86f77457f56379f8", - }, - { - "Text": "Gas Station Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 415.416443, "y": 35.6602058, "z": 2.18918633 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5913877a86f774432f15d444", - }, - { - "Text": "Gas Station Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 415.779572, "y": 38.5554962, "z": 2.17909455 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780d0652459777df90dcb74", - }, - { - "Text": "USEC Stash", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 562.780945, "y": -58.9465332, "z": 2.216738 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da743f586f7744014504f72", - }, - { - "Text": "USEC Stash", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 568.747131, "y": -50.85814, "z": 2.193743 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da743f586f7744014504f72", - }, - { - "Text": "Orange Tanker Truck", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 101.818916, "y": -5.54527664, "z": 3.44780731 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5937ee6486f77408994ba448", - }, - { - "Text": "Military Checkpoint", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 577.6575, "y": 4.049543, "z": 0.8078748 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5913915886f774123603c392", - }, - { - "Text": "ZB-013", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 198.927917, "y": -146.172791, "z": -1.779768 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - }, - { - "Text": "Portable Bunkhouse", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 202.664337, "y": 11.72344, "z": 4.73085976 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938144586f77473c2087145", - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc deleted file mode 100644 index 74966341..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc +++ /dev/null @@ -1,215 +0,0 @@ -{ - "DisplayName": "Factory (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["factory4_day", "factory4_night"], - "CoordinateRotation": 90, - "Bounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "DefaultLevel": 0, - "Layers": { - "Tunnels": { - "Level": -1, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_-1.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": -100 }, - "Max": { "x": 77.6, "y": 67.2, "z": -1 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_0.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": -1 }, - "Max": { "x": 77.6, "y": 67.2, "z": 3 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_1.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": 3 }, - "Max": { "x": 77.6, "y": 67.2, "z": 6 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_2.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": 6 }, - "Max": { "x": 77.6, "y": 67.2, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Office Building", - "Position": { "x": 21, "y": 39, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Med Tent", - "Position": { "x": -17.5, "y": -28, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Silos", - "Position": { "x": 4.5, "y": 10.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Heli Crash", - "Position": { "x": 30, "y": -8.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Scav Bunker", - "Position": { "x": -20.5, "y": 23, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Blue Containers", - "Position": { "x": -18, "y": 50, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Glass Hall", - "Position": { "x": 69.3, "y": -20, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Boilers", - "Position": { "x": 58, "y": 6.3, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Forklifts", - "Position": { "x": 66, "y": -42, "z": 0 }, - "FontSize": 14, - }, - ], - "StaticMarkers": [ - { - "Text": "Camera Bunker Door (Mechanic)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -14.5749989, "y": 40.36, "z": -2.086 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Office Window (Woods/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 17.8332214, "y": 39.8851128, "z": 8.730333 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Cellars (Customs, ZB-1013)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 77.529, "y": -28.891, "z": -4.657 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Gate 3 (Woods, ZB-016)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 58.709, "y": 64.112, "z": 0.84 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Gate 0 (Customs, ZB-1011)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -63.7400055, "y": 55.902, "z": 1.749 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Med Tent Gate (Customs, ZB-1012)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -18.4857769, "y": -60.1718826, "z": 1.16133332 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Locked Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 29.2459984, "y": 36.52492, "z": 9.155067 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Pumping Station", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 43.1875839, "y": -14.1608534, "z": 1.01413012 }, - "Category": "LockedDoor", - "AssociatedItemId": "57a349b2245977762b199ec7", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Gate 0", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -53.754, "y": 58.93033, "z": 2.33300042 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Cellars", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 66.42518, "y": -29.8983536, "z": -1.53579187 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Pumping Station", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 40.9448547, "y": -6.261415, "z": 0.9631303 }, - "Category": "LockedDoor", - "AssociatedItemId": "593858c486f774253a24cb52", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Med Tent", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -20.3113289, "y": -49.138, "z": 1.27600038 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc deleted file mode 100644 index 61890086..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc +++ /dev/null @@ -1,207 +0,0 @@ -{ - "DisplayName": "Ground Zero (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["Sandbox", "Sandbox_high"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "DefaultLevel": 0, - "Layers": { - "Garage": { - "Level": -1, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_-1.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - // garage - "Min": { "x": 43, "y": -100, "z": -100 }, - "Max": { "x": 117, "y": 190, "z": 21 }, - }, - { - // underpass - "Min": { "x": 117, "y": 49, "z": -100 }, - "Max": { "x": 143, "y": 80, "z": 21 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_0.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - "Min": { "x": -99, "y": -124, "z": -100 }, - "Max": { "x": 249, "y": 364, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_1.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - // rest of 2nd floor - "Min": { "x": -99, "y": -124, "z": 28 }, - "Max": { "x": 249, "y": 364, "z": 32.3 }, - }, - { - // m showroom - "Min": { "x": 91, "y": 216, "z": 26 }, - "Max": { "x": 98, "y": 228, "z": 31 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_2.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - "Min": { "x": -99, "y": -124, "z": 32.3 }, - "Max": { "x": 249, "y": 364, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "TerraGroup", - "Position": { "x": -50, "y": 0, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Skyside", - "Position": { "x": 150, "y": 1, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Fusion", - "Position": { "x": 141, "y": 142, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Empire", - "Position": { "x": 14, "y": 201, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Capital Insight", - "Position": { "x": 115, "y": 285, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Nakatani", - "Position": { "x": 2, "y": 324, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Elemental Global", - "Position": { "x": 80, "y": -118, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Oasis", - "Position": { "x": 115, "y": 104, "z": 22 }, - "FontSize": 16, - }, - { - "Text": "ASAP Winery", - "Position": { "x": 115, "y": 30, "z": 22 }, - "FontSize": 12, - }, - { - "Text": "Tarbank", - "Position": { "x": 43, "y": 150, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "GAGRIN Hotel", - "Position": { "x": 58, "y": 234, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "M Showroom", - "Position": { "x": 97, "y": 223, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Science Offices", - "Position": { "x": -13, "y": 48, "z": 29 }, - "FontSize": 12, - }, - ], - "StaticMarkers": [ - { - "Text": "Scav Checkpoint (Streets, Expo CP)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 26.1550121, "y": -82.52659, "z": 24.5091858 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Police Cordon SUV (Woods/Interchange/Streets)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -19.5134068, "y": 114.942139, "z": 23.7110023 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Emercom Checkpoint (Therapist)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 151.625, "y": -97.45658, "z": 24.662056 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Nakatani Basement Stairs (Coyote/Streets/Labs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -16.1249924, "y": 335.063416, "z": 14.7620564 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Mira Ave (Streets, Klimov Ave)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 218.225, "y": -38.5065842, "z": 17.9920559 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Underground Parking Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 107.056, "y": 50.6362534, "z": 13.499 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "658199972dc4e60f6d556a2f", - }, - { - "Text": "TerraGroup Science Offices", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -17.975647, "y": 58.5532341, "z": 30.7062054 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "658199aa38c79576a2569e13", - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc deleted file mode 100644 index a88eb483..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc +++ /dev/null @@ -1,627 +0,0 @@ -{ - "DisplayName": "Interchange (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["Interchange"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "DefaultLevel": 0, - "Layers": { - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_0.png", - "ImageBounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "GameBounds": [ - { - "Min": { "x": -364, "y": -443, "z": -100 }, - "Max": { "x": 534, "y": 452, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_1.png", - "ImageBounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "GameBounds": [ - { - // mall - "Min": { "x": -222, "y": -327, "z": 25 }, - "Max": { "x": 120, "y": 218, "z": 34 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_2.png", - "ImageBounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "GameBounds": [ - { - // mall - "Min": { "x": -222, "y": -443, "z": 34 }, - "Max": { "x": 120, "y": 218, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Power Station", - "Position": { "x": -186.4, "y": -318.7, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Go Kart", - "Position": { "x": 155, "y": -253, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Four Camp", - "Position": { "x": 158, "y": -78.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Cargo Containers", - "Position": { "x": 68.2, "y": 312.9, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Wall Break", - "Position": { "x": -260.2, "y": 123.8, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Ramps", - "Position": { "x": -175.5, "y": 145.1, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "OLI Tower", - "Position": { "x": 202.3, "y": 219.4, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "IDEA Tower", - "Position": { "x": 46.5, "y": -358.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Scav Camp", - "Position": { "x": 263.2, "y": -11.1, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Highway Construction", - "Position": { "x": 373.5, "y": -391.2, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Garage A", - "Position": { "x": 33, "y": -222, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Garage B", - "Position": { "x": 47, "y": -112, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Garage C", - "Position": { "x": 0, "y": 47, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Garage D", - "Position": { "x": 28, "y": 138, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "IDEA", - "Position": { "x": -34, "y": -235, "z": 26 }, - "FontSize": 14, - }, - { - "Text": "Goshan", - "Position": { "x": -115, "y": -45, "z": 26 }, - "FontSize": 14, - }, - { - "Text": "OLI", - "Position": { "x": -28, "y": 140, "z": 26 }, - "FontSize": 14, - }, - { - "Text": "Nortex", - "Position": { "x": 87, "y": -165, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "TRend", - "Position": { "x": 60, "y": -152, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Mode7", - "Position": { "x": 69.5, "y": -134, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "TTS", - "Position": { "x": 19, "y": -129, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Book Store", - "Position": { "x": -38, "y": -129, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Dino Clothes", - "Position": { "x": 91, "y": -119, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "EMERCOM", - "Position": { "x": 18, "y": -103, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Kostin", - "Position": { "x": -28, "y": -103, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Bizarro", - "Position": { "x": -65, "y": -103, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Spiel", - "Position": { "x": 92, "y": -87, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Voyage", - "Position": { "x": -18, "y": -87, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Viking", - "Position": { "x": 57, "y": -66, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Mantis", - "Position": { "x": 13, "y": -66, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "German", - "Position": { "x": -18, "y": -72, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "The National", - "Position": { "x": 57, "y": -32, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Brutal", - "Position": { "x": 13, "y": -32, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Kiba", - "Position": { "x": -18, "y": -25, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Pretty Lights", - "Position": { "x": -34, "y": -20, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Telespot", - "Position": { "x": 92, "y": -18, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Revis", - "Position": { "x": 62, "y": -12, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "ADIK", - "Position": { "x": 19, "y": -6, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Generic", - "Position": { "x": -28, "y": 0.5, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Top Brand", - "Position": { "x": 92, "y": 15, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Sports", - "Position": { "x": 61, "y": 15, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Yushka", - "Position": { "x": 70, "y": 32, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Rasmussen", - "Position": { "x": 19.5, "y": 26, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Avokado", - "Position": { "x": -37, "y": 26, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Boots 4 Life", - "Position": { "x": 91, "y": 55, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Texho", - "Position": { "x": 61, "y": 50, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Dom", - "Position": { "x": 6, "y": 49, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Father & Sons", - "Position": { "x": 38, "y": -170, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Tarkovstar", - "Position": { "x": 69, "y": -150, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Eastland", - "Position": { "x": 26, "y": -149, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Arena", - "Position": { "x": 71, "y": -130, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "ТАРЗДРАВ", - "Position": { "x": 54, "y": -128, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "МЕБЕЛЬ МК", - "Position": { "x": 20, "y": -128, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Intourist", - "Position": { "x": 69, "y": -116, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Burger Spot", - "Position": { "x": -27, "y": -103, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "FCK", - "Position": { "x": 70, "y": -94, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "McDaniels", - "Position": { "x": 70, "y": -87, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Tarducks", - "Position": { "x": 64, "y": -69, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Coffee Joy", - "Position": { "x": 43, "y": -69, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Jacob & Jacob", - "Position": { "x": 15, "y": -74, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "ПУШКИН", - "Position": { "x": -34, "y": -79, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Sushi Huyushi", - "Position": { "x": 64, "y": -34, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Underway", - "Position": { "x": -17, "y": -32, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Burger House", - "Position": { "x": 67, "y": -23.5, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Philly Cute", - "Position": { "x": -34, "y": -24, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Shiccos", - "Position": { "x": 67, "y": -16, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "УЗЕЙ ИСТОРИИ", - "Position": { "x": 17, "y": 0, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Papillon", - "Position": { "x": 92, "y": 17, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "ЗАКРЫТО НА РЕМОНТ", - "Position": { "x": 58, "y": 13, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "НА-СВЯЗИ", - "Position": { "x": 70, "y": 27, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "СКОРО ОТКРЫТИЕ", - "Position": { "x": 54, "y": 24, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Figaro", - "Position": { "x": 19, "y": 26, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "АПТЕКА", - "Position": { "x": 71, "y": 47, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "SARA", - "Position": { "x": 53, "y": 47, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Urban Clothes", - "Position": { "x": 26, "y": 46, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "TECHLIGHT", - "Position": { "x": 91, "y": 54, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Fashion Store", - "Position": { "x": 39, "y": 67, "z": 35 }, - "FontSize": 10, - }, - ], - "StaticMarkers": [ - { - "Text": "Main Power Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -201.108, "y": -357.8291, "z": 23.1857 }, - "Category": "Switch", - }, - { - "Text": "Saferoom Urinal Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -51.547, "y": -125.440712, "z": 36.86 }, - "Category": "Switch", - }, - { - "Text": "2nd Floor Alarm Console", - "ImagePath": "Markers/lever.png", - "Position": { "x": -46.555, "y": -55.202, "z": 37.347 }, - "Category": "Switch", - }, - { - "Text": "1st Floor Alarm Console", - "ImagePath": "Markers/lever.png", - "Position": { "x": -67.1342545, "y": 53.7422676, "z": 27.9506 }, - "Category": "Switch", - }, - { - "Text": "Inside Saferoom Exfil Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -50.6210022, "y": 45.617, "z": 22.632 }, - "Category": "Switch", - }, - { - "Text": "Object 14 Container Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -47.698, "y": 42.6198, "z": 22.891 }, - "Category": "Switch", - }, - { - "Text": "Emercom Checkpoint (Lotus/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -317.21, "y": 267.94, "z": 21.94955 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railway (Painter/Customs/Woods/Streets)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 474.67, "y": -436.09, "z": 20.92 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Power Station SUV (Painter/Streets/Woods/GZ)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -251.93, "y": -366.99, "z": 21.7130013 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Scav Camp (Ragman/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 284.442, "y": -27.493, "z": 21.94955 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Saferoom (Flea Market)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -47.73, "y": 44.055, "z": 22.97 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Power Substation Utility Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -223.115845, "y": -271.3501, "z": 22.55412 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d49886f77455f9731921", - }, - { - "Text": "ULTRA Medical Storage", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 67.55801, "y": 40.891, "z": 37.60174 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5e42c71586f7747f245e1343", - }, - { - "Text": "Kiba Arms Inner Grate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -9.887001, "y": -33.76517, "z": 28.241 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5addaffe86f77470b455f900", - }, - { - "Text": "Kiba Arms Outer Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -9.444001, "y": -33.709, "z": 28.241 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d7d286f77450166e0a89", - }, - { - "Text": "Object #11SR Saferoom", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -51.9328041, "y": 45.8337746, "z": 22.35359 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5e42c81886f7742a01529f57", - }, - { - "Text": "Object #21WS", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 140.195663, "y": 263.315277, "z": 25.2079964 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5e42c83786f7742a021fdf3c", - }, - { - "Text": "NecrusPharm Pharmacy", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 68.53804, "y": -255.424225, "z": 22.4947357 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d64486f774079b080af8", - }, - { - "Text": "Emercom Medical Unit", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 24.136982, "y": -112.8551, "z": 28.4790325 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5db3786f7743568421cce", - }, - { - "Text": "Emercom Medical Unit", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 34.14116, "y": -108.287651, "z": 28.4790325 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5db3786f7743568421cce", - }, - { - "Text": "Emercom Medical Unit", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 6.732233, "y": -107.304314, "z": 28.4790344 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5db3786f7743568421cce", - }, - { - "Text": "OLI Logistics Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 83.1990051, "y": 115.673004, "z": 28.1199989 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5cfbd86f7742c825d6104", - }, - { - "Text": "OLI Outlet Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -102.823967, "y": 80.48102, "z": 28.12 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d20586f77449be26d877", - }, - { - "Text": "OLI Admin Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 85.18402, "y": 104.638214, "z": 28.1199989 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5ccd186f774446d5706e9", - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc deleted file mode 100644 index b8c48250..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc +++ /dev/null @@ -1,283 +0,0 @@ -{ - "DisplayName": "Labs (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["laboratory"], - "CoordinateRotation": 270, - "Bounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "DefaultLevel": 0, - "Layers": { - "Technical": { - "Level": -1, - "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_-1.png", - "ImageBounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "GameBounds": [ - { - "Min": { "x": -292, "y": -441, "z": -100 }, - "Max": { "x": -96, "y": -223, "z": -0.9 }, - }, - ], - }, - "First Level": { - "Level": 0, - "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_0.png", - "ImageBounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "GameBounds": [ - { - "Min": { "x": -292, "y": -441, "z": -0.9 }, - "Max": { "x": -96, "y": -223, "z": 3 }, - }, - ], - }, - "Second Level": { - "Level": 1, - "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_1.png", - "ImageBounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "GameBounds": [ - { - "Min": { "x": -271, "y": -422, "z": 3 }, - "Max": { "x": -101, "y": -270, "z": 100 }, - }, - ], - }, - }, - "Labels": [], - "StaticMarkers": [ - { - "Text": "Cargo Elevator (Coyote/Streets/Ground Zero)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -112.152, "y": -408.64, "z": 5.376 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Main Elevator (Streets, Stylobate Elevator)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -282.304016, "y": -334.896, "z": -3.631999 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Ventilation Shaft (Streets, Vent Shaft)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -144.866, "y": -399.385, "z": -2.424 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewage Conduit (Streets, Sewer River)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -123.711, "y": -255.3735, "z": -3.6609993 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Hangar Gate (Streets, Catacombs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -170.66, "y": -240.77, "z": 2.08 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Medical Block Elevator Power", - "ImagePath": "Markers/lever.png", - "Position": { "x": -124.758, "y": -313.806, "z": -2.31599617 }, - "Category": "Switch", - }, - // { // main elevator - // "Text": "call_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -281.022, "y": -335.477, "z": -2.83799934 }, - // "Category": "Switch" - // }, - // { // medical block call button - // "Text": "call_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -114.112, "y": -343.2, "z": -2.84599972 }, - // "Category": "Switch" - // }, - // { // cargo elevator - // "Text": "call_button (1)", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -114.037, "y": -406.427979, "z": 5.31399727 }, - // "Category": "Switch" - // }, - // { // cargo elevator - // "Text": "floor_button (1)", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -112.378006, "y": -406.806, "z": 5.353998 }, - // "Category": "Switch" - // }, - { - "Text": "Main Elevator Power Button", - "ImagePath": "Markers/lever.png", - "Position": { "x": -271.439, "y": -366.10498, "z": -2.380001 }, - "Category": "Switch", - }, - // { // main elevator - // "Text": "floor_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -282.361, "y": -335.86, "z": -2.91199875 }, - // "Category": "Switch" - // }, - { - "Text": "Open Parking Gate", - "ImagePath": "Markers/lever.png", - "Position": { "x": -243.443, "y": -382.513, "z": 5.076 }, - "Category": "Switch", - }, - { - "Text": "Water Level Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -136.76, "y": -254.510513, "z": -2.825999 }, - "Category": "Switch", - }, - // { // not sure, located in sterile lab? - // "Text": "Power", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -121.007996, "y": -353.548, "z": -2.83698225 }, - // "Category": "Switch" - // }, - // { // medical block elevator - // "Text": "floor_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -112.802, "y": -342.762, "z": -2.84599972 }, - // "Category": "Switch" - // }, - { - "Text": "Disable Parking Gate Alarm", - "ImagePath": "Markers/lever.png", - "Position": { "x": -220.756, "y": -381.263, "z": 5.249 }, - "Category": "Switch", - }, - { - "Text": "TerraGroup Manager's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -165.246277, "y": -349.197, "z": 5.131374 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2a1e86f77431ea0ea84c", - }, - { - "Text": "TerraGroup Manager's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -165.242874, "y": -338.086, "z": 5.135374 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2a1e86f77431ea0ea84c", - }, - { - "Text": "Weapon Testing Area", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -181.966461, "y": -318.226044, "z": 1.37873685 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2d1f86f77431e9280bee", - }, - { - "Text": "Weapon Testing Area", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -179.862, "y": -310.3296, "z": 1.37899876 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2d1f86f77431e9280bee", - }, - { - "Text": "Infirmary (Blue)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -123.229095, "y": -406.524384, "z": 1.03631592 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0c5f86f7744bb2683cf0", - }, - { - "Text": "Sterile Lab (Green)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -135.89798, "y": -346.9675, "z": 5.185806 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0dc586f7744baf2e7b79", - }, - { - "Text": "Sterile Lab (Green)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -138.6131, "y": -346.966125, "z": 5.25222349 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0dc586f7744baf2e7b79", - }, - { - "Text": "Card with a Blue Marking", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -130.268463, "y": -339.944275, "z": 5.15560675 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5efde6b4f5448336730dbd61", - }, - { - "Text": "Security #2 (Yellow)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -212.695, "y": -376.538, "z": 5.145301 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0d6d86f7744bb2683e1f", - }, - { - "Text": "Test Room (Black)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -132.893, "y": -348.72, "z": 1.43501759 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0f4986f7744bb01837fa", - }, - { - "Text": "Test Room (Black)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -128.794, "y": -349.91507, "z": 1.43701744 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0f4986f7744bb01837fa", - }, - { - "Text": "Security Office (Violet)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -261.993, "y": -317.240021, "z": 5.147805 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e495a86f7743109743dfb", - }, - { - "Text": "Security Office (Red)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -257.222015, "y": -322.925018, "z": 5.24803066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0efb86f7744baf2e7b7b", - }, - { - "Text": "Arsenal Storage", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -250.839066, "y": -326.758667, "z": 5.097125 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1f79a086f7746ed066fb8f", - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc deleted file mode 100644 index 61e9e94f..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc +++ /dev/null @@ -1,320 +0,0 @@ -{ - "DisplayName": "Lighthouse (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["Lighthouse"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -545, "y": -998 }, - "Max": { "x": 512, "y": 721 }, - }, - "DefaultLevel": 0, - "Layers": { - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Lighthouse_TarkovData/Layers/lighthouse_layer_0.png", - "ImageBounds": { - "Min": { "x": -545, "y": -998 }, - "Max": { "x": 512, "y": 721 }, - }, - "GameBounds": [ - { - "Min": { "x": -545, "y": -998, "z": -100 }, - "Max": { "x": 512, "y": 721, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Train Yard", - "Position": { "x": -30, "y": -882, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Drug Lab", - "Position": { "x": -120, "y": -841, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Water Treatment", - "Position": { "x": -65, "y": -600, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Plant 1", - "Position": { "x": 40, "y": -618, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Plant 2", - "Position": { "x": -98, "y": -742, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Plant 3", - "Position": { "x": -189, "y": -665, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Pipes", - "Position": { "x": -182, "y": -552, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Gunner Nest", - "Position": { "x": 18, "y": -453, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Island", - "Position": { "x": -177, "y": -356, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cabins", - "Position": { "x": -278, "y": -323, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cottages", - "Position": { "x": -162, "y": -225, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Convenience", - "Position": { "x": -55, "y": -288, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Red Brick", - "Position": { "x": -75, "y": -284, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Hillside", - "Position": { "x": -147, "y": -247, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Boathouses", - "Position": { "x": 125, "y": -153, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Dead Tree", - "Position": { "x": 62, "y": -60, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Construction", - "Position": { "x": 0, "y": -188, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Pikes Peak Resort", - "Position": { "x": -107, "y": -53, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Grand Chalet", - "Position": { "x": -133, "y": 100, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Tennis Court", - "Position": { "x": -70, "y": 129, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Lightkeeper Island", - "Position": { "x": 382, "y": 496, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crash Site", - "Position": { "x": -125, "y": 296, "z": 0 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "Side Tunnel (Shoreline, Tunnel)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -68.3, "y": 318.11, "z": 6.83 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Scav Hideout at the Grotto (Artem)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 180.66, "y": -485.94, "z": 1.18 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Road to Military Base SUV (Reserve, CP Fence*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -328.951263, "y": -784.3581, "z": 16.73 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Mountain Pass (Shoreline, Path to Lighthouse*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -172.35, "y": -6.39, "z": 41.89 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Path to Shoreline", - "ImagePath": "Markers/exit.png", - "Position": { "x": -364.4, "y": -121.4, "z": 28.758 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Northern Checkpoint (Woods/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 111.943, "y": -991.981, "z": 11.86 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Southern Road (Shoreline, Ruined Road)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -295.8, "y": 420.6, "z": 11.86 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Armored Train (all maps besides GZ*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 6.27001953, "y": -873.78, "z": 14.1133 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - // { - // "Text": "OuterSwitcher", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 445.3035, "y": 457.5599, "z": 33.391 }, - // "Category": "Switch" - // }, - // { - // "Text": "InnerSwitcher", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 444.6317, "y": 457.6145, "z": 33.391 }, - // "Category": "Switch" - // }, - // { - // "Text": "railing_door 1", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 445.426117, "y": 458.187561, "z": 32.1270027 }, - // "Category": "Switch" - // }, - { - "Text": "Convenience Store Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -58.5892944, "y": -292.9962, "z": 6.55390024 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61a64428a8c6aa1b795f0ba1", - }, - { - "Text": "Shared Bedroom", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 328.6411, "y": 487.244019, "z": 6.041643 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987dfc402c7f69bf010923", - }, - { - "Text": "Conference Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 333.8, "y": 519.1168, "z": 6.0705 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987cb98081af308d7558c8", - }, - { - "Text": "Merin Trunk", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 91.1099854, "y": -130.918991, "z": 8.382999 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61aa5b518f5e7a39b41416e2", - }, - { - "Text": "Radar Station Commandant Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 355.204, "y": 549.386963, "z": 16.545002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987c658081af308d7558c6", - }, - { - "Text": "Hillside House", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -147.043427, "y": -243.326172, "z": 12.66918 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61a6444b8c141d68246e2d2f", - }, - { - "Text": "Operating Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 32.899, "y": -636.186, "z": 5.93999767 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987da96188c076bc0d8c51", - }, - { - "Text": "Water Treatment Plant Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -120.901962, "y": -736.4641, "z": 5.938982 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987e26a77ec735f90a2995", - }, - { - "Text": "Rogue USEC Barrack", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -176.519043, "y": -654.164063, "z": 5.939995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62a9cb937377a65d7b070cef", - }, - { - "Text": "Police Car", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 83.79875, "y": -553.2562, "z": 6.61099958 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61aa5aed32a4743c3453d319", - }, - { - "Text": "Rogue USEC Workshop", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -168.6745, "y": -497.287079, "z": 5.798998 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61aa81fcb225ac1ead7957c3", - }, - { - "Text": "Rogue USEC Stash", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 47.3759, "y": -553.3956, "z": 5.67344 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61a64492ba05ef10d62adcc1", - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc deleted file mode 100644 index 87f17ccb..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc +++ /dev/null @@ -1,556 +0,0 @@ -{ - "DisplayName": "Reserve (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["RezervBase"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -303.5, "y": -275 }, - "Max": { "x": 292, "y": 271.5 }, - }, - "DefaultLevel": 0, - "Layers": { - "Bunkers": { - "Level": -1, - "ImagePath": "Maps/Reserve_TarkovData/Layers/reserve_layer_-1.png", - "ImageBounds": { - "Min": { "x": -303.5, "y": -275 }, - "Max": { "x": 292, "y": 271.5 }, - }, - "GameBounds": [ - { - "Min": { "x": -303.5, "y": -275, "z": -100 }, - "Max": { "x": 292, "y": 271.5, "z": -8 }, - }, - ], - }, - "Ground Level": { - "Level": 0, - "ImagePath": "Maps/Reserve_TarkovData/Layers/reserve_layer_0.png", - "ImageBounds": { - "Min": { "x": -303.5, "y": -275 }, - "Max": { "x": 292, "y": 271.5 }, - }, - "GameBounds": [ - { - "Min": { "x": -303.5, "y": -275, "z": -8 }, - "Max": { "x": 292, "y": 271.5, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "K Buildings", - "Position": { "x": 31, "y": -104, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "White Queen", - "Position": { "x": -25, "y": 180, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "White Pawn", - "Position": { "x": -104, "y": 93, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Black Bishop", - "Position": { "x": -140, "y": -14.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White Bishop", - "Position": { "x": -67, "y": -30, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White King", - "Position": { "x": -49.5, "y": 15.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Black Knight", - "Position": { "x": 14.5, "y": -10.8, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White Knight", - "Position": { "x": 82.2, "y": -30.2, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White Rook", - "Position": { "x": 149, "y": -124, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "Train Station", - "Position": { "x": 161, "y": -149, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "Black Pawn", - "Position": { "x": -165, "y": 57, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Barracks", - "Position": { "x": 165, "y": -215, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "E1 Bunkers", - "Position": { "x": -220, "y": -13, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "E2 Bunkers", - "Position": { "x": 173, "y": -3, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "д - Warehouse Bunkers", - "Position": { "x": 82, "y": -170, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "Garage", - "Position": { "x": 98.5, "y": 29.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Mechanic", - "Position": { "x": 55.5, "y": 60.6, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Gas Station", - "Position": { "x": 29.7, "y": 29.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Shipping Yard", - "Position": { "x": -31, "y": -150, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "K1", - "Position": { "x": 8, "y": -76, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K2", - "Position": { "x": 65.5, "y": -92, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K3", - "Position": { "x": 2, "y": -96.5, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K4", - "Position": { "x": 60, "y": -112, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K5", - "Position": { "x": -4, "y": -118, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K6", - "Position": { "x": 54, "y": -133, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "Dome", - "Position": { "x": -8.5, "y": 175, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Tarmac", - "Position": { "x": -120, "y": 37, "z": 0 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "Scav Lands (Customs, Military Base CP)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -124.67, "y": -144.92, "z": -3.28 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Hole in the Wall (Customs, Dorms Car*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -261.41, "y": 47.95, "z": -6.033997 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Checkpoint Fence (Lighthouse, Northeast Mountains*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 66.76, "y": 138.26, "z": -4.43 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "D-2 (Peacekeeper/Shoreline*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -121.479065, "y": 172.24913, "z": -17.0010071 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Bunker Hermetic Door (Scorpion/Woods*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 62.3918457, "y": -194.269928, "z": -5.257 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Cliff Descent (Shoreline, Climber's Trail)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -12.8, "y": 206.78, "z": 20.93 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewer Manhole (Sally/Streets)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 40.18, "y": 76.45, "z": -5.12 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Armored Train (all maps besides GZ*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 144.986, "y": -147.352, "z": -3.92 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Bunker Hermetic Door Power", - "ImagePath": "Markers/lever.png", - "Position": { "x": -60.7597275, "y": 78.22821, "z": -5.55217171 }, - "Category": "Switch", - }, - { - "Text": "D-2 Power Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -117.184174, "y": 22.6676826, "z": -12.954 }, - "Category": "Switch", - }, - // { // near bunker hermetic door - // "Text": "Reset", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 65.71171, "y": -190.604248, "z": -6.683 }, - // "Category": "Switch" - // }, - { - "Text": "D-2 Open Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -117.449867, "y": 168.546936, "z": -16.9842987 }, - "Category": "Switch", - }, - { - "Text": "RB-AO", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 194.756973, "y": -203.553268, "z": -5.801999 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c66d86f774405611c7d6", - }, - { - "Text": "RB-VO Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 189.6508, "y": -224.790009, "z": -5.8030014 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c62a86f7744036212b3f", - }, - { - "Text": "RB-KPRL", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -40.4498749, "y": 173.891434, "z": 19.66215 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e0e0e86f774321140eb56", - }, - { - "Text": "RB-KPRL", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -44.2896843, "y": 171.655853, "z": 19.6481476 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e0e0e86f774321140eb56", - }, - { - "Text": "RB-ST", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 100.7764, "y": 43.67282, "z": -6.714003 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d9f1fa686f774726974a992", - }, - { - "Text": "RB-SMP", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -78.7131653, "y": -29.4600983, "z": -3.78035355 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d947d3886f774447b415893", - }, - { - "Text": "RB-KSM", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -60.01116, "y": -34.5081, "z": -3.78035355 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d947d4e86f774447b415895", - }, - { - "Text": "RB-PSP1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 71.1095, "y": -146.997528, "z": -11.128006 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cb3886f77440556dbf09", - }, - { - "Text": "RB-PSP2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 83.5344238, "y": -100.622009, "z": -11.1000061 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d95d6fa86f77424484aa5e9", - }, - { - "Text": "RB-PSV2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 42.9962158, "y": -114.069916, "z": -11.1259995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d95d6be86f77424444eb3a7", - }, - { - "Text": "RB-PSV1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 50.81842, "y": -91.86203, "z": -11.1000061 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cb5686f77440545d1286", - }, - { - "Text": "RB-PSP1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 80.91522, "y": -124.236908, "z": -11.128006 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cb3886f77440556dbf09", - }, - { - "Text": "RB-PSV2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 38.3938, "y": -138.232147, "z": -11.128006 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d95d6be86f77424444eb3a7", - }, - { - "Text": "RB-AK", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -134.622513, "y": -12.8279257, "z": -2.13919544 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c78786f774403a401e3e", - }, - { - "Text": "RB-AM", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -133.289352, "y": -16.0929947, "z": -5.13899755 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c88d86f77440556dbf07", - }, - { - "Text": "RB-TB", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -162.7683, "y": 65.7317047, "z": -8.171001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c6fc86f774403a401e3c", - }, - { - "Text": "RB-ORB2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -123.018578, "y": 98.53613, "z": -2.36699772 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80ccdd86f77474f7575e02", - }, - { - "Text": "RB-OB", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -167.807968, "y": 34.4820557, "z": 0.525999069 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c6c586f77440351beef1", - }, - { - "Text": "RB-ORB3", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -170.236115, "y": 33.9814758, "z": -2.36400938 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cd1a86f77402aa362f42", - }, - { - "Text": "RB-ORB1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -122.855316, "y": 97.5226746, "z": 3.43500519 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80ccac86f77470841ff452", - }, - { - "Text": "RB-BK Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -157.878387, "y": 72.86379, "z": -8.188297 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c60f86f77440373c4ece", - }, - { - "Text": "RB-RH", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -51.4290428, "y": 19.6974564, "z": 0.3399992 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da5cdcd86f774529238fb9b", - }, - { - "Text": "RB-OP", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -68.47772, "y": 22.4145622, "z": -9.729001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c8f586f77440373c4ed0", - }, - { - "Text": "RB-GN", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -62.8870544, "y": 31.4578876, "z": -9.723853 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e3ecc86f774414c78d05e", - }, - { - "Text": "RB-KORL", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -2.507956, "y": 174.912, "z": 23.420002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e0db586f7744450412a42", - }, - { - "Text": "RB-RS", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -0.7069602, "y": 182.247, "z": 23.42 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da46e3886f774653b7a83fe", - }, - { - "Text": "RB-RLSA", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -10.9659786, "y": 180.645, "z": 23.420002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ede7b0c6d23e5473e6e8c66", - }, - { - // seems to be straight on MP22 but the floor below - "Text": "RB-MP13", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 87.58351, "y": -37.0245056, "z": -5.82550049 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cbd886f77470855c26c2", - }, - { - "Text": "RB-MP21", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 10.9685087, "y": -7.38929558, "z": -2.99313354 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80ca9086f774403a401e40", - }, - { - "Text": "RB-MP11", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 8.245274, "y": -17.522274, "z": -5.851448 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c95986f77440351beef3", - }, - { - "Text": "RB-MP12", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 8.266094, "y": -17.478508, "z": -3.00213623 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c93086f7744036212b41", - }, - { - "Text": "RB-MP22", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 87.5893555, "y": -37.00447, "z": -2.98300171 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cab086f77440535be201", - }, - { - "Text": "RB-PKPM Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -120.251823, "y": 27.7044983, "z": -13.483 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ede7a8229445733cb4c18e2", - }, - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc deleted file mode 100644 index 92c858e4..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc +++ /dev/null @@ -1,548 +0,0 @@ -{ - "DisplayName": "Shoreline (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["Shoreline"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "DefaultLevel": 0, - "Layers": { - "Underground": { - "Level": -1, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_-1.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - // west wing - "Min": { "x": -237, "y": -104, "z": -100 }, - "Max": { "x": -137, "y": -68, "z": -5 }, - }, - { - // admin - "Min": { "x": -268, "y": -163, "z": -100 }, - "Max": { "x": -234, "y": -134, "z": -5 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_0.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - "Min": { "x": -1060, "y": -415, "z": -100 }, - "Max": { "x": 508, "y": 622, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_1.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - "Min": { "x": -375, "y": -178, "z": -1 }, - "Max": { "x": -128, "y": -55, "z": 2 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_2.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - "Min": { "x": -375, "y": -178, "z": 2 }, - "Max": { "x": -128, "y": -55, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Resort", - "Position": { "x": -252, "y": -71.2, "z": -3 }, - "FontSize": 16, - }, - { - "Text": "Power Station", - "Position": { "x": -215.8, "y": 178.4, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Gas Station", - "Position": { "x": -189.3, "y": 420, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Weather Station", - "Position": { "x": -496, "y": 257, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Radio Tower", - "Position": { "x": -708.9, "y": 93.9, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Swamp", - "Position": { "x": 326, "y": -118.5, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Village", - "Position": { "x": 418.4, "y": 118, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cabins", - "Position": { "x": 288, "y": 144, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cottages", - "Position": { "x": 128, "y": 93, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Tank Bridge", - "Position": { "x": -355, "y": 188, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Pier", - "Position": { "x": -338.6, "y": 525, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Scav Island", - "Position": { "x": 216, "y": 424, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Bus Stop", - "Position": { "x": -96, "y": -6, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Construction", - "Position": { "x": 52, "y": 134, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Bunker", - "Position": { "x": -153, "y": -290, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crane", - "Position": { "x": -625, "y": 484, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Scav Farm", - "Position": { "x": -622, "y": -202, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "West Wing", - "Position": { "x": -171, "y": -83, "z": -3 }, - "FontSize": 16, - }, - { - "Text": "East Wing", - "Position": { "x": -329, "y": -83, "z": -3 }, - "FontSize": 16, - }, - { - "Text": "Admin", - "Position": { "x": -252, "y": -146, "z": -3 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "Ruined Road (Lighthouse, Southern Road)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 368.559326, "y": 334.897644, "z": -61.12998 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Old Bunker (Peacekeeper)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -388.99, "y": -383.73, "z": -2.66 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Smuggler's Path (Customs/Reserve*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -730.79, "y": -255.47, "z": -26.0 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "North Fence SUV (Customs, Dorms SUV)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -542.9488, "y": -381.020721, "z": -16.9900017 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Road to Customs (Customs, Sniper Roadblock*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -861.65, "y": -0.36, "z": -41.7699776 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railway Bridge (Ref/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -1026.47, "y": 299.85, "z": -60.79 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Tunnel (Lighthouse, Side Tunnel)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 376.36, "y": 319.25, "z": -55.9399757 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Path to Lighthouse", - "ImagePath": "Markers/exit.png", - "Position": { "x": 448.9, "y": -254.6, "z": -44.7 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Pier Boat (Lighthouse*/Customs/Woods*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -336.8407, "y": 568.4276, "z": -66.11997 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Climber's Trail (Reserve, Cliff Descent)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -204.5, "y": -359.71, "z": -10.74 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "HEP Station Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -220.38063, "y": 185.880585, "z": -33.858 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e15b686f774445103b190", - }, - { - "Text": "HEP Station Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -220.703171, "y": 193.687332, "z": -33.8470345 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e15b686f774445103b190", - }, - { - "Text": "SMW Car", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 157.352051, "y": 133.891, "z": -47.3859329 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eb38b86f774153b320eb0", - }, - { - "Text": "Cottage Back Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 102.532318, "y": 102.731339, "z": -47.2590027 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eb6ac86f7743124037a28", - }, - { - "Text": "West Wing Room 203", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -229.608261, "y": -92.90662, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a144dfd86f77445cb5a0982", - }, - { - "Text": "West Wing Room 216", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -179.379257, "y": -80.91263, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee30786f774023b6ee08f", - }, - { - "Text": "West Wing Room 306", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -216.905258, "y": -92.90662, "z": 3.03088379 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13f46386f7741dd7384b04", - }, - { - "Text": "West Wing Room 220", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -166.686264, "y": -80.91263, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee34586f774023b6ee092", - }, - { - "Text": "East Wing Room 206", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -285.857239, "y": -92.88861, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee4b586f7743698200d22", - }, - { - "Text": "East Wing Room 205", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -281.692261, "y": -92.88861, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a144bdb86f7741d374bbde0", - }, - { - "Text": "East Wing Room 313", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -313.835754, "y": -84.47537, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eecf686f7740350630097", - }, - { - "Text": "Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -142.583267, "y": -79.9176, "z": 3.05788422 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea79b86f7741d4a35298e", - }, - { - "Text": "West Wing Room 218", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -173.983749, "y": -84.50137, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13eebd86f7746fd639aa93", - }, - { - "Text": "East Wing Room 328", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -357.303284, "y": -79.9165955, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eee1486f77402aa773226", - }, - { - "Text": "East Wing Room 226", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -351.9118, "y": -84.47537, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13f35286f77413ef1436b0", - }, - { - "Text": "East Wing Office 107", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -333.767029, "y": -79.95798, "z": -2.70200348 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea64786f7741707720468", - }, - { - "Text": "West Wing Room 205", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -221.073288, "y": -92.90662, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ec6d286f7742c0b518fb5", - }, - { - "Text": "East Wing Room 222", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -343.3838, "y": -84.47537, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13f24186f77410e57c5626", - }, - { - "Text": "West Wing Room 112", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -189.173019, "y": -85.4490051, "z": -2.69580078 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0dc95c86f77452440fc675", - }, - { - "Text": "West Wing Room 104", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -157.433029, "y": -85.4490051, "z": -2.69580078 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0dc45586f7742f6b0b73e3", - }, - { - "Text": "West Wing Room 219", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -170.853256, "y": -80.91263, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13ef0686f7746e5a411744", - }, - { - "Text": "East Wing Room 308", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -294.3863, "y": -92.88861, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a145d7b86f7744cbb6f4a13", - }, - { - "Text": "East Wing Room 310", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -303.411255, "y": -81.46161, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eec9686f77402ac5c39f2", - }, - { - "Text": "West Wing Room 301", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -229.202621, "y": -100.151733, "z": 3.03088379 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13ef7e86f7741290491063", - }, - { - "Text": "West Wing Room 222", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -161.293747, "y": -84.50137, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a1452ee86f7746f33111763", - }, - { - "Text": "Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -142.583267, "y": -79.9176, "z": 0.164085388 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea79b86f7741d4a35298e", - }, - { - "Text": "East Wing Room 306", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -285.857239, "y": -92.88861, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a145d4786f7744cbb6f4a12", - }, - { - "Text": "Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -360.193237, "y": -79.8936157, "z": 3.04288483 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea79b86f7741d4a35298e", - }, - { - "Text": "East Wing Room 316", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -323.389282, "y": -80.8936157, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a145ebb86f77458f1796f05", - }, - { - "Text": "East Wing Room 314", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -317.992737, "y": -84.47537, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eed4386f77405112912aa", - }, - { - "Text": "East Wing Sanitar's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -323.547, "y": -79.961, "z": -2.70200348 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5eff09cd30a7dc22fd1ddfed", - }, - { - "Text": "West Wing Room 223", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -165.451767, "y": -84.50137, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee37f86f774023657a86f", - }, - // { - // "Text": "safe 1", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": -266.10675, "y": -147.65097, "z": -0.3202896 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0f08bc86f77478f33b84c2" - // }, - // { - // "Text": "West Wing Room 321 Safe", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": -165.664047, "y": -89.05765, "z": 2.53099823 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0eff2986f7741fd654e684" - // }, - // { - // "Text": "Cottage Safe", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": 93.71925, "y": 111.979019, "z": -45.01355 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0f068686f7745b0d4ea242" - // }, - // { - // "Text": "safe 4", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": -242.451981, "y": -153.367249, "z": -0.3202896 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0f0f5886f7741c4e32a472" - // } - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc deleted file mode 100644 index a4ecd897..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc +++ /dev/null @@ -1,1092 +0,0 @@ -{ - "DisplayName": "Streets of Tarkov (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["TarkovStreets"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "DefaultLevel": 0, - "Layers": { - "Underground": { - "Level": -1, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_-1.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // Concordia underground - "Min": { "x": 147, "y": 338, "z": -4 }, - "Max": { "x": 277, "y": 416, "z": 0 }, - }, - { - // Subway underground - "Min": { "x": -15, "y": -25, "z": -5 }, - "Max": { "x": 39, "y": 33, "z": -2 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_0.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - "Min": { "x": -279, "y": -299, "z": -100 }, - "Max": { "x": 324, "y": 533, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_1.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // concordia 2nd floor - "Min": { "x": 128, "y": 339, "z": 6 }, - "Max": { "x": 287, "y": 416, "z": 9 }, - }, - { - // building south of concordia 2nd floor - "Min": { "x": 128, "y": 335, "z": 6 }, - "Max": { "x": 152, "y": 460, "z": 9 }, - }, - { - // real estate agency office 2nd floor - "Min": { "x": -68, "y": 449, "z": 6 }, - "Max": { "x": -34, "y": 475, "z": 10 }, - }, - { - // cinema 2nd floor - "Min": { "x": -197, "y": 370, "z": 6 }, - "Max": { "x": -120, "y": 432, "z": 12 }, - }, - { - // courtyard building 2nd floor - "Min": { "x": -175, "y": 477, "z": 6 }, - "Max": { "x": -160, "y": 491, "z": 10 }, - }, - { - // north of courtyard building 2nd floor - "Min": { "x": -189, "y": 451, "z": 6 }, - "Max": { "x": -171, "y": 473, "z": 10 }, - }, - { - // construction 2nd floor - "Min": { "x": 188, "y": 284, "z": 6 }, - "Max": { "x": 218, "y": 314, "z": 10 }, - }, - { - // Sparja grocery 2nd floor - "Min": { "x": 107, "y": 283, "z": 6 }, - "Max": { "x": 132, "y": 294, "z": 10 }, - }, - { - // Lexos 2nd floor - "Min": { "x": 46, "y": 257, "z": 5.5 }, - "Max": { "x": 106, "y": 352, "z": 10 }, - }, - { - // abandoned factory 2nd floor - "Min": { "x": -156, "y": 265, "z": 3 }, - "Max": { "x": -77, "y": 305, "z": 6 }, - }, - { - // hotels 2nd floor - "Min": { "x": -214, "y": 235, "z": 6 }, - "Max": { "x": -163, "y": 307, "z": 10 }, - }, - { - // financial office 2nd floor - "Min": { "x": -190, "y": 217, "z": 5.5 }, - "Max": { "x": -157, "y": 235, "z": 8 }, - }, - { - // family market 2nd floor - "Min": { "x": -234, "y": 271, "z": 4.5 }, - "Max": { "x": -209, "y": 290, "z": 7 }, - }, - { - // tarbank 2nd floor - "Min": { "x": 31, "y": 198, "z": 6 }, - "Max": { "x": 88, "y": 240, "z": 9 }, - }, - { - // chekannaya apartments 2nd floor - "Min": { "x": 91, "y": 205, "z": 6 }, - "Max": { "x": 161, "y": 240, "z": 9 }, - }, - { - // pharmacy 1 2nd floor - "Min": { "x": 32, "y": 144, "z": 5 }, - "Max": { "x": 57, "y": 173, "z": 8 }, - }, - { - // post office 2nd floor - "Min": { "x": 31, "y": 60, "z": 3 }, - "Max": { "x": 59, "y": 140, "z": 6 }, - }, - { - // archive building 2nd floor - "Min": { "x": 74, "y": 122, "z": 3.5 }, - "Max": { "x": 90, "y": 146, "z": 7 }, - }, - { - // zmeisky apartment 2nd floor - "Min": { "x": 99, "y": 118, "z": 3.5 }, - "Max": { "x": 140, "y": 159, "z": 7 }, - }, - { - // vet clinic 2nd floor - "Min": { "x": 209, "y": 166, "z": 3 }, - "Max": { "x": 235, "y": 183, "z": 6 }, - }, - { - // x-ray building 2nd floor - "Min": { "x": 180, "y": 91, "z": 1 }, - "Max": { "x": 197, "y": 127, "z": 4 }, - }, - { - // school 2nd floor - "Min": { "x": 199, "y": 96, "z": 3 }, - "Max": { "x": 224, "y": 160, "z": 6 }, - }, - { - // rusted key door building 2nd floor - "Min": { "x": 173, "y": 48, "z": -2 }, - "Max": { "x": 199, "y": 85, "z": 1 }, - }, - { - // CCCP building 2nd floor - "Min": { "x": 241, "y": 45, "z": -2 }, - "Max": { "x": 253, "y": 62, "z": 1 }, - }, - { - // pinewood hotel complex 2nd floor - "Min": { "x": -125, "y": 45, "z": 4 }, - "Max": { "x": -13, "y": 173, "z": 6.5 }, - }, - { - // kilov shopping mall + beluga 2nd floor - "Min": { "x": -171, "y": -89, "z": 4 }, - "Max": { "x": -14, "y": -7, "z": 6.5 }, - }, - { - // cardinal bank building 2nd floor - "Min": { "x": -97, "y": -73, "z": 2 }, - "Max": { "x": 149, "y": -14, "z": 6 }, - }, - { - // cardinal apartments northeast 2nd floor - "Min": { "x": 39, "y": -160, "z": 8.5 }, - "Max": { "x": 77, "y": -114, "z": 12 }, - }, - { - // across primorsky ave from cardinal 2nd floor - "Min": { "x": -73, "y": -160, "z": 5 }, - "Max": { "x": -44, "y": -141, "z": 8 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_2.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // concordia 3rd floor - "Min": { "x": 128, "y": 339, "z": 9 }, - "Max": { "x": 287, "y": 416, "z": 12 }, - }, - { - // cinema 3rd floor - "Min": { "x": -179, "y": 377, "z": 12 }, - "Max": { "x": -155, "y": 423, "z": 18 }, - }, - { - // abandoned factory 3rd floor - "Min": { "x": -156, "y": 265, "z": 6 }, - "Max": { "x": -77, "y": 305, "z": 11 }, - }, - { - // family market 3rd floor - "Min": { "x": -234, "y": 271, "z": 7 }, - "Max": { "x": -209, "y": 290, "z": 10 }, - }, - { - // tarbank 3rd floor - "Min": { "x": 31, "y": 198, "z": 9 }, - "Max": { "x": 88, "y": 240, "z": 12 }, - }, - { - // chekannaya apartments 3rd floor - "Min": { "x": 91, "y": 205, "z": 9 }, - "Max": { "x": 161, "y": 240, "z": 12 }, - }, - { - // post office 3rd floor - "Min": { "x": 31, "y": 60, "z": 6 }, - "Max": { "x": 59, "y": 140, "z": 9 }, - }, - { - // zmeisky apartment 3rd floor - "Min": { "x": 99, "y": 118, "z": 7 }, - "Max": { "x": 140, "y": 159, "z": 9 }, - }, - { - // rusted key door building 3rd floor - "Min": { "x": 173, "y": 48, "z": 1 }, - "Max": { "x": 199, "y": 85, "z": 4 }, - }, - { - // pinewood hotel complex 3rd floor - "Min": { "x": -125, "y": 45, "z": 6.5 }, - "Max": { "x": -13, "y": 173, "z": 12 }, - }, - { - // kilov shopping mall + beluga 3rd floor - "Min": { "x": -171, "y": -79, "z": 6.5 }, - "Max": { "x": -14, "y": -5, "z": 12 }, - }, - { - // cardinal apartments northeast 3rd floor - "Min": { "x": 39, "y": -160, "z": 12 }, - "Max": { "x": 77, "y": -114, "z": 15 }, - }, - { - // across primorsky ave from cardinal 3rd floor - "Min": { "x": -73, "y": -160, "z": 8 }, - "Max": { "x": -44, "y": -141, "z": 12 }, - }, - ], - }, - "4th Floor": { - "Level": 3, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_3.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // abandoned factory 4th floor - "Min": { "x": -140, "y": 263, "z": 11 }, - "Max": { "x": -123, "y": 278, "z": 15 }, - }, - { - // family market 4th floor - "Min": { "x": -234, "y": 271, "z": 10 }, - "Max": { "x": -209, "y": 290, "z": 14 }, - }, - { - // tarbank 4th floor - "Min": { "x": 31, "y": 198, "z": 12 }, - "Max": { "x": 88, "y": 240, "z": 15 }, - }, - { - // post office 4th floor + apartments - "Min": { "x": 31, "y": 60, "z": 9 }, - "Max": { "x": 59, "y": 164, "z": 14 }, - }, - { - // zmeisky apartment 4th floor - "Min": { "x": 99, "y": 118, "z": 9 }, - "Max": { "x": 140, "y": 159, "z": 12 }, - }, - { - // rusted key door building 4th floor - "Min": { "x": 173, "y": 48, "z": 4 }, - "Max": { "x": 199, "y": 85, "z": 8 }, - }, - ], - }, - "5th Floor": { - "Level": 4, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_4.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // zmeisky apartment 5th floor - "Min": { "x": 99, "y": 118, "z": 12 }, - "Max": { "x": 140, "y": 159, "z": 15 }, - }, - { - // rusted key door building 5th floor - "Min": { "x": 170, "y": 81, "z": 8 }, - "Max": { "x": 181, "y": 89, "z": 12 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Primorsky Ave.", - "Position": { "x": 9, "y": 308, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Primorsky Ave.", - "Position": { "x": 9, "y": 104, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Primorsky Ave.", - "Position": { "x": 9, "y": -80, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Kilmov St.", - "Position": { "x": 125, "y": 10, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Kilmov St.", - "Position": { "x": -104, "y": 28, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 10, - }, - { - "Text": "Nikitskaya St.", - "Position": { "x": -125, "y": 210, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Verhnyaya St.", - "Position": { "x": -112, "y": 361, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Malevecha St.", - "Position": { "x": -200, "y": 290, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -64, - }, - { - "Text": "Chekannaya St.", - "Position": { "x": 111, "y": 251, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Nizhnyaya St.", - "Position": { "x": -101, "y": 441, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Razvedchikov St.", - "Position": { "x": 174, "y": 430, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -30, - }, - { - "Text": "Zmejskij Alley", - "Position": { "x": 140, "y": 150, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -68, - }, - { - "Text": "Kamchatskaya St.", - "Position": { "x": 232, "y": 100, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Kilmov Shopping Mall", - "Position": { "x": -128, "y": -35, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Beluga", - "Position": { "x": -45, "y": -52, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cardinal Apartments", - "Position": { "x": 99, "y": -71, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Construction", - "Position": { "x": 230, "y": 295, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Lexos", - "Position": { "x": 66, "y": 305, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Sparja Grocery", - "Position": { "x": 140, "y": 300, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Cinema", - "Position": { "x": -175, "y": 400, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Shestyorochka", - "Position": { "x": -218, "y": 135, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Pinewood Hotel", - "Position": { "x": -35, "y": 64, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Teppakot / Koener", - "Position": { "x": 65, "y": 398, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Concordia", - "Position": { "x": 207, "y": 363, "z": 0 }, - "FontSize": 18, - }, - { - "Text": "Cardinal Bank", - "Position": { "x": 89, "y": -20, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "LERM Expo", - "Position": { "x": 239, "y": -60, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Sparja Express", - "Position": { "x": -64, "y": 166, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Burger Spot", - "Position": { "x": -30, "y": 138, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Post Office", - "Position": { "x": 42, "y": 97, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Pharmacy 1", - "Position": { "x": 42, "y": 160, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Office", - "Position": { "x": -173, "y": 226, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Corner Restaurant", - "Position": { "x": -197, "y": 340, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Pharmacy 2", - "Position": { "x": -43, "y": 335, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Pharmacy 3", - "Position": { "x": 90, "y": -227, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Tarbank", - "Position": { "x": 67, "y": 230, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "School", - "Position": { "x": 211, "y": 129, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Vet Clinic", - "Position": { "x": 222, "y": 173, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Hive", - "Position": { "x": -212, "y": 300, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Family Market", - "Position": { "x": -223, "y": 279, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Marked Hotel", - "Position": { "x": -200, "y": 248, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "South Hotel", - "Position": { "x": -175, "y": 297, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Abandoned Factory", - "Position": { "x": -119, "y": 287, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Diner", - "Position": { "x": -80, "y": 235, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Primorskij 49", - "Position": { "x": -13, "y": 244, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Prestigio Cage", - "Position": { "x": 39, "y": 230, "z": 0 }, - "FontSize": 10, - }, - { - "Text": "Bilbo Coffee", - "Position": { "x": -70, "y": 343, "z": 0 }, - "FontSize": 10, - }, - ], - "StaticMarkers": [ - { - "Text": "Basement Descent (Coyote/Labs/Ground Zero)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 74.769, "y": 49.22, "z": -0.701999664 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Entrance to Catacombs (Labs, Hangar Gate)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -249.008026, "y": 243.797, "z": 2.566 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Ventilation Shaft (Lab, Vents)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -124.127106, "y": 425.738983, "z": 3.114 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewer Manhole (Sally/Reserve)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 276.113, "y": 345.389984, "z": 5.356 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Primorsky Ave Taxi (Woods/Interchange/GZ)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -2.191315, "y": 461.232971, "z": 3.2 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sylovate Elevator (Labs, Main Elevator)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -44.7435, "y": -72.6544, "z": 11.04 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Crash Site (Painter/Customs/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 312.74, "y": 405.96, "z": 6.8 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewer River (Labs, Sewage Conduit)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -264.267, "y": 223.92, "z": -1.535 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Klimov Street (Ground Zero, Mira Ave)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -263.41, "y": 43.19, "z": 2.9 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Expo Checkpoint (Ground Zero, Scav Camp)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 213.12, "y": -104.96, "z": 0.09 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Ruined House (Hephaestus)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -248.971, "y": 344.275, "z": 7.195 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "MVD Academy Entrance Hall Guard Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -250.476974, "y": 131.546, "z": 3.98400116 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dc4b6ba9e979af6b79f4", - }, - { - "Text": "Pinewood Hotel Room 215", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -67.00622, "y": 59.3249474, "z": 6.024556 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f08cd6db0635c197600", - }, - { - "Text": "Relaxation Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -208.164185, "y": 295.5338, "z": 4.28889942 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dbf0b8d7830efc45016f", - }, - { - "Text": "Abandoned Factory Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -133.4689, "y": 272.9284, "z": 9.712829 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a3a93f8a56922e82001f5d", - }, - { - "Text": "Financial Institution Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -168.1108, "y": 230.025009, "z": 7.11500072 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39667c9b3aa4b61683e98", - }, - { - "Text": "Financial Institution Small Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -186.393311, "y": 229.271469, "z": 3.72240162 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71ed21031ac76fe773c7f", - }, - { - "Text": "Backup Hideout", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -130.730026, "y": 391.625732, "z": 3.37588024 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6398fd8ad3de3849057f5128", - }, - { - "Text": "Real Estate Agency Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -62.37935, "y": 460.344177, "z": 7.906067 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dc5740562727a654ebb1", - }, - { - "Text": "Iron Gate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 131.168167, "y": 227.64386, "z": 10.5814857 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f6e64283b5e9c56b289", - }, - { - "Text": "Iron Gate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 126.369164, "y": 227.644852, "z": 10.5938711 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f6e64283b5e9c56b289", - }, - { - "Text": "Iron Gate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 132.49292, "y": 225.1011, "z": 10.5825262 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f6e64283b5e9c56b289", - }, - { - "Text": "Stair Landing", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 108.3958, "y": 224.57489, "z": 7.45609 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39fd1c9b3aa4b61683efb", - }, - { - "Text": "Chekannaya Apartment 15", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 107.048935, "y": 227.6278, "z": 7.51593971 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39fc0af870e651d58e6ae", - }, - { - "Text": "Primorsky 46-48 Skybridge", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 49.5526543, "y": 147.7725, "z": 12.7623 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39e1d234195315d4020bd", - }, - { - "Text": "Primorsky 48 Apartment", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 45.3423576, "y": 151.024933, "z": 6.742015 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71eb5b7f4570d3a29316b", - }, - // { // tarbank cash register - // "Text": "door 17", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 66.95923, "y": 231.536, "z": 3.841999 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "64ccc2111779ad6ba200a139" - // }, - // { // tarbank cash register - // "Text": "door 18", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 68.86824, "y": 231.536, "z": 3.841999 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "64ccc2111779ad6ba200a139" - // }, - { - "Text": "Zmeisky 3 Apartment 8", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 104.26915, "y": 129.2099, "z": 4.99642372 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39dfe3901f439517cafba", - }, - { - "Text": "Archive Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 80.078, "y": 138.528, "z": 4.941001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39e49cd6db0635c1975fc", - }, - { - "Text": "Zmeisky 5 Apartment 20", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 124.2521, "y": 143.391266, "z": 14.5957794 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39df18a56922e82001f25", - }, - { - "Text": "Mysterious Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 186.18, "y": 227.438, "z": 0.849899948 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc25f95763a1ae376e447", - }, - { - "Text": "Rusted Key Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 177.724213, "y": 78.84773, "z": 6.821482 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64d4b23dc1b37504b41ac2b6", - }, - { - "Text": "PE Teacher's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 207.952087, "y": 140.7129, "z": 1.39300013 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc268c41e91416064ebc7", - }, - { - "Text": "X-Ray Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 184.997482, "y": 100.691429, "z": 2.82870531 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc246ff54fb38131acf29", - }, - { - "Text": "\"Negotiation\" Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 165.190918, "y": 165.05, "z": 1.79457092 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dbe43a2e5248357dbe9a", - }, - // { // usec cottage safe key bugged - // "Text": "door 27", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 174.013977, "y": 163.48201, "z": 1.14044952 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - { - "Text": "Construction Site Bunkhouse", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 181.878983, "y": 312.128, "z": 6.85800028 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39cb1c9b3aa4b61683ee2", - }, - { - "Text": "Car Dealership Closed Section", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 63.478, "y": 301.057, "z": 7.8760004 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a397d3af870e651d58e65b", - }, - { - "Text": "Car Dealership Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 66.86121, "y": 310.662476, "z": 7.935705 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a399193901f439517cafb6", - }, - { - "Text": "Cargo Container Mesh Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 83.1959839, "y": 296.521, "z": 3.72701359 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39fdf1e21260da44a0256", - }, - { - "Text": "Aspect Company Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 55.03196, "y": 332.649078, "z": 3.91900015 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ce572331dd890873175115", - }, - { - "Text": "Supply Department Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 57.615963, "y": 334.707031, "z": 6.847 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39ce4cd6db0635c1975fa", - }, - { - "Text": "Concordia Apartment 8 Home Cinema", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 217.9483, "y": 400.558655, "z": 10.3969755 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1ec1779ad6ba200a137", - }, - { - "Text": "Concordia Apartment 34", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 227.979279, "y": 406.048645, "z": 10.3969755 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1d4a0f13c24561edf27", - }, - { - "Text": "Concordia Apartment 8", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 224.331543, "y": 400.559357, "z": 10.4224167 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71e781031ac76fe773c7d", - }, - { - "Text": "Concordia Apartment 64 Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 274.591, "y": 383.685974, "z": 7.404751 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71e86b7f4570d3a293169", - }, - { - "Text": "Concordia Apartment 63", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 268.47, "y": 387.507, "z": 7.4047513 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1f4ff54fb38131acf27", - }, - { - "Text": "Concordia Apartment 64", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 272.6917, "y": 378.880249, "z": 7.46978951 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71e922b25f7513905ca20", - }, - { - "Text": "Concordia Security", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 211.010483, "y": 406.7196, "z": -0.205203056 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39c7964283b5e9c56b280", - }, - { - "Text": "Store Manager's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 119.953995, "y": 290.827026, "z": 7.776001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39c69af870e651d58e6aa", - }, - { - "Text": "TerraGroup Security Armory", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 60.7049751, "y": -79.95239, "z": 1.29402184 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc24de61ea448b507d34d", - }, - { - "Text": "TerraGroup Meeting Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 46.6899338, "y": -59.4043961, "z": 1.31902039 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc206793ca11c8f450a38", - }, - { - "Text": "Beluga Restaurant Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -19.6295967, "y": -64.19723, "z": 10.6449995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1fe088064307e14a6f7", - }, - { - "Text": "Beluga Restaurant Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -27.806633, "y": -60.68901, "z": 10.6449995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1fe088064307e14a6f7", - }, - // { // goshan cash register - // "Text": "door 55", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -208.95, "y": 179.655991, "z": 4.057 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5ad7247386f7747487619dc3" - // }, - // { // goshan cash register - // "Text": "door 56", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -208.95, "y": 182.011, "z": 4.059 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5ad7247386f7747487619dc3" - // }, - // { // bugged pinewood safe - // "Text": "door 57", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -77.5323944, "y": 53.20392, "z": 5.3959837 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - // { // bugged pinewood safe - // "Text": "door 58", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -67.94231, "y": 53.4928131, "z": 5.31730938 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - // { // bugged pinewood safe - // "Text": "door 59", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -49.45166, "y": 64.02192, "z": 5.273139 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - // { // goshan cash register - // "Text": "door 60", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -30.653595, "y": 468.8241, "z": 3.66407585 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5ad7247386f7747487619dc3" - // }, - // { // unknown - // "Text": "door 61", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 78.59352, "y": 124.437378, "z": 1.328997 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "63a39e6acd6db0635c1975fe" - // }, - // { // unknown - // "Text": "door 62", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 76.57499, "y": 132.901367, "z": 4.36699724 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "63a39e5b234195315d4020bf" - // }, - // { // unknown - // "Text": "door 63", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 58.10759, "y": 337.684021, "z": 6.26939726 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "63a39ddda3a2b32b5f6e007a" - // } - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc b/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc deleted file mode 100644 index 5932da25..00000000 --- a/configs/Default/DynamicMaps optional tooltips/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc +++ /dev/null @@ -1,216 +0,0 @@ -{ - "DisplayName": "Woods (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["Woods"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -692, "y": -915 }, - "Max": { "x": 647, "y": 443 }, - }, - "DefaultLevel": 0, - "Layers": { - "Ground Level": { - "Level": 0, - "ImagePath": "Maps/Woods_TarkovData/Layers/woods_layer_0.png", - "ImageBounds": { - "Min": { "x": -692, "y": -915 }, - "Max": { "x": 647, "y": 443 }, - }, - "GameBounds": [ - { - "Min": { "x": -692, "y": -915, "z": -100 }, - "Max": { "x": 647, "y": 443, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Sawmill", - "Position": { "x": 10, "y": -3, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Scav Town", - "Position": { "x": -485, "y": -390, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Old Sawmill", - "Position": { "x": -517, "y": -210, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cultist Village", - "Position": { "x": -80, "y": -705, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "USEC Camp", - "Position": { "x": 290, "y": -475, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Military Camp", - "Position": { "x": -188, "y": 235, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Ponds", - "Position": { "x": -5, "y": -515, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crash Site", - "Position": { "x": -252, "y": -37, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Checkpoint", - "Position": { "x": 239, "y": -65, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Shack", - "Position": { "x": 244, "y": 125, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Lumber", - "Position": { "x": -16, "y": -122, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Cabins", - "Position": { "x": -3, "y": -74, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Bus Stop", - "Position": { "x": -234, "y": 368, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Jaeger's Camp", - "Position": { "x": -327, "y": 19, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Sniper Rock", - "Position": { "x": 85, "y": -147, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Convoy", - "Position": { "x": 200, "y": -606, "z": 0 }, - "FontSize": 12, - }, - ], - "StaticMarkers": [ - { - "Text": "Factory Gate (Customs, Old Gas Gate)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -363.8, "y": 365.53, "z": 1.43 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Scav Bunker (Prapor)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 220.426651, "y": -705.7956, "z": 20.538269 }, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Mountain Stash (Jaeger)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -206.59436, "y": -215.9796, "z": 31.47127 }, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "RUAF Gate (Customs, Factory Corner)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -134.26001, "y": 419.8, "z": -2.37 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "ZB-016 (Hideout/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -389.159973, "y": 11.0449905, "z": 4.147001 }, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "ZB-014 (Scorpion)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 447.659973, "y": 57.46, "z": -13.46346 }, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "UN Roadblock (Customs/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -527.8743, "y": 288.2304, "z": 1.68126917 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Bridge SUV (Streets/Interchange/GZ)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -484.5639, "y": -506.413239, "z": 15.5812693 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Outskirts (Customs/Lighthouse)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 347.315643, "y": 347.0304, "z": -9.148731 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "North UN Roadblock (Customs, RUAF Roadblock*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -561.1143, "y": -58.7096, "z": 9.321269 }, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Yotota Car", - "ImagePath": "Markers/car_door.png", - "Position": { "x": -0.1508789, "y": -61.946167, "z": -0.680201769 }, - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "Category": "LockedDoor", - "AssociatedItemId": "591ae8f986f77406f854be45", - }, - { - "Text": "ZB-014", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 448.623047, "y": 65.5839844, "z": -13.269 }, - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "Category": "LockedDoor", - "AssociatedItemId": "591afe0186f77431bd616a11", - }, - // { - // "Text": "Shtrman's Stash", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 25.1087952, "y": -29.55574, "z": -1.47199988 }, - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "Category": "LockedDoor", - // "AssociatedItemId": "5d08d21286f774736e7c94c3" - // } - ], -} diff --git a/configs/Default/DynamicMaps optional tooltips/Instructions.txt b/configs/Default/DynamicMaps optional tooltips/Instructions.txt deleted file mode 100644 index 8a217e3b..00000000 --- a/configs/Default/DynamicMaps optional tooltips/Instructions.txt +++ /dev/null @@ -1,5 +0,0 @@ -YOU MUST HAVE DYNAMIC MAPS ALREADY DOWNLOADED - -Copy the "DynamicMaps" folder above and paste it into the BepInEx/plugins folder, replacing the files when prompted. - -If you want to revert, just redownload dynamic maps. \ No newline at end of file diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc deleted file mode 100644 index 67f3c3a9..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Customs_TarkovDev/Customs_TarkovDev.jsonc +++ /dev/null @@ -1,691 +0,0 @@ -{ - "DisplayName": "Customs (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["bigmap"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "DefaultLevel": 0, - "Layers": { - "Underground": { - "Level": -1, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_-1.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - // zb-1011 - "Min": { "x": 620, "y": -137, "z": -100 }, - "Max": { "x": 635, "y": -125, "z": 0.5 }, - }, - { - // zb-1012 - "Min": { "x": 458, "y": -122, "z": -100 }, - "Max": { "x": 473, "y": -110, "z": 0.5 }, - }, - { - // old gas - "Min": { "x": 308, "y": -184, "z": -100 }, - "Max": { "x": 314, "y": -173, "z": 0.5 }, - }, - { - // switch basement - "Min": { "x": 323, "y": -88, "z": -100 }, - "Max": { "x": 349, "y": -32, "z": 0.5 }, - }, - { - // zb-013 - "Min": { "x": 193, "y": -158, "z": -100 }, - "Max": { "x": 219, "y": -137, "z": 0.5 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_0.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - "Min": { "x": -372, "y": -306, "z": -100 }, - "Max": { "x": 698, "y": 235, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_1.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - // dorms - "Min": { "x": 165, "y": 125, "z": 2.7 }, - "Max": { "x": 243, "y": 190, "z": 5.0 }, - }, - { - // mechanic - "Min": { "x": 72, "y": -170, "z": 2.7 }, - "Max": { "x": 116, "y": -83, "z": 6.5 }, - }, - { - // switch 2nd - "Min": { "x": 341, "y": -84, "z": 2.7 }, - "Max": { "x": 356, "y": -30, "z": 6.5 }, - }, - { - // switch 2nd - "Min": { "x": 321, "y": -59, "z": 2.7 }, - "Max": { "x": 334, "y": -52, "z": 6.5 }, - }, - { - // scav checkpoint - "Min": { "x": 577, "y": -1, "z": 2.7 }, - "Max": { "x": 589, "y": 10, "z": 6.5 }, - }, - { - // dead scav warehouse - "Min": { "x": 532, "y": -134, "z": 2.7 }, - "Max": { "x": 580, "y": -104, "z": 100 }, - }, - { - // pump 2nd - "Min": { "x": 599, "y": -139, "z": 2.7 }, - "Max": { "x": 625, "y": -120, "z": 100 }, - }, - { - // big red 2nd - "Min": { "x": -223, "y": -131, "z": 5.7 }, - "Max": { "x": -199, "y": -90, "z": 100 }, - }, - { - // skeleton - "Min": { "x": 169, "y": -160, "z": 5.7 }, - "Max": { "x": 239, "y": 3, "z": 100 }, - }, - { - // switch sniper - "Min": { "x": 316, "y": -95, "z": 5.7 }, - "Max": { "x": 336, "y": -56, "z": 100 }, - }, - { - // USEC 2nd - "Min": { "x": 556, "y": -92, "z": 5.7 }, - "Max": { "x": 584, "y": -46, "z": 100 }, - }, - { - // construction 2nd - "Min": { "x": 65, "y": -22, "z": 5.7 }, - "Max": { "x": 93, "y": 0, "z": 100 }, - }, - { - // chemical warehouse sniper scav - "Min": { "x": 450, "y": -90, "z": 14 }, - "Max": { "x": 497, "y": -44, "z": 15 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Customs_TarkovDev/Layers/customs_level_2.png", - "ImageBounds": { - "Min": { "x": -372, "y": -306 }, - "Max": { "x": 698, "y": 235 }, - }, - "GameBounds": [ - { - // dorms - "Min": { "x": 165, "y": 125, "z": 5.0 }, - "Max": { "x": 234, "y": 190, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - // all of these labels are from Tarkov.dev map data under MIT license - { - "Text": "Big Red", - "Position": { "x": -215, "y": -119, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Dorms", - "Position": { "x": 200, "y": 150, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "New Gas", - "Position": { "x": 404, "y": 31, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Old Gas", - "Position": { "x": 331, "y": -173, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Fortress", - "Position": { "x": 201, "y": -127, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crackhouse", - "Position": { "x": 83, "y": -153, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Streamer House", - "Position": { "x": 567, "y": -67, "z": 0 }, - }, - { - "Text": "Main Bridge", - "Position": { "x": -69, "y": 7, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 6, - }, - { - "Text": "Sniper Hill", - "Position": { "x": 110, "y": 85, "z": 0 }, - }, - { - "Text": "Storage", - "Position": { "x": -288, "y": -134, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Trailer Park", - "Position": { "x": -211, "y": -219, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Junk Bridge", - "Position": { "x": -66, "y": 46, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Repair Shop", - "Position": { "x": 106, "y": -90, "z": 0 }, - }, - { - "Text": "Sniper Ridge", - "Position": { "x": 491, "y": 63, "z": 0 }, - "DegreesRotation": 5, - }, - { - "Text": "Old Construction", - "Position": { "x": 75, "y": -9, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Skeleton", - "Position": { "x": 200, "y": -13, "z": 0 }, - "FontSize": 16, - "DegreesRotation": -9, - }, - { - "Text": "Warehouse 3", - "Position": { "x": 390, "y": -94, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Depot", - "Position": { "x": 472, "y": -67, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Warehouse 7", - "Position": { "x": 555, "y": -118, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Military Checkpoint", - "Position": { "x": 572, "y": 0, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Bus Station", - "Position": { "x": 238, "y": 53, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Warehouse 4", - "Position": { "x": 333, "y": -67, "z": 1 }, - "FontSize": 16, - }, - { - "Text": "Powerline Tower", - "Position": { "x": 497, "y": 110, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Warehouse 17", - "Position": { "x": 46, "y": -59, "z": 0 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "ZB-013 Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": 352.230316, "y": -40.8052826, "z": 2.61458874 }, - "Category": "Switch", - }, - { - "Text": "Military Base CP (Reserve, Scav Lands)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 643.3982, "y": 126.869247, "z": 2.400003 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railroad to Military Base (Reserve, Scav Land rails*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 489.058228, "y": 221.391266, "z": 3.950006 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sniper Roadblock (Reserve*/Shoreline)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 15.3699341, "y": 127.94, "z": 0.139977932 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railroad to Port (Ref/Shoreline)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -142.550232, "y": 46.9100037, "z": -0.629980564 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Trailer Park Workers' Shack (Legs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -248.540222, "y": -232.9901, "z": 2.550012 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railroad to Tarkov (Painter/Streets/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -166.020264, "y": -218.380112, "z": 2.42000723 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Warehouse 17 (Skier)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 45.9998779, "y": -78.43004, "z": 3.61000967 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Old Gas Station Gate (Woods/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 301.639923, "y": -197.940048, "z": 3.469995 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Factory Far Corner (Woods, RUAF Gate)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 654.53, "y": -160.49, "z": 3.19999838 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Scav Checkpoint (Woods/Lighthouse)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 652.24, "y": -27.1200027, "z": 1.00499988 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "ZB-013 (Factory, Cellars)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 200.9755, "y": -153.086456, "z": -1.1484108 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Dorms SUV (Shoreline, North Fence SUV)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 181.08, "y": 213.25, "z": -0.71 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "ZB-1011 (Hideout/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 621.4368, "y": -127.700775, "z": -2.65 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Crossroads (Lotus/Interchange/Shoreline*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -335.120239, "y": -73.98008, "z": -3.97000742 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Trailer Park (Ragman/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -313.720276, "y": -233.2801, "z": -1.72000742 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "RUAF Roadblock (Woods, UN Roadblock)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -14.5001221, "y": -138.450043, "z": 1.92000723 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Smuggler's Boat (Lighthouse*/Shoreline/Woods*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -43.11017, "y": 119.40004, "z": -14.2250118 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "ZB-1012 (Hideout/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 459.427826, "y": -111.042969, "z": -2.31699228 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Tarcone Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -205.499237, "y": -109.994392, "z": 8.110943 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780d0532459777a5108b9a2", - }, - { - "Text": "Portable Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -251.320953, "y": -221.941071, "z": 3.85700083 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780d07a2459777de4559324", - }, - { - "Text": "Trailer Park Portable Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -194.560135, "y": -207.398911, "z": 2.34600019 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5913611c86f77479e0084092", - }, - { - "Text": "Factory Shortcut", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 356.052551, "y": -14.5693512, "z": 2.34000182 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - }, - { - "Text": "Unknown Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 370.014923, "y": -50.08902, "z": 2.15399933 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "593962ca86f774068014d9af", - }, - { - "Text": "Factory Shortcut", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 356.957367, "y": -8.079105, "z": 2.14515162 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - }, - { - "Text": "Dorm 114", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 233.549591, "y": 159.682587, "z": 0.889000237 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59387a4986f77401cc236e62", - }, - { - "Text": "Dorm 206", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 230.641281, "y": 138.671631, "z": 3.86939716 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938603e86f77435642354f4", - }, - { - "Text": "Dorm 105", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 227.877258, "y": 135.61264, "z": 0.8901995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "591382d986f774465a6413a7", - }, - { - "Text": "Dorm 110", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 231.0886, "y": 159.435349, "z": 0.910999358 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59136e1e86f774432f15d133", - }, - { - "Text": "Dorm 104", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 230.101257, "y": 134.913879, "z": 0.8860002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "591383f186f7744a4c5edcf3", - }, - { - "Text": "Dorm Guard Desk", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 225.517273, "y": 138.366241, "z": 0.8858002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59136a4486f774447a1ed172", - }, - { - "Text": "Dorm 204", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 173.379211, "y": 150.356216, "z": 3.83760285 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "59148c8a86f774197930e983", - }, - { - "Text": "Dorm 108", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 177.473969, "y": 178.489075, "z": 0.8406372 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5914578086f774123569ffa4", - }, - { - "Text": "Dorm 314 Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 180.671432, "y": 183.722443, "z": 6.84058475 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf7f2459777de4559322", - }, - { - "Text": "Dorm 218", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 190.192383, "y": 175.3542, "z": 3.84178257 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf9e2459777df90dcb73", - }, - { - "Text": "Dorm 118", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 194.794083, "y": 174.546783, "z": 0.830601 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5672c92d4bdc2d180f8b4567", - }, - { - "Text": "Dorm 220", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 193.957886, "y": 174.821625, "z": 3.831203 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cfa52459777dfb276eb1", - }, - { - "Text": "Dorm 308", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 177.4756, "y": 178.488113, "z": 6.850606 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf722459777a5108b9a1", - }, - { - "Text": "Dorm 315", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 179.284683, "y": 174.810455, "z": 6.830814 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf692459777de4559321", - }, - { - "Text": "Dorm 214", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 178.105484, "y": 183.746643, "z": 3.83598375 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cf942459777df90dcb72", - }, - { - "Text": "Dorm 203", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 176.041077, "y": 150.26828, "z": 3.83258247 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938504186f7740991483f30", - }, - { - "Text": "Dorm 103", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 175.734467, "y": 149.366577, "z": 0.820169449 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938994586f774523a425196", - }, - { - "Text": "Dorm 306", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 174.544632, "y": 157.45575, "z": 6.828404 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780cda02459777b272ede61", - }, - { - "Text": "Dorm 303", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 176.039612, "y": 150.268463, "z": 6.82898426 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "593aa4be86f77457f56379f8", - }, - { - "Text": "Gas Station Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 415.416443, "y": 35.6602058, "z": 2.18918633 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5913877a86f774432f15d444", - }, - { - "Text": "Gas Station Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 415.779572, "y": 38.5554962, "z": 2.17909455 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5780d0652459777df90dcb74", - }, - { - "Text": "USEC Stash", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 562.780945, "y": -58.9465332, "z": 2.216738 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da743f586f7744014504f72", - }, - { - "Text": "USEC Stash", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 568.747131, "y": -50.85814, "z": 2.193743 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da743f586f7744014504f72", - }, - { - "Text": "Orange Tanker Truck", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 101.818916, "y": -5.54527664, "z": 3.44780731 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5937ee6486f77408994ba448", - }, - { - "Text": "Military Checkpoint", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 577.6575, "y": 4.049543, "z": 0.8078748 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5913915886f774123603c392", - }, - { - "Text": "ZB-013", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 198.927917, "y": -146.172791, "z": -1.779768 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - }, - { - "Text": "Portable Bunkhouse", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 202.664337, "y": 11.72344, "z": 4.73085976 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5938144586f77473c2087145", - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc deleted file mode 100644 index 74966341..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Factory_TarkovDev/Factory_TarkovDev.jsonc +++ /dev/null @@ -1,215 +0,0 @@ -{ - "DisplayName": "Factory (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["factory4_day", "factory4_night"], - "CoordinateRotation": 90, - "Bounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "DefaultLevel": 0, - "Layers": { - "Tunnels": { - "Level": -1, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_-1.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": -100 }, - "Max": { "x": 77.6, "y": 67.2, "z": -1 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_0.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": -1 }, - "Max": { "x": 77.6, "y": 67.2, "z": 3 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_1.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": 3 }, - "Max": { "x": 77.6, "y": 67.2, "z": 6 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Factory_TarkovDev/Layers/factory_layer_2.png", - "ImageBounds": { - "Min": { "x": -65, "y": -64.5 }, - "Max": { "x": 77.6, "y": 67.2 }, - }, - "GameBounds": [ - { - "Min": { "x": -65, "y": -64.5, "z": 6 }, - "Max": { "x": 77.6, "y": 67.2, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Office Building", - "Position": { "x": 21, "y": 39, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Med Tent", - "Position": { "x": -17.5, "y": -28, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Silos", - "Position": { "x": 4.5, "y": 10.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Heli Crash", - "Position": { "x": 30, "y": -8.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Scav Bunker", - "Position": { "x": -20.5, "y": 23, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Blue Containers", - "Position": { "x": -18, "y": 50, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Glass Hall", - "Position": { "x": 69.3, "y": -20, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Boilers", - "Position": { "x": 58, "y": 6.3, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Forklifts", - "Position": { "x": 66, "y": -42, "z": 0 }, - "FontSize": 14, - }, - ], - "StaticMarkers": [ - { - "Text": "Camera Bunker Door (Mechanic)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -14.5749989, "y": 40.36, "z": -2.086 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Office Window (Woods/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 17.8332214, "y": 39.8851128, "z": 8.730333 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Cellars (Customs, ZB-1013)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 77.529, "y": -28.891, "z": -4.657 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Gate 3 (Woods, ZB-016)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 58.709, "y": 64.112, "z": 0.84 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Gate 0 (Customs, ZB-1011)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -63.7400055, "y": 55.902, "z": 1.749 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Med Tent Gate (Customs, ZB-1012)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -18.4857769, "y": -60.1718826, "z": 1.16133332 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Locked Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 29.2459984, "y": 36.52492, "z": 9.155067 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Pumping Station", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 43.1875839, "y": -14.1608534, "z": 1.01413012 }, - "Category": "LockedDoor", - "AssociatedItemId": "57a349b2245977762b199ec7", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Gate 0", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -53.754, "y": 58.93033, "z": 2.33300042 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Cellars", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 66.42518, "y": -29.8983536, "z": -1.53579187 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Pumping Station", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 40.9448547, "y": -6.261415, "z": 0.9631303 }, - "Category": "LockedDoor", - "AssociatedItemId": "593858c486f774253a24cb52", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - { - "Text": "Med Tent", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -20.3113289, "y": -49.138, "z": 1.27600038 }, - "Category": "LockedDoor", - "AssociatedItemId": "5448ba0b4bdc2d02308b456c", - "Color": { "r": 1, "g": 0.921569, "b": 0.015686275, "a": 1.0 }, - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc deleted file mode 100644 index 61890086..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/GroundZero_TarkovDev/GroundZero_TarkovDev.jsonc +++ /dev/null @@ -1,207 +0,0 @@ -{ - "DisplayName": "Ground Zero (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["Sandbox", "Sandbox_high"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "DefaultLevel": 0, - "Layers": { - "Garage": { - "Level": -1, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_-1.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - // garage - "Min": { "x": 43, "y": -100, "z": -100 }, - "Max": { "x": 117, "y": 190, "z": 21 }, - }, - { - // underpass - "Min": { "x": 117, "y": 49, "z": -100 }, - "Max": { "x": 143, "y": 80, "z": 21 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_0.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - "Min": { "x": -99, "y": -124, "z": -100 }, - "Max": { "x": 249, "y": 364, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_1.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - // rest of 2nd floor - "Min": { "x": -99, "y": -124, "z": 28 }, - "Max": { "x": 249, "y": 364, "z": 32.3 }, - }, - { - // m showroom - "Min": { "x": 91, "y": 216, "z": 26 }, - "Max": { "x": 98, "y": 228, "z": 31 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/GroundZero_TarkovDev/Layers/ground_zero_layer_2.png", - "ImageBounds": { - "Min": { "x": -99, "y": -124 }, - "Max": { "x": 249, "y": 364 }, - }, - "GameBounds": [ - { - "Min": { "x": -99, "y": -124, "z": 32.3 }, - "Max": { "x": 249, "y": 364, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "TerraGroup", - "Position": { "x": -50, "y": 0, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Skyside", - "Position": { "x": 150, "y": 1, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Fusion", - "Position": { "x": 141, "y": 142, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Empire", - "Position": { "x": 14, "y": 201, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Capital Insight", - "Position": { "x": 115, "y": 285, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Nakatani", - "Position": { "x": 2, "y": 324, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Elemental Global", - "Position": { "x": 80, "y": -118, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Oasis", - "Position": { "x": 115, "y": 104, "z": 22 }, - "FontSize": 16, - }, - { - "Text": "ASAP Winery", - "Position": { "x": 115, "y": 30, "z": 22 }, - "FontSize": 12, - }, - { - "Text": "Tarbank", - "Position": { "x": 43, "y": 150, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "GAGRIN Hotel", - "Position": { "x": 58, "y": 234, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "M Showroom", - "Position": { "x": 97, "y": 223, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Science Offices", - "Position": { "x": -13, "y": 48, "z": 29 }, - "FontSize": 12, - }, - ], - "StaticMarkers": [ - { - "Text": "Scav Checkpoint (Streets, Expo CP)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 26.1550121, "y": -82.52659, "z": 24.5091858 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Police Cordon SUV (Woods/Interchange/Streets)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -19.5134068, "y": 114.942139, "z": 23.7110023 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Emercom Checkpoint (Therapist)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 151.625, "y": -97.45658, "z": 24.662056 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Nakatani Basement Stairs (Coyote/Streets/Labs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -16.1249924, "y": 335.063416, "z": 14.7620564 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Mira Ave (Streets, Klimov Ave)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 218.225, "y": -38.5065842, "z": 17.9920559 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Underground Parking Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 107.056, "y": 50.6362534, "z": 13.499 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "658199972dc4e60f6d556a2f", - }, - { - "Text": "TerraGroup Science Offices", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -17.975647, "y": 58.5532341, "z": 30.7062054 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "658199aa38c79576a2569e13", - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc deleted file mode 100644 index a88eb483..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Interchange_TarkovDev/Interchange_TarkovDev.jsonc +++ /dev/null @@ -1,627 +0,0 @@ -{ - "DisplayName": "Interchange (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["Interchange"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "DefaultLevel": 0, - "Layers": { - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_0.png", - "ImageBounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "GameBounds": [ - { - "Min": { "x": -364, "y": -443, "z": -100 }, - "Max": { "x": 534, "y": 452, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_1.png", - "ImageBounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "GameBounds": [ - { - // mall - "Min": { "x": -222, "y": -327, "z": 25 }, - "Max": { "x": 120, "y": 218, "z": 34 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Interchange_TarkovDev/Layers/interchange_layer_2.png", - "ImageBounds": { - "Min": { "x": -364, "y": -443 }, - "Max": { "x": 534, "y": 452 }, - }, - "GameBounds": [ - { - // mall - "Min": { "x": -222, "y": -443, "z": 34 }, - "Max": { "x": 120, "y": 218, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Power Station", - "Position": { "x": -186.4, "y": -318.7, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Go Kart", - "Position": { "x": 155, "y": -253, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Four Camp", - "Position": { "x": 158, "y": -78.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Cargo Containers", - "Position": { "x": 68.2, "y": 312.9, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Wall Break", - "Position": { "x": -260.2, "y": 123.8, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Ramps", - "Position": { "x": -175.5, "y": 145.1, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "OLI Tower", - "Position": { "x": 202.3, "y": 219.4, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "IDEA Tower", - "Position": { "x": 46.5, "y": -358.5, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Scav Camp", - "Position": { "x": 263.2, "y": -11.1, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Highway Construction", - "Position": { "x": 373.5, "y": -391.2, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Garage A", - "Position": { "x": 33, "y": -222, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Garage B", - "Position": { "x": 47, "y": -112, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Garage C", - "Position": { "x": 0, "y": 47, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Garage D", - "Position": { "x": 28, "y": 138, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "IDEA", - "Position": { "x": -34, "y": -235, "z": 26 }, - "FontSize": 14, - }, - { - "Text": "Goshan", - "Position": { "x": -115, "y": -45, "z": 26 }, - "FontSize": 14, - }, - { - "Text": "OLI", - "Position": { "x": -28, "y": 140, "z": 26 }, - "FontSize": 14, - }, - { - "Text": "Nortex", - "Position": { "x": 87, "y": -165, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "TRend", - "Position": { "x": 60, "y": -152, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Mode7", - "Position": { "x": 69.5, "y": -134, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "TTS", - "Position": { "x": 19, "y": -129, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Book Store", - "Position": { "x": -38, "y": -129, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Dino Clothes", - "Position": { "x": 91, "y": -119, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "EMERCOM", - "Position": { "x": 18, "y": -103, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Kostin", - "Position": { "x": -28, "y": -103, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Bizarro", - "Position": { "x": -65, "y": -103, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Spiel", - "Position": { "x": 92, "y": -87, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Voyage", - "Position": { "x": -18, "y": -87, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Viking", - "Position": { "x": 57, "y": -66, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Mantis", - "Position": { "x": 13, "y": -66, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "German", - "Position": { "x": -18, "y": -72, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "The National", - "Position": { "x": 57, "y": -32, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Brutal", - "Position": { "x": 13, "y": -32, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Kiba", - "Position": { "x": -18, "y": -25, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Pretty Lights", - "Position": { "x": -34, "y": -20, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Telespot", - "Position": { "x": 92, "y": -18, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Revis", - "Position": { "x": 62, "y": -12, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "ADIK", - "Position": { "x": 19, "y": -6, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Generic", - "Position": { "x": -28, "y": 0.5, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Top Brand", - "Position": { "x": 92, "y": 15, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Sports", - "Position": { "x": 61, "y": 15, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Yushka", - "Position": { "x": 70, "y": 32, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Rasmussen", - "Position": { "x": 19.5, "y": 26, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Avokado", - "Position": { "x": -37, "y": 26, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Boots 4 Life", - "Position": { "x": 91, "y": 55, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Texho", - "Position": { "x": 61, "y": 50, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Dom", - "Position": { "x": 6, "y": 49, "z": 26 }, - "FontSize": 10, - }, - { - "Text": "Father & Sons", - "Position": { "x": 38, "y": -170, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Tarkovstar", - "Position": { "x": 69, "y": -150, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Eastland", - "Position": { "x": 26, "y": -149, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Arena", - "Position": { "x": 71, "y": -130, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "ТАРЗДРАВ", - "Position": { "x": 54, "y": -128, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "МЕБЕЛЬ МК", - "Position": { "x": 20, "y": -128, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Intourist", - "Position": { "x": 69, "y": -116, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Burger Spot", - "Position": { "x": -27, "y": -103, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "FCK", - "Position": { "x": 70, "y": -94, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "McDaniels", - "Position": { "x": 70, "y": -87, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Tarducks", - "Position": { "x": 64, "y": -69, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Coffee Joy", - "Position": { "x": 43, "y": -69, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Jacob & Jacob", - "Position": { "x": 15, "y": -74, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "ПУШКИН", - "Position": { "x": -34, "y": -79, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Sushi Huyushi", - "Position": { "x": 64, "y": -34, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Underway", - "Position": { "x": -17, "y": -32, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Burger House", - "Position": { "x": 67, "y": -23.5, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Philly Cute", - "Position": { "x": -34, "y": -24, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Shiccos", - "Position": { "x": 67, "y": -16, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "УЗЕЙ ИСТОРИИ", - "Position": { "x": 17, "y": 0, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Papillon", - "Position": { "x": 92, "y": 17, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "ЗАКРЫТО НА РЕМОНТ", - "Position": { "x": 58, "y": 13, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "НА-СВЯЗИ", - "Position": { "x": 70, "y": 27, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "СКОРО ОТКРЫТИЕ", - "Position": { "x": 54, "y": 24, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Figaro", - "Position": { "x": 19, "y": 26, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "АПТЕКА", - "Position": { "x": 71, "y": 47, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "SARA", - "Position": { "x": 53, "y": 47, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Urban Clothes", - "Position": { "x": 26, "y": 46, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "TECHLIGHT", - "Position": { "x": 91, "y": 54, "z": 35 }, - "FontSize": 10, - }, - { - "Text": "Fashion Store", - "Position": { "x": 39, "y": 67, "z": 35 }, - "FontSize": 10, - }, - ], - "StaticMarkers": [ - { - "Text": "Main Power Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -201.108, "y": -357.8291, "z": 23.1857 }, - "Category": "Switch", - }, - { - "Text": "Saferoom Urinal Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -51.547, "y": -125.440712, "z": 36.86 }, - "Category": "Switch", - }, - { - "Text": "2nd Floor Alarm Console", - "ImagePath": "Markers/lever.png", - "Position": { "x": -46.555, "y": -55.202, "z": 37.347 }, - "Category": "Switch", - }, - { - "Text": "1st Floor Alarm Console", - "ImagePath": "Markers/lever.png", - "Position": { "x": -67.1342545, "y": 53.7422676, "z": 27.9506 }, - "Category": "Switch", - }, - { - "Text": "Inside Saferoom Exfil Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -50.6210022, "y": 45.617, "z": 22.632 }, - "Category": "Switch", - }, - { - "Text": "Object 14 Container Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -47.698, "y": 42.6198, "z": 22.891 }, - "Category": "Switch", - }, - { - "Text": "Emercom Checkpoint (Lotus/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -317.21, "y": 267.94, "z": 21.94955 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railway (Painter/Customs/Woods/Streets)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 474.67, "y": -436.09, "z": 20.92 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Power Station SUV (Painter/Streets/Woods/GZ)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -251.93, "y": -366.99, "z": 21.7130013 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Scav Camp (Ragman/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 284.442, "y": -27.493, "z": 21.94955 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Saferoom (Flea Market)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -47.73, "y": 44.055, "z": 22.97 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Power Substation Utility Cabin", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -223.115845, "y": -271.3501, "z": 22.55412 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d49886f77455f9731921", - }, - { - "Text": "ULTRA Medical Storage", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 67.55801, "y": 40.891, "z": 37.60174 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5e42c71586f7747f245e1343", - }, - { - "Text": "Kiba Arms Inner Grate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -9.887001, "y": -33.76517, "z": 28.241 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5addaffe86f77470b455f900", - }, - { - "Text": "Kiba Arms Outer Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -9.444001, "y": -33.709, "z": 28.241 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d7d286f77450166e0a89", - }, - { - "Text": "Object #11SR Saferoom", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -51.9328041, "y": 45.8337746, "z": 22.35359 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5e42c81886f7742a01529f57", - }, - { - "Text": "Object #21WS", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 140.195663, "y": 263.315277, "z": 25.2079964 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5e42c83786f7742a021fdf3c", - }, - { - "Text": "NecrusPharm Pharmacy", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 68.53804, "y": -255.424225, "z": 22.4947357 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d64486f774079b080af8", - }, - { - "Text": "Emercom Medical Unit", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 24.136982, "y": -112.8551, "z": 28.4790325 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5db3786f7743568421cce", - }, - { - "Text": "Emercom Medical Unit", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 34.14116, "y": -108.287651, "z": 28.4790325 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5db3786f7743568421cce", - }, - { - "Text": "Emercom Medical Unit", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 6.732233, "y": -107.304314, "z": 28.4790344 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5db3786f7743568421cce", - }, - { - "Text": "OLI Logistics Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 83.1990051, "y": 115.673004, "z": 28.1199989 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5cfbd86f7742c825d6104", - }, - { - "Text": "OLI Outlet Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -102.823967, "y": 80.48102, "z": 28.12 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5d20586f77449be26d877", - }, - { - "Text": "OLI Admin Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 85.18402, "y": 104.638214, "z": 28.1199989 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ad5ccd186f774446d5706e9", - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc deleted file mode 100644 index b8c48250..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Labs_TarkovDev/Labs_TarkovDev.jsonc +++ /dev/null @@ -1,283 +0,0 @@ -{ - "DisplayName": "Labs (TarkovDev)", - "Author": "Tarkov.dev", - "AuthorLink": "https://tarkov.dev", - "MapInternalNames": ["laboratory"], - "CoordinateRotation": 270, - "Bounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "DefaultLevel": 0, - "Layers": { - "Technical": { - "Level": -1, - "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_-1.png", - "ImageBounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "GameBounds": [ - { - "Min": { "x": -292, "y": -441, "z": -100 }, - "Max": { "x": -96, "y": -223, "z": -0.9 }, - }, - ], - }, - "First Level": { - "Level": 0, - "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_0.png", - "ImageBounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "GameBounds": [ - { - "Min": { "x": -292, "y": -441, "z": -0.9 }, - "Max": { "x": -96, "y": -223, "z": 3 }, - }, - ], - }, - "Second Level": { - "Level": 1, - "ImagePath": "Maps/Labs_TarkovDev/Layers/labs_layer_1.png", - "ImageBounds": { - "Min": { "x": -292, "y": -441 }, - "Max": { "x": -96, "y": -223 }, - }, - "GameBounds": [ - { - "Min": { "x": -271, "y": -422, "z": 3 }, - "Max": { "x": -101, "y": -270, "z": 100 }, - }, - ], - }, - }, - "Labels": [], - "StaticMarkers": [ - { - "Text": "Cargo Elevator (Coyote/Streets/Ground Zero)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -112.152, "y": -408.64, "z": 5.376 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Main Elevator (Streets, Stylobate Elevator)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -282.304016, "y": -334.896, "z": -3.631999 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Ventilation Shaft (Streets, Vent Shaft)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -144.866, "y": -399.385, "z": -2.424 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewage Conduit (Streets, Sewer River)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -123.711, "y": -255.3735, "z": -3.6609993 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Hangar Gate (Streets, Catacombs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -170.66, "y": -240.77, "z": 2.08 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Medical Block Elevator Power", - "ImagePath": "Markers/lever.png", - "Position": { "x": -124.758, "y": -313.806, "z": -2.31599617 }, - "Category": "Switch", - }, - // { // main elevator - // "Text": "call_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -281.022, "y": -335.477, "z": -2.83799934 }, - // "Category": "Switch" - // }, - // { // medical block call button - // "Text": "call_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -114.112, "y": -343.2, "z": -2.84599972 }, - // "Category": "Switch" - // }, - // { // cargo elevator - // "Text": "call_button (1)", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -114.037, "y": -406.427979, "z": 5.31399727 }, - // "Category": "Switch" - // }, - // { // cargo elevator - // "Text": "floor_button (1)", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -112.378006, "y": -406.806, "z": 5.353998 }, - // "Category": "Switch" - // }, - { - "Text": "Main Elevator Power Button", - "ImagePath": "Markers/lever.png", - "Position": { "x": -271.439, "y": -366.10498, "z": -2.380001 }, - "Category": "Switch", - }, - // { // main elevator - // "Text": "floor_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -282.361, "y": -335.86, "z": -2.91199875 }, - // "Category": "Switch" - // }, - { - "Text": "Open Parking Gate", - "ImagePath": "Markers/lever.png", - "Position": { "x": -243.443, "y": -382.513, "z": 5.076 }, - "Category": "Switch", - }, - { - "Text": "Water Level Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -136.76, "y": -254.510513, "z": -2.825999 }, - "Category": "Switch", - }, - // { // not sure, located in sterile lab? - // "Text": "Power", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -121.007996, "y": -353.548, "z": -2.83698225 }, - // "Category": "Switch" - // }, - // { // medical block elevator - // "Text": "floor_button", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": -112.802, "y": -342.762, "z": -2.84599972 }, - // "Category": "Switch" - // }, - { - "Text": "Disable Parking Gate Alarm", - "ImagePath": "Markers/lever.png", - "Position": { "x": -220.756, "y": -381.263, "z": 5.249 }, - "Category": "Switch", - }, - { - "Text": "TerraGroup Manager's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -165.246277, "y": -349.197, "z": 5.131374 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2a1e86f77431ea0ea84c", - }, - { - "Text": "TerraGroup Manager's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -165.242874, "y": -338.086, "z": 5.135374 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2a1e86f77431ea0ea84c", - }, - { - "Text": "Weapon Testing Area", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -181.966461, "y": -318.226044, "z": 1.37873685 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2d1f86f77431e9280bee", - }, - { - "Text": "Weapon Testing Area", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -179.862, "y": -310.3296, "z": 1.37899876 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e2d1f86f77431e9280bee", - }, - { - "Text": "Infirmary (Blue)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -123.229095, "y": -406.524384, "z": 1.03631592 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0c5f86f7744bb2683cf0", - }, - { - "Text": "Sterile Lab (Green)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -135.89798, "y": -346.9675, "z": 5.185806 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0dc586f7744baf2e7b79", - }, - { - "Text": "Sterile Lab (Green)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -138.6131, "y": -346.966125, "z": 5.25222349 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0dc586f7744baf2e7b79", - }, - { - "Text": "Card with a Blue Marking", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -130.268463, "y": -339.944275, "z": 5.15560675 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5efde6b4f5448336730dbd61", - }, - { - "Text": "Security #2 (Yellow)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -212.695, "y": -376.538, "z": 5.145301 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0d6d86f7744bb2683e1f", - }, - { - "Text": "Test Room (Black)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -132.893, "y": -348.72, "z": 1.43501759 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0f4986f7744bb01837fa", - }, - { - "Text": "Test Room (Black)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -128.794, "y": -349.91507, "z": 1.43701744 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0f4986f7744bb01837fa", - }, - { - "Text": "Security Office (Violet)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -261.993, "y": -317.240021, "z": 5.147805 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1e495a86f7743109743dfb", - }, - { - "Text": "Security Office (Red)", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -257.222015, "y": -322.925018, "z": 5.24803066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1d0efb86f7744baf2e7b7b", - }, - { - "Text": "Arsenal Storage", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -250.839066, "y": -326.758667, "z": 5.097125 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5c1f79a086f7746ed066fb8f", - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc deleted file mode 100644 index 61e9e94f..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Lighthouse_TarkovData/Lighthouse_TarkovData.jsonc +++ /dev/null @@ -1,320 +0,0 @@ -{ - "DisplayName": "Lighthouse (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["Lighthouse"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -545, "y": -998 }, - "Max": { "x": 512, "y": 721 }, - }, - "DefaultLevel": 0, - "Layers": { - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Lighthouse_TarkovData/Layers/lighthouse_layer_0.png", - "ImageBounds": { - "Min": { "x": -545, "y": -998 }, - "Max": { "x": 512, "y": 721 }, - }, - "GameBounds": [ - { - "Min": { "x": -545, "y": -998, "z": -100 }, - "Max": { "x": 512, "y": 721, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Train Yard", - "Position": { "x": -30, "y": -882, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Drug Lab", - "Position": { "x": -120, "y": -841, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Water Treatment", - "Position": { "x": -65, "y": -600, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Plant 1", - "Position": { "x": 40, "y": -618, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Plant 2", - "Position": { "x": -98, "y": -742, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Plant 3", - "Position": { "x": -189, "y": -665, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Pipes", - "Position": { "x": -182, "y": -552, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Gunner Nest", - "Position": { "x": 18, "y": -453, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Island", - "Position": { "x": -177, "y": -356, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cabins", - "Position": { "x": -278, "y": -323, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cottages", - "Position": { "x": -162, "y": -225, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Convenience", - "Position": { "x": -55, "y": -288, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Red Brick", - "Position": { "x": -75, "y": -284, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Hillside", - "Position": { "x": -147, "y": -247, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Boathouses", - "Position": { "x": 125, "y": -153, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Dead Tree", - "Position": { "x": 62, "y": -60, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Construction", - "Position": { "x": 0, "y": -188, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Pikes Peak Resort", - "Position": { "x": -107, "y": -53, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Grand Chalet", - "Position": { "x": -133, "y": 100, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Tennis Court", - "Position": { "x": -70, "y": 129, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Lightkeeper Island", - "Position": { "x": 382, "y": 496, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crash Site", - "Position": { "x": -125, "y": 296, "z": 0 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "Side Tunnel (Shoreline, Tunnel)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -68.3, "y": 318.11, "z": 6.83 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Scav Hideout at the Grotto (Artem)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 180.66, "y": -485.94, "z": 1.18 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Road to Military Base SUV (Reserve, CP Fence*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -328.951263, "y": -784.3581, "z": 16.73 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Mountain Pass (Shoreline, Path to Lighthouse*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -172.35, "y": -6.39, "z": 41.89 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Path to Shoreline", - "ImagePath": "Markers/exit.png", - "Position": { "x": -364.4, "y": -121.4, "z": 28.758 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Northern Checkpoint (Woods/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 111.943, "y": -991.981, "z": 11.86 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Southern Road (Shoreline, Ruined Road)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -295.8, "y": 420.6, "z": 11.86 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Armored Train (all maps besides GZ*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 6.27001953, "y": -873.78, "z": 14.1133 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - // { - // "Text": "OuterSwitcher", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 445.3035, "y": 457.5599, "z": 33.391 }, - // "Category": "Switch" - // }, - // { - // "Text": "InnerSwitcher", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 444.6317, "y": 457.6145, "z": 33.391 }, - // "Category": "Switch" - // }, - // { - // "Text": "railing_door 1", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 445.426117, "y": 458.187561, "z": 32.1270027 }, - // "Category": "Switch" - // }, - { - "Text": "Convenience Store Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -58.5892944, "y": -292.9962, "z": 6.55390024 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61a64428a8c6aa1b795f0ba1", - }, - { - "Text": "Shared Bedroom", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 328.6411, "y": 487.244019, "z": 6.041643 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987dfc402c7f69bf010923", - }, - { - "Text": "Conference Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 333.8, "y": 519.1168, "z": 6.0705 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987cb98081af308d7558c8", - }, - { - "Text": "Merin Trunk", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 91.1099854, "y": -130.918991, "z": 8.382999 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61aa5b518f5e7a39b41416e2", - }, - { - "Text": "Radar Station Commandant Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 355.204, "y": 549.386963, "z": 16.545002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987c658081af308d7558c6", - }, - { - "Text": "Hillside House", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -147.043427, "y": -243.326172, "z": 12.66918 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61a6444b8c141d68246e2d2f", - }, - { - "Text": "Operating Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 32.899, "y": -636.186, "z": 5.93999767 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987da96188c076bc0d8c51", - }, - { - "Text": "Water Treatment Plant Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -120.901962, "y": -736.4641, "z": 5.938982 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62987e26a77ec735f90a2995", - }, - { - "Text": "Rogue USEC Barrack", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -176.519043, "y": -654.164063, "z": 5.939995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "62a9cb937377a65d7b070cef", - }, - { - "Text": "Police Car", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 83.79875, "y": -553.2562, "z": 6.61099958 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61aa5aed32a4743c3453d319", - }, - { - "Text": "Rogue USEC Workshop", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -168.6745, "y": -497.287079, "z": 5.798998 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61aa81fcb225ac1ead7957c3", - }, - { - "Text": "Rogue USEC Stash", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 47.3759, "y": -553.3956, "z": 5.67344 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "61a64492ba05ef10d62adcc1", - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc deleted file mode 100644 index 87f17ccb..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Reserve_TarkovData/Reserve_TarkovData.jsonc +++ /dev/null @@ -1,556 +0,0 @@ -{ - "DisplayName": "Reserve (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["RezervBase"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -303.5, "y": -275 }, - "Max": { "x": 292, "y": 271.5 }, - }, - "DefaultLevel": 0, - "Layers": { - "Bunkers": { - "Level": -1, - "ImagePath": "Maps/Reserve_TarkovData/Layers/reserve_layer_-1.png", - "ImageBounds": { - "Min": { "x": -303.5, "y": -275 }, - "Max": { "x": 292, "y": 271.5 }, - }, - "GameBounds": [ - { - "Min": { "x": -303.5, "y": -275, "z": -100 }, - "Max": { "x": 292, "y": 271.5, "z": -8 }, - }, - ], - }, - "Ground Level": { - "Level": 0, - "ImagePath": "Maps/Reserve_TarkovData/Layers/reserve_layer_0.png", - "ImageBounds": { - "Min": { "x": -303.5, "y": -275 }, - "Max": { "x": 292, "y": 271.5 }, - }, - "GameBounds": [ - { - "Min": { "x": -303.5, "y": -275, "z": -8 }, - "Max": { "x": 292, "y": 271.5, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "K Buildings", - "Position": { "x": 31, "y": -104, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "White Queen", - "Position": { "x": -25, "y": 180, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "White Pawn", - "Position": { "x": -104, "y": 93, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Black Bishop", - "Position": { "x": -140, "y": -14.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White Bishop", - "Position": { "x": -67, "y": -30, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White King", - "Position": { "x": -49.5, "y": 15.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Black Knight", - "Position": { "x": 14.5, "y": -10.8, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White Knight", - "Position": { "x": 82.2, "y": -30.2, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "White Rook", - "Position": { "x": 149, "y": -124, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "Train Station", - "Position": { "x": 161, "y": -149, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "Black Pawn", - "Position": { "x": -165, "y": 57, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Barracks", - "Position": { "x": 165, "y": -215, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "E1 Bunkers", - "Position": { "x": -220, "y": -13, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "E2 Bunkers", - "Position": { "x": 173, "y": -3, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "д - Warehouse Bunkers", - "Position": { "x": 82, "y": -170, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "Garage", - "Position": { "x": 98.5, "y": 29.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Mechanic", - "Position": { "x": 55.5, "y": 60.6, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Gas Station", - "Position": { "x": 29.7, "y": 29.5, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 14.5, - }, - { - "Text": "Shipping Yard", - "Position": { "x": -31, "y": -150, "z": 0 }, - "FontSize": 16, - "DegreesRotation": 14.5, - }, - { - "Text": "K1", - "Position": { "x": 8, "y": -76, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K2", - "Position": { "x": 65.5, "y": -92, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K3", - "Position": { "x": 2, "y": -96.5, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K4", - "Position": { "x": 60, "y": -112, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K5", - "Position": { "x": -4, "y": -118, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "K6", - "Position": { "x": 54, "y": -133, "z": 0 }, - "FontSize": 12, - "DegreesRotation": 14.5, - }, - { - "Text": "Dome", - "Position": { "x": -8.5, "y": 175, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Tarmac", - "Position": { "x": -120, "y": 37, "z": 0 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "Scav Lands (Customs, Military Base CP)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -124.67, "y": -144.92, "z": -3.28 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Hole in the Wall (Customs, Dorms Car*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -261.41, "y": 47.95, "z": -6.033997 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Checkpoint Fence (Lighthouse, Northeast Mountains*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 66.76, "y": 138.26, "z": -4.43 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "D-2 (Peacekeeper/Shoreline*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -121.479065, "y": 172.24913, "z": -17.0010071 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Bunker Hermetic Door (Scorpion/Woods*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 62.3918457, "y": -194.269928, "z": -5.257 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Cliff Descent (Shoreline, Climber's Trail)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -12.8, "y": 206.78, "z": 20.93 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewer Manhole (Sally/Streets)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 40.18, "y": 76.45, "z": -5.12 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Armored Train (all maps besides GZ*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 144.986, "y": -147.352, "z": -3.92 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Bunker Hermetic Door Power", - "ImagePath": "Markers/lever.png", - "Position": { "x": -60.7597275, "y": 78.22821, "z": -5.55217171 }, - "Category": "Switch", - }, - { - "Text": "D-2 Power Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -117.184174, "y": 22.6676826, "z": -12.954 }, - "Category": "Switch", - }, - // { // near bunker hermetic door - // "Text": "Reset", - // "ImagePath": "Markers/lever.png", - // "Position": { "x": 65.71171, "y": -190.604248, "z": -6.683 }, - // "Category": "Switch" - // }, - { - "Text": "D-2 Open Switch", - "ImagePath": "Markers/lever.png", - "Position": { "x": -117.449867, "y": 168.546936, "z": -16.9842987 }, - "Category": "Switch", - }, - { - "Text": "RB-AO", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 194.756973, "y": -203.553268, "z": -5.801999 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c66d86f774405611c7d6", - }, - { - "Text": "RB-VO Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 189.6508, "y": -224.790009, "z": -5.8030014 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c62a86f7744036212b3f", - }, - { - "Text": "RB-KPRL", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -40.4498749, "y": 173.891434, "z": 19.66215 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e0e0e86f774321140eb56", - }, - { - "Text": "RB-KPRL", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -44.2896843, "y": 171.655853, "z": 19.6481476 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e0e0e86f774321140eb56", - }, - { - "Text": "RB-ST", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 100.7764, "y": 43.67282, "z": -6.714003 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d9f1fa686f774726974a992", - }, - { - "Text": "RB-SMP", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -78.7131653, "y": -29.4600983, "z": -3.78035355 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d947d3886f774447b415893", - }, - { - "Text": "RB-KSM", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -60.01116, "y": -34.5081, "z": -3.78035355 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d947d4e86f774447b415895", - }, - { - "Text": "RB-PSP1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 71.1095, "y": -146.997528, "z": -11.128006 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cb3886f77440556dbf09", - }, - { - "Text": "RB-PSP2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 83.5344238, "y": -100.622009, "z": -11.1000061 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d95d6fa86f77424484aa5e9", - }, - { - "Text": "RB-PSV2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 42.9962158, "y": -114.069916, "z": -11.1259995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d95d6be86f77424444eb3a7", - }, - { - "Text": "RB-PSV1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 50.81842, "y": -91.86203, "z": -11.1000061 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cb5686f77440545d1286", - }, - { - "Text": "RB-PSP1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 80.91522, "y": -124.236908, "z": -11.128006 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cb3886f77440556dbf09", - }, - { - "Text": "RB-PSV2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 38.3938, "y": -138.232147, "z": -11.128006 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d95d6be86f77424444eb3a7", - }, - { - "Text": "RB-AK", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -134.622513, "y": -12.8279257, "z": -2.13919544 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c78786f774403a401e3e", - }, - { - "Text": "RB-AM", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -133.289352, "y": -16.0929947, "z": -5.13899755 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c88d86f77440556dbf07", - }, - { - "Text": "RB-TB", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -162.7683, "y": 65.7317047, "z": -8.171001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c6fc86f774403a401e3c", - }, - { - "Text": "RB-ORB2", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -123.018578, "y": 98.53613, "z": -2.36699772 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80ccdd86f77474f7575e02", - }, - { - "Text": "RB-OB", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -167.807968, "y": 34.4820557, "z": 0.525999069 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c6c586f77440351beef1", - }, - { - "Text": "RB-ORB3", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -170.236115, "y": 33.9814758, "z": -2.36400938 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cd1a86f77402aa362f42", - }, - { - "Text": "RB-ORB1", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -122.855316, "y": 97.5226746, "z": 3.43500519 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80ccac86f77470841ff452", - }, - { - "Text": "RB-BK Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -157.878387, "y": 72.86379, "z": -8.188297 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c60f86f77440373c4ece", - }, - { - "Text": "RB-RH", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -51.4290428, "y": 19.6974564, "z": 0.3399992 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da5cdcd86f774529238fb9b", - }, - { - "Text": "RB-OP", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -68.47772, "y": 22.4145622, "z": -9.729001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c8f586f77440373c4ed0", - }, - { - "Text": "RB-GN", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -62.8870544, "y": 31.4578876, "z": -9.723853 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e3ecc86f774414c78d05e", - }, - { - "Text": "RB-KORL", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -2.507956, "y": 174.912, "z": 23.420002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e0db586f7744450412a42", - }, - { - "Text": "RB-RS", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -0.7069602, "y": 182.247, "z": 23.42 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5da46e3886f774653b7a83fe", - }, - { - "Text": "RB-RLSA", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -10.9659786, "y": 180.645, "z": 23.420002 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ede7b0c6d23e5473e6e8c66", - }, - { - // seems to be straight on MP22 but the floor below - "Text": "RB-MP13", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 87.58351, "y": -37.0245056, "z": -5.82550049 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cbd886f77470855c26c2", - }, - { - "Text": "RB-MP21", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 10.9685087, "y": -7.38929558, "z": -2.99313354 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80ca9086f774403a401e40", - }, - { - "Text": "RB-MP11", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 8.245274, "y": -17.522274, "z": -5.851448 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c95986f77440351beef3", - }, - { - "Text": "RB-MP12", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 8.266094, "y": -17.478508, "z": -3.00213623 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80c93086f7744036212b41", - }, - { - "Text": "RB-MP22", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 87.5893555, "y": -37.00447, "z": -2.98300171 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d80cab086f77440535be201", - }, - { - "Text": "RB-PKPM Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -120.251823, "y": 27.7044983, "z": -13.483 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5ede7a8229445733cb4c18e2", - }, - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc deleted file mode 100644 index 92c858e4..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Shoreline_TarkovData/Shoreline_TarkovData.jsonc +++ /dev/null @@ -1,548 +0,0 @@ -{ - "DisplayName": "Shoreline (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["Shoreline"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "DefaultLevel": 0, - "Layers": { - "Underground": { - "Level": -1, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_-1.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - // west wing - "Min": { "x": -237, "y": -104, "z": -100 }, - "Max": { "x": -137, "y": -68, "z": -5 }, - }, - { - // admin - "Min": { "x": -268, "y": -163, "z": -100 }, - "Max": { "x": -234, "y": -134, "z": -5 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_0.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - "Min": { "x": -1060, "y": -415, "z": -100 }, - "Max": { "x": 508, "y": 622, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_1.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - "Min": { "x": -375, "y": -178, "z": -1 }, - "Max": { "x": -128, "y": -55, "z": 2 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Shoreline_TarkovData/Layers/shoreline_layer_2.png", - "ImageBounds": { - "Min": { "x": -1060, "y": -415 }, - "Max": { "x": 508, "y": 622 }, - }, - "GameBounds": [ - { - "Min": { "x": -375, "y": -178, "z": 2 }, - "Max": { "x": -128, "y": -55, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Resort", - "Position": { "x": -252, "y": -71.2, "z": -3 }, - "FontSize": 16, - }, - { - "Text": "Power Station", - "Position": { "x": -215.8, "y": 178.4, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Gas Station", - "Position": { "x": -189.3, "y": 420, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Weather Station", - "Position": { "x": -496, "y": 257, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Radio Tower", - "Position": { "x": -708.9, "y": 93.9, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Swamp", - "Position": { "x": 326, "y": -118.5, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Village", - "Position": { "x": 418.4, "y": 118, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cabins", - "Position": { "x": 288, "y": 144, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cottages", - "Position": { "x": 128, "y": 93, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Tank Bridge", - "Position": { "x": -355, "y": 188, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Pier", - "Position": { "x": -338.6, "y": 525, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Scav Island", - "Position": { "x": 216, "y": 424, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Bus Stop", - "Position": { "x": -96, "y": -6, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Construction", - "Position": { "x": 52, "y": 134, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Bunker", - "Position": { "x": -153, "y": -290, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crane", - "Position": { "x": -625, "y": 484, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Scav Farm", - "Position": { "x": -622, "y": -202, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "West Wing", - "Position": { "x": -171, "y": -83, "z": -3 }, - "FontSize": 16, - }, - { - "Text": "East Wing", - "Position": { "x": -329, "y": -83, "z": -3 }, - "FontSize": 16, - }, - { - "Text": "Admin", - "Position": { "x": -252, "y": -146, "z": -3 }, - "FontSize": 16, - }, - ], - "StaticMarkers": [ - { - "Text": "Ruined Road (Lighthouse, Southern Road)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 368.559326, "y": 334.897644, "z": -61.12998 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Old Bunker (Peacekeeper)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -388.99, "y": -383.73, "z": -2.66 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Smuggler's Path (Customs/Reserve*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -730.79, "y": -255.47, "z": -26.0 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "North Fence SUV (Customs, Dorms SUV)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -542.9488, "y": -381.020721, "z": -16.9900017 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Road to Customs (Customs, Sniper Roadblock*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -861.65, "y": -0.36, "z": -41.7699776 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Railway Bridge (Ref/Customs)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -1026.47, "y": 299.85, "z": -60.79 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Tunnel (Lighthouse, Side Tunnel)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 376.36, "y": 319.25, "z": -55.9399757 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Path to Lighthouse", - "ImagePath": "Markers/exit.png", - "Position": { "x": 448.9, "y": -254.6, "z": -44.7 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Pier Boat (Lighthouse*/Customs/Woods*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -336.8407, "y": 568.4276, "z": -66.11997 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - }, - { - "Text": "Climber's Trail (Reserve, Cliff Descent)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -204.5, "y": -359.71, "z": -10.74 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "HEP Station Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -220.38063, "y": 185.880585, "z": -33.858 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e15b686f774445103b190", - }, - { - "Text": "HEP Station Storage Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -220.703171, "y": 193.687332, "z": -33.8470345 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5d8e15b686f774445103b190", - }, - { - "Text": "SMW Car", - "ImagePath": "Markers/car_door.png", - "Position": { "x": 157.352051, "y": 133.891, "z": -47.3859329 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eb38b86f774153b320eb0", - }, - { - "Text": "Cottage Back Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 102.532318, "y": 102.731339, "z": -47.2590027 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eb6ac86f7743124037a28", - }, - { - "Text": "West Wing Room 203", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -229.608261, "y": -92.90662, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a144dfd86f77445cb5a0982", - }, - { - "Text": "West Wing Room 216", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -179.379257, "y": -80.91263, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee30786f774023b6ee08f", - }, - { - "Text": "West Wing Room 306", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -216.905258, "y": -92.90662, "z": 3.03088379 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13f46386f7741dd7384b04", - }, - { - "Text": "West Wing Room 220", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -166.686264, "y": -80.91263, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee34586f774023b6ee092", - }, - { - "Text": "East Wing Room 206", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -285.857239, "y": -92.88861, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee4b586f7743698200d22", - }, - { - "Text": "East Wing Room 205", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -281.692261, "y": -92.88861, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a144bdb86f7741d374bbde0", - }, - { - "Text": "East Wing Room 313", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -313.835754, "y": -84.47537, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eecf686f7740350630097", - }, - { - "Text": "Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -142.583267, "y": -79.9176, "z": 3.05788422 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea79b86f7741d4a35298e", - }, - { - "Text": "West Wing Room 218", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -173.983749, "y": -84.50137, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13eebd86f7746fd639aa93", - }, - { - "Text": "East Wing Room 328", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -357.303284, "y": -79.9165955, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eee1486f77402aa773226", - }, - { - "Text": "East Wing Room 226", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -351.9118, "y": -84.47537, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13f35286f77413ef1436b0", - }, - { - "Text": "East Wing Office 107", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -333.767029, "y": -79.95798, "z": -2.70200348 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea64786f7741707720468", - }, - { - "Text": "West Wing Room 205", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -221.073288, "y": -92.90662, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ec6d286f7742c0b518fb5", - }, - { - "Text": "East Wing Room 222", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -343.3838, "y": -84.47537, "z": 0.134880066 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13f24186f77410e57c5626", - }, - { - "Text": "West Wing Room 112", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -189.173019, "y": -85.4490051, "z": -2.69580078 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0dc95c86f77452440fc675", - }, - { - "Text": "West Wing Room 104", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -157.433029, "y": -85.4490051, "z": -2.69580078 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0dc45586f7742f6b0b73e3", - }, - { - "Text": "West Wing Room 219", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -170.853256, "y": -80.91263, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13ef0686f7746e5a411744", - }, - { - "Text": "East Wing Room 308", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -294.3863, "y": -92.88861, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a145d7b86f7744cbb6f4a13", - }, - { - "Text": "East Wing Room 310", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -303.411255, "y": -81.46161, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eec9686f77402ac5c39f2", - }, - { - "Text": "West Wing Room 301", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -229.202621, "y": -100.151733, "z": 3.03088379 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a13ef7e86f7741290491063", - }, - { - "Text": "West Wing Room 222", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -161.293747, "y": -84.50137, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a1452ee86f7746f33111763", - }, - { - "Text": "Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -142.583267, "y": -79.9176, "z": 0.164085388 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea79b86f7741d4a35298e", - }, - { - "Text": "East Wing Room 306", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -285.857239, "y": -92.88861, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a145d4786f7744cbb6f4a12", - }, - { - "Text": "Utility Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -360.193237, "y": -79.8936157, "z": 3.04288483 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ea79b86f7741d4a35298e", - }, - { - "Text": "East Wing Room 316", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -323.389282, "y": -80.8936157, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a145ebb86f77458f1796f05", - }, - { - "Text": "East Wing Room 314", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -317.992737, "y": -84.47537, "z": 3.02988434 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0eed4386f77405112912aa", - }, - { - "Text": "East Wing Sanitar's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -323.547, "y": -79.961, "z": -2.70200348 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5eff09cd30a7dc22fd1ddfed", - }, - { - "Text": "West Wing Room 223", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -165.451767, "y": -84.50137, "z": 0.137084961 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "5a0ee37f86f774023657a86f", - }, - // { - // "Text": "safe 1", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": -266.10675, "y": -147.65097, "z": -0.3202896 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0f08bc86f77478f33b84c2" - // }, - // { - // "Text": "West Wing Room 321 Safe", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": -165.664047, "y": -89.05765, "z": 2.53099823 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0eff2986f7741fd654e684" - // }, - // { - // "Text": "Cottage Safe", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": 93.71925, "y": 111.979019, "z": -45.01355 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0f068686f7745b0d4ea242" - // }, - // { - // "Text": "safe 4", - // "ImagePath": "Markers/locked_safe.png", - // "Position": { "x": -242.451981, "y": -153.367249, "z": -0.3202896 }, - // "Category": "Locked", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5a0f0f5886f7741c4e32a472" - // } - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc deleted file mode 100644 index a4ecd897..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Streets_TarkovData/Streets_TarkovData.jsonc +++ /dev/null @@ -1,1092 +0,0 @@ -{ - "DisplayName": "Streets of Tarkov (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["TarkovStreets"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "DefaultLevel": 0, - "Layers": { - "Underground": { - "Level": -1, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_-1.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // Concordia underground - "Min": { "x": 147, "y": 338, "z": -4 }, - "Max": { "x": 277, "y": 416, "z": 0 }, - }, - { - // Subway underground - "Min": { "x": -15, "y": -25, "z": -5 }, - "Max": { "x": 39, "y": 33, "z": -2 }, - }, - ], - }, - "Ground Floor": { - "Level": 0, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_0.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - "Min": { "x": -279, "y": -299, "z": -100 }, - "Max": { "x": 324, "y": 533, "z": 100 }, - }, - ], - }, - "2nd Floor": { - "Level": 1, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_1.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // concordia 2nd floor - "Min": { "x": 128, "y": 339, "z": 6 }, - "Max": { "x": 287, "y": 416, "z": 9 }, - }, - { - // building south of concordia 2nd floor - "Min": { "x": 128, "y": 335, "z": 6 }, - "Max": { "x": 152, "y": 460, "z": 9 }, - }, - { - // real estate agency office 2nd floor - "Min": { "x": -68, "y": 449, "z": 6 }, - "Max": { "x": -34, "y": 475, "z": 10 }, - }, - { - // cinema 2nd floor - "Min": { "x": -197, "y": 370, "z": 6 }, - "Max": { "x": -120, "y": 432, "z": 12 }, - }, - { - // courtyard building 2nd floor - "Min": { "x": -175, "y": 477, "z": 6 }, - "Max": { "x": -160, "y": 491, "z": 10 }, - }, - { - // north of courtyard building 2nd floor - "Min": { "x": -189, "y": 451, "z": 6 }, - "Max": { "x": -171, "y": 473, "z": 10 }, - }, - { - // construction 2nd floor - "Min": { "x": 188, "y": 284, "z": 6 }, - "Max": { "x": 218, "y": 314, "z": 10 }, - }, - { - // Sparja grocery 2nd floor - "Min": { "x": 107, "y": 283, "z": 6 }, - "Max": { "x": 132, "y": 294, "z": 10 }, - }, - { - // Lexos 2nd floor - "Min": { "x": 46, "y": 257, "z": 5.5 }, - "Max": { "x": 106, "y": 352, "z": 10 }, - }, - { - // abandoned factory 2nd floor - "Min": { "x": -156, "y": 265, "z": 3 }, - "Max": { "x": -77, "y": 305, "z": 6 }, - }, - { - // hotels 2nd floor - "Min": { "x": -214, "y": 235, "z": 6 }, - "Max": { "x": -163, "y": 307, "z": 10 }, - }, - { - // financial office 2nd floor - "Min": { "x": -190, "y": 217, "z": 5.5 }, - "Max": { "x": -157, "y": 235, "z": 8 }, - }, - { - // family market 2nd floor - "Min": { "x": -234, "y": 271, "z": 4.5 }, - "Max": { "x": -209, "y": 290, "z": 7 }, - }, - { - // tarbank 2nd floor - "Min": { "x": 31, "y": 198, "z": 6 }, - "Max": { "x": 88, "y": 240, "z": 9 }, - }, - { - // chekannaya apartments 2nd floor - "Min": { "x": 91, "y": 205, "z": 6 }, - "Max": { "x": 161, "y": 240, "z": 9 }, - }, - { - // pharmacy 1 2nd floor - "Min": { "x": 32, "y": 144, "z": 5 }, - "Max": { "x": 57, "y": 173, "z": 8 }, - }, - { - // post office 2nd floor - "Min": { "x": 31, "y": 60, "z": 3 }, - "Max": { "x": 59, "y": 140, "z": 6 }, - }, - { - // archive building 2nd floor - "Min": { "x": 74, "y": 122, "z": 3.5 }, - "Max": { "x": 90, "y": 146, "z": 7 }, - }, - { - // zmeisky apartment 2nd floor - "Min": { "x": 99, "y": 118, "z": 3.5 }, - "Max": { "x": 140, "y": 159, "z": 7 }, - }, - { - // vet clinic 2nd floor - "Min": { "x": 209, "y": 166, "z": 3 }, - "Max": { "x": 235, "y": 183, "z": 6 }, - }, - { - // x-ray building 2nd floor - "Min": { "x": 180, "y": 91, "z": 1 }, - "Max": { "x": 197, "y": 127, "z": 4 }, - }, - { - // school 2nd floor - "Min": { "x": 199, "y": 96, "z": 3 }, - "Max": { "x": 224, "y": 160, "z": 6 }, - }, - { - // rusted key door building 2nd floor - "Min": { "x": 173, "y": 48, "z": -2 }, - "Max": { "x": 199, "y": 85, "z": 1 }, - }, - { - // CCCP building 2nd floor - "Min": { "x": 241, "y": 45, "z": -2 }, - "Max": { "x": 253, "y": 62, "z": 1 }, - }, - { - // pinewood hotel complex 2nd floor - "Min": { "x": -125, "y": 45, "z": 4 }, - "Max": { "x": -13, "y": 173, "z": 6.5 }, - }, - { - // kilov shopping mall + beluga 2nd floor - "Min": { "x": -171, "y": -89, "z": 4 }, - "Max": { "x": -14, "y": -7, "z": 6.5 }, - }, - { - // cardinal bank building 2nd floor - "Min": { "x": -97, "y": -73, "z": 2 }, - "Max": { "x": 149, "y": -14, "z": 6 }, - }, - { - // cardinal apartments northeast 2nd floor - "Min": { "x": 39, "y": -160, "z": 8.5 }, - "Max": { "x": 77, "y": -114, "z": 12 }, - }, - { - // across primorsky ave from cardinal 2nd floor - "Min": { "x": -73, "y": -160, "z": 5 }, - "Max": { "x": -44, "y": -141, "z": 8 }, - }, - ], - }, - "3rd Floor": { - "Level": 2, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_2.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // concordia 3rd floor - "Min": { "x": 128, "y": 339, "z": 9 }, - "Max": { "x": 287, "y": 416, "z": 12 }, - }, - { - // cinema 3rd floor - "Min": { "x": -179, "y": 377, "z": 12 }, - "Max": { "x": -155, "y": 423, "z": 18 }, - }, - { - // abandoned factory 3rd floor - "Min": { "x": -156, "y": 265, "z": 6 }, - "Max": { "x": -77, "y": 305, "z": 11 }, - }, - { - // family market 3rd floor - "Min": { "x": -234, "y": 271, "z": 7 }, - "Max": { "x": -209, "y": 290, "z": 10 }, - }, - { - // tarbank 3rd floor - "Min": { "x": 31, "y": 198, "z": 9 }, - "Max": { "x": 88, "y": 240, "z": 12 }, - }, - { - // chekannaya apartments 3rd floor - "Min": { "x": 91, "y": 205, "z": 9 }, - "Max": { "x": 161, "y": 240, "z": 12 }, - }, - { - // post office 3rd floor - "Min": { "x": 31, "y": 60, "z": 6 }, - "Max": { "x": 59, "y": 140, "z": 9 }, - }, - { - // zmeisky apartment 3rd floor - "Min": { "x": 99, "y": 118, "z": 7 }, - "Max": { "x": 140, "y": 159, "z": 9 }, - }, - { - // rusted key door building 3rd floor - "Min": { "x": 173, "y": 48, "z": 1 }, - "Max": { "x": 199, "y": 85, "z": 4 }, - }, - { - // pinewood hotel complex 3rd floor - "Min": { "x": -125, "y": 45, "z": 6.5 }, - "Max": { "x": -13, "y": 173, "z": 12 }, - }, - { - // kilov shopping mall + beluga 3rd floor - "Min": { "x": -171, "y": -79, "z": 6.5 }, - "Max": { "x": -14, "y": -5, "z": 12 }, - }, - { - // cardinal apartments northeast 3rd floor - "Min": { "x": 39, "y": -160, "z": 12 }, - "Max": { "x": 77, "y": -114, "z": 15 }, - }, - { - // across primorsky ave from cardinal 3rd floor - "Min": { "x": -73, "y": -160, "z": 8 }, - "Max": { "x": -44, "y": -141, "z": 12 }, - }, - ], - }, - "4th Floor": { - "Level": 3, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_3.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // abandoned factory 4th floor - "Min": { "x": -140, "y": 263, "z": 11 }, - "Max": { "x": -123, "y": 278, "z": 15 }, - }, - { - // family market 4th floor - "Min": { "x": -234, "y": 271, "z": 10 }, - "Max": { "x": -209, "y": 290, "z": 14 }, - }, - { - // tarbank 4th floor - "Min": { "x": 31, "y": 198, "z": 12 }, - "Max": { "x": 88, "y": 240, "z": 15 }, - }, - { - // post office 4th floor + apartments - "Min": { "x": 31, "y": 60, "z": 9 }, - "Max": { "x": 59, "y": 164, "z": 14 }, - }, - { - // zmeisky apartment 4th floor - "Min": { "x": 99, "y": 118, "z": 9 }, - "Max": { "x": 140, "y": 159, "z": 12 }, - }, - { - // rusted key door building 4th floor - "Min": { "x": 173, "y": 48, "z": 4 }, - "Max": { "x": 199, "y": 85, "z": 8 }, - }, - ], - }, - "5th Floor": { - "Level": 4, - "ImagePath": "Maps/Streets_TarkovData/Layers/streets_layer_4.png", - "ImageBounds": { - "Min": { "x": -279, "y": -299 }, - "Max": { "x": 324, "y": 533 }, - }, - "GameBounds": [ - { - // zmeisky apartment 5th floor - "Min": { "x": 99, "y": 118, "z": 12 }, - "Max": { "x": 140, "y": 159, "z": 15 }, - }, - { - // rusted key door building 5th floor - "Min": { "x": 170, "y": 81, "z": 8 }, - "Max": { "x": 181, "y": 89, "z": 12 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Primorsky Ave.", - "Position": { "x": 9, "y": 308, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Primorsky Ave.", - "Position": { "x": 9, "y": 104, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Primorsky Ave.", - "Position": { "x": 9, "y": -80, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Kilmov St.", - "Position": { "x": 125, "y": 10, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Kilmov St.", - "Position": { "x": -104, "y": 28, "z": 0 }, - "FontSize": 14, - "DegreesRotation": 10, - }, - { - "Text": "Nikitskaya St.", - "Position": { "x": -125, "y": 210, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Verhnyaya St.", - "Position": { "x": -112, "y": 361, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Malevecha St.", - "Position": { "x": -200, "y": 290, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -64, - }, - { - "Text": "Chekannaya St.", - "Position": { "x": 111, "y": 251, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Nizhnyaya St.", - "Position": { "x": -101, "y": 441, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Razvedchikov St.", - "Position": { "x": 174, "y": 430, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -30, - }, - { - "Text": "Zmejskij Alley", - "Position": { "x": 140, "y": 150, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -68, - }, - { - "Text": "Kamchatskaya St.", - "Position": { "x": 232, "y": 100, "z": 0 }, - "FontSize": 14, - "DegreesRotation": -90, - }, - { - "Text": "Kilmov Shopping Mall", - "Position": { "x": -128, "y": -35, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Beluga", - "Position": { "x": -45, "y": -52, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cardinal Apartments", - "Position": { "x": 99, "y": -71, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Construction", - "Position": { "x": 230, "y": 295, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Lexos", - "Position": { "x": 66, "y": 305, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Sparja Grocery", - "Position": { "x": 140, "y": 300, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Cinema", - "Position": { "x": -175, "y": 400, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Shestyorochka", - "Position": { "x": -218, "y": 135, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Pinewood Hotel", - "Position": { "x": -35, "y": 64, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Teppakot / Koener", - "Position": { "x": 65, "y": 398, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Concordia", - "Position": { "x": 207, "y": 363, "z": 0 }, - "FontSize": 18, - }, - { - "Text": "Cardinal Bank", - "Position": { "x": 89, "y": -20, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "LERM Expo", - "Position": { "x": 239, "y": -60, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Sparja Express", - "Position": { "x": -64, "y": 166, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Burger Spot", - "Position": { "x": -30, "y": 138, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Post Office", - "Position": { "x": 42, "y": 97, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Pharmacy 1", - "Position": { "x": 42, "y": 160, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Office", - "Position": { "x": -173, "y": 226, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Corner Restaurant", - "Position": { "x": -197, "y": 340, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Pharmacy 2", - "Position": { "x": -43, "y": 335, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Pharmacy 3", - "Position": { "x": 90, "y": -227, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Tarbank", - "Position": { "x": 67, "y": 230, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "School", - "Position": { "x": 211, "y": 129, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Vet Clinic", - "Position": { "x": 222, "y": 173, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Hive", - "Position": { "x": -212, "y": 300, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Family Market", - "Position": { "x": -223, "y": 279, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Marked Hotel", - "Position": { "x": -200, "y": 248, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "South Hotel", - "Position": { "x": -175, "y": 297, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Abandoned Factory", - "Position": { "x": -119, "y": 287, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Diner", - "Position": { "x": -80, "y": 235, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Primorskij 49", - "Position": { "x": -13, "y": 244, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Prestigio Cage", - "Position": { "x": 39, "y": 230, "z": 0 }, - "FontSize": 10, - }, - { - "Text": "Bilbo Coffee", - "Position": { "x": -70, "y": 343, "z": 0 }, - "FontSize": 10, - }, - ], - "StaticMarkers": [ - { - "Text": "Basement Descent (Coyote/Labs/Ground Zero)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 74.769, "y": 49.22, "z": -0.701999664 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Entrance to Catacombs (Labs, Hangar Gate)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -249.008026, "y": 243.797, "z": 2.566 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Ventilation Shaft (Lab, Vents)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -124.127106, "y": 425.738983, "z": 3.114 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewer Manhole (Sally/Reserve)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 276.113, "y": 345.389984, "z": 5.356 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Primorsky Ave Taxi (Woods/Interchange/GZ)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -2.191315, "y": 461.232971, "z": 3.2 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sylovate Elevator (Labs, Main Elevator)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -44.7435, "y": -72.6544, "z": 11.04 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Crash Site (Painter/Customs/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 312.74, "y": 405.96, "z": 6.8 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Sewer River (Labs, Sewage Conduit)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -264.267, "y": 223.92, "z": -1.535 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Klimov Street (Ground Zero, Mira Ave)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -263.41, "y": 43.19, "z": 2.9 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Expo Checkpoint (Ground Zero, Scav Camp)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 213.12, "y": -104.96, "z": 0.09 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "Ruined House (Hephaestus)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -248.971, "y": 344.275, "z": 7.195 }, - "Category": "Extract", - "ShowInRaid": false, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - }, - { - "Text": "MVD Academy Entrance Hall Guard Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -250.476974, "y": 131.546, "z": 3.98400116 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dc4b6ba9e979af6b79f4", - }, - { - "Text": "Pinewood Hotel Room 215", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -67.00622, "y": 59.3249474, "z": 6.024556 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f08cd6db0635c197600", - }, - { - "Text": "Relaxation Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -208.164185, "y": 295.5338, "z": 4.28889942 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dbf0b8d7830efc45016f", - }, - { - "Text": "Abandoned Factory Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -133.4689, "y": 272.9284, "z": 9.712829 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a3a93f8a56922e82001f5d", - }, - { - "Text": "Financial Institution Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -168.1108, "y": 230.025009, "z": 7.11500072 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39667c9b3aa4b61683e98", - }, - { - "Text": "Financial Institution Small Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -186.393311, "y": 229.271469, "z": 3.72240162 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71ed21031ac76fe773c7f", - }, - { - "Text": "Backup Hideout", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -130.730026, "y": 391.625732, "z": 3.37588024 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6398fd8ad3de3849057f5128", - }, - { - "Text": "Real Estate Agency Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -62.37935, "y": 460.344177, "z": 7.906067 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dc5740562727a654ebb1", - }, - { - "Text": "Iron Gate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 131.168167, "y": 227.64386, "z": 10.5814857 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f6e64283b5e9c56b289", - }, - { - "Text": "Iron Gate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 126.369164, "y": 227.644852, "z": 10.5938711 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f6e64283b5e9c56b289", - }, - { - "Text": "Iron Gate", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 132.49292, "y": 225.1011, "z": 10.5825262 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39f6e64283b5e9c56b289", - }, - { - "Text": "Stair Landing", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 108.3958, "y": 224.57489, "z": 7.45609 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39fd1c9b3aa4b61683efb", - }, - { - "Text": "Chekannaya Apartment 15", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 107.048935, "y": 227.6278, "z": 7.51593971 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39fc0af870e651d58e6ae", - }, - { - "Text": "Primorsky 46-48 Skybridge", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 49.5526543, "y": 147.7725, "z": 12.7623 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39e1d234195315d4020bd", - }, - { - "Text": "Primorsky 48 Apartment", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 45.3423576, "y": 151.024933, "z": 6.742015 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71eb5b7f4570d3a29316b", - }, - // { // tarbank cash register - // "Text": "door 17", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 66.95923, "y": 231.536, "z": 3.841999 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "64ccc2111779ad6ba200a139" - // }, - // { // tarbank cash register - // "Text": "door 18", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 68.86824, "y": 231.536, "z": 3.841999 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "64ccc2111779ad6ba200a139" - // }, - { - "Text": "Zmeisky 3 Apartment 8", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 104.26915, "y": 129.2099, "z": 4.99642372 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39dfe3901f439517cafba", - }, - { - "Text": "Archive Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 80.078, "y": 138.528, "z": 4.941001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39e49cd6db0635c1975fc", - }, - { - "Text": "Zmeisky 5 Apartment 20", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 124.2521, "y": 143.391266, "z": 14.5957794 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39df18a56922e82001f25", - }, - { - "Text": "Mysterious Marked Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 186.18, "y": 227.438, "z": 0.849899948 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc25f95763a1ae376e447", - }, - { - "Text": "Rusted Key Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 177.724213, "y": 78.84773, "z": 6.821482 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64d4b23dc1b37504b41ac2b6", - }, - { - "Text": "PE Teacher's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 207.952087, "y": 140.7129, "z": 1.39300013 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc268c41e91416064ebc7", - }, - { - "Text": "X-Ray Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 184.997482, "y": 100.691429, "z": 2.82870531 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc246ff54fb38131acf29", - }, - { - "Text": "\"Negotiation\" Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 165.190918, "y": 165.05, "z": 1.79457092 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "6582dbe43a2e5248357dbe9a", - }, - // { // usec cottage safe key bugged - // "Text": "door 27", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 174.013977, "y": 163.48201, "z": 1.14044952 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - { - "Text": "Construction Site Bunkhouse", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 181.878983, "y": 312.128, "z": 6.85800028 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39cb1c9b3aa4b61683ee2", - }, - { - "Text": "Car Dealership Closed Section", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 63.478, "y": 301.057, "z": 7.8760004 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a397d3af870e651d58e65b", - }, - { - "Text": "Car Dealership Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 66.86121, "y": 310.662476, "z": 7.935705 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a399193901f439517cafb6", - }, - { - "Text": "Cargo Container Mesh Door", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 83.1959839, "y": 296.521, "z": 3.72701359 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39fdf1e21260da44a0256", - }, - { - "Text": "Aspect Company Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 55.03196, "y": 332.649078, "z": 3.91900015 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ce572331dd890873175115", - }, - { - "Text": "Supply Department Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 57.615963, "y": 334.707031, "z": 6.847 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39ce4cd6db0635c1975fa", - }, - { - "Text": "Concordia Apartment 8 Home Cinema", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 217.9483, "y": 400.558655, "z": 10.3969755 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1ec1779ad6ba200a137", - }, - { - "Text": "Concordia Apartment 34", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 227.979279, "y": 406.048645, "z": 10.3969755 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1d4a0f13c24561edf27", - }, - { - "Text": "Concordia Apartment 8", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 224.331543, "y": 400.559357, "z": 10.4224167 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71e781031ac76fe773c7d", - }, - { - "Text": "Concordia Apartment 64 Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 274.591, "y": 383.685974, "z": 7.404751 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71e86b7f4570d3a293169", - }, - { - "Text": "Concordia Apartment 63", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 268.47, "y": 387.507, "z": 7.4047513 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1f4ff54fb38131acf27", - }, - { - "Text": "Concordia Apartment 64", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 272.6917, "y": 378.880249, "z": 7.46978951 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a71e922b25f7513905ca20", - }, - { - "Text": "Concordia Security", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 211.010483, "y": 406.7196, "z": -0.205203056 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39c7964283b5e9c56b280", - }, - { - "Text": "Store Manager's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 119.953995, "y": 290.827026, "z": 7.776001 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "63a39c69af870e651d58e6aa", - }, - { - "Text": "TerraGroup Security Armory", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 60.7049751, "y": -79.95239, "z": 1.29402184 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc24de61ea448b507d34d", - }, - { - "Text": "TerraGroup Meeting Room", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 46.6899338, "y": -59.4043961, "z": 1.31902039 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc206793ca11c8f450a38", - }, - { - "Text": "Beluga Restaurant Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -19.6295967, "y": -64.19723, "z": 10.6449995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1fe088064307e14a6f7", - }, - { - "Text": "Beluga Restaurant Director's Office", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": -27.806633, "y": -60.68901, "z": 10.6449995 }, - "Category": "LockedDoor", - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "AssociatedItemId": "64ccc1fe088064307e14a6f7", - }, - // { // goshan cash register - // "Text": "door 55", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -208.95, "y": 179.655991, "z": 4.057 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5ad7247386f7747487619dc3" - // }, - // { // goshan cash register - // "Text": "door 56", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -208.95, "y": 182.011, "z": 4.059 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5ad7247386f7747487619dc3" - // }, - // { // bugged pinewood safe - // "Text": "door 57", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -77.5323944, "y": 53.20392, "z": 5.3959837 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - // { // bugged pinewood safe - // "Text": "door 58", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -67.94231, "y": 53.4928131, "z": 5.31730938 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - // { // bugged pinewood safe - // "Text": "door 59", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -49.45166, "y": 64.02192, "z": 5.273139 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "61aa5ba8018e9821b7368da9" - // }, - // { // goshan cash register - // "Text": "door 60", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": -30.653595, "y": 468.8241, "z": 3.66407585 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "5ad7247386f7747487619dc3" - // }, - // { // unknown - // "Text": "door 61", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 78.59352, "y": 124.437378, "z": 1.328997 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "63a39e6acd6db0635c1975fe" - // }, - // { // unknown - // "Text": "door 62", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 76.57499, "y": 132.901367, "z": 4.36699724 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "63a39e5b234195315d4020bf" - // }, - // { // unknown - // "Text": "door 63", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 58.10759, "y": 337.684021, "z": 6.26939726 }, - // "Category": "LockedDoor", - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "AssociatedItemId": "63a39ddda3a2b32b5f6e007a" - // } - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc deleted file mode 100644 index 5932da25..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/DynamicMaps/Maps/Woods_TarkovData/Woods_TarkovData.jsonc +++ /dev/null @@ -1,216 +0,0 @@ -{ - "DisplayName": "Woods (TarkovData)", - "Author": "Shebuka", - "AuthorLink": "https://github.com/TarkovTracker/tarkovdata/", - "MapInternalNames": ["Woods"], - "CoordinateRotation": 180, - "Bounds": { - "Min": { "x": -692, "y": -915 }, - "Max": { "x": 647, "y": 443 }, - }, - "DefaultLevel": 0, - "Layers": { - "Ground Level": { - "Level": 0, - "ImagePath": "Maps/Woods_TarkovData/Layers/woods_layer_0.png", - "ImageBounds": { - "Min": { "x": -692, "y": -915 }, - "Max": { "x": 647, "y": 443 }, - }, - "GameBounds": [ - { - "Min": { "x": -692, "y": -915, "z": -100 }, - "Max": { "x": 647, "y": 443, "z": 100 }, - }, - ], - }, - }, - "Labels": [ - { - "Text": "Sawmill", - "Position": { "x": 10, "y": -3, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Scav Town", - "Position": { "x": -485, "y": -390, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Old Sawmill", - "Position": { "x": -517, "y": -210, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Cultist Village", - "Position": { "x": -80, "y": -705, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "USEC Camp", - "Position": { "x": 290, "y": -475, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Military Camp", - "Position": { "x": -188, "y": 235, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Ponds", - "Position": { "x": -5, "y": -515, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Crash Site", - "Position": { "x": -252, "y": -37, "z": 0 }, - "FontSize": 16, - }, - { - "Text": "Checkpoint", - "Position": { "x": 239, "y": -65, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Shack", - "Position": { "x": 244, "y": 125, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Lumber", - "Position": { "x": -16, "y": -122, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Cabins", - "Position": { "x": -3, "y": -74, "z": 0 }, - "FontSize": 14, - }, - { - "Text": "Bus Stop", - "Position": { "x": -234, "y": 368, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Jaeger's Camp", - "Position": { "x": -327, "y": 19, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Sniper Rock", - "Position": { "x": 85, "y": -147, "z": 0 }, - "FontSize": 12, - }, - { - "Text": "Convoy", - "Position": { "x": 200, "y": -606, "z": 0 }, - "FontSize": 12, - }, - ], - "StaticMarkers": [ - { - "Text": "Factory Gate (Customs, Old Gas Gate)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -363.8, "y": 365.53, "z": 1.43 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Scav Bunker (Prapor)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 220.426651, "y": -705.7956, "z": 20.538269 }, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Mountain Stash (Jaeger)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -206.59436, "y": -215.9796, "z": 31.47127 }, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "RUAF Gate (Customs, Factory Corner)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -134.26001, "y": 419.8, "z": -2.37 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "ZB-016 (Hideout/Factory)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -389.159973, "y": 11.0449905, "z": 4.147001 }, - "Color": { "r": 1.0, "g": 1.0, "b": 1.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "ZB-014 (Scorpion)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 447.659973, "y": 57.46, "z": -13.46346 }, - "Color": { "r": 1.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "UN Roadblock (Customs/Interchange)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -527.8743, "y": 288.2304, "z": 1.68126917 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Bridge SUV (Streets/Interchange/GZ)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -484.5639, "y": -506.413239, "z": 15.5812693 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Outskirts (Customs/Lighthouse)", - "ImagePath": "Markers/exit.png", - "Position": { "x": 347.315643, "y": 347.0304, "z": -9.148731 }, - "Color": { "r": 0.0, "g": 1.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "North UN Roadblock (Customs, RUAF Roadblock*)", - "ImagePath": "Markers/exit.png", - "Position": { "x": -561.1143, "y": -58.7096, "z": 9.321269 }, - "Color": { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }, - "Category": "Extract", - "ShowInRaid": false, - }, - { - "Text": "Yotota Car", - "ImagePath": "Markers/car_door.png", - "Position": { "x": -0.1508789, "y": -61.946167, "z": -0.680201769 }, - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "Category": "LockedDoor", - "AssociatedItemId": "591ae8f986f77406f854be45", - }, - { - "Text": "ZB-014", - "ImagePath": "Markers/door_with_lock.png", - "Position": { "x": 448.623047, "y": 65.5839844, "z": -13.269 }, - "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - "Category": "LockedDoor", - "AssociatedItemId": "591afe0186f77431bd616a11", - }, - // { - // "Text": "Shtrman's Stash", - // "ImagePath": "Markers/door_with_lock.png", - // "Position": { "x": 25.1087952, "y": -29.55574, "z": -1.47199988 }, - // "Color": { "r": 1.0, "g": 0.921568632, "b": 0.0156862754, "a": 1.0 }, - // "Category": "LockedDoor", - // "AssociatedItemId": "5d08d21286f774736e7c94c3" - // } - ], -} diff --git a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt b/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt deleted file mode 100644 index 8a217e3b..00000000 --- a/configs/OriginalNarcoticsConfig/DynamicMaps compatibility/Instructions.txt +++ /dev/null @@ -1,5 +0,0 @@ -YOU MUST HAVE DYNAMIC MAPS ALREADY DOWNLOADED - -Copy the "DynamicMaps" folder above and paste it into the BepInEx/plugins folder, replacing the files when prompted. - -If you want to revert, just redownload dynamic maps. \ No newline at end of file From dc8b93ce0d3ec3ea57b3bfaa17b456c55872b545 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 21:44:56 +0100 Subject: [PATCH 074/203] chore: remove unused default Tooltips --- configs/Default/Tooltips.json | 222 ---------------------------------- 1 file changed, 222 deletions(-) delete mode 100644 configs/Default/Tooltips.json diff --git a/configs/Default/Tooltips.json b/configs/Default/Tooltips.json deleted file mode 100644 index b0d54168..00000000 --- a/configs/Default/Tooltips.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", - "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", - "comment": "If you are using the standard config, this should be set to false", - - "language": "english", - - "moddedTraderCompat": true, - "additionalLocalesToggle": true, - - "moddedTraderExtracts": [ - "Trailer Park Workers Shack", - "Trailer Park Workers' Shack (Legs)", - "Scav_Hideout_at_the_grotto", - "Hideout at the Grotto (Artem)", - "Railroad To Tarkov", - "RR to Tarkov (Painter/Streets/Interchange)", - "NW Exfil", - "Railway (Painter/Customs/Woods/Streets)", - "PP Exfil", - "Power Station SUV (Painter/Streets/Woods/GZ)", - "E4", - "Crash Site (Painter/Customs/Interchange)", - "ZB-014", - "ZB-014 (Scorpion)", - "EXFIL_Bunker", - "Bunker Hermetic Door (Scorpion/Woods*)", - "SE Exfil", - "Emercom Checkpoint (Lotus/Customs)", - "Crossroads", - "Crossroads (Lotus/Interchange/Shoreline*)", - "Nakatani_stairs_free_exit", - "Nakatani Basement Stairs (Coyote/Streets/Labs)", - "scav_e1", - "Basement Descent (Coyote/Labs/Ground Zero)", - "lab_Elevator_Cargo", - "Cargo Elevator (Coyote/Streets/Ground Zero)", - "E3", - "Ruined House (Hephaestus)", - "EXFIL_Vent", - "Manhole (Sally/Streets)", - "scav_e4", - "Manhole (Sally/Reserve)" - ], - - "localesToChangeAdditional": ["Saferoom Exfil", "Saferoom (Flea Market)"], - - "localesToChange": [ - "East Gate", - "Scav Bunker (Prapor)", - "Unity_free_exit", - "Emercom Checkpoint (Therapist)", - "Warehouse 17", - "Warehouse 17 (Skier)", - "Mountain Stash", - "Mountain Stash (Jaeger)", - "Interchange Cooperation", - "Scav Camp (Ragman/Customs)", - "Trailer Park", - "Trailer Park (Ragman/Interchange)", - "EXFIL_Bunker_D2", - "D-2 (Peacekeeper/Shoreline*)", - "South Fence Passage", - "Old Bunker (Peacekeeper)", - "Camera Bunker Door", - "Camera Bunker Door (Mechanic)", - "Railroad To Port", - "RR to Port (Ref/Shoreline)", - "Road_at_railbridge", - "Railbridge (Ref/Customs)", - - "Gate 3", - "Gate 3 (Woods, ZB-1016)", - "Gate m", - "Med Tent Gates (Customs, ZB-1012)", - "Gate 0", - "Gate 0 (Customs, ZB-1011)", - "Cellars", - "Cellars (Customs, ZB-1013)", - "Office Window", - "Office Window (Customs/Woods)", - - "ZB-1011", - "ZB-1011 (Hideout/Factory)", - "ZB-1012", - "ZB-1012 (Factory, Med Tent Gates)", - "EXFIL_ZB013", - "ZB-1013 (Factory, Cellars)", - "Military Checkpoint", - "Scav Checkpoint (Woods/Lighthouse)", - "Sniper Roadblock", - "Sniper Roadblock (Reserve*/Shoreline)", - "Smuggler's Boat", - "Smuggler's Boat (Lighthouse*/Shoreline/Woods*", - "Dorms V-Ex", - "Dorms SUV (Shoreline, North Fence SUV)", - "RUAF Roadblock", - "RUAF Roadblock (Woods, UN Roadblock)", - "Old Azs Gate", - "Old Gas Gate (Factory/Woods)", - "Shack", - "Military Base Checkpoint (Reserve, Scav lands)", - "Crossroads", - "Crossroads (Interchange/Shoreline*)", - "Railroad To Military Base", - "RR to Military Base (Reserve, Scav land rails*)", - "Factory Far Corner", - "Factory Corner (Woods, RUAF Gate)", - "Railroad To Tarkov", - "RR to Tarkov (Streets/Interchange)", - - "un-sec", - "North UN Roadblock (Customs, RUAF Roadblock*)", - "Factory gate", - "Factory Gate (Customs, Old Gas Gate)", - "ZB-016", - "ZB-016 (Factory, Gate 3)", - "Outskirts", - "Outskirts (Customs/Lighthouse)", - "UN Roadblock", - "UN Roadblock (Customs/Interchange)", - "South V-Ex", - "Bridge SUV (Streets/Interchange/GZ)", - "RUAF Gate", - "RUAF Gate (Customs, Factory Corner)", - - "EXFIL_ScavCooperation", - "Scav lands (Customs, Military Base CP)", - "EXFIL_Train", - "Armored Train (all maps besides GZ*)", - "Exit1", - "Hole in the Wall (Customs, Dorms Car*)", - "Exit4", - "Checkpoint Fence (Lighthouse, Northeast Mountains*)", - "Alpinist", - "Cliff Descent (Shoreline, Climber's Trail)", - "EXFIL_Vent", - "Manhole (Streets, Manhole)", - "EXFIL_Bunker", - "Bunker Hermetic Door (Woods, ZB-014*)", - - "SE Exfil", - "Emercom Checkpoint (Customs, Crossroads)", - "NW Exfil", - "Railway (Customs/Woods/Streets)", - "PP Exfil", - "Power Station SUV (Streets/Woods/GZ)", - - "E1", - "Stylobate Elevator (Labs, Main Elevator)", - "E2", - "Sewer River (Labs, Sewage Conduit)", - "E4", - "Crash Site (Customs/Interchange)", - "E7", - "Expo Checkpoint (Ground Zero, Scav Camp)", - "E7_car", - "Primorsky Ave Taxi (Woods/Interchange/GZ)", - "E9_sniper", - "Klimov Ave (Ground Zero, Mira Ave)", - "scav_e1", - "Basement Descent (Labs/Ground Zero)", - "scav_e2", - "Entrance to Catacombs (Labs, Hangar Gate)", - "scav_e3", - "Vent Shaft (Lab, Vents)", - "scav_e4", - "Manhole (Reserve, Manhole)", - - "Road to Customs", - "Road to Customs (Customs, Sniper Roadblock*)", - "Pier Boat", - "Pier Boat (Lighthouse*/Customs/Woods*)", - "Tunnel", - "Tunnel (Lighthouse, Side Tunnel)", - "Wrecked Road", - "Ruined Road (Lighthouse, Southern Road)", - "Smugglers_Trail_coop", - "Smuggler's Path (Customs/Reserve*)", - "Shorl_V-Ex", - "North Fence SUV (Customs, Dorms SUV)", - "Lighthouse_pass", - "Path to Lighthouse", - "RedRebel_alp", - "Climber's Trail (Reserve, Cliff Descent)", - - "Nothern_Checkpoint", - "Northern Checkpoint (Woods/Customs)", - " V-ex_light", - "Military Base SUV (Reserve, CP Fence)", - "Shorl_free", - "Path to Shoreline", - "Coastal_South_road", - "Southern Road (Shoreline, Ruined Road)", - "Alpinist_light", - "Mountain Pass (Shoreline, Path to Shoreline*)", - "Tunnel_Shared", - "Side Tunnel (Shoreline, Tunnel)", - "EXFIL_Train", - "Armored Train (all maps besides GZ*)", - - "lab_Elevator_Cargo", - "Cargo Elevator (Streets/Ground Zero)", - "lab_Elevator_Main", - "Main Elevator (Streets, Stylobate Elevator)", - "lab_Hangar_Gate", - "Hangar Gate (Streets, Catacombs)", - "lab_Under_Storage_Collector", - "Sewage Conduit (Streets, Sewer River)", - "lab_Vent", - "Vents (Streets, Vent Shaft)", - - "Sandbox_VExit", - "Police Car (Woods/Interchange/Streets)", - "Nakatani_stairs_free_exit", - "Nakatani Basement Stairs (Streets/Labs)", - "Sniper_exit", - "Mira Ave (Streets, Klimov Ave)", - "Scav_coop_exit", - "Scav Checkpoint (Streets, Expo CP)" - ] -} From 60cfd2e3bf63e2581b9cb826426993937e47e440 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 21:45:36 +0100 Subject: [PATCH 075/203] fix: Requisitions trader id in DevilFlippy config --- configs/DevilFlippy/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index 5b1b8364..2b502643 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -460,7 +460,7 @@ }, "access_via": ["LotusHideout"] }, - "Requisitions": { + "66f0eaa93f6cc015bc1f3acb": { "// Trader name": "Requisitions", "override_description": true, "// Requisitions is available at Near Kamchatskaya Arch": true, From 5bb0268fb2b02bd00e3f04587dc80be4f286a5c5 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 21:57:51 +0100 Subject: [PATCH 076/203] feat(config): add Requisitions trader integration in default config (accessible in RuinedHouse) --- configs/Default/config.json | 41 +++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index e37b81f2..8ce10a8b 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -323,7 +323,7 @@ "en": "Warehouse 17 at Customs", "es-mx": "Warehouse 17 at Customs", "es": "Warehouse 17 at Customs", - "fr": "Entrepôt 17 à la douane", + "fr": "Entrepôt 17 aux douanes", "ge": "Warehouse 17 at Customs", "hu": "Warehouse 17 at Customs", "it": "Warehouse 17 at Customs", @@ -616,6 +616,7 @@ }, "66f4db5ca4958508883d700c": { "// Trader name": "Saria", + "disable_warning": true, "override_description": true, "location_description": { "ch": "With Peacekeeper in Bunker D2", @@ -638,6 +639,31 @@ }, "access_via": ["PeacekeeperHideout"] }, + "66f0eaa93f6cc015bc1f3acb": { + "// Trader name": "Requisitions", + "disable_warning": true, + "override_description": true, + "location_description": { + "ch": "In a ruined house in Tarkov streets", + "cz": "In a ruined house in Tarkov streets", + "en": "In a ruined house in Tarkov streets", + "es-mx": "In a ruined house in Tarkov streets", + "es": "In a ruined house in Tarkov streets", + "fr": "Dans une maison ruinée dans les rues de Tarkov", + "ge": "In a ruined house in Tarkov streets", + "hu": "In a ruined house in Tarkov streets", + "it": "In a ruined house in Tarkov streets", + "jp": "In a ruined house in Tarkov streets", + "kr": "In a ruined house in Tarkov streets", + "pl": "In a ruined house in Tarkov streets", + "po": "In a ruined house in Tarkov streets", + "ro": "In a ruined house in Tarkov streets", + "ru": "In a ruined house in Tarkov streets", + "sk": "In a ruined house in Tarkov streets", + "tu": "In a ruined house in Tarkov streets" + }, + "access_via": ["RuinedHouse"] + }, "lotus": { "// mod integration for lotus": true, "disable_warning": true, @@ -1081,7 +1107,7 @@ }, "PeacekeeperHideout": { "displayName": { - "en": "Peacekeeper" + "en": "Peacekeeper/Saria" } }, "LegsHideout": { @@ -1252,7 +1278,7 @@ }, "RefHideout": { "displayName": { - "en": "Customs/Shoreline" + "en": "Ref/Customs/Shoreline" } }, "LighthouseCar": { @@ -1286,7 +1312,11 @@ "en": "Harry/Coyote" } }, - "RuinedHouse": {}, + "RuinedHouse": { + "displayName": { + "en": "Requisitions" + } + }, "ExpoCP": { "displayName": { "en": "GZ/Streets" @@ -1330,6 +1360,9 @@ "en": "in Warehouse 17", "fr": "à l'entrepôt 17" } + }, + "SafeRoom": { + "override_tooltips_template": "$exfilDisplayName" } } } From 1446603af093def03b138e462602e0ce7ba7ec8c Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 22:07:11 +0100 Subject: [PATCH 077/203] feat: add override_tooltips_template for offraid_positions --- configs/Default/config.json | 7 ++--- src/config.ts | 1 + src/services/ExfilsTooltipsTemplater.ts | 39 +++++++++++++------------ 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 8ce10a8b..a70c3ed9 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -1245,7 +1245,9 @@ "en": "Streets/Interchange/Woods/GZ" } }, - "SafeRoom": {}, + "SafeRoom": { + "override_tooltips_template": "$exfilDisplayName" + }, "Railway": { "displayName": { "en": "Painter + Streets/Woods/Interchange" @@ -1360,9 +1362,6 @@ "en": "in Warehouse 17", "fr": "à l'entrepôt 17" } - }, - "SafeRoom": { - "override_tooltips_template": "$exfilDisplayName" } } } diff --git a/src/config.ts b/src/config.ts index 39a76b74..9a048d1c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -147,6 +147,7 @@ export type InfiltrationsConfig = { }; export type OffraidPositionDefinition = { + override_tooltips_template?: string; // this one will be used only if there is no override on exfil config displayName?: ByLocale; }; diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts index 93315d70..0fae14ac 100644 --- a/src/services/ExfilsTooltipsTemplater.ts +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -88,17 +88,21 @@ export class ExfilsTooltipsTemplater { private computeLocaleValue( config: MinimumConfigForTooltipsTemplater, - { exfilName, offraidPosition, locale }: ComputeLocaleValueParameter, + params: ComputeLocaleValueParameter, ): string { - const exfilDisplayName = this.resolveExfilDisplayName(config, exfilName, locale); + const exfilVanillaDisplayName = this.snapshotLocales[params.locale][params.exfilName]; + + const exfilDisplayName = + ExfilsTooltipsTemplater.resolveExfilDisplayName(config, params) ?? + exfilVanillaDisplayName ?? + 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; const offraidPositionDisplayName = ExfilsTooltipsTemplater.resolveOffraidPositionDisplayName( config, - offraidPosition, - locale, + params, ); - const tooltipsTemplate = ExfilsTooltipsTemplater.resolveTooltipsTemplate(config, exfilName); + const tooltipsTemplate = ExfilsTooltipsTemplater.resolveTooltipsTemplate(config, params); const templatedValue = tooltipsTemplate .replace(EXFIL_DISPLAY_NAME_VARIABLE, exfilDisplayName) @@ -107,29 +111,22 @@ export class ExfilsTooltipsTemplater { return templatedValue; } - private resolveExfilDisplayName( + private static resolveExfilDisplayName( config: MinimumConfigForTooltipsTemplater, - exfilName: string, - locale: LocaleName, - ): string { + { exfilName, locale }: ComputeLocaleValueParameter, + ): string | undefined { const exfilConfig = config?.exfiltrations_config?.[exfilName]; const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( locale, exfilConfig?.displayName, ); - if (resolvedDisplayName) { - return resolvedDisplayName; - } - - const vanillaResolvedValue = this.snapshotLocales[locale][exfilName]; - return vanillaResolvedValue ?? 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; + return resolvedDisplayName; } private static resolveOffraidPositionDisplayName( config: MinimumConfigForTooltipsTemplater, - offraidPosition: string, - locale: LocaleName, + { offraidPosition, locale }: ComputeLocaleValueParameter, ): string { const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( @@ -146,14 +143,18 @@ export class ExfilsTooltipsTemplater { private static resolveTooltipsTemplate( config: MinimumConfigForTooltipsTemplater, - exfilName: string, + { offraidPosition, exfilName }: ComputeLocaleValueParameter, ): string { const exfilConfig = config.exfiltrations_config?.[exfilName]; - if (exfilConfig?.override_tooltips_template) { return exfilConfig.override_tooltips_template; } + const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; + if (offraidPositionDefinition?.override_tooltips_template) { + return offraidPositionDefinition?.override_tooltips_template; + } + if (config.exfiltrations_tooltips_template) { return config.exfiltrations_tooltips_template; } From 5d206451da09c4201b0d7b44e0cb5a78f14fbc66 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 22:34:00 +0100 Subject: [PATCH 078/203] feat(config): french translations for tooltips --- configs/Default/config.json | 123 ++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 41 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index a70c3ed9..8f9073c6 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -1117,12 +1117,14 @@ }, "TherapistHideout": { "displayName": { - "en": "Therapist" + "en": "Therapist", + "fr": "La Toubib" } }, "MechanicHideout": { "displayName": { - "en": "Mechanic" + "en": "Mechanic", + "fr": "Le Mécano" } }, "ArtemHideout": { @@ -1132,57 +1134,68 @@ }, "FactoryZB-016": { "displayName": { - "en": "Woods/Factory" + "en": "Woods/Factory", + "fr": "Bois/Usine" } }, "FactoryZB-013": { "displayName": { - "en": "Customs/Factory" + "en": "Customs/Factory", + "fr": "Douanes/Usine" } }, "FactoryZB-1012": { "displayName": { - "en": "Customs/Factory" + "en": "Customs/Factory", + "fr": "Douanes/Usine" } }, "FactoryZB-1011": { "displayName": { - "en": "Customs/Factory" + "en": "Customs/Factory", + "fr": "Douanes/Usine" } }, "SniperRB": { "displayName": { - "en": "Customs/Reserve/Shoreline" + "en": "Customs/Reserve/Shoreline", + "fr": "Douanes/Réserve/Littoral" } }, "SmugglersBoat": { "displayName": { - "en": "Boat" + "en": "Boat", + "fr": "Bâteau" } }, "RUAFCustoms": { "displayName": { - "en": "Customs/Woods" + "en": "Customs/Woods", + "fr": "Douanes/Bois" } }, "Crossroads": { "displayName": { - "en": "Customs/Interchange/Shoreline" + "en": "Customs/Interchange/Shoreline", + "fr": "Douanes/Échangeur/Littoral" } }, "GasGate": { "displayName": { - "en": "Customs/Woods/Factory" + "en": "Customs/Woods/Factory", + "fr": "Douanes/Bois/Usine" } }, "TarkovRR": { "displayName": { - "en": "Painter + Customs/Interchange/Streets" + "en": "Painter + Customs/Interchange/Streets", + "fr": "Painter + Dounes/Échangeur/Rues" } }, "MilBaseRR": { "displayName": { - "en": "Customs/Reserve" + "en": "Customs/Reserve", + "fr": "Douanes/Réserve" } }, "MilBaseCP": { @@ -1192,27 +1205,32 @@ }, "NorthUNRoadblock": { "displayName": { - "en": "Customs/Woods" + "en": "Customs/Woods", + "fr": "Douanes/Bois" } }, "FactoryGate": { "displayName": { - "en": "Customs/Woods" + "en": "Customs/Woods", + "fr": "Douanes/Bois" } }, "Outskirts": { "displayName": { - "en": "Priscilu + Customs/Woods/Lighthouse" + "en": "Priscilu + Customs/Woods/Lighthouse", + "fr": "Priscilu + Douanes/Bois/Phare" } }, "UNRoadblock": { "displayName": { - "en": "Customs/Woods/Interchange" + "en": "Customs/Woods/Interchange", + "fr": "Douanes/Bois/Échangeur" } }, "RUAFWoods": { "displayName": { - "en": "Customs/Woods" + "en": "Customs/Woods", + "fr": "Douanes/Bois" } }, "ReserveZB-014": { @@ -1222,27 +1240,32 @@ }, "HoleinWall": { "displayName": { - "en": "Customs/Reserve" + "en": "Customs/Reserve", + "fr": "Douanes/Réserve" } }, "CPFence": { "displayName": { - "en": "Lighthouse/Reserve" + "en": "Lighthouse/Reserve", + "fr": "Phare/Réserve" } }, "CliffDescent": { "displayName": { - "en": "Shoreline/Reserve" + "en": "Shoreline/Reserve", + "fr": "Littoral/Réserve" } }, "Manhole": { "displayName": { - "en": "Sally + Streets/Reserve" + "en": "Sally + Streets/Reserve", + "fr": "Sally + Rues/Réserve" } }, "CityCar": { "displayName": { - "en": "Streets/Interchange/Woods/GZ" + "en": "Streets/Interchange/Woods/GZ", + "fr": "Rues/Échangeur/Bois/Point Zero" } }, "SafeRoom": { @@ -1250,47 +1273,56 @@ }, "Railway": { "displayName": { - "en": "Painter + Streets/Woods/Interchange" + "en": "Painter + Streets/Woods/Interchange", + "fr": "Painter + Rues/Bois/Échangeur" } }, "InterchangeScavCamp": { "displayName": { - "en": "Customs/Interchange" + "en": "Customs/Interchange", + "fr": "Douanes/Échangeur" } }, "RoadtoCustoms": { "displayName": { - "en": "Customs/Interchange/Shoreline" + "en": "Customs/Interchange/Shoreline", + "fr": "Douanes/Échangeur/Littoral" } }, "PierBoat": { "displayName": { - "en": "Customs/Shoreline/Lighthouse/Woods" + "en": "Customs/Shoreline/Lighthouse/Woods", + "fr": "Douanes/Littoral/Phare/Bois" } }, "ShorelineLighthouseRoad": { "displayName": { - "en": "Shoreline/Lighthouse" + "en": "Shoreline/Lighthouse", + "fr": "Littoral/Phare" } }, "ShorelineDormsCar": { "displayName": { - "en": "Customs/Shoreline" + "en": "Customs/Shoreline", + "fr": "Douanes/Littoral" } }, "RefHideout": { "displayName": { - "en": "Ref/Customs/Shoreline" + "en": "Ref + Customs/Shoreline", + "fr": "Ref + Douanes/Littoral" } }, "LighthouseCar": { "displayName": { - "en": "Reserve/Lighthouse" + "en": "Reserve/Lighthouse", + "fr": "Réserve/Phare" } }, "LighthouseShorelinePath": { "displayName": { - "en": "Shoreline/Lighthouse" + "en": "Shoreline/Lighthouse", + "fr": "Littoral/Phare" } }, "ArmoredTrain": { @@ -1301,12 +1333,14 @@ }, "MountainPass": { "displayName": { - "en": "Shoreline/Lighthouse" + "en": "Shoreline/Lighthouse", + "fr": "Littoral/Phare" } }, "LighthouseShorelineTunnel": { "displayName": { - "en": "Shoreline/Lighthouse" + "en": "Shoreline/Lighthouse", + "fr": "Littoral/Phare" } }, "BasementDescent": { @@ -1321,37 +1355,44 @@ }, "ExpoCP": { "displayName": { - "en": "GZ/Streets" + "en": "GZ/Streets", + "fr": "Point Zero/Rues" } }, "KlimovStreet": { "displayName": { - "en": "GZ/Streets" + "en": "GZ/Streets", + "fr": "Point Zero/Rues" } }, "VentShaft": { "displayName": { - "en": "Streets/Lab" + "en": "Streets/Lab", + "fr": "Rues/Labo" } }, "SewerRiver": { "displayName": { - "en": "Streets/Lab" + "en": "Streets/Lab", + "fr": "Rues/Labo" } }, "StylobateElevator": { "displayName": { - "en": "Streets/Lab" + "en": "Streets/Lab", + "fr": "Rues/Labo" } }, "CrashSite": { "displayName": { - "en": "Painter + Streets/Interchange/Woods" + "en": "Painter + Streets/Interchange/Woods", + "fr": "Painter + Rues/Échangeur/Labo" } }, "Catacombs": { "displayName": { - "en": "Streets/Lab" + "en": "Streets/Lab", + "fr": "Rues/Labo" } } }, From 4a2c9f3443b2dd170a203977711bfdccc23ea14f Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:04:21 +0100 Subject: [PATCH 079/203] style: apply prettier on ExfilsTooltipsTemplater --- src/services/ExfilsTooltipsTemplater.ts | 352 ++++++++++++------------ 1 file changed, 176 insertions(+), 176 deletions(-) diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts index 0fae14ac..16423861 100644 --- a/src/services/ExfilsTooltipsTemplater.ts +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -1,176 +1,176 @@ -import type { ByLocale, Config, LocaleName, MapName } from '../config'; -import { deepClone } from '../utils'; - -const EXFIL_DISPLAY_NAME_VARIABLE = '$exfilDisplayName'; -const OFFRAID_POSITION_DISPLAY_NAME_VARIABLE = '$offraidPositionDisplayName'; - -const DEFAULT_FALLBACK_LANGUAGE = 'en'; - -type AllLocalesInDb = Record>; -type PartialLocales = Partial>>; - -export type MinimumConfigForTooltipsTemplater = Pick< - Config, - 'exfiltrations' | 'exfiltrations_config' | 'exfiltrations_tooltips_template' | 'offraid_positions' ->; - -export type LocalesMutationReport = { - nbLocalesImpacted: number; - nbTotalValuesUpdated: number; -}; - -type ComputeLocaleValueParameter = { - locale: LocaleName; - exfilName: string; - offraidPosition: string; -}; - -export class ExfilsTooltipsTemplater { - // this is used to be sure to keep the vanilla locales even after mutations are applied to the database - private readonly snapshotLocales: AllLocalesInDb; - - constructor(allLocales: AllLocalesInDb) { - this.snapshotLocales = deepClone(allLocales); - } - - public computeLocales(config: MinimumConfigForTooltipsTemplater): PartialLocales { - const result: PartialLocales = {}; - - Object.keys(this.snapshotLocales).forEach(locale => { - const localeValues: Record = {}; - result[locale] = localeValues; - - Object.keys(config.exfiltrations).forEach(mapName => { - const exfils = config.exfiltrations[mapName as MapName]; - - Object.keys(exfils).forEach(exfilName => { - const offraidPosition = exfils[exfilName]; - - const computeParams: ComputeLocaleValueParameter = { - locale: locale as LocaleName, - exfilName, - offraidPosition, - }; - - localeValues[exfilName] = this.computeLocaleValue(config, computeParams); - }); - }); - }); - - return result; - } - - public static mutateLocales( - allLocales: AllLocalesInDb, - partialLocales: PartialLocales, - ): LocalesMutationReport { - const report: LocalesMutationReport = { - nbLocalesImpacted: 0, - nbTotalValuesUpdated: 0, - }; - - void Object.keys(allLocales).forEach(localeName => { - if (partialLocales[localeName]) { - const values = allLocales[localeName]; - const newValues = partialLocales[localeName] ?? {}; - const nbNewValues = Object.keys(newValues).length; - - if (nbNewValues > 0) { - void Object.assign(values, newValues); // mutation here - report.nbLocalesImpacted += 1; - report.nbTotalValuesUpdated += nbNewValues; - } - } - }); - - return report; - } - - private computeLocaleValue( - config: MinimumConfigForTooltipsTemplater, - params: ComputeLocaleValueParameter, - ): string { - const exfilVanillaDisplayName = this.snapshotLocales[params.locale][params.exfilName]; - - const exfilDisplayName = - ExfilsTooltipsTemplater.resolveExfilDisplayName(config, params) ?? - exfilVanillaDisplayName ?? - 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; - - const offraidPositionDisplayName = ExfilsTooltipsTemplater.resolveOffraidPositionDisplayName( - config, - params, - ); - - const tooltipsTemplate = ExfilsTooltipsTemplater.resolveTooltipsTemplate(config, params); - - const templatedValue = tooltipsTemplate - .replace(EXFIL_DISPLAY_NAME_VARIABLE, exfilDisplayName) - .replace(OFFRAID_POSITION_DISPLAY_NAME_VARIABLE, offraidPositionDisplayName); - - return templatedValue; - } - - private static resolveExfilDisplayName( - config: MinimumConfigForTooltipsTemplater, - { exfilName, locale }: ComputeLocaleValueParameter, - ): string | undefined { - const exfilConfig = config?.exfiltrations_config?.[exfilName]; - const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( - locale, - exfilConfig?.displayName, - ); - - return resolvedDisplayName; - } - - private static resolveOffraidPositionDisplayName( - config: MinimumConfigForTooltipsTemplater, - { offraidPosition, locale }: ComputeLocaleValueParameter, - ): string { - const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; - const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( - locale, - offraidPositionDefinition?.displayName, - ); - - if (resolvedDisplayName) { - return resolvedDisplayName; - } - - return offraidPosition; - } - - private static resolveTooltipsTemplate( - config: MinimumConfigForTooltipsTemplater, - { offraidPosition, exfilName }: ComputeLocaleValueParameter, - ): string { - const exfilConfig = config.exfiltrations_config?.[exfilName]; - if (exfilConfig?.override_tooltips_template) { - return exfilConfig.override_tooltips_template; - } - - const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; - if (offraidPositionDefinition?.override_tooltips_template) { - return offraidPositionDefinition?.override_tooltips_template; - } - - if (config.exfiltrations_tooltips_template) { - return config.exfiltrations_tooltips_template; - } - - // by default, the tooltips template is the name of the exfil itself - return EXFIL_DISPLAY_NAME_VARIABLE; - } - - private static resolveDisplayName = ( - locale: LocaleName, - displayName: ByLocale | undefined, - ): string | undefined => { - if (!displayName) { - return undefined; - } - - return displayName[locale] ?? displayName[DEFAULT_FALLBACK_LANGUAGE]; - }; -} +import type { ByLocale, Config, LocaleName, MapName } from '../config'; +import { deepClone } from '../utils'; + +const EXFIL_DISPLAY_NAME_VARIABLE = '$exfilDisplayName'; +const OFFRAID_POSITION_DISPLAY_NAME_VARIABLE = '$offraidPositionDisplayName'; + +const DEFAULT_FALLBACK_LANGUAGE = 'en'; + +type AllLocalesInDb = Record>; +type PartialLocales = Partial>>; + +export type MinimumConfigForTooltipsTemplater = Pick< + Config, + 'exfiltrations' | 'exfiltrations_config' | 'exfiltrations_tooltips_template' | 'offraid_positions' +>; + +export type LocalesMutationReport = { + nbLocalesImpacted: number; + nbTotalValuesUpdated: number; +}; + +type ComputeLocaleValueParameter = { + locale: LocaleName; + exfilName: string; + offraidPosition: string; +}; + +export class ExfilsTooltipsTemplater { + // this is used to be sure to keep the vanilla locales even after mutations are applied to the database + private readonly snapshotLocales: AllLocalesInDb; + + constructor(allLocales: AllLocalesInDb) { + this.snapshotLocales = deepClone(allLocales); + } + + public computeLocales(config: MinimumConfigForTooltipsTemplater): PartialLocales { + const result: PartialLocales = {}; + + Object.keys(this.snapshotLocales).forEach(locale => { + const localeValues: Record = {}; + result[locale] = localeValues; + + Object.keys(config.exfiltrations).forEach(mapName => { + const exfils = config.exfiltrations[mapName as MapName]; + + Object.keys(exfils).forEach(exfilName => { + const offraidPosition = exfils[exfilName]; + + const computeParams: ComputeLocaleValueParameter = { + locale: locale as LocaleName, + exfilName, + offraidPosition, + }; + + localeValues[exfilName] = this.computeLocaleValue(config, computeParams); + }); + }); + }); + + return result; + } + + public static mutateLocales( + allLocales: AllLocalesInDb, + partialLocales: PartialLocales, + ): LocalesMutationReport { + const report: LocalesMutationReport = { + nbLocalesImpacted: 0, + nbTotalValuesUpdated: 0, + }; + + void Object.keys(allLocales).forEach(localeName => { + if (partialLocales[localeName]) { + const values = allLocales[localeName]; + const newValues = partialLocales[localeName] ?? {}; + const nbNewValues = Object.keys(newValues).length; + + if (nbNewValues > 0) { + void Object.assign(values, newValues); // mutation here + report.nbLocalesImpacted += 1; + report.nbTotalValuesUpdated += nbNewValues; + } + } + }); + + return report; + } + + private computeLocaleValue( + config: MinimumConfigForTooltipsTemplater, + params: ComputeLocaleValueParameter, + ): string { + const exfilVanillaDisplayName = this.snapshotLocales[params.locale][params.exfilName]; + + const exfilDisplayName = + ExfilsTooltipsTemplater.resolveExfilDisplayName(config, params) ?? + exfilVanillaDisplayName ?? + 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; + + const offraidPositionDisplayName = ExfilsTooltipsTemplater.resolveOffraidPositionDisplayName( + config, + params, + ); + + const tooltipsTemplate = ExfilsTooltipsTemplater.resolveTooltipsTemplate(config, params); + + const templatedValue = tooltipsTemplate + .replace(EXFIL_DISPLAY_NAME_VARIABLE, exfilDisplayName) + .replace(OFFRAID_POSITION_DISPLAY_NAME_VARIABLE, offraidPositionDisplayName); + + return templatedValue; + } + + private static resolveExfilDisplayName( + config: MinimumConfigForTooltipsTemplater, + { exfilName, locale }: ComputeLocaleValueParameter, + ): string | undefined { + const exfilConfig = config?.exfiltrations_config?.[exfilName]; + const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( + locale, + exfilConfig?.displayName, + ); + + return resolvedDisplayName; + } + + private static resolveOffraidPositionDisplayName( + config: MinimumConfigForTooltipsTemplater, + { offraidPosition, locale }: ComputeLocaleValueParameter, + ): string { + const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; + const resolvedDisplayName = ExfilsTooltipsTemplater.resolveDisplayName( + locale, + offraidPositionDefinition?.displayName, + ); + + if (resolvedDisplayName) { + return resolvedDisplayName; + } + + return offraidPosition; + } + + private static resolveTooltipsTemplate( + config: MinimumConfigForTooltipsTemplater, + { offraidPosition, exfilName }: ComputeLocaleValueParameter, + ): string { + const exfilConfig = config.exfiltrations_config?.[exfilName]; + if (exfilConfig?.override_tooltips_template) { + return exfilConfig.override_tooltips_template; + } + + const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; + if (offraidPositionDefinition?.override_tooltips_template) { + return offraidPositionDefinition?.override_tooltips_template; + } + + if (config.exfiltrations_tooltips_template) { + return config.exfiltrations_tooltips_template; + } + + // by default, the tooltips template is the name of the exfil itself + return EXFIL_DISPLAY_NAME_VARIABLE; + } + + private static resolveDisplayName = ( + locale: LocaleName, + displayName: ByLocale | undefined, + ): string | undefined => { + if (!displayName) { + return undefined; + } + + return displayName[locale] ?? displayName[DEFAULT_FALLBACK_LANGUAGE]; + }; +} From 3330e78d9a4b1f71411866c638352a053d652553 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:05:43 +0100 Subject: [PATCH 080/203] chore: cleanup DevilFlippy tooltips + save extract-legacy-tooltips script --- configs/DevilFlippy/FR/Tooltips.json | 179 ----------- configs/DevilFlippy/Tooltips.json | 177 ----------- configs/DevilFlippy/config.json | 440 +++++++++++++++++++++++++++ scripts/extract-legacy-tooltips.js | 62 +++- 4 files changed, 491 insertions(+), 367 deletions(-) delete mode 100644 configs/DevilFlippy/FR/Tooltips.json delete mode 100644 configs/DevilFlippy/Tooltips.json diff --git a/configs/DevilFlippy/FR/Tooltips.json b/configs/DevilFlippy/FR/Tooltips.json deleted file mode 100644 index e9cc6ee0..00000000 --- a/configs/DevilFlippy/FR/Tooltips.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", - "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", - "comment": "If you are using the standard config, this should be set to false", - - "language": "french", - - "moddedTraderCompat": false, - "additionalLocalesToggle": false, - - "moddedTraderExtracts": [ - "Saferoom Exfil", - "Saferoom (Goblin King)", - "EXFIL_ZB013", - "ZB-1013 Storage Bunker (Broker)" - ], - - "localesToChangeAdditional": [], - - "localesToChange": [ - "Gate 3", - "Porte 3 vers Douanes - Prapor/Svetlana/Evelyn (Hideout)", - "Gate m", - "Porte de la tente médicale vers Douanes - Prapor/Svetlana/Evelyn (Planque)", - "Gate 0", - "Porte 0 vers Bois", - "Cellars", - "Caves vers Base militaire - Anastasia", - "Camera Bunker Door", - "Caméra porte Bunker - Mechano", - - "ZB-1011", - "ZB-1011 vers Usine - Prapor/Svetlana/Evelyn (Planque)", - "ZB-1012", - "ZB-1012 vers Usine - Prapor/Svetlana/Evelyn (Planque)", - "ZB-1013", - "ZB-1013 vers ZB-016", - "Smuggler's Boat", - "Bateau du passeur vers Littoral, Bois, Phare", - "Dorms V-Ex", - "Véhicule des dortoirs vers Littoral", - "RUAF Gate", - "porte RUAF vers Bois Barrage ONU nord", - "Crossroads", - "Carrefour vers Échangeur - Ragman", - "Sniper Roadblock", - "Barrage sniper vers Littoral", - "Military Checkpoint", - "Poste de contrôle scavs vers Bois barrage Ruaf", - "Warehouse 17", - "Entrepôt 17 - Skier", - - "South V-Ex", - "Véhicule du pont vers Échangeur, Ground Zero", - "ZB-014", - "ZB-014 planque secondaire", - "ZB-016", - "ZB-016 vers Douanes ZB-1013", - "un-sec", - "Barrage ONU nord vers Douanes RUAF", - "RUAF Gate", - "Barrage Ruaf vers Douanes Scav CP", - "Factory Gate", - "Porte de l'usine vers Usine Porte 0", - "Outskirts", - "Périphérie vers Phare", - "Mountain Stash", - "Cache de la montagne - Jaeger", - - "EXFIL_ScavCooperation", - "Territoires scavs - Marché noir", - "EXFIL_Train", - "Train blindé vers Phare, Littoral - Ref", - "EXFIL_Bunker", - "Porte bunker hermétique vers Usine - Anastasia", - "Alpinist", - "Falaise vers Littoral - Peacekeeper", - "EXFIL_vent", - "Bouche d'égout vers Littoral - Peacekeeper", - "EXFIL_BUNKER_D2", - "D-2 vers Littoral - Peacekeeper", - - "PP Exfil", - "Véhicule de la centrale électrique vers Échangeur, Bois, Ground Zero", - "Saferoom Exfil", - "Pièce sécurisée - Marché noir", - "NW Exfil", - "Extraction du chemin de fer vers Rues de Tarkov - Lotus", - "SE Exfil", - "Point de contrôle Emercom vers Douanes - Ragman", - "Hole Exfill", - "Trou dans la clôture vers Rues de Tarkov", - - "Wrecked Road", - "Route en ruine vers Phare", - "RedRebel_alp", - "Parcours d'escalade vers Base militaire - Peacekeeper", - "Road to Customs", - "Route vers les douanes", - "Pier Boat", - "Jetée vers Douanes, Bois, Phare", - "Tunnel", - "Tunnel vers Phare", - "Lighthouse_pass", - "Sentier vers le phare", - "Smugglers_Trail_coop", - "Chemin du passeur vers Douanes", - "Shorl_V-Ex", - "Véhicule de la route nord vers Douanes", - "Road_at_railbridge", - "Pont ferroviaire - Ref", - - " V-ex_light", - "Véhicule vers la base militaire", - "Shorl_free", - "Sentier vers litorral", - "Coastal_South_road", - "Éboulement route sud vers Littoral", - "Scav_Hideout_at_the_grotto", - "Planque scav dans la grotte - Artem", - "EXFIL_Train", - "Train blindé vers Base militaire, Littoral - Ref", - "Nothern_Checkpoint", - "Poste de contrôle nord vers Phare", - "Alpinist_light", - "Le col vers Littoral", - "Tunnel", - "Tunnel Annexe vers Littoral", - - "E1", - "Ascenseur du bâtiment Stylobate vers labo - Scorpion", - "E2", - "Rivière des égouts vers labo", - "E3", - "Maison endommagée vers Échangeur", - "scav_e2", - "Entrée des catacombes vers labo", - "scav_e3", - "Conduit de ventilation vers labo", - "E4", - "Site du crash vers Échangeur - Lotus", - "E7", - "Point de contrôle de l'expo vers Ground Zero - Marché noir", - "E7_car", - "Véhicule de l'avenue Primorsky vers labo", - "E8", - "Parking du complexe d'appartements Cardinal - The Painter", - "E9_sniper", - "Rue Klimov vers Ground Zero", - "scav_e1", - "Descente du sous-sol vers labo, GZ", - "scav_e5", - "Arche Kamchatskaya - Requisitions", - - "lab_Hangar_Gate", - "Hangar Gate vers Catacomb", - "lab_Under_Storage_Collector", - "Conduit d'eaux usées", - "lab_Elevator_Main", - "Ascenseur principal vers Stylobate Building - Scorpion", - "lab_Elevator_Cargo", - "Ascenseur de service vers Rues de Tarkov, GZ", - "lab_Vent", - "Conduit de ventilation", - "lab_Parking_Gate", - "Porte du garage vers Rues de Tarkov car", - - "Unity_free_exit", - "Point de contrôle Emercom - Toubib", - "Sandbox_VExit", - "Véhicule du cordon de police vers Échangeur, Bois", - "Nakatani_stairs_free_exit", - "Escaliers du souterrain Nakatani vers Rues de Tarkov, labo", - "Sniper_exit", - "Avenue Mira vers Rues de Tarkov", - "Scav_coop_exit", - "Poste de contôle scav vers Rues de Tarkov - Marché noir" - ] -} diff --git a/configs/DevilFlippy/Tooltips.json b/configs/DevilFlippy/Tooltips.json deleted file mode 100644 index ce254821..00000000 --- a/configs/DevilFlippy/Tooltips.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", - "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", - "comment": "If you are using the standard config, this should be set to false", - - "moddedTraderCompat": false, - "additionalLocalesToggle": false, - - "moddedTraderExtracts": [ - "Saferoom Exfil", - "Saferoom (Goblin King)", - "EXFIL_ZB013", - "ZB-1013 Storage Bunker (Broker)" - ], - - "localesToChangeAdditional": [], - - "localesToChange": [ - "Gate 3", - "Gate 3 To Customs - Prapor/Svetlana/Evelyn (Hideout)", - "Gate m", - "Med Tent Gates to Customs - Prapor/Svetlana/Evelyn (Hideout)", - "Gate 0", - "Gate 0 to Woods", - "Cellars", - "Cellars To Reserve - Anastasia", - "Camera Bunker Door", - "Camera Bunker Door - Mechanic", - - "ZB-1011", - "ZB-1011 To Factory - Prapor/Svetlana/Evelyn (Hideout)", - "ZB-1012", - "ZB-1012 to Factory - Prapor/Svetlana/Evelyn (Hideout)", - "ZB-1013", - "ZB-1013 to ZB-016", - "Smuggler's Boat", - "Smuggler's Boat to Shoreline, Woods, Lighthouse", - "Dorms V-Ex", - "Dorms SUV to Shoreline", - "RUAF Roadblock", - "RUAF Roadblock to Woods North UN Roadblock", - "Crossroads", - "Crossroads to Interchange - Ragman", - "Sniper Roadblock", - "Sniper Roadblock to Shoreline", - "Military Checkpoint", - "Scav Checkpoint to Woods", - "Warehouse 17", - "Warehouse 17 - Skier", - - "South V-Ex", - "Bridge SUV to Interchange, Ground Zero", - "ZB-014", - "ZB-014 secondary Stash", - "ZB-016", - "ZB-016 to Customs ZB-1013", - "un-sec", - "Northern UN Roadblock to Customs RUAF", - "Factory Gate", - "Factory Gate to Factory Gate 0", - "Outskirts", - "Outskirts to Lighthouse", - "RUAF Gate", - "RUAF Gate to Customs Scav Checkpoint", - "Mountain Stash", - "Mountain Stash - Jaeger", - - "EXFIL_ScavCooperation", - "Scav Lands - Flea", - "EXFIL_Train", - "Armored Train to Lighthouse, Shoreline - Ref", - "EXFIL_Bunker", - "Bunker Hermetic Door to Factory - Anastasia", - "Alpinist", - "Cliff Descent to Shoreline - Peacekeeper", - "EXFIL_vent", - "Sewer Manhole to Shoreline - Peacekeeper", - "EXFIL_BUNKER_D2", - "D-2 to Shoreline - Peacekeeper", - - "PP Exfil", - "SUV to Interchange, Woods, Ground Zero", - "Saferoom Exfil", - "Saferoom Exfil - Flea", - "NW Exfil", - "Railway Exfil to Streets - Lotus", - "SE Exfil", - "Emercom Checkpoint to Customs - Ragman", - "Hole Exfill", - "Hole in the Fence to Streets", - - "Wrecked Road", - "Ruined Road to Lighthouse", - "RedRebel_alp", - "Climber's Trail to Reserve - Peacekeeper", - "Road to Customs", - "Road to Customs", - "Pier Boat", - "Pier Boat to Customs, Woods, Lighthouse", - "Tunnel", - "Tunnel to Lighthouse", - "Lighthouse_pass", - "Path to Lighthouse", - "Smugglers_Trail_coop", - "Smuggler's Path to Customs", - "Shorl_V-Ex", - "SUV to Customs", - "Road_at_railbridge", - "Railway Bridge - Ref", - - " V-ex_light", - "Road to Military Base V-Ex", - "Shorl_free", - "Path to Shoreline", - "Coastal_South_road", - "Southern Road to Shoreline", - "Scav_Hideout_at_the_grotto", - "Hideout at the Grotto - Artem", - "EXFIL_Train", - "Armored Train to Reserve, Shoreline - Ref", - "Nothern_Checkpoint", - "Northern Checkpoint to lighthouse", - "Alpinist_light", - "Mountain Pass to Shoreline", - "Tunnel", - "Side Tunnel to Shoreline", - - "E1", - "Stylobate Building Elevator to Labs - Scorpion", - "E2", - "Sewer River to Labs", - "E3", - "Damaged House to Interchange", - "scav_e2", - "Entrance to Catacombs to labs", - "scav_e3", - "Vent Shaft to Labs", - "E4", - "Crash Site to Interchange - Lotus", - "E7", - "Expo Checkpoint to Ground Zero - Flea", - "E7_car", - "Primorsky Ave Taxi V-Ex to Labs", - "E8", - "Cardinal Apartment Complex - The Painter", - "E9_sniper", - "Klimov Street to Ground Zero", - "scav_e1", - "Basement Descent to Labs, GZ", - "scav_e5", - "Near Kamchatskaya Arch - Requisitions", - - "lab_Hangar_Gate", - "Hangar Gate to Catacomb", - "lab_Under_Storage_Collector", - "Sewage Conduit", - "lab_Elevator_Main", - "Main Elevator to Stylobate Building - Scorpion", - "lab_Elevator_Cargo", - "Cargo Elevator to Streets, GZ", - "lab_Vent", - "Ventilation Shaft", - "lab_Parking_Gate", - "Parking Gate to Street car", - - "Unity_free_exit", - "Emercom Checkpoint - Therapist", - "Sandbox_VExit", - "Police Cordon V-Ex to Interchange, Woods", - "Nakatani_stairs_free_exit", - "Nakatani Basement Stairs to Streets, Labs", - "Sniper_exit", - "Mira Ave to Streets", - "Scav_coop_exit", - "Scav Checkpoint to Streets - Flea" - ] -} diff --git a/configs/DevilFlippy/config.json b/configs/DevilFlippy/config.json index 2b502643..7648f492 100644 --- a/configs/DevilFlippy/config.json +++ b/configs/DevilFlippy/config.json @@ -831,5 +831,445 @@ } } } + }, + "exfiltrations_config": { + "Gate 3": { + "displayName": { + "en": "Gate 3 To Customs - Prapor/Svetlana/Evelyn (Hideout)", + "fr": "Porte 3 vers Douanes - Prapor/Svetlana/Evelyn (Hideout)" + } + }, + "Gate m": { + "displayName": { + "en": "Med Tent Gates to Customs - Prapor/Svetlana/Evelyn (Hideout)", + "fr": "Porte de la tente médicale vers Douanes - Prapor/Svetlana/Evelyn (Planque)" + } + }, + "Gate 0": { + "displayName": { + "en": "Gate 0 to Woods", + "fr": "Porte 0 vers Bois" + } + }, + "Cellars": { + "displayName": { + "en": "Cellars To Reserve - Anastasia", + "fr": "Caves vers Base militaire - Anastasia" + } + }, + "Camera Bunker Door": { + "displayName": { + "en": "Camera Bunker Door - Mechanic", + "fr": "Caméra porte Bunker - Mechano" + } + }, + "ZB-1011": { + "displayName": { + "en": "ZB-1011 To Factory - Prapor/Svetlana/Evelyn (Hideout)", + "fr": "ZB-1011 vers Usine - Prapor/Svetlana/Evelyn (Planque)" + } + }, + "ZB-1012": { + "displayName": { + "en": "ZB-1012 to Factory - Prapor/Svetlana/Evelyn (Hideout)", + "fr": "ZB-1012 vers Usine - Prapor/Svetlana/Evelyn (Planque)" + } + }, + "ZB-1013": { + "displayName": { + "en": "ZB-1013 to ZB-016", + "fr": "ZB-1013 vers ZB-016" + } + }, + "Smuggler's Boat": { + "displayName": { + "en": "Smuggler's Boat to Shoreline, Woods, Lighthouse", + "fr": "Bateau du passeur vers Littoral, Bois, Phare" + } + }, + "Dorms V-Ex": { + "displayName": { + "en": "Dorms SUV to Shoreline", + "fr": "Véhicule des dortoirs vers Littoral" + } + }, + "RUAF Roadblock": { + "displayName": { + "en": "RUAF Roadblock to Woods North UN Roadblock", + "fr": "porte RUAF vers Bois Barrage ONU nord" + } + }, + "Crossroads": { + "displayName": { + "en": "Crossroads to Interchange - Ragman", + "fr": "Carrefour vers Échangeur - Ragman" + } + }, + "Sniper Roadblock": { + "displayName": { + "en": "Sniper Roadblock to Shoreline", + "fr": "Barrage sniper vers Littoral" + } + }, + "Military Checkpoint": { + "displayName": { + "en": "Scav Checkpoint to Woods", + "fr": "Poste de contrôle scavs vers Bois barrage Ruaf" + } + }, + "Warehouse 17": { + "displayName": { + "en": "Warehouse 17 - Skier", + "fr": "Entrepôt 17 - Skier" + } + }, + "South V-Ex": { + "displayName": { + "en": "Bridge SUV to Interchange, Ground Zero", + "fr": "Véhicule du pont vers Échangeur, Ground Zero" + } + }, + "ZB-014": { + "displayName": { + "en": "ZB-014 secondary Stash", + "fr": "ZB-014 planque secondaire" + } + }, + "ZB-016": { + "displayName": { + "en": "ZB-016 to Customs ZB-1013", + "fr": "ZB-016 vers Douanes ZB-1013" + } + }, + "un-sec": { + "displayName": { + "en": "Northern UN Roadblock to Customs RUAF", + "fr": "Barrage ONU nord vers Douanes RUAF" + } + }, + "Factory Gate": { + "displayName": { + "en": "Factory Gate to Factory Gate 0", + "fr": "Porte de l'usine vers Usine Porte 0" + } + }, + "Outskirts": { + "displayName": { + "en": "Outskirts to Lighthouse", + "fr": "Périphérie vers Phare" + } + }, + "RUAF Gate": { + "displayName": { + "en": "RUAF Gate to Customs Scav Checkpoint", + "fr": "Barrage Ruaf vers Douanes Scav CP" + } + }, + "Mountain Stash": { + "displayName": { + "en": "Mountain Stash - Jaeger", + "fr": "Cache de la montagne - Jaeger" + } + }, + "EXFIL_ScavCooperation": { + "displayName": { + "en": "Scav Lands - Flea", + "fr": "Territoires scavs - Marché noir" + } + }, + "EXFIL_Bunker": { + "displayName": { + "en": "Bunker Hermetic Door to Factory - Anastasia", + "fr": "Porte bunker hermétique vers Usine - Anastasia" + } + }, + "Alpinist": { + "displayName": { + "en": "Cliff Descent to Shoreline - Peacekeeper", + "fr": "Falaise vers Littoral - Peacekeeper" + } + }, + "EXFIL_vent": { + "displayName": { + "en": "Sewer Manhole to Shoreline - Peacekeeper", + "fr": "Bouche d'égout vers Littoral - Peacekeeper" + } + }, + "EXFIL_BUNKER_D2": { + "displayName": { + "en": "D-2 to Shoreline - Peacekeeper", + "fr": "D-2 vers Littoral - Peacekeeper" + } + }, + "PP Exfil": { + "displayName": { + "en": "SUV to Interchange, Woods, Ground Zero", + "fr": "Véhicule de la centrale électrique vers Échangeur, Bois, Ground Zero" + } + }, + "Saferoom Exfil": { + "displayName": { + "en": "Saferoom Exfil - Flea", + "fr": "Pièce sécurisée - Marché noir" + } + }, + "NW Exfil": { + "displayName": { + "en": "Railway Exfil to Streets - Lotus", + "fr": "Extraction du chemin de fer vers Rues de Tarkov - Lotus" + } + }, + "SE Exfil": { + "displayName": { + "en": "Emercom Checkpoint to Customs - Ragman", + "fr": "Point de contrôle Emercom vers Douanes - Ragman" + } + }, + "Hole Exfill": { + "displayName": { + "en": "Hole in the Fence to Streets", + "fr": "Trou dans la clôture vers Rues de Tarkov" + } + }, + "Wrecked Road": { + "displayName": { + "en": "Ruined Road to Lighthouse", + "fr": "Route en ruine vers Phare" + } + }, + "RedRebel_alp": { + "displayName": { + "en": "Climber's Trail to Reserve - Peacekeeper", + "fr": "Parcours d'escalade vers Base militaire - Peacekeeper" + } + }, + "Road to Customs": { + "displayName": { + "en": "Road to Customs", + "fr": "Route vers les douanes" + } + }, + "Pier Boat": { + "displayName": { + "en": "Pier Boat to Customs, Woods, Lighthouse", + "fr": "Jetée vers Douanes, Bois, Phare" + } + }, + "Tunnel": { + "displayName": { + "en": "Tunnel to Lighthouse", + "fr": "Tunnel Annexe vers Littoral" + } + }, + "Lighthouse_pass": { + "displayName": { + "en": "Path to Lighthouse", + "fr": "Sentier vers le phare" + } + }, + "Smugglers_Trail_coop": { + "displayName": { + "en": "Smuggler's Path to Customs", + "fr": "Chemin du passeur vers Douanes" + } + }, + "Shorl_V-Ex": { + "displayName": { + "en": "SUV to Customs", + "fr": "Véhicule de la route nord vers Douanes" + } + }, + "Road_at_railbridge": { + "displayName": { + "en": "Railway Bridge - Ref", + "fr": "Pont ferroviaire - Ref" + } + }, + " V-ex_light": { + "displayName": { + "en": "Road to Military Base V-Ex", + "fr": "Véhicule vers la base militaire" + } + }, + "Shorl_free": { + "displayName": { + "en": "Path to Shoreline", + "fr": "Sentier vers litorral" + } + }, + "Coastal_South_road": { + "displayName": { + "en": "Southern Road to Shoreline", + "fr": "Éboulement route sud vers Littoral" + } + }, + "Scav_Hideout_at_the_grotto": { + "displayName": { + "en": "Hideout at the Grotto - Artem", + "fr": "Planque scav dans la grotte - Artem" + } + }, + "EXFIL_Train": { + "displayName": { + "en": "Armored Train - Ref", + "fr": "Train blindé - Ref" + } + }, + "Nothern_Checkpoint": { + "displayName": { + "en": "Northern Checkpoint to lighthouse", + "fr": "Poste de contrôle nord vers Phare" + } + }, + "Alpinist_light": { + "displayName": { + "en": "Mountain Pass to Shoreline", + "fr": "Le col vers Littoral" + } + }, + "tunnel_shared": { + "displayName": { + "en": "Side Tunnel to Shoreline", + "fr": "Tunnel vers Phare" + } + }, + "E1": { + "displayName": { + "en": "Stylobate Building Elevator to Labs - Scorpion", + "fr": "Ascenseur du bâtiment Stylobate vers labo - Scorpion" + } + }, + "E2": { + "displayName": { + "en": "Sewer River to Labs", + "fr": "Rivière des égouts vers labo" + } + }, + "E3": { + "displayName": { + "en": "Damaged House to Interchange", + "fr": "Maison endommagée vers Échangeur" + } + }, + "scav_e2": { + "displayName": { + "en": "Entrance to Catacombs to labs", + "fr": "Entrée des catacombes vers labo" + } + }, + "scav_e3": { + "displayName": { + "en": "Vent Shaft to Labs", + "fr": "Conduit de ventilation vers labo" + } + }, + "E4": { + "displayName": { + "en": "Crash Site to Interchange - Lotus", + "fr": "Site du crash vers Échangeur - Lotus" + } + }, + "E7": { + "displayName": { + "en": "Expo Checkpoint to Ground Zero - Flea", + "fr": "Point de contrôle de l'expo vers Ground Zero - Marché noir" + } + }, + "E7_car": { + "displayName": { + "en": "Primorsky Ave Taxi V-Ex to Labs", + "fr": "Véhicule de l'avenue Primorsky vers labo" + } + }, + "E8": { + "displayName": { + "en": "Cardinal Apartment Complex - The Painter", + "fr": "Parking du complexe d'appartements Cardinal - The Painter" + } + }, + "E9_sniper": { + "displayName": { + "en": "Klimov Street to Ground Zero", + "fr": "Rue Klimov vers Ground Zero" + } + }, + "scav_e1": { + "displayName": { + "en": "Basement Descent to Labs, GZ", + "fr": "Descente du sous-sol vers labo, GZ" + } + }, + "scav_e5": { + "displayName": { + "en": "Near Kamchatskaya Arch - Requisitions", + "fr": "Arche Kamchatskaya - Requisitions" + } + }, + "lab_Hangar_Gate": { + "displayName": { + "en": "Hangar Gate to Catacomb", + "fr": "Hangar Gate vers Catacomb" + } + }, + "lab_Under_Storage_Collector": { + "displayName": { + "en": "Sewage Conduit", + "fr": "Conduit d'eaux usées" + } + }, + "lab_Elevator_Main": { + "displayName": { + "en": "Main Elevator to Stylobate Building - Scorpion", + "fr": "Ascenseur principal vers Stylobate Building - Scorpion" + } + }, + "lab_Elevator_Cargo": { + "displayName": { + "en": "Cargo Elevator to Streets, GZ", + "fr": "Ascenseur de service vers Rues de Tarkov, GZ" + } + }, + "lab_Vent": { + "displayName": { + "en": "Ventilation Shaft", + "fr": "Conduit de ventilation" + } + }, + "lab_Parking_Gate": { + "displayName": { + "en": "Parking Gate to Street car", + "fr": "Porte du garage vers Rues de Tarkov car" + } + }, + "Unity_free_exit": { + "displayName": { + "en": "Emercom Checkpoint - Therapist", + "fr": "Point de contrôle Emercom - Toubib" + } + }, + "Sandbox_VExit": { + "displayName": { + "en": "Police Cordon V-Ex to Interchange, Woods", + "fr": "Véhicule du cordon de police vers Échangeur, Bois" + } + }, + "Nakatani_stairs_free_exit": { + "displayName": { + "en": "Nakatani Basement Stairs to Streets, Labs", + "fr": "Escaliers du souterrain Nakatani vers Rues de Tarkov, labo" + } + }, + "Sniper_exit": { + "displayName": { + "en": "Mira Ave to Streets", + "fr": "Avenue Mira vers Rues de Tarkov" + } + }, + "Scav_coop_exit": { + "displayName": { + "en": "Scav Checkpoint to Streets - Flea", + "fr": "Poste de contôle scav vers Rues de Tarkov - Marché noir" + } + } } } diff --git a/scripts/extract-legacy-tooltips.js b/scripts/extract-legacy-tooltips.js index e8fc1f84..2a59c71c 100644 --- a/scripts/extract-legacy-tooltips.js +++ b/scripts/extract-legacy-tooltips.js @@ -1,11 +1,15 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const Tooltips = require('../configs/Default/Tooltips.json'); +const loadTooltips = tooltipsPath => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const Tooltips = require(`../configs/${tooltipsPath}/Tooltips.json`); -const localesToChange = Tooltips.localesToChange ?? []; -const additionalLocales = - (Tooltips.additionalLocalesToggle ? Tooltips.localesToChangeAdditional : []) ?? []; -const moddedLocales = (Tooltips.moddedTraderCompat ? Tooltips.moddedTraderExtracts : []) ?? []; -const allLocales = [...localesToChange, ...additionalLocales, ...moddedLocales]; + const localesToChange = Tooltips.localesToChange ?? []; + const additionalLocales = + (Tooltips.additionalLocalesToggle ? Tooltips.localesToChangeAdditional : []) ?? []; + const moddedLocales = (Tooltips.moddedTraderCompat ? Tooltips.moddedTraderExtracts : []) ?? []; + const allLocales = [...localesToChange, ...additionalLocales, ...moddedLocales]; + + return { allLocales, language: Tooltips.language || 'en' }; +}; const localeMappings = { english: 'en', @@ -76,17 +80,53 @@ const createExfilConfig = (rawLang, localeValue) => { const isOdd = n => Boolean(n % 2); const isEven = n => !isOdd(n); -const extractExfiltrationsConfigFromLocales = locales => { +const extractExfiltrationsConfigFromLocales = (locales, lang) => { const exfiltrationsConfig = {}; locales.forEach((localeKey, i) => { if (isEven(i)) { const localeValue = locales[i + 1]; - exfiltrationsConfig[localeKey] = createExfilConfig(Tooltips.language, localeValue); + if (exfiltrationsConfig[localeKey]) { + throw new Error(`duplicate found for localeKey ${localeKey}`); + } + exfiltrationsConfig[localeKey] = createExfilConfig(lang, localeValue); } }); return exfiltrationsConfig; }; -const exfiltrations_config = extractExfiltrationsConfigFromLocales(allLocales); +const mergeConfigs = (configA, configB) => { + const result = {}; + + Object.keys(configA).forEach(exfilName => { + const exfilConfigA = configA[exfilName]; + const exfilConfigB = configB[exfilName]; + result[exfilName] = { + displayName: { + ...exfilConfigA.displayName, + ...exfilConfigB.displayName, + }, + }; + }); + + return result; +}; + +const Tooltips_EN = loadTooltips('DevilFlippy'); +const Tooltips_FR = loadTooltips('DevilFlippy/FR'); + +const configEN = extractExfiltrationsConfigFromLocales( + Tooltips_EN.allLocales, + Tooltips_EN.language, +); +const configFR = extractExfiltrationsConfigFromLocales( + Tooltips_FR.allLocales, + Tooltips_FR.language, +); + +const mergedConfigs = mergeConfigs(configEN, configFR); +console.log(JSON.stringify(mergedConfigs, undefined, 2)); -console.log(JSON.stringify(exfiltrations_config, undefined, 2)); +console.log( + 'same amount of keys found between EN and FR: ', + Object.keys(configFR).length === Object.keys(configEN).length, +); From 3481c7942072e646d5532ba5fc965f0af8447a63 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:28:50 +0100 Subject: [PATCH 081/203] chore: cleanup LegacyPTTv5 tooltips --- configs/LegacyPathToTarkovV5/Tooltips.json | 96 ------------- configs/LegacyPathToTarkovV5/config.json | 152 +++++++++++++++++++++ scripts/extract-legacy-tooltips.js | 16 +-- 3 files changed, 155 insertions(+), 109 deletions(-) delete mode 100644 configs/LegacyPathToTarkovV5/Tooltips.json diff --git a/configs/LegacyPathToTarkovV5/Tooltips.json b/configs/LegacyPathToTarkovV5/Tooltips.json deleted file mode 100644 index 78080e84..00000000 --- a/configs/LegacyPathToTarkovV5/Tooltips.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", - "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", - "comment": "If you are using the standard config, this should be set to false", - - "language": "english", - - "moddedTraderCompat": false, - "additionalLocalesToggle": false, - - "moddedTraderExtracts": [ - "Saferoom Exfil", - "Saferoom (Goblin King)", - "EXFIL_ZB013", - "ZB-1013 Storage Bunker (Broker)" - ], - - "localesToChangeAdditional": [], - - "localesToChange": [ - "Gate 3", - "Gate 3 to Customs - Mechanic (Hideout)", - "Office Window", - "Office Window to woods - Jeager", - - "Gate 3", - "Gate 3 to Customs - Mechanic (Hideout)", - "Office Window", - "Office Window to woods - Jeager", - - "Railroad To Tarkov", - "Railroad To Tarkov to Streets, GZ - Therapist, ", - "Railroad To Military Base", - "Railroad To Military Base to Reserve - Skier", - "ZB-1011", - "ZB-1011 to Factory - Mechanic (Hideout)", - "Old Azs Gate", - "Old Gas Station Gate to Interchange - Ragman", - - "Factory Gate", - "Factory Gate to Factory - Jeager", - "South V-Ex", - "South V-Ex to Shoreline", - - "EXFIL_ScavCooperation", - "Scav Lands to Customs - Skier", - "Exit4", - "Checkpoint Fence to Lighthouse", - "EXFIL_Bunker_D2", - "D-2 to interchange", - - "NW Exfil", - "Railway Exfil to Customs - Ragman", - "Saferoom Exfil", - "Saferoom to Reserve, Shoreline", - "PP Exfil", - "Power Station V-Ex to Customs, Streets, GZ, Labs - Prapor", - - "Tunnel", - "Tunnel to Lighthouse - Peacekeeper", - "Shorl_V-Ex", - "Road to North V-Ex to Woods", - "South Fence Passage", - "Old Bunker to Reserve, Interchange", - - "Coastal_South_Road", - "Southern Road to Shoreline - Peacekeeper", - " V-Ex_light", - "Road to Military Base V-Ex to Reserve", - - "E5", - "Collapsed Crane to Customs, GZ - Therapist", - "E7_car", - "Primorsky Ave Taxi V-Ex to Customs, Interchange, GZ, Labs - Prapor", - - "lab_Parking_Gate", - "Parking Gate", - "lab_Hangar_Gate", - "Hangar Gate", - "lab_Elevator_Med", - "Medical Block Elevator", - "lab_Under_Storage_Collector", - "Sewage Conduit", - "lab_Elevator_Main", - "Main Elevator", - "lab_Vent", - "Ventilation Shaft", - "lab_Elevator_Cargo", - "Cargo Elevator", - - "Scav_coop_exit", - "Scav Checkpoint to Customs, Streets - Therapist", - "Sandbox_VExit", - "Police Cordon V-Ex to Customs, Interchange, Streets, Labs - Prapor" - ] -} diff --git a/configs/LegacyPathToTarkovV5/config.json b/configs/LegacyPathToTarkovV5/config.json index 4f92b0de..f299079f 100644 --- a/configs/LegacyPathToTarkovV5/config.json +++ b/configs/LegacyPathToTarkovV5/config.json @@ -422,5 +422,157 @@ "KlimovStash": { "tarkovstreets": ["Klimov Street"] } + }, + "exfiltrations_config": { + "Gate 3": { + "displayName": { + "en": "Gate 3 to Customs - Mechanic (Hideout)" + } + }, + "Office Window": { + "displayName": { + "en": "Office Window to woods - Jeager" + } + }, + "Railroad To Tarkov": { + "displayName": { + "en": "Railroad To Tarkov to Streets, GZ - Therapist, " + } + }, + "Railroad To Military Base": { + "displayName": { + "en": "Railroad To Military Base to Reserve - Skier" + } + }, + "ZB-1011": { + "displayName": { + "en": "ZB-1011 to Factory - Mechanic (Hideout)" + } + }, + "Old Azs Gate": { + "displayName": { + "en": "Old Gas Station Gate to Interchange - Ragman" + } + }, + "Factory Gate": { + "displayName": { + "en": "Factory Gate to Factory - Jeager" + } + }, + "South V-Ex": { + "displayName": { + "en": "South V-Ex to Shoreline" + } + }, + "EXFIL_ScavCooperation": { + "displayName": { + "en": "Scav Lands to Customs - Skier" + } + }, + "Exit4": { + "displayName": { + "en": "Checkpoint Fence to Lighthouse" + } + }, + "EXFIL_Bunker_D2": { + "displayName": { + "en": "D-2 to interchange" + } + }, + "NW Exfil": { + "displayName": { + "en": "Railway Exfil to Customs - Ragman" + } + }, + "Saferoom Exfil": { + "displayName": { + "en": "Saferoom to Reserve, Shoreline" + } + }, + "PP Exfil": { + "displayName": { + "en": "Power Station V-Ex to Customs, Streets, GZ, Labs - Prapor" + } + }, + "Tunnel": { + "displayName": { + "en": "Tunnel to Lighthouse - Peacekeeper" + } + }, + "Shorl_V-Ex": { + "displayName": { + "en": "Road to North V-Ex to Woods" + } + }, + "South Fence Passage": { + "displayName": { + "en": "Old Bunker to Reserve, Interchange" + } + }, + "Coastal_South_Road": { + "displayName": { + "en": "Southern Road to Shoreline - Peacekeeper" + } + }, + " V-Ex_light": { + "displayName": { + "en": "Road to Military Base V-Ex to Reserve" + } + }, + "E5": { + "displayName": { + "en": "Collapsed Crane to Customs, GZ - Therapist" + } + }, + "E7_car": { + "displayName": { + "en": "Primorsky Ave Taxi V-Ex to Customs, Interchange, GZ, Labs - Prapor" + } + }, + "lab_Parking_Gate": { + "displayName": { + "en": "Parking Gate" + } + }, + "lab_Hangar_Gate": { + "displayName": { + "en": "Hangar Gate" + } + }, + "lab_Elevator_Med": { + "displayName": { + "en": "Medical Block Elevator" + } + }, + "lab_Under_Storage_Collector": { + "displayName": { + "en": "Sewage Conduit" + } + }, + "lab_Elevator_Main": { + "displayName": { + "en": "Main Elevator" + } + }, + "lab_Vent": { + "displayName": { + "en": "Ventilation Shaft" + } + }, + "lab_Elevator_Cargo": { + "displayName": { + "en": "Cargo Elevator" + } + }, + "Scav_coop_exit": { + "displayName": { + "en": "Scav Checkpoint to Customs, Streets - Therapist" + } + }, + "Sandbox_VExit": { + "displayName": { + "en": "Police Cordon V-Ex to Customs, Interchange, Streets, Labs - Prapor" + } + } } } diff --git a/scripts/extract-legacy-tooltips.js b/scripts/extract-legacy-tooltips.js index 2a59c71c..426aec67 100644 --- a/scripts/extract-legacy-tooltips.js +++ b/scripts/extract-legacy-tooltips.js @@ -110,23 +110,13 @@ const mergeConfigs = (configA, configB) => { return result; }; +void mergeConfigs; -const Tooltips_EN = loadTooltips('DevilFlippy'); -const Tooltips_FR = loadTooltips('DevilFlippy/FR'); +const Tooltips_EN = loadTooltips('LegacyPathToTarkovV5'); const configEN = extractExfiltrationsConfigFromLocales( Tooltips_EN.allLocales, Tooltips_EN.language, ); -const configFR = extractExfiltrationsConfigFromLocales( - Tooltips_FR.allLocales, - Tooltips_FR.language, -); - -const mergedConfigs = mergeConfigs(configEN, configFR); -console.log(JSON.stringify(mergedConfigs, undefined, 2)); -console.log( - 'same amount of keys found between EN and FR: ', - Object.keys(configFR).length === Object.keys(configEN).length, -); +console.log(JSON.stringify(configEN, undefined, 2)); From 04438d7d446be5948f6974ffb1624d5c8a02c747 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:31:39 +0100 Subject: [PATCH 082/203] chore: cleanup NarcotisConfig tooltips --- configs/OriginalNarcoticsConfig/Tooltips.json | 222 --------- configs/OriginalNarcoticsConfig/config.json | 427 ++++++++++++++++++ scripts/extract-legacy-tooltips.js | 2 +- 3 files changed, 428 insertions(+), 223 deletions(-) delete mode 100644 configs/OriginalNarcoticsConfig/Tooltips.json diff --git a/configs/OriginalNarcoticsConfig/Tooltips.json b/configs/OriginalNarcoticsConfig/Tooltips.json deleted file mode 100644 index b0d54168..00000000 --- a/configs/OriginalNarcoticsConfig/Tooltips.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", - "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", - "comment": "If you are using the standard config, this should be set to false", - - "language": "english", - - "moddedTraderCompat": true, - "additionalLocalesToggle": true, - - "moddedTraderExtracts": [ - "Trailer Park Workers Shack", - "Trailer Park Workers' Shack (Legs)", - "Scav_Hideout_at_the_grotto", - "Hideout at the Grotto (Artem)", - "Railroad To Tarkov", - "RR to Tarkov (Painter/Streets/Interchange)", - "NW Exfil", - "Railway (Painter/Customs/Woods/Streets)", - "PP Exfil", - "Power Station SUV (Painter/Streets/Woods/GZ)", - "E4", - "Crash Site (Painter/Customs/Interchange)", - "ZB-014", - "ZB-014 (Scorpion)", - "EXFIL_Bunker", - "Bunker Hermetic Door (Scorpion/Woods*)", - "SE Exfil", - "Emercom Checkpoint (Lotus/Customs)", - "Crossroads", - "Crossroads (Lotus/Interchange/Shoreline*)", - "Nakatani_stairs_free_exit", - "Nakatani Basement Stairs (Coyote/Streets/Labs)", - "scav_e1", - "Basement Descent (Coyote/Labs/Ground Zero)", - "lab_Elevator_Cargo", - "Cargo Elevator (Coyote/Streets/Ground Zero)", - "E3", - "Ruined House (Hephaestus)", - "EXFIL_Vent", - "Manhole (Sally/Streets)", - "scav_e4", - "Manhole (Sally/Reserve)" - ], - - "localesToChangeAdditional": ["Saferoom Exfil", "Saferoom (Flea Market)"], - - "localesToChange": [ - "East Gate", - "Scav Bunker (Prapor)", - "Unity_free_exit", - "Emercom Checkpoint (Therapist)", - "Warehouse 17", - "Warehouse 17 (Skier)", - "Mountain Stash", - "Mountain Stash (Jaeger)", - "Interchange Cooperation", - "Scav Camp (Ragman/Customs)", - "Trailer Park", - "Trailer Park (Ragman/Interchange)", - "EXFIL_Bunker_D2", - "D-2 (Peacekeeper/Shoreline*)", - "South Fence Passage", - "Old Bunker (Peacekeeper)", - "Camera Bunker Door", - "Camera Bunker Door (Mechanic)", - "Railroad To Port", - "RR to Port (Ref/Shoreline)", - "Road_at_railbridge", - "Railbridge (Ref/Customs)", - - "Gate 3", - "Gate 3 (Woods, ZB-1016)", - "Gate m", - "Med Tent Gates (Customs, ZB-1012)", - "Gate 0", - "Gate 0 (Customs, ZB-1011)", - "Cellars", - "Cellars (Customs, ZB-1013)", - "Office Window", - "Office Window (Customs/Woods)", - - "ZB-1011", - "ZB-1011 (Hideout/Factory)", - "ZB-1012", - "ZB-1012 (Factory, Med Tent Gates)", - "EXFIL_ZB013", - "ZB-1013 (Factory, Cellars)", - "Military Checkpoint", - "Scav Checkpoint (Woods/Lighthouse)", - "Sniper Roadblock", - "Sniper Roadblock (Reserve*/Shoreline)", - "Smuggler's Boat", - "Smuggler's Boat (Lighthouse*/Shoreline/Woods*", - "Dorms V-Ex", - "Dorms SUV (Shoreline, North Fence SUV)", - "RUAF Roadblock", - "RUAF Roadblock (Woods, UN Roadblock)", - "Old Azs Gate", - "Old Gas Gate (Factory/Woods)", - "Shack", - "Military Base Checkpoint (Reserve, Scav lands)", - "Crossroads", - "Crossroads (Interchange/Shoreline*)", - "Railroad To Military Base", - "RR to Military Base (Reserve, Scav land rails*)", - "Factory Far Corner", - "Factory Corner (Woods, RUAF Gate)", - "Railroad To Tarkov", - "RR to Tarkov (Streets/Interchange)", - - "un-sec", - "North UN Roadblock (Customs, RUAF Roadblock*)", - "Factory gate", - "Factory Gate (Customs, Old Gas Gate)", - "ZB-016", - "ZB-016 (Factory, Gate 3)", - "Outskirts", - "Outskirts (Customs/Lighthouse)", - "UN Roadblock", - "UN Roadblock (Customs/Interchange)", - "South V-Ex", - "Bridge SUV (Streets/Interchange/GZ)", - "RUAF Gate", - "RUAF Gate (Customs, Factory Corner)", - - "EXFIL_ScavCooperation", - "Scav lands (Customs, Military Base CP)", - "EXFIL_Train", - "Armored Train (all maps besides GZ*)", - "Exit1", - "Hole in the Wall (Customs, Dorms Car*)", - "Exit4", - "Checkpoint Fence (Lighthouse, Northeast Mountains*)", - "Alpinist", - "Cliff Descent (Shoreline, Climber's Trail)", - "EXFIL_Vent", - "Manhole (Streets, Manhole)", - "EXFIL_Bunker", - "Bunker Hermetic Door (Woods, ZB-014*)", - - "SE Exfil", - "Emercom Checkpoint (Customs, Crossroads)", - "NW Exfil", - "Railway (Customs/Woods/Streets)", - "PP Exfil", - "Power Station SUV (Streets/Woods/GZ)", - - "E1", - "Stylobate Elevator (Labs, Main Elevator)", - "E2", - "Sewer River (Labs, Sewage Conduit)", - "E4", - "Crash Site (Customs/Interchange)", - "E7", - "Expo Checkpoint (Ground Zero, Scav Camp)", - "E7_car", - "Primorsky Ave Taxi (Woods/Interchange/GZ)", - "E9_sniper", - "Klimov Ave (Ground Zero, Mira Ave)", - "scav_e1", - "Basement Descent (Labs/Ground Zero)", - "scav_e2", - "Entrance to Catacombs (Labs, Hangar Gate)", - "scav_e3", - "Vent Shaft (Lab, Vents)", - "scav_e4", - "Manhole (Reserve, Manhole)", - - "Road to Customs", - "Road to Customs (Customs, Sniper Roadblock*)", - "Pier Boat", - "Pier Boat (Lighthouse*/Customs/Woods*)", - "Tunnel", - "Tunnel (Lighthouse, Side Tunnel)", - "Wrecked Road", - "Ruined Road (Lighthouse, Southern Road)", - "Smugglers_Trail_coop", - "Smuggler's Path (Customs/Reserve*)", - "Shorl_V-Ex", - "North Fence SUV (Customs, Dorms SUV)", - "Lighthouse_pass", - "Path to Lighthouse", - "RedRebel_alp", - "Climber's Trail (Reserve, Cliff Descent)", - - "Nothern_Checkpoint", - "Northern Checkpoint (Woods/Customs)", - " V-ex_light", - "Military Base SUV (Reserve, CP Fence)", - "Shorl_free", - "Path to Shoreline", - "Coastal_South_road", - "Southern Road (Shoreline, Ruined Road)", - "Alpinist_light", - "Mountain Pass (Shoreline, Path to Shoreline*)", - "Tunnel_Shared", - "Side Tunnel (Shoreline, Tunnel)", - "EXFIL_Train", - "Armored Train (all maps besides GZ*)", - - "lab_Elevator_Cargo", - "Cargo Elevator (Streets/Ground Zero)", - "lab_Elevator_Main", - "Main Elevator (Streets, Stylobate Elevator)", - "lab_Hangar_Gate", - "Hangar Gate (Streets, Catacombs)", - "lab_Under_Storage_Collector", - "Sewage Conduit (Streets, Sewer River)", - "lab_Vent", - "Vents (Streets, Vent Shaft)", - - "Sandbox_VExit", - "Police Car (Woods/Interchange/Streets)", - "Nakatani_stairs_free_exit", - "Nakatani Basement Stairs (Streets/Labs)", - "Sniper_exit", - "Mira Ave (Streets, Klimov Ave)", - "Scav_coop_exit", - "Scav Checkpoint (Streets, Expo CP)" - ] -} diff --git a/configs/OriginalNarcoticsConfig/config.json b/configs/OriginalNarcoticsConfig/config.json index c650223c..92709169 100644 --- a/configs/OriginalNarcoticsConfig/config.json +++ b/configs/OriginalNarcoticsConfig/config.json @@ -1012,5 +1012,432 @@ "tarkovstreets": ["Catacombs"], "laboratory": ["Hangar Gate"] } + }, + "exfiltrations_config": { + "East Gate": { + "displayName": { + "en": "Scav Bunker (Prapor)" + } + }, + "Unity_free_exit": { + "displayName": { + "en": "Emercom Checkpoint (Therapist)" + } + }, + "Warehouse 17": { + "displayName": { + "en": "Warehouse 17 (Skier)" + } + }, + "Mountain Stash": { + "displayName": { + "en": "Mountain Stash (Jaeger)" + } + }, + "Interchange Cooperation": { + "displayName": { + "en": "Scav Camp (Ragman/Customs)" + } + }, + "Trailer Park": { + "displayName": { + "en": "Trailer Park (Ragman/Interchange)" + } + }, + "EXFIL_Bunker_D2": { + "displayName": { + "en": "D-2 (Peacekeeper/Shoreline*)" + } + }, + "South Fence Passage": { + "displayName": { + "en": "Old Bunker (Peacekeeper)" + } + }, + "Camera Bunker Door": { + "displayName": { + "en": "Camera Bunker Door (Mechanic)" + } + }, + "Railroad To Port": { + "displayName": { + "en": "RR to Port (Ref/Shoreline)" + } + }, + "Road_at_railbridge": { + "displayName": { + "en": "Railbridge (Ref/Customs)" + } + }, + "Gate 3": { + "displayName": { + "en": "Gate 3 (Woods, ZB-1016)" + } + }, + "Gate m": { + "displayName": { + "en": "Med Tent Gates (Customs, ZB-1012)" + } + }, + "Gate 0": { + "displayName": { + "en": "Gate 0 (Customs, ZB-1011)" + } + }, + "Cellars": { + "displayName": { + "en": "Cellars (Customs, ZB-1013)" + } + }, + "Office Window": { + "displayName": { + "en": "Office Window (Customs/Woods)" + } + }, + "ZB-1011": { + "displayName": { + "en": "ZB-1011 (Hideout/Factory)" + } + }, + "ZB-1012": { + "displayName": { + "en": "ZB-1012 (Factory, Med Tent Gates)" + } + }, + "EXFIL_ZB013": { + "displayName": { + "en": "ZB-1013 (Factory, Cellars)" + } + }, + "Military Checkpoint": { + "displayName": { + "en": "Scav Checkpoint (Woods/Lighthouse)" + } + }, + "Sniper Roadblock": { + "displayName": { + "en": "Sniper Roadblock (Reserve*/Shoreline)" + } + }, + "Smuggler's Boat": { + "displayName": { + "en": "Smuggler's Boat (Lighthouse*/Shoreline/Woods*" + } + }, + "Dorms V-Ex": { + "displayName": { + "en": "Dorms SUV (Shoreline, North Fence SUV)" + } + }, + "RUAF Roadblock": { + "displayName": { + "en": "RUAF Roadblock (Woods, UN Roadblock)" + } + }, + "Old Azs Gate": { + "displayName": { + "en": "Old Gas Gate (Factory/Woods)" + } + }, + "Shack": { + "displayName": { + "en": "Military Base Checkpoint (Reserve, Scav lands)" + } + }, + "Railroad To Military Base": { + "displayName": { + "en": "RR to Military Base (Reserve, Scav land rails*)" + } + }, + "Factory Far Corner": { + "displayName": { + "en": "Factory Corner (Woods, RUAF Gate)" + } + }, + "un-sec": { + "displayName": { + "en": "North UN Roadblock (Customs, RUAF Roadblock*)" + } + }, + "Factory gate": { + "displayName": { + "en": "Factory Gate (Customs, Old Gas Gate)" + } + }, + "ZB-016": { + "displayName": { + "en": "ZB-016 (Factory, Gate 3)" + } + }, + "Outskirts": { + "displayName": { + "en": "Outskirts (Customs/Lighthouse)" + } + }, + "UN Roadblock": { + "displayName": { + "en": "UN Roadblock (Customs/Interchange)" + } + }, + "South V-Ex": { + "displayName": { + "en": "Bridge SUV (Streets/Interchange/GZ)" + } + }, + "RUAF Gate": { + "displayName": { + "en": "RUAF Gate (Customs, Factory Corner)" + } + }, + "EXFIL_ScavCooperation": { + "displayName": { + "en": "Scav lands (Customs, Military Base CP)" + } + }, + "EXFIL_Train": { + "displayName": { + "en": "Armored Train (all maps besides GZ*)" + } + }, + "Exit1": { + "displayName": { + "en": "Hole in the Wall (Customs, Dorms Car*)" + } + }, + "Exit4": { + "displayName": { + "en": "Checkpoint Fence (Lighthouse, Northeast Mountains*)" + } + }, + "Alpinist": { + "displayName": { + "en": "Cliff Descent (Shoreline, Climber's Trail)" + } + }, + "E1": { + "displayName": { + "en": "Stylobate Elevator (Labs, Main Elevator)" + } + }, + "E2": { + "displayName": { + "en": "Sewer River (Labs, Sewage Conduit)" + } + }, + "E7": { + "displayName": { + "en": "Expo Checkpoint (Ground Zero, Scav Camp)" + } + }, + "E7_car": { + "displayName": { + "en": "Primorsky Ave Taxi (Woods/Interchange/GZ)" + } + }, + "E9_sniper": { + "displayName": { + "en": "Basement Descent (Labs/Ground Zero)" + } + }, + "scav_e2": { + "displayName": { + "en": "Entrance to Catacombs (Labs, Hangar Gate)" + } + }, + "scav_e3": { + "displayName": { + "en": "Vent Shaft (Lab, Vents)" + } + }, + "Road to Customs": { + "displayName": { + "en": "Road to Customs (Customs, Sniper Roadblock*)" + } + }, + "Pier Boat": { + "displayName": { + "en": "Pier Boat (Lighthouse*/Customs/Woods*)" + } + }, + "Tunnel": { + "displayName": { + "en": "Tunnel (Lighthouse, Side Tunnel)" + } + }, + "Wrecked Road": { + "displayName": { + "en": "Ruined Road (Lighthouse, Southern Road)" + } + }, + "Smugglers_Trail_coop": { + "displayName": { + "en": "Smuggler's Path (Customs/Reserve*)" + } + }, + "Shorl_V-Ex": { + "displayName": { + "en": "North Fence SUV (Customs, Dorms SUV)" + } + }, + "Lighthouse_pass": { + "displayName": { + "en": "Path to Lighthouse" + } + }, + "RedRebel_alp": { + "displayName": { + "en": "Climber's Trail (Reserve, Cliff Descent)" + } + }, + "Nothern_Checkpoint": { + "displayName": { + "en": "Northern Checkpoint (Woods/Customs)" + } + }, + " V-ex_light": { + "displayName": { + "en": "Military Base SUV (Reserve, CP Fence)" + } + }, + "Shorl_free": { + "displayName": { + "en": "Path to Shoreline" + } + }, + "Coastal_South_road": { + "displayName": { + "en": "Southern Road (Shoreline, Ruined Road)" + } + }, + "Alpinist_light": { + "displayName": { + "en": "Mountain Pass (Shoreline, Path to Shoreline*)" + } + }, + "Tunnel_Shared": { + "displayName": { + "en": "Side Tunnel (Shoreline, Tunnel)" + } + }, + "lab_Elevator_Main": { + "displayName": { + "en": "Main Elevator (Streets, Stylobate Elevator)" + } + }, + "lab_Hangar_Gate": { + "displayName": { + "en": "Hangar Gate (Streets, Catacombs)" + } + }, + "lab_Under_Storage_Collector": { + "displayName": { + "en": "Sewage Conduit (Streets, Sewer River)" + } + }, + "lab_Vent": { + "displayName": { + "en": "Vents (Streets, Vent Shaft)" + } + }, + "Sandbox_VExit": { + "displayName": { + "en": "Police Car (Woods/Interchange/Streets)" + } + }, + "Sniper_exit": { + "displayName": { + "en": "Mira Ave (Streets, Klimov Ave)" + } + }, + "Scav_coop_exit": { + "displayName": { + "en": "Scav Checkpoint (Streets, Expo CP)" + } + }, + "Saferoom Exfil": { + "displayName": { + "en": "Saferoom (Flea Market)" + } + }, + "Trailer Park Workers Shack": { + "displayName": { + "en": "Trailer Park Workers' Shack (Legs)" + } + }, + "Scav_Hideout_at_the_grotto": { + "displayName": { + "en": "Hideout at the Grotto (Artem)" + } + }, + "Railroad To Tarkov": { + "displayName": { + "en": "RR to Tarkov (Painter/Streets/Interchange)" + } + }, + "NW Exfil": { + "displayName": { + "en": "Railway (Painter/Customs/Woods/Streets)" + } + }, + "PP Exfil": { + "displayName": { + "en": "Power Station SUV (Painter/Streets/Woods/GZ)" + } + }, + "E4": { + "displayName": { + "en": "Crash Site (Painter/Customs/Interchange)" + } + }, + "ZB-014": { + "displayName": { + "en": "ZB-014 (Scorpion)" + } + }, + "EXFIL_Bunker": { + "displayName": { + "en": "Bunker Hermetic Door (Scorpion/Woods*)" + } + }, + "SE Exfil": { + "displayName": { + "en": "Emercom Checkpoint (Lotus/Customs)" + } + }, + "Crossroads": { + "displayName": { + "en": "Crossroads (Lotus/Interchange/Shoreline*)" + } + }, + "Nakatani_stairs_free_exit": { + "displayName": { + "en": "Nakatani Basement Stairs (Coyote/Streets/Labs)" + } + }, + "scav_e1": { + "displayName": { + "en": "Basement Descent (Coyote/Labs/Ground Zero)" + } + }, + "lab_Elevator_Cargo": { + "displayName": { + "en": "Cargo Elevator (Coyote/Streets/Ground Zero)" + } + }, + "E3": { + "displayName": { + "en": "Ruined House (Hephaestus)" + } + }, + "EXFIL_Vent": { + "displayName": { + "en": "Manhole (Sally/Streets)" + } + }, + "scav_e4": { + "displayName": { + "en": "Manhole (Sally/Reserve)" + } + } } } diff --git a/scripts/extract-legacy-tooltips.js b/scripts/extract-legacy-tooltips.js index 426aec67..8afe11ca 100644 --- a/scripts/extract-legacy-tooltips.js +++ b/scripts/extract-legacy-tooltips.js @@ -112,7 +112,7 @@ const mergeConfigs = (configA, configB) => { }; void mergeConfigs; -const Tooltips_EN = loadTooltips('LegacyPathToTarkovV5'); +const Tooltips_EN = loadTooltips('OriginalNarcoticsConfig'); const configEN = extractExfiltrationsConfigFromLocales( Tooltips_EN.allLocales, From d13cd740641569d8f21fb41277e46908110e5096 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:35:57 +0100 Subject: [PATCH 083/203] chore: cleanup PTTR tooltips --- configs/PathToTarkovReloaded/Tooltips.json | 40 +-- configs/PathToTarkovReloaded/config.json | 327 +++++++++++++++++++++ scripts/extract-legacy-tooltips.js | 2 +- 3 files changed, 329 insertions(+), 40 deletions(-) diff --git a/configs/PathToTarkovReloaded/Tooltips.json b/configs/PathToTarkovReloaded/Tooltips.json index 34a10b73..1f16d6b7 100644 --- a/configs/PathToTarkovReloaded/Tooltips.json +++ b/configs/PathToTarkovReloaded/Tooltips.json @@ -47,21 +47,12 @@ "The Boat", "Boat (Machine,Artem)", - "Smuggler's Boat", - "Boat (Machine,Artem)", - - "Gate 0", - "WoodsFactoryGate (Prapor)", - "WoodsFactoryGate", "Gate 0 (Prapor)", "Hole Exfil", "Crossroads (The Machine)", - "Crossroads", - "Hole Exfil (The Machine)", - "ZB-1012", "ZB-1012 to Factory, Med tent gate(Mechanic)", @@ -94,23 +85,15 @@ "Outskirts Water", "Northern Bridge (to Streets, Car)", - "South V-Ex", - "Bridge Car (to Streets, Car)", - "un-sec", - "N. UN Roadblock (to Customs, RUAF)", "UN Roadblock", "UN Roadblock (to Customs, RUAF)", "Factory gate", "Factory Gate (to Factory, Med Tent)", - "Outskirts", - "Outskirts (to Lighthouse, N. Checkpoint)", "Old Azs Gate", "Old Gas Gate (to Factory, Gate 0)", "Factory Far Corner", "Factory Far Corner (to Factory, Gate 3)", - "RUAF Roadblock", - "RUAF Roadblock (to Woods, N. UN Roadblock)", "Railroad To Tarkov", "RR to Tarkov (to Interchange, Railway)", "Crossroads", @@ -122,8 +105,6 @@ "NW Exfil", "Railway (to Customs, RR to Tarkov)", - "PP Exfil", - "Power Station Car (to Streets, Underpass)", "SE Exfil", "Emercom (to Streets, Underpass)", @@ -155,10 +136,6 @@ "EXFIL_BUNKER_D2", "D-2 (to Woods, Snip er Rock Bunker *1way)", - "Road to Customs", - "Road to Customs (to Customs, Crossroads)", - "Pier Boat", - "Pier Boat (to Lighthouse, Woods, Customs, Machine,Artem,Jaeger)", "Tunnel", "Tunnel (to Lighthouse, Side Tunnel)", "Lighthouse_pass", @@ -196,21 +173,6 @@ "lab_Under_Storage_Collector", "Sewage Conduit (to Streets, Sewer River)", "lab_Vent", - "Vents (to Streets, Vents)", - - "5a7c2eca46aef81a7ca2145d Location", - "", - "5ac3b934156ae10c4430e83c Location", - "", - "54cb50c76803fa8b248b4571 Location", - "", - "54cb57776803fa99248b456e Location", - "", - "58330581ace78e27b8b10cee Location", - "", - "5935c25fb3acc3127c3d8cd9 Location", - "", - "5c0647fdd443bc2504c2d371 Location", - "" + "Vents (to Streets, Vents)" ] } diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index f5b047c3..1f3d3a31 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -742,5 +742,332 @@ "tarkovstreets": ["Catacombs"], "laboratory": ["Hangar Gate"] } + }, + "exfiltrations_config": { + "Gate 0": { + "displayName": { + "en": "Gate 0 (to Customs, Old Gas Gate)" + } + }, + "Gate 3": { + "displayName": { + "en": "Gate 3 (to Customs, Factory Far Corner)" + } + }, + "Gate m": { + "displayName": { + "en": "Medical Tent (to Woods, Factory Gate)" + } + }, + "Outskirts Water": { + "displayName": { + "en": "Northern Bridge (to Streets, Car)" + } + }, + "UN Roadblock": { + "displayName": { + "en": "UN Roadblock (to Customs, RUAF)" + } + }, + "Factory gate": { + "displayName": { + "en": "Factory Gate (to Factory, Med Tent)" + } + }, + "Old Azs Gate": { + "displayName": { + "en": "Old Gas Gate (to Factory, Gate 0)" + } + }, + "Factory Far Corner": { + "displayName": { + "en": "Factory Far Corner (to Factory, Gate 3)" + } + }, + "Railroad To Tarkov": { + "displayName": { + "en": "RR to Tarkov (to Interchange, Railway)" + } + }, + "Crossroads": { + "displayName": { + "en": "Crossroads (to Shoreline, Road to Customs)" + } + }, + "Railroad To Port": { + "displayName": { + "en": "RR to Port (to Shoreline, Railbridge)" + } + }, + "Railroad To Military Base": { + "displayName": { + "en": "RR to Mil Base (to Reserve, Train Station *1way)" + } + }, + "NW Exfil": { + "displayName": { + "en": "Railway (to Customs, RR to Tarkov)" + } + }, + "SE Exfil": { + "displayName": { + "en": "Emercom (to Streets, Underpass)" + } + }, + "E1": { + "displayName": { + "en": "Underpass (to Interchange, Emercom)" + } + }, + "E2": { + "displayName": { + "en": "Sewer River (to Lab, Sewage Conduit)" + } + }, + "E4": { + "displayName": { + "en": "Evac to Mil Base (to Reserve, Checkpoint Fence)" + } + }, + "E7_car": { + "displayName": { + "en": "Primorsky Ave Taxi (to Woods, Bridge Car)" + } + }, + "scav_e1": { + "displayName": { + "en": "Basement Descent (to Lab, Main Elevator)" + } + }, + "scav_e2": { + "displayName": { + "en": "Entrance to Catacombs (to Lab, Parking Gate)" + } + }, + "scav_e3": { + "displayName": { + "en": "Vents (to Lab, Vents)" + } + }, + "scav_e4": { + "displayName": { + "en": "Manhole (to Reserve, Manhole)" + } + }, + "Alpinist": { + "displayName": { + "en": "Cliff Descent (to Shoreline, N. Cliffs *1way)" + } + }, + "EXFIL_vent": { + "displayName": { + "en": "Manhole (to Streets, Manhole)" + } + }, + "Exit4": { + "displayName": { + "en": "Checkpoint Fence (to Streets, Evac to Mil Base)" + } + }, + "EXFIL_Bunker": { + "displayName": { + "en": "Bunker Hermetic Door (to Shoreline, Checkpoint *1way)" + } + }, + "EXFIL_BUNKER_D2": { + "displayName": { + "en": "D-2 (to Woods, Snip er Rock Bunker *1way)" + } + }, + "Tunnel": { + "displayName": { + "en": "Tunnel (to Lighthouse, Side Tunnel)" + } + }, + "Lighthouse_pass": { + "displayName": { + "en": "Path to Lighthouse (... you get it)" + } + }, + "South Fence Passage": { + "displayName": { + "en": "North Fence Passage (to Reserve, Hole in Wall *1way)" + } + }, + "Road_at_railbridge": { + "displayName": { + "en": "Railbridge (to Customs, RR to Port)" + } + }, + "Nothern_Checkpoint": { + "displayName": { + "en": "Northern CP (to Woods, Outskirts)" + } + }, + " V-ex_light": { + "displayName": { + "en": "Car Ride Home" + } + }, + "Shorl_free": { + "displayName": { + "en": "Path to Shoreline (I swear if you ask)" + } + }, + "Coastal_South_road": { + "displayName": { + "en": "Southern Road (to Shoreline, Tunnel)" + } + }, + "Alpinist_light": { + "displayName": { + "en": "Mountain Pass (to Shoreline, Path to Shoreline)" + } + }, + "Tunnel_Shared": { + "displayName": { + "en": "Side Tunnel (to Shoreline, Tunnel)" + } + }, + "Scav_Hideout_at_the_grotto": { + "displayName": { + "en": "Hideout at the Grotto (to Shoreline, Pier Boat)" + } + }, + "lab_Elevator_Cargo": { + "displayName": { + "en": "Cargo Elevator (to Streets, Basement)" + } + }, + "lab_Elevator_Main": { + "displayName": { + "en": "Main Elevator (to Streets, Basement)" + } + }, + "lab_Elevator_med": { + "displayName": { + "en": "Medical Block Elevator (to Streets, Basement)" + } + }, + "lab_Hangar_Gate": { + "displayName": { + "en": "Hangar Gate (to Streets, Catacombs)" + } + }, + "lab_Parking_Gate": { + "displayName": { + "en": "Parking Gate (to Streets, Catacombs)" + } + }, + "lab_Under_Storage_Collector": { + "displayName": { + "en": "Sewage Conduit (to Streets, Sewer River)" + } + }, + "lab_Vent": { + "displayName": { + "en": "Vents (to Streets, Vents)" + } + }, + "RUAF Roadblock": { + "displayName": { + "en": "North UN Woods(PeaceKeeper)" + } + }, + "un-sec": { + "displayName": { + "en": "RUAF Roadblock(PeaceKeeper)" + } + }, + "Road to Customs": { + "displayName": { + "en": "Road to Customs to Customs, SniperRoadblock(Skier)" + } + }, + "Sniper Roadblock": { + "displayName": { + "en": "Sniper Roadblock to Shoreline, Road to Customs(Skier)" + } + }, + "Smuggler's Boat": { + "displayName": { + "en": "Shoreline,Woods,Lighthouse(Machine,Artem,Jaeger)" + } + }, + "PP Exfil": { + "displayName": { + "en": "Car (Home,Prapor,Therapist,Rag,Jae,Harry)" + } + }, + "South V-Ex": { + "displayName": { + "en": "Car (Jaeger)" + } + }, + "Dorms V-Ex": { + "displayName": { + "en": "Car (Jaeger)" + } + }, + " V-Ex_light": { + "displayName": { + "en": "Car (Jaeger)" + } + }, + "Pier Boat": { + "displayName": { + "en": "Boat (Machine,Artem)" + } + }, + "The Boat": { + "displayName": { + "en": "Boat (Machine,Artem)" + } + }, + "WoodsFactoryGate": { + "displayName": { + "en": "Gate 0 (Prapor)" + } + }, + "Hole Exfil": { + "displayName": { + "en": "Crossroads (The Machine)" + } + }, + "ZB-1012": { + "displayName": { + "en": "ZB-1012 to Factory, Med tent gate(Mechanic)" + } + }, + "ZB-1011": { + "displayName": { + "en": "Zb-1011 to Factory, Cellars(Mechanic)" + } + }, + "ZB-1013": { + "displayName": { + "en": "ZB-1013 to Factory, Gate 3(Mechanic)" + } + }, + "ZB-1014": { + "displayName": { + "en": "ZB-1014 to Factory, Gate 3(Mechanic)" + } + }, + "Outskirts": { + "displayName": { + "en": "Outskirts to Reserve and Shoreline (Priscillu)" + } + }, + "Checkpoint Fence": { + "displayName": { + "en": "Checkpoint Fence to Woods and Shoreline (Priscillu)" + } + }, + "Nakatani_stairs_free_exit": { + "displayName": { + "en": "Nakatani Basement (Hideout)" + } + } } } diff --git a/scripts/extract-legacy-tooltips.js b/scripts/extract-legacy-tooltips.js index 8afe11ca..d250b807 100644 --- a/scripts/extract-legacy-tooltips.js +++ b/scripts/extract-legacy-tooltips.js @@ -112,7 +112,7 @@ const mergeConfigs = (configA, configB) => { }; void mergeConfigs; -const Tooltips_EN = loadTooltips('OriginalNarcoticsConfig'); +const Tooltips_EN = loadTooltips('PathToTarkovReloaded'); const configEN = extractExfiltrationsConfigFromLocales( Tooltips_EN.allLocales, From b74d067e5f3c9a84472fad513cc9184ff4f96fd0 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:44:10 +0100 Subject: [PATCH 084/203] chore: full cleanup of the pttr legacy tooltips --- configs/PathToTarkovReloaded/Tooltips.json | 178 --------------------- scripts/extract-legacy-tooltips.js | 122 -------------- src/config.ts | 9 -- src/mod.ts | 24 +-- src/pttr-tooltips.ts | 82 ---------- 5 files changed, 3 insertions(+), 412 deletions(-) delete mode 100644 configs/PathToTarkovReloaded/Tooltips.json delete mode 100644 scripts/extract-legacy-tooltips.js delete mode 100644 src/pttr-tooltips.ts diff --git a/configs/PathToTarkovReloaded/Tooltips.json b/configs/PathToTarkovReloaded/Tooltips.json deleted file mode 100644 index 1f16d6b7..00000000 --- a/configs/PathToTarkovReloaded/Tooltips.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "comment": "In the locales arrays below, even indexes (including 0) must be locale keywords, and odd indexes are the overwrite locale values.", - "comment": "If you are using the mode that includes the extra trader and specific trader/ stash locations, this should be set to true", - "comment": "If you are using the standard config, this should be set to false", - - "moddedTraderCompat": false, - "additionalLocalesToggle": true, - - "moddedTraderExtracts": [ - "Saferoom Exfil", - "Saferoom (Goblin King)", - "EXFIL_ZB013", - "ZB-1013 Storage Bunker (Broker)" - ], - - "localesToChangeAdditional": [ - "RUAF Roadblock", - "North UN Woods(PeaceKeeper)", - - "un-sec", - "RUAF Roadblock(PeaceKeeper)", - - "Road to Customs", - "Road to Customs to Customs, SniperRoadblock(Skier)", - - "Sniper Roadblock", - "Sniper Roadblock to Shoreline, Road to Customs(Skier)", - - "Smuggler's Boat", - "Shoreline,Woods,Lighthouse(Machine,Artem,Jaeger)", - - "PP Exfil", - "Car (Home,Prapor,Therapist,Rag,Jae,Harry)", - - "South V-Ex", - "Car (Jaeger)", - - "Dorms V-Ex", - "Car (Jaeger)", - - " V-Ex_light", - "Car (Jaeger)", - - "Pier Boat", - "Boat (Machine,Artem)", - - "The Boat", - "Boat (Machine,Artem)", - - "WoodsFactoryGate", - "Gate 0 (Prapor)", - - "Hole Exfil", - "Crossroads (The Machine)", - - "ZB-1012", - "ZB-1012 to Factory, Med tent gate(Mechanic)", - - "ZB-1011", - "Zb-1011 to Factory, Cellars(Mechanic)", - - "ZB-1013", - "ZB-1013 to Factory, Gate 3(Mechanic)", - - "ZB-1014", - "ZB-1014 to Factory, Gate 3(Mechanic)", - - "Outskirts", - "Outskirts to Reserve and Shoreline (Priscillu)", - - "Checkpoint Fence", - "Checkpoint Fence to Woods and Shoreline (Priscillu)", - - "Nakatani_stairs_free_exit", - "Nakatani Basement (Hideout)" - ], - - "localesToChange": [ - "Gate 0", - "Gate 0 (to Customs, Old Gas Gate)", - "Gate 3", - "Gate 3 (to Customs, Factory Far Corner)", - "Gate m", - "Medical Tent (to Woods, Factory Gate)", - - "Outskirts Water", - "Northern Bridge (to Streets, Car)", - "UN Roadblock", - "UN Roadblock (to Customs, RUAF)", - "Factory gate", - "Factory Gate (to Factory, Med Tent)", - - "Old Azs Gate", - "Old Gas Gate (to Factory, Gate 0)", - "Factory Far Corner", - "Factory Far Corner (to Factory, Gate 3)", - "Railroad To Tarkov", - "RR to Tarkov (to Interchange, Railway)", - "Crossroads", - "Crossroads (to Shoreline, Road to Customs)", - "Railroad To Port", - "RR to Port (to Shoreline, Railbridge)", - "Railroad To Military Base", - "RR to Mil Base (to Reserve, Train Station *1way)", - - "NW Exfil", - "Railway (to Customs, RR to Tarkov)", - "SE Exfil", - "Emercom (to Streets, Underpass)", - - "E1", - "Underpass (to Interchange, Emercom)", - "E2", - "Sewer River (to Lab, Sewage Conduit)", - "E4", - "Evac to Mil Base (to Reserve, Checkpoint Fence)", - "E7_car", - "Primorsky Ave Taxi (to Woods, Bridge Car)", - "scav_e1", - "Basement Descent (to Lab, Main Elevator)", - "scav_e2", - "Entrance to Catacombs (to Lab, Parking Gate)", - "scav_e3", - "Vents (to Lab, Vents)", - "scav_e4", - "Manhole (to Reserve, Manhole)", - - "Alpinist", - "Cliff Descent (to Shoreline, N. Cliffs *1way)", - "EXFIL_vent", - "Manhole (to Streets, Manhole)", - "Exit4", - "Checkpoint Fence (to Streets, Evac to Mil Base)", - "EXFIL_Bunker", - "Bunker Hermetic Door (to Shoreline, Checkpoint *1way)", - "EXFIL_BUNKER_D2", - "D-2 (to Woods, Snip er Rock Bunker *1way)", - - "Tunnel", - "Tunnel (to Lighthouse, Side Tunnel)", - "Lighthouse_pass", - "Path to Lighthouse (... you get it)", - "South Fence Passage", - "North Fence Passage (to Reserve, Hole in Wall *1way)", - "Road_at_railbridge", - "Railbridge (to Customs, RR to Port)", - - "Nothern_Checkpoint", - "Northern CP (to Woods, Outskirts)", - " V-ex_light", - "Car Ride Home", - "Shorl_free", - "Path to Shoreline (I swear if you ask)", - "Coastal_South_road", - "Southern Road (to Shoreline, Tunnel)", - "Alpinist_light", - "Mountain Pass (to Shoreline, Path to Shoreline)", - "Tunnel_Shared", - "Side Tunnel (to Shoreline, Tunnel)", - "Scav_Hideout_at_the_grotto", - "Hideout at the Grotto (to Shoreline, Pier Boat)", - - "lab_Elevator_Cargo", - "Cargo Elevator (to Streets, Basement)", - "lab_Elevator_Main", - "Main Elevator (to Streets, Basement)", - "lab_Elevator_med", - "Medical Block Elevator (to Streets, Basement)", - "lab_Hangar_Gate", - "Hangar Gate (to Streets, Catacombs)", - "lab_Parking_Gate", - "Parking Gate (to Streets, Catacombs)", - "lab_Under_Storage_Collector", - "Sewage Conduit (to Streets, Sewer River)", - "lab_Vent", - "Vents (to Streets, Vents)" - ] -} diff --git a/scripts/extract-legacy-tooltips.js b/scripts/extract-legacy-tooltips.js deleted file mode 100644 index d250b807..00000000 --- a/scripts/extract-legacy-tooltips.js +++ /dev/null @@ -1,122 +0,0 @@ -const loadTooltips = tooltipsPath => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const Tooltips = require(`../configs/${tooltipsPath}/Tooltips.json`); - - const localesToChange = Tooltips.localesToChange ?? []; - const additionalLocales = - (Tooltips.additionalLocalesToggle ? Tooltips.localesToChangeAdditional : []) ?? []; - const moddedLocales = (Tooltips.moddedTraderCompat ? Tooltips.moddedTraderExtracts : []) ?? []; - const allLocales = [...localesToChange, ...additionalLocales, ...moddedLocales]; - - return { allLocales, language: Tooltips.language || 'en' }; -}; - -const localeMappings = { - english: 'en', - en: 'en', - chinese: 'ch', - ch: 'ch', - czech: 'cz', - cz: 'cz', - french: 'fr', - fr: 'fr', - german: 'ge', - ge: 'ge', - hungarian: 'hu', - hu: 'hu', - italian: 'it', - it: 'it', - japanese: 'jp', - jp: 'jp', - korean: 'kr', - kr: 'kr', - polish: 'pl', - pl: 'pl', - portuguese: 'po', - po: 'po', - slovakian: 'sk', - sk: 'sk', - spanish: 'es', - es: 'es', - turkish: 'tu', - tu: 'tu', - russian: 'ru', - ru: 'ru', - romanian: 'ro', - ro: 'ro', -}; - -const getLang = rawLang => { - return localeMappings[rawLang] ?? rawLang ?? 'en'; -}; - -const createExfilConfig = (rawLang, localeValue) => { - const lang = getLang(rawLang); - - return { - displayName: { - // ch: localeValue, - // cz: localeValue, - // en: localeValue, - // 'es-mx': localeValue, - // es: localeValue, - // fr: localeValue, - // ge: localeValue, - // hu: localeValue, - // it: localeValue, - // jp: localeValue, - // kr: localeValue, - // pl: localeValue, - // po: localeValue, - // ro: localeValue, - // ru: localeValue, - // sk: localeValue, - // tu: localeValue, - [lang]: localeValue, - }, - }; -}; - -const isOdd = n => Boolean(n % 2); -const isEven = n => !isOdd(n); - -const extractExfiltrationsConfigFromLocales = (locales, lang) => { - const exfiltrationsConfig = {}; - locales.forEach((localeKey, i) => { - if (isEven(i)) { - const localeValue = locales[i + 1]; - if (exfiltrationsConfig[localeKey]) { - throw new Error(`duplicate found for localeKey ${localeKey}`); - } - exfiltrationsConfig[localeKey] = createExfilConfig(lang, localeValue); - } - }); - return exfiltrationsConfig; -}; - -const mergeConfigs = (configA, configB) => { - const result = {}; - - Object.keys(configA).forEach(exfilName => { - const exfilConfigA = configA[exfilName]; - const exfilConfigB = configB[exfilName]; - result[exfilName] = { - displayName: { - ...exfilConfigA.displayName, - ...exfilConfigB.displayName, - }, - }; - }); - - return result; -}; -void mergeConfigs; - -const Tooltips_EN = loadTooltips('PathToTarkovReloaded'); - -const configEN = extractExfiltrationsConfigFromLocales( - Tooltips_EN.allLocales, - Tooltips_EN.language, -); - -console.log(JSON.stringify(configEN, undefined, 2)); diff --git a/src/config.ts b/src/config.ts index 9a048d1c..9a9e03d8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -192,15 +192,6 @@ export type Config = Omit { - try { - return require(path.join(CONFIGS_DIR, userConfig.selectedConfig, 'Tooltips.json')); - } catch (_err) { - return undefined; - } -}; - class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { private packageJson: PackageJson; private config: Config; private spawnConfig: SpawnConfig; - private tooltipsConfig: PathToTarkovReloadedTooltipsConfig | undefined; public logger: ILogger; public debug: (data: string) => void; public container: DependencyContainer; @@ -67,8 +56,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { this.config, ); - this.tooltipsConfig = getTooltipsConfig(userConfig); - this.logger = container.resolve('WinstonLogger'); this.debug = this.config.debug ? (data: string) => this.logger.debug(`Path To Tarkov: ${data}`, true) @@ -164,11 +151,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { this.pathToTarkovController.tradersAvailabilityService.init(quests); - if (this.tooltipsConfig) { - pathToTarkovReloadedTooltipsConfigCompat(db, this.tooltipsConfig); - this.debug('injected legacy PTTR Tooltips.json file'); - } - const [api, executeOnStartAPICallbacks] = createPathToTarkovAPI( this.pathToTarkovController, this.logger, diff --git a/src/pttr-tooltips.ts b/src/pttr-tooltips.ts deleted file mode 100644 index 7fbeced8..00000000 --- a/src/pttr-tooltips.ts +++ /dev/null @@ -1,82 +0,0 @@ -import type { DatabaseServer } from '@spt/servers/DatabaseServer'; -import type { PathToTarkovReloadedTooltipsConfig } from './config'; - -export const pathToTarkovReloadedTooltipsConfigCompat = ( - db: DatabaseServer, - tooltipsConfig: PathToTarkovReloadedTooltipsConfig, -): void => { - const database = db.getTables(); - const locales = database.locales?.global; - - if (!locales) { - throw new Error('Cannot load locales from db'); - } - - const tooltipLocale = tooltipsConfig.language?.toLowerCase() ?? 'en'; - const localesToChange = tooltipsConfig.localesToChange ?? []; - const localesToChangeAdditional = tooltipsConfig.localesToChangeAdditional ?? []; - const additionalLocalesToggle = tooltipsConfig.additionalLocalesToggle; - const moddedTraderExtracts = tooltipsConfig.moddedTraderExtracts ?? []; - const moddedTraderCompat = tooltipsConfig.moddedTraderCompat; - - // updated to cover all language locales - const updateLocale = (localeObj: Record): void => { - for (let i = 0; i < localesToChange.length; i += 2) { - localeObj[localesToChange[i]] = localesToChange[i + 1]; - } - if (additionalLocalesToggle) { - for (let i = 0; i < localesToChangeAdditional.length; i += 2) { - localeObj[localesToChangeAdditional[i]] = localesToChangeAdditional[i + 1]; - } - } - if (moddedTraderCompat) { - for (let i = 0; i < moddedTraderExtracts.length; i += 2) { - localeObj[moddedTraderExtracts[i]] = moddedTraderExtracts[i + 1]; - } - } - }; - - const localeMappings = { - english: locales.en, - en: locales.en, - chinese: locales.ch, - ch: locales.ch, - czech: locales.cz, - cz: locales.cz, - french: locales.fr, - fr: locales.fr, - german: locales.ge, - ge: locales.ge, - hungarian: locales.hu, - hu: locales.hu, - italian: locales.it, - it: locales.it, - japanese: locales.jp, - jp: locales.jp, - korean: locales.kr, - kr: locales.kr, - polish: locales.pl, - pl: locales.pl, - portuguese: locales.po, - po: locales.po, - slovakian: locales.sk, - sk: locales.sk, - spanish: locales.es, - es: locales.es, - turkish: locales.tu, - tu: locales.tu, - russian: locales.ru, - ru: locales.ru, - romanian: locales.ro, - ro: locales.ro, - }; - - // Get the locale object based on tooltipLocale - const selectedLocale = localeMappings[tooltipLocale as keyof typeof localeMappings]; - - if (!selectedLocale) { - throw new Error(`incorrect language '${tooltipLocale}' found in Tooltips.json`); - } - - updateLocale(selectedLocale); -}; From 4f95c2308104430e9dfd5725e2feb48eea13c213 Mon Sep 17 00:00:00 2001 From: Trap Date: Wed, 11 Dec 2024 23:47:10 +0100 Subject: [PATCH 085/203] fix: trim tooltips_template during validation --- src/services/ExfilsTooltipsTemplater.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts index 16423861..1fa9fbb9 100644 --- a/src/services/ExfilsTooltipsTemplater.ts +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -146,16 +146,16 @@ export class ExfilsTooltipsTemplater { { offraidPosition, exfilName }: ComputeLocaleValueParameter, ): string { const exfilConfig = config.exfiltrations_config?.[exfilName]; - if (exfilConfig?.override_tooltips_template) { + if (exfilConfig?.override_tooltips_template?.trim()) { return exfilConfig.override_tooltips_template; } const offraidPositionDefinition = config.offraid_positions?.[offraidPosition]; - if (offraidPositionDefinition?.override_tooltips_template) { + if (offraidPositionDefinition?.override_tooltips_template?.trim()) { return offraidPositionDefinition?.override_tooltips_template; } - if (config.exfiltrations_tooltips_template) { + if (config.exfiltrations_tooltips_template?.trim()) { return config.exfiltrations_tooltips_template; } From c3139f8cb5acc0ee029c108456e925e34e89cd81 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 12 Dec 2024 00:06:50 +0100 Subject: [PATCH 086/203] chore: rename PTT-BepInEx into PTT-Plugin --- .gitignore | 3 --- .prettierignore | 2 +- {PTT-BepInEx => PTT-Plugin}/.gitattributes | 0 {PTT-BepInEx => PTT-Plugin}/.gitignore | 0 {PTT-BepInEx => PTT-Plugin}/NuGet.Config | 0 {PTT-BepInEx => PTT-Plugin}/PTT.csproj | 0 {PTT-BepInEx => PTT-Plugin}/PTT.sln | 0 {PTT-BepInEx => PTT-Plugin}/Patches/HideLockedTraderPatch.cs | 0 .../Patches/InitAllExfiltrationPointsPatch.cs | 0 .../Patches/ScavExfiltrationPointPatch.cs | 0 {PTT-BepInEx => PTT-Plugin}/Plugin.cs | 0 {PTT-BepInEx => PTT-Plugin}/Settings/Config.cs | 0 {PTT-BepInEx => PTT-Plugin}/Utils/Trader.cs | 0 package.json | 4 ++-- scripts/prepare-files.js | 2 +- 15 files changed, 4 insertions(+), 7 deletions(-) rename {PTT-BepInEx => PTT-Plugin}/.gitattributes (100%) rename {PTT-BepInEx => PTT-Plugin}/.gitignore (100%) rename {PTT-BepInEx => PTT-Plugin}/NuGet.Config (100%) rename {PTT-BepInEx => PTT-Plugin}/PTT.csproj (100%) rename {PTT-BepInEx => PTT-Plugin}/PTT.sln (100%) rename {PTT-BepInEx => PTT-Plugin}/Patches/HideLockedTraderPatch.cs (100%) rename {PTT-BepInEx => PTT-Plugin}/Patches/InitAllExfiltrationPointsPatch.cs (100%) rename {PTT-BepInEx => PTT-Plugin}/Patches/ScavExfiltrationPointPatch.cs (100%) rename {PTT-BepInEx => PTT-Plugin}/Plugin.cs (100%) rename {PTT-BepInEx => PTT-Plugin}/Settings/Config.cs (100%) rename {PTT-BepInEx => PTT-Plugin}/Utils/Trader.cs (100%) diff --git a/.gitignore b/.gitignore index ebe00112..3da30b4b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,3 @@ /Trap-PathToTarkov* /mod.zip /configs/UserConfig.json - -/PTT-BepInEx/bin -/PTT-BepInEx/obj diff --git a/.prettierignore b/.prettierignore index 0edb48c0..19130472 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,6 +3,6 @@ /dist/ /src/*.js /Trap-PathToTarkov-* -/PTT-BepInEx/ +/PTT-Plugin/ *.md package-lock.json diff --git a/PTT-BepInEx/.gitattributes b/PTT-Plugin/.gitattributes similarity index 100% rename from PTT-BepInEx/.gitattributes rename to PTT-Plugin/.gitattributes diff --git a/PTT-BepInEx/.gitignore b/PTT-Plugin/.gitignore similarity index 100% rename from PTT-BepInEx/.gitignore rename to PTT-Plugin/.gitignore diff --git a/PTT-BepInEx/NuGet.Config b/PTT-Plugin/NuGet.Config similarity index 100% rename from PTT-BepInEx/NuGet.Config rename to PTT-Plugin/NuGet.Config diff --git a/PTT-BepInEx/PTT.csproj b/PTT-Plugin/PTT.csproj similarity index 100% rename from PTT-BepInEx/PTT.csproj rename to PTT-Plugin/PTT.csproj diff --git a/PTT-BepInEx/PTT.sln b/PTT-Plugin/PTT.sln similarity index 100% rename from PTT-BepInEx/PTT.sln rename to PTT-Plugin/PTT.sln diff --git a/PTT-BepInEx/Patches/HideLockedTraderPatch.cs b/PTT-Plugin/Patches/HideLockedTraderPatch.cs similarity index 100% rename from PTT-BepInEx/Patches/HideLockedTraderPatch.cs rename to PTT-Plugin/Patches/HideLockedTraderPatch.cs diff --git a/PTT-BepInEx/Patches/InitAllExfiltrationPointsPatch.cs b/PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs similarity index 100% rename from PTT-BepInEx/Patches/InitAllExfiltrationPointsPatch.cs rename to PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs diff --git a/PTT-BepInEx/Patches/ScavExfiltrationPointPatch.cs b/PTT-Plugin/Patches/ScavExfiltrationPointPatch.cs similarity index 100% rename from PTT-BepInEx/Patches/ScavExfiltrationPointPatch.cs rename to PTT-Plugin/Patches/ScavExfiltrationPointPatch.cs diff --git a/PTT-BepInEx/Plugin.cs b/PTT-Plugin/Plugin.cs similarity index 100% rename from PTT-BepInEx/Plugin.cs rename to PTT-Plugin/Plugin.cs diff --git a/PTT-BepInEx/Settings/Config.cs b/PTT-Plugin/Settings/Config.cs similarity index 100% rename from PTT-BepInEx/Settings/Config.cs rename to PTT-Plugin/Settings/Config.cs diff --git a/PTT-BepInEx/Utils/Trader.cs b/PTT-Plugin/Utils/Trader.cs similarity index 100% rename from PTT-BepInEx/Utils/Trader.cs rename to PTT-Plugin/Utils/Trader.cs diff --git a/package.json b/package.json index 9022ffe4..f41b998d 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "rebuild": "npm run clean && npm run build", "build": "tsc", "build:all": "npm run build:doc && npm run build && npm run build:client", - "build:client": "cd PTT-BepInEx && dotnet.exe build", - "clean:client": "cd PTT-BepInEx && dotnet.exe clean && rimraf bin obj", + "build:client": "cd PTT-Plugin && dotnet.exe build", + "clean:client": "cd PTT-Plugin && dotnet.exe clean && rimraf bin obj", "test:all": "npm run lint:all && npm run test && npm run build:release", "test": "npx jest --verbose", "test:watch": "npx jest --watch", diff --git a/scripts/prepare-files.js b/scripts/prepare-files.js index 4b77a1bc..cf9e6a57 100644 --- a/scripts/prepare-files.js +++ b/scripts/prepare-files.js @@ -7,7 +7,7 @@ const { mkdirp } = require('mkdirp'); // // eslint-disable-next-line @typescript-eslint/no-var-requires // const cpr = require('cpr'); -const PTTClientDir = 'PTT-BepInEx'; +const PTTClientDir = 'PTT-Plugin'; const dllFileName = 'Trap.PathToTarkov.dll'; const main = async modName => { From b167e639341a1fe18e770aaaa1e688d57984293e Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 12 Dec 2024 00:15:48 +0100 Subject: [PATCH 087/203] fix: vanilla_exfils_requirements is now forbidden by config analysis --- src/config-analysis.ts | 5 +++++ src/path-to-tarkov-controller.ts | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 73794904..0b103b21 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -308,6 +308,11 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 8. check for additional spawnpoints errors.push(...getErrorsForAdditionalSpawnpoints(config)); + // 9. check for usage of "vanilla_exfils_requirements" + if (config.vanilla_exfils_requirements) { + errors.push('"vanilla_exfils_requirements" is no longer supported since version 6'); + } + return { errors, warnings, diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index d9ccbcb1..f32e001f 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -568,11 +568,6 @@ export class PathToTarkovController { return; } - // TODO: move this into config-analysis - if (config.vanilla_exfils_requirements) { - this.logger.warning('Path To Tarkov: "vanilla_exfils_requirements" is no longer supported'); - } - // TODO(refactor): implement an indexBy util const indexedExits = locationBase.exits.reduce>( (indexed, exit) => { From fc16d821ad9f92fe93976f00e3ca21a12f46c0ca Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 12 Dec 2024 22:32:05 +0100 Subject: [PATCH 088/203] feat: implement debug_exfiltrations_tooltips_locale + refactor --- configs/Default/config.json | 1 + src/config-analysis.ts | 33 ++++++++-- src/config.ts | 71 +++++++++++++++------ src/mod.ts | 19 +----- src/path-to-tarkov-controller.ts | 82 +++++++++++++++++++++---- src/services/ExfilsTooltipsTemplater.ts | 6 +- 6 files changed, 155 insertions(+), 57 deletions(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index 8f9073c6..aee10c3a 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -1,6 +1,7 @@ { "enabled": true, "debug": true, + "debug_exfiltrations_tooltips_locale": "en", "initial_offraid_position": "FactoryZB-1011", "respawn_at": ["FactoryZB-1011"], "reset_offraid_position_on_player_die": true, diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 0b103b21..19233218 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -1,6 +1,12 @@ import { isValidExfilForMap } from './all-exfils'; import type { ByMap } from './config'; -import { EMPTY_STASH, type Config, type MapName, type SpawnConfig } from './config'; +import { + EMPTY_STASH, + isLocalAvailable, + type Config, + type MapName, + type SpawnConfig, +} from './config'; import { ensureArray, isEmpty } from './utils'; const MIN_NEEDED_MAPS = [ @@ -272,6 +278,25 @@ const getErrorsForAdditionalSpawnpoints = (config: Config): string[] => { return errors; }; +const getErrorsForGeneralConfig = (config: Config): string[] => { + const errors: string[] = []; + + // check for wrong locale on `debug_exfiltrations_tooltips_locale` + const debugTooltipsLocale = config.debug_exfiltrations_tooltips_locale; + if (debugTooltipsLocale && !isLocalAvailable(debugTooltipsLocale)) { + errors.push( + `wrong locale "${debugTooltipsLocale}" set to "debug_exfiltrations_tooltips_locale"`, + ); + } + + // check for usage of "vanilla_exfils_requirements" + if (config.vanilla_exfils_requirements) { + errors.push('"vanilla_exfils_requirements" is no longer supported since version 6'); + } + + return errors; +}; + export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigValidationResult => { const errors: string[] = []; const warnings: string[] = []; @@ -308,10 +333,8 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 8. check for additional spawnpoints errors.push(...getErrorsForAdditionalSpawnpoints(config)); - // 9. check for usage of "vanilla_exfils_requirements" - if (config.vanilla_exfils_requirements) { - errors.push('"vanilla_exfils_requirements" is no longer supported since version 6'); - } + // 9. check the rest of the config + errors.push(...getErrorsForGeneralConfig(config)); return { errors, diff --git a/src/config.ts b/src/config.ts index 9a9e03d8..0470cecf 100644 --- a/src/config.ts +++ b/src/config.ts @@ -17,26 +17,56 @@ export type ByMap = { terminal: T; }; -export type ByLocale = { - ch?: T; - cz?: T; - en?: T; - 'es-mx'?: T; - es?: T; - fr?: T; - ge?: T; - hu?: T; - it?: T; - jp?: T; - kr?: T; - pl?: T; - po?: T; - ro?: T; - ru?: T; - sk?: T; - tu?: T; +type AvailableLocales = { + ch: T; + cz: T; + en: T; + 'es-mx': T; + es: T; + fr: T; + ge: T; + hu: T; + it: T; + jp: T; + kr: T; + pl: T; + po: T; + ro: T; + ru: T; + sk: T; + tu: T; }; +export type ByLocale = Partial>; + +export const INDEXED_AVAILABLE_LOCALES: AvailableLocales = { + ch: true, + cz: true, + en: true, + 'es-mx': true, + es: true, + fr: true, + ge: true, + hu: true, + it: true, + jp: true, + kr: true, + pl: true, + po: true, + ro: true, + ru: true, + sk: true, + tu: true, +}; + +export const isLocalAvailable = (givenLocale: string): boolean => { + const availableLocales: Record = INDEXED_AVAILABLE_LOCALES; + const locale = givenLocale.trim().toLowerCase(); + return Boolean(availableLocales[locale]); +}; + +export const AVAILABLE_LOCALES: string[] = Object.keys(INDEXED_AVAILABLE_LOCALES); + type ByProfileId = Record; export type MapName = keyof ByMap; @@ -159,6 +189,7 @@ export type ExfiltrationConfig = { type RawConfig = { enabled: boolean; debug?: boolean; + debug_exfiltrations_tooltips_locale?: string; override_by_profiles?: OverrideByProfiles; bypass_keep_found_in_raid_tweak?: boolean; initial_offraid_position: string; @@ -167,7 +198,7 @@ type RawConfig = { hideout_multistash_enabled: boolean; player_scav_move_offraid_position: boolean; workbench_always_enabled: boolean; - vanilla_exfils_requirements?: boolean; + vanilla_exfils_requirements?: boolean; // no longer supported bypass_exfils_override?: boolean; disable_all_transits?: boolean; bypass_uninstall_procedure: boolean; @@ -183,7 +214,7 @@ type RawConfig = { infiltrations: Infiltrations; infiltrations_config?: InfiltrationsConfig; exfiltrations_config?: Record; // TODO: validate in config-analysis - exfiltrations_tooltips_template?: string; // TODO: validate in config-analysis + exfiltrations_tooltips_template?: string; // TODO(config-analysis): error when unknown template variable usage is found offraid_positions?: Record; // TODO: validate in config-analysis }; diff --git a/src/mod.ts b/src/mod.ts index ea0605a1..8d281f31 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -21,7 +21,7 @@ import { SPAWN_CONFIG_FILENAME, } from './config'; import { EventWatcher } from './event-watcher'; -import { createStaticRoutePeeker, disableRunThrough } from './helpers'; +import { createStaticRoutePeeker } from './helpers'; import { PathToTarkovController } from './path-to-tarkov-controller'; import { purgeProfiles } from './uninstall'; @@ -149,8 +149,6 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { return; } - this.pathToTarkovController.tradersAvailabilityService.init(quests); - const [api, executeOnStartAPICallbacks] = createPathToTarkovAPI( this.pathToTarkovController, this.logger, @@ -165,20 +163,7 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { this.executeOnStartAPICallbacks = executeOnStartAPICallbacks; - this.pathToTarkovController.injectTooltipsInLocales(this.config); - this.pathToTarkovController.tradersController.initTraders(this.config); - - const nbAddedTemplates = - this.pathToTarkovController.stashController.initSecondaryStashTemplates( - this.config.hideout_secondary_stashes, - ); - this.debug(`${nbAddedTemplates} secondary stash templates added`); - - if (!this.config.enable_run_through) { - disableRunThrough(db); - this.debug('disabled run through in-raid status'); - } - + this.pathToTarkovController.loaded(this.config); this.logger.success(`===> Successfully loaded ${getModDisplayName(this.packageJson, true)}`); } } diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index f32e001f..d361c417 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -6,13 +6,14 @@ import type { DatabaseServer } from '@spt/servers/DatabaseServer'; import type { SaveServer } from '@spt/servers/SaveServer'; import type { Config, ConfigGetter, MapName, Profile, SpawnConfig } from './config'; -import { MAPLIST, VANILLA_STASH_IDS } from './config'; +import { AVAILABLE_LOCALES, MAPLIST, VANILLA_STASH_IDS } from './config'; import { changeRestrictionsInRaid, checkAccessVia, createExitPoint, createSpawnPoint, + disableRunThrough, isIgnoredArea, isPlayerSpawnPoint, PTT_INFILTRATION, @@ -37,6 +38,7 @@ import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBody import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; import { KeepFoundInRaidTweak } from './keep-fir-tweak'; +import type { AllLocalesInDb } from './services/ExfilsTooltipsTemplater'; import { ExfilsTooltipsTemplater } from './services/ExfilsTooltipsTemplater'; type IndexedLocations = Record; @@ -59,17 +61,17 @@ const getIndexedLocations = (locations: ILocations): IndexedLocations => { }; export class PathToTarkovController { - public stashController: StashController; public tradersController: TradersController; - + public getConfig: ConfigGetter; // configs are indexed by sessionId private configCache: Record = {}; - public getConfig: ConfigGetter; + private stashController: StashController; + private tooltipsTemplater: ExfilsTooltipsTemplater | undefined; constructor( private readonly baseConfig: Config, public spawnConfig: SpawnConfig, - public tradersAvailabilityService: TradersAvailabilityService, + private tradersAvailabilityService: TradersAvailabilityService, private readonly container: DependencyContainer, private readonly db: DatabaseServer, private readonly saveServer: SaveServer, @@ -103,22 +105,35 @@ export class PathToTarkovController { this.overrideControllers(); } - // TODO: make it dynamic (aka intercept instead of mutating the db) - injectTooltipsInLocales(config: Config): void { + loaded(config: Config): void { const allLocales = this.db.getTables()?.locales?.global; + const quests = this.db.getTables()?.templates?.quests; + + if (!quests) { + throw new Error('Path To Tarkov: no quests found in db'); + } if (!allLocales) { throw new Error('Path To Tarkov: no locales found in db'); } - const templater = new ExfilsTooltipsTemplater(allLocales); - const partialLocales = templater.computeLocales(config); - const report = ExfilsTooltipsTemplater.mutateLocales(allLocales, partialLocales); + this.tooltipsTemplater = new ExfilsTooltipsTemplater(allLocales); - const nbValuesUpdated = report.nbTotalValuesUpdated / report.nbLocalesImpacted; - this.debug( - `${nbValuesUpdated} extract tooltip values updated for ${report.nbLocalesImpacted} locales (total of ${report.nbTotalValuesUpdated})`, + this.tradersAvailabilityService.init(quests); + this.injectTooltipsInLocales(config); + this.tradersController.initTraders(config); + + const nbAddedTemplates = this.stashController.initSecondaryStashTemplates( + config.hideout_secondary_stashes, ); + this.debug(`${nbAddedTemplates} secondary stash templates added`); + + if (!config.enable_run_through) { + disableRunThrough(this.db); + this.debug('disabled run through in-raid status'); + } + + this.debugExfiltrationsTooltips(config); } setConfig(config: Config, sessionId: string): void { @@ -199,6 +214,47 @@ export class PathToTarkovController { this.updateLocationBaseTransits(locationBase, sessionId); } + private debugExfiltrationsTooltips(config: Config): void { + const locale = config.debug_exfiltrations_tooltips_locale; + if (!locale || !this.tooltipsTemplater) { + return; + } + + const partialLocales = this.tooltipsTemplater.computeLocales(config); + const mergedLocales: AllLocalesInDb = AVAILABLE_LOCALES.reduce( + (locales, locale) => { + locales[locale] = {}; + return locales; + }, + {}, + ); + void ExfilsTooltipsTemplater.mutateLocales(mergedLocales, partialLocales); + const valuesForCountry = mergedLocales[locale]; + + this.debug(`debug exfils tooltips => ${JSON.stringify(valuesForCountry, undefined, 2)}`); + } + + // TODO: make it dynamic (aka intercept instead of mutating the db) + private injectTooltipsInLocales(config: Config): void { + const allLocales = this.db.getTables()?.locales?.global; + + if (!allLocales) { + throw new Error('Path To Tarkov: no locales found in db'); + } + + if (!this.tooltipsTemplater) { + throw new Error('Path To Tarkov: tooltips templater is missing'); + } + + const partialLocales = this.tooltipsTemplater.computeLocales(config); + const report = ExfilsTooltipsTemplater.mutateLocales(allLocales, partialLocales); + + const nbValuesUpdated = report.nbTotalValuesUpdated / report.nbLocalesImpacted; + this.debug( + `${nbValuesUpdated} extract tooltip values updated for ${report.nbLocalesImpacted} locales (total of ${report.nbTotalValuesUpdated})`, + ); + } + private getRespawnOffraidPosition = (sessionId: string): string => { const profile: Profile = this.saveServer.getProfile(sessionId); const profileTemplateId = profile.info.edition; diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts index 1fa9fbb9..038a1b98 100644 --- a/src/services/ExfilsTooltipsTemplater.ts +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -6,8 +6,8 @@ const OFFRAID_POSITION_DISPLAY_NAME_VARIABLE = '$offraidPositionDisplayName'; const DEFAULT_FALLBACK_LANGUAGE = 'en'; -type AllLocalesInDb = Record>; -type PartialLocales = Partial>>; +export type AllLocalesInDb = Record>; +export type PartialLocales = Partial>>; export type MinimumConfigForTooltipsTemplater = Pick< Config, @@ -52,6 +52,7 @@ export class ExfilsTooltipsTemplater { offraidPosition, }; + // TODO: retrieve locale from exfilName localeValues[exfilName] = this.computeLocaleValue(config, computeParams); }); }); @@ -90,6 +91,7 @@ export class ExfilsTooltipsTemplater { config: MinimumConfigForTooltipsTemplater, params: ComputeLocaleValueParameter, ): string { + // TODO: retrieve locale from exfilName const exfilVanillaDisplayName = this.snapshotLocales[params.locale][params.exfilName]; const exfilDisplayName = From 74740fa76415ed554afb4dec576ce551f688c526 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 12 Dec 2024 23:42:36 +0100 Subject: [PATCH 089/203] test: add external-resources test for checking eft locales unicity --- tests/external-resources.test.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/external-resources.test.ts diff --git a/tests/external-resources.test.ts b/tests/external-resources.test.ts new file mode 100644 index 00000000..ab12199e --- /dev/null +++ b/tests/external-resources.test.ts @@ -0,0 +1,21 @@ +import { readFileSync } from 'node:fs'; + +describe('external resources', () => { + describe('EN locales', () => { + const locales: Record = JSON.parse( + readFileSync('./external-resources/locales_global_en.json').toString(), + ); + + it('should have the same length once lower cased', () => { + const localeNames = Object.keys(locales); + + const lowerCasedLocales = localeNames.reduce>((acc, localeName) => { + acc[localeName.toLowerCase()] = locales[localeName]; + return acc; + }, {}); + + const nbLowerCasedLocales = Object.keys(lowerCasedLocales).length; + expect(nbLowerCasedLocales).toBe(localeNames.length); + }); + }); +}); From b67fd09859a72d8a81b36721f9a7fccdf23a8b42 Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 13 Dec 2024 00:06:16 +0100 Subject: [PATCH 090/203] refactor: configs test --- src/utils.ts | 2 +- tests/configs.test.ts | 81 ++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 32da3ae3..028d79be 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -34,7 +34,7 @@ export const getModDisplayName = (packageJson: PackageJson, withVersion = false) return `${packageJson.displayName}`; }; -// deep clone taken on stackoverflow +// stackoverflow deep clone export function deepClone(item: T): T { if (!item) { return item; diff --git a/tests/configs.test.ts b/tests/configs.test.ts index e21ca33e..e1585798 100644 --- a/tests/configs.test.ts +++ b/tests/configs.test.ts @@ -1,18 +1,31 @@ +import { readdirSync } from 'fs'; import path from 'path'; import type { Config, SpawnConfig } from '../src/config'; import { processConfig, processSpawnConfig } from '../src/config'; import { readJsonFile } from '../src/utils'; import { analyzeConfig } from '../src/config-analysis'; +import { CONFIG_FILENAME, SPAWN_CONFIG_FILENAME, CONFIGS_DIR } from '../src/config'; -const loadConfig = (dirPath: string): Config => { - return processConfig(readJsonFile(path.join(dirPath, 'config.json'))); -}; +const SHARED_PLAYER_SPAWNPOINTS_NAME = SPAWN_CONFIG_FILENAME; -const loadSpawnConfig = (config: Config): SpawnConfig => { - return processSpawnConfig(readJsonFile('./configs/shared_player_spawnpoints.json'), config); +const loadConfigs = ( + dirPath: string, + rawSpawnConfig: SpawnConfig, +): { config: Config; spawnConfig: SpawnConfig } => { + const config = processConfig(readJsonFile(path.join(dirPath, CONFIG_FILENAME))); + const spawnConfig = processSpawnConfig(rawSpawnConfig, config); + return { config, spawnConfig }; }; +const getDirectories = (source: string) => + readdirSync(source, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + describe('PTT embedded configs', () => { + const rawSpawnConfig: SpawnConfig = readJsonFile( + path.join(CONFIGS_DIR, SHARED_PLAYER_SPAWNPOINTS_NAME), + ); const originalConsole = console; beforeEach(() => { @@ -23,53 +36,19 @@ describe('PTT embedded configs', () => { global.console = originalConsole; }); - const testConfig = (dirPath: string) => { - const config = loadConfig(dirPath); - const spawnConfig = loadSpawnConfig(config); - - const { errors, warnings } = analyzeConfig(config, spawnConfig); - - if (errors.length > 0) { - errors.forEach(err => console.error(err)); - } - - if (warnings.length > 0) { - warnings.forEach(warn => console.warn(warn)); - } - - expect(errors.length).toBe(0); - expect(warnings.length).toBe(0); - }; - - it('should validate the default config', () => { - testConfig('./configs/Default'); - }); - - it('should validate the ExampleOverrideByProfiles config', () => { - testConfig('./configs/ExampleOverrideByProfiles'); - }); + void getDirectories(CONFIGS_DIR).forEach(configName => { + describe(`${configName} config`, () => { + const configPath = path.join(CONFIGS_DIR, configName); + const { config, spawnConfig } = loadConfigs(configPath, rawSpawnConfig); + const { errors, warnings } = analyzeConfig(config, spawnConfig); - it('should validate the LegacyPathToTarkovV4 config', () => { - testConfig('./configs/LegacyPathToTarkovV4'); - }); - - it('should validate the LegacyPathToTarkovV5 config', () => { - testConfig('./configs/LegacyPathToTarkovV5'); - }); - - it('should validate the LinearPath config', () => { - testConfig('./configs/LinearPath'); - }); - - it('should validate the OriginalNarcoticsConfig config', () => { - testConfig('./configs/OriginalNarcoticsConfig'); - }); - - it('should validate the PathToTarkovReloaded config', () => { - testConfig('./configs/PathToTarkovReloaded'); - }); + test(`no error detected for ${configName} config`, () => { + expect(errors).toHaveLength(0); + }); - it('should validate the DevilFlippy config', () => { - testConfig('./configs/DevilFlippy'); + test(`no warning detected for ${configName} config`, () => { + expect(warnings).toHaveLength(0); + }); + }); }); }); From 16fcc3a8c0683c8a186656f6fe63b9dd10fe21f7 Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 13 Dec 2024 00:23:51 +0100 Subject: [PATCH 091/203] refactor: add debugTooltipsForLocale to ExfilsTooltipsTemplater --- src/path-to-tarkov-controller.ts | 17 ++-------- src/services/ExfilsTooltipsTemplater.ts | 43 +++++++++++++++++++------ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/path-to-tarkov-controller.ts b/src/path-to-tarkov-controller.ts index d361c417..7a9d131c 100644 --- a/src/path-to-tarkov-controller.ts +++ b/src/path-to-tarkov-controller.ts @@ -6,7 +6,7 @@ import type { DatabaseServer } from '@spt/servers/DatabaseServer'; import type { SaveServer } from '@spt/servers/SaveServer'; import type { Config, ConfigGetter, MapName, Profile, SpawnConfig } from './config'; -import { AVAILABLE_LOCALES, MAPLIST, VANILLA_STASH_IDS } from './config'; +import { MAPLIST, VANILLA_STASH_IDS } from './config'; import { changeRestrictionsInRaid, @@ -38,7 +38,6 @@ import type { IGetBodyResponseData } from '@spt/models/eft/httpResponse/IGetBody import { TradersAvailabilityService } from './services/TradersAvailabilityService'; import { fixRepeatableQuestsForPmc } from './fix-repeatable-quests'; import { KeepFoundInRaidTweak } from './keep-fir-tweak'; -import type { AllLocalesInDb } from './services/ExfilsTooltipsTemplater'; import { ExfilsTooltipsTemplater } from './services/ExfilsTooltipsTemplater'; type IndexedLocations = Record; @@ -220,18 +219,8 @@ export class PathToTarkovController { return; } - const partialLocales = this.tooltipsTemplater.computeLocales(config); - const mergedLocales: AllLocalesInDb = AVAILABLE_LOCALES.reduce( - (locales, locale) => { - locales[locale] = {}; - return locales; - }, - {}, - ); - void ExfilsTooltipsTemplater.mutateLocales(mergedLocales, partialLocales); - const valuesForCountry = mergedLocales[locale]; - - this.debug(`debug exfils tooltips => ${JSON.stringify(valuesForCountry, undefined, 2)}`); + const localeValues = this.tooltipsTemplater.debugTooltipsForLocale(locale, config); + this.debug(`debug exfils tooltips => ${JSON.stringify(localeValues, undefined, 2)}`); } // TODO: make it dynamic (aka intercept instead of mutating the db) diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts index 038a1b98..55ea334a 100644 --- a/src/services/ExfilsTooltipsTemplater.ts +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -1,13 +1,18 @@ -import type { ByLocale, Config, LocaleName, MapName } from '../config'; +import { + AVAILABLE_LOCALES, + type ByLocale, + type Config, + type LocaleName, + type MapName, +} from '../config'; import { deepClone } from '../utils'; +const DEFAULT_FALLBACK_LANGUAGE = 'en'; + const EXFIL_DISPLAY_NAME_VARIABLE = '$exfilDisplayName'; const OFFRAID_POSITION_DISPLAY_NAME_VARIABLE = '$offraidPositionDisplayName'; -const DEFAULT_FALLBACK_LANGUAGE = 'en'; - -export type AllLocalesInDb = Record>; -export type PartialLocales = Partial>>; +type AllLocalesInDb = Record>; export type MinimumConfigForTooltipsTemplater = Pick< Config, @@ -19,13 +24,15 @@ export type LocalesMutationReport = { nbTotalValuesUpdated: number; }; -type ComputeLocaleValueParameter = { +export type ComputeLocaleValueParameter = { locale: LocaleName; exfilName: string; offraidPosition: string; }; export class ExfilsTooltipsTemplater { + public static readonly ERROR_NO_EXFIL = 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; + // this is used to be sure to keep the vanilla locales even after mutations are applied to the database private readonly snapshotLocales: AllLocalesInDb; @@ -33,8 +40,8 @@ export class ExfilsTooltipsTemplater { this.snapshotLocales = deepClone(allLocales); } - public computeLocales(config: MinimumConfigForTooltipsTemplater): PartialLocales { - const result: PartialLocales = {}; + public computeLocales(config: MinimumConfigForTooltipsTemplater): Partial { + const result: Partial = {}; Object.keys(this.snapshotLocales).forEach(locale => { const localeValues: Record = {}; @@ -61,9 +68,25 @@ export class ExfilsTooltipsTemplater { return result; } + public debugTooltipsForLocale( + locale: string, + config: MinimumConfigForTooltipsTemplater, + ): Record { + const partialLocales = this.computeLocales(config); + const mergedLocales: AllLocalesInDb = AVAILABLE_LOCALES.reduce( + (locales, locale) => { + locales[locale] = {}; + return locales; + }, + {}, + ); + void ExfilsTooltipsTemplater.mutateLocales(mergedLocales, partialLocales); + return mergedLocales[locale]; + } + public static mutateLocales( allLocales: AllLocalesInDb, - partialLocales: PartialLocales, + partialLocales: Partial, ): LocalesMutationReport { const report: LocalesMutationReport = { nbLocalesImpacted: 0, @@ -97,7 +120,7 @@ export class ExfilsTooltipsTemplater { const exfilDisplayName = ExfilsTooltipsTemplater.resolveExfilDisplayName(config, params) ?? exfilVanillaDisplayName ?? - 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; + ExfilsTooltipsTemplater.ERROR_NO_EXFIL; const offraidPositionDisplayName = ExfilsTooltipsTemplater.resolveOffraidPositionDisplayName( config, From 4b714af801d5cf530d4b90b2586b0e6458cbf9ec Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 13 Dec 2024 00:30:05 +0100 Subject: [PATCH 092/203] style: apply prettier --- tests/external-resources.test.ts | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/external-resources.test.ts b/tests/external-resources.test.ts index ab12199e..81fb7e75 100644 --- a/tests/external-resources.test.ts +++ b/tests/external-resources.test.ts @@ -1,21 +1,21 @@ -import { readFileSync } from 'node:fs'; - -describe('external resources', () => { - describe('EN locales', () => { - const locales: Record = JSON.parse( - readFileSync('./external-resources/locales_global_en.json').toString(), - ); - - it('should have the same length once lower cased', () => { - const localeNames = Object.keys(locales); - - const lowerCasedLocales = localeNames.reduce>((acc, localeName) => { - acc[localeName.toLowerCase()] = locales[localeName]; - return acc; - }, {}); - - const nbLowerCasedLocales = Object.keys(lowerCasedLocales).length; - expect(nbLowerCasedLocales).toBe(localeNames.length); - }); - }); -}); +import { readFileSync } from 'node:fs'; + +describe('external resources', () => { + describe('EN locales', () => { + const locales: Record = JSON.parse( + readFileSync('./external-resources/locales_global_en.json').toString(), + ); + + it('should have the same length once lower cased', () => { + const localeNames = Object.keys(locales); + + const lowerCasedLocales = localeNames.reduce>((acc, localeName) => { + acc[localeName.toLowerCase()] = locales[localeName]; + return acc; + }, {}); + + const nbLowerCasedLocales = Object.keys(lowerCasedLocales).length; + expect(nbLowerCasedLocales).toBe(localeNames.length); + }); + }); +}); From 16391a0fa9513fb24d9bed027e37706864b244c7 Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 13 Dec 2024 01:56:49 +0100 Subject: [PATCH 093/203] fix: non-case sensitive ExfilsTooltipsTemplater --- src/config.ts | 2 +- src/services/ExfilsTooltipsTemplater.ts | 44 +++++++++++++++++++++---- tests/configs.test.ts | 25 ++++++++++++-- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/config.ts b/src/config.ts index 0470cecf..4c8885a6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -111,7 +111,7 @@ export type RawStashConfig = { access_via: AccessVia; }; -export type LocaleName = keyof ByLocale; +export type LocaleName = keyof AvailableLocales; type InsuranceConfig = { insurance_price_coef?: number; diff --git a/src/services/ExfilsTooltipsTemplater.ts b/src/services/ExfilsTooltipsTemplater.ts index 55ea334a..6c3068cb 100644 --- a/src/services/ExfilsTooltipsTemplater.ts +++ b/src/services/ExfilsTooltipsTemplater.ts @@ -14,6 +14,33 @@ const OFFRAID_POSITION_DISPLAY_NAME_VARIABLE = '$offraidPositionDisplayName'; type AllLocalesInDb = Record>; +type LocaleKey = string; + +type LocaleKeysLowerCaseMapping = { + [localeName: string]: { + [lowerCasedLocaleKey: string]: LocaleKey; + }; +}; + +class ExfilsLocaleResolver { + private readonly localeKeysMapping: LocaleKeysLowerCaseMapping = {}; + + constructor(allLocales: AllLocalesInDb) { + void Object.keys(allLocales).forEach(localeName => { + const localeValues: Record = {}; + this.localeKeysMapping[localeName] = localeValues; + + void Object.keys(allLocales[localeName]).forEach(localeKey => { + localeValues[localeKey.toLowerCase()] = localeKey; + }); + }); + } + + public retrieveKey(exfilName: string, locale: LocaleName): string { + return this.localeKeysMapping?.[locale]?.[exfilName.toLowerCase()] ?? exfilName; + } +} + export type MinimumConfigForTooltipsTemplater = Pick< Config, 'exfiltrations' | 'exfiltrations_config' | 'exfiltrations_tooltips_template' | 'offraid_positions' @@ -26,18 +53,21 @@ export type LocalesMutationReport = { export type ComputeLocaleValueParameter = { locale: LocaleName; + localeKey: string; exfilName: string; offraidPosition: string; }; export class ExfilsTooltipsTemplater { - public static readonly ERROR_NO_EXFIL = 'PTT_ERROR_NO_EXFIL_LOCALE_FOUND'; + public static readonly ERROR_NO_EXFIL = 'PTT_ERROR_EXFIL_LOCALE_NOT_FOUND'; // this is used to be sure to keep the vanilla locales even after mutations are applied to the database private readonly snapshotLocales: AllLocalesInDb; + private readonly localeResolver: ExfilsLocaleResolver; constructor(allLocales: AllLocalesInDb) { this.snapshotLocales = deepClone(allLocales); + this.localeResolver = new ExfilsLocaleResolver(allLocales); } public computeLocales(config: MinimumConfigForTooltipsTemplater): Partial { @@ -53,14 +83,17 @@ export class ExfilsTooltipsTemplater { Object.keys(exfils).forEach(exfilName => { const offraidPosition = exfils[exfilName]; + const localeName = locale as LocaleName; + const localeKey = this.localeResolver.retrieveKey(exfilName, localeName); + const computeParams: ComputeLocaleValueParameter = { - locale: locale as LocaleName, + locale: localeName, + localeKey, exfilName, offraidPosition, }; - // TODO: retrieve locale from exfilName - localeValues[exfilName] = this.computeLocaleValue(config, computeParams); + localeValues[localeKey] = this.computeLocaleValue(config, computeParams); }); }); }); @@ -114,8 +147,7 @@ export class ExfilsTooltipsTemplater { config: MinimumConfigForTooltipsTemplater, params: ComputeLocaleValueParameter, ): string { - // TODO: retrieve locale from exfilName - const exfilVanillaDisplayName = this.snapshotLocales[params.locale][params.exfilName]; + const exfilVanillaDisplayName = this.snapshotLocales[params.locale]?.[params.localeKey]; const exfilDisplayName = ExfilsTooltipsTemplater.resolveExfilDisplayName(config, params) ?? diff --git a/tests/configs.test.ts b/tests/configs.test.ts index e1585798..38c13df5 100644 --- a/tests/configs.test.ts +++ b/tests/configs.test.ts @@ -1,10 +1,11 @@ -import { readdirSync } from 'fs'; +import { readFileSync, readdirSync } from 'fs'; import path from 'path'; import type { Config, SpawnConfig } from '../src/config'; import { processConfig, processSpawnConfig } from '../src/config'; import { readJsonFile } from '../src/utils'; import { analyzeConfig } from '../src/config-analysis'; import { CONFIG_FILENAME, SPAWN_CONFIG_FILENAME, CONFIGS_DIR } from '../src/config'; +import { ExfilsTooltipsTemplater } from '../src/services/ExfilsTooltipsTemplater'; const SHARED_PLAYER_SPAWNPOINTS_NAME = SPAWN_CONFIG_FILENAME; @@ -26,6 +27,11 @@ describe('PTT embedded configs', () => { const rawSpawnConfig: SpawnConfig = readJsonFile( path.join(CONFIGS_DIR, SHARED_PLAYER_SPAWNPOINTS_NAME), ); + + const enLocales: Record = JSON.parse( + readFileSync('./external-resources/locales_global_en.json').toString(), + ); + const originalConsole = console; beforeEach(() => { @@ -42,13 +48,26 @@ describe('PTT embedded configs', () => { const { config, spawnConfig } = loadConfigs(configPath, rawSpawnConfig); const { errors, warnings } = analyzeConfig(config, spawnConfig); - test(`no error detected for ${configName} config`, () => { + test(`no error detected during config analysis`, () => { expect(errors).toHaveLength(0); }); - test(`no warning detected for ${configName} config`, () => { + test(`no warning detected during config analysis`, () => { expect(warnings).toHaveLength(0); }); + + test(`exfils tooltips are rendered without any error (english locale)`, () => { + const allLocales = { en: enLocales }; + const templater = new ExfilsTooltipsTemplater(allLocales); + + const localeValues = templater.debugTooltipsForLocale('en', config); + + const localeKeysWithErrors = Object.entries(localeValues) + .filter(([_key, val]) => val.startsWith(ExfilsTooltipsTemplater.ERROR_NO_EXFIL)) + .map(([key]) => key); + + expect(localeKeysWithErrors).toHaveLength(0); + }); }); }); }); From cbc6f50e4c31f1dbc073fdc89d1dfc678dfab58b Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 13 Dec 2024 02:43:42 +0100 Subject: [PATCH 094/203] chore: change exfiltrations_tooltips_template in default config --- configs/Default/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/Default/config.json b/configs/Default/config.json index aee10c3a..909aae9d 100644 --- a/configs/Default/config.json +++ b/configs/Default/config.json @@ -1089,7 +1089,7 @@ "laboratory": ["Hangar Gate"] } }, - "exfiltrations_tooltips_template": "$exfilDisplayName ($offraidPositionDisplayName)", + "exfiltrations_tooltips_template": "$exfilDisplayName -> $offraidPositionDisplayName", "offraid_positions": { "PraporHideout": { "displayName": { From bf35905fcf6e0b684f8cd171bcfd8a27b436a37f Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 13 Dec 2024 02:45:07 +0100 Subject: [PATCH 095/203] ci: build-and-lint github workflow on push only --- .github/workflows/build-and-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-lint.yaml b/.github/workflows/build-and-lint.yaml index 597e339a..7d39144c 100644 --- a/.github/workflows/build-and-lint.yaml +++ b/.github/workflows/build-and-lint.yaml @@ -1,5 +1,5 @@ name: Build and Test -on: [push, pull_request, pull_request_target] +on: [push] jobs: build: From 07f925047d66472a9e6904cce5892fdd0d677a8f Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 19 Dec 2024 19:08:47 +0100 Subject: [PATCH 096/203] fix: gunsmith id in PTTv4 and PTTR configs --- configs/LegacyPathToTarkovV4/config.json | 2 +- configs/PathToTarkovReloaded/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/LegacyPathToTarkovV4/config.json b/configs/LegacyPathToTarkovV4/config.json index 0cadbf06..41f27501 100644 --- a/configs/LegacyPathToTarkovV4/config.json +++ b/configs/LegacyPathToTarkovV4/config.json @@ -337,7 +337,7 @@ }, "access_via": ["WoodsCustoms"] }, - "gunsmith": { + "4e7ef752240141bca059b2ea": { "// mod integration for Gunsmith": true, "// Gunsmith is available after extracting from Tunnel (shoreline map) or Lighthouse Tunnel (lighthouse map)": true, "disable_warning": true, diff --git a/configs/PathToTarkovReloaded/config.json b/configs/PathToTarkovReloaded/config.json index 1f3d3a31..8ee2134d 100644 --- a/configs/PathToTarkovReloaded/config.json +++ b/configs/PathToTarkovReloaded/config.json @@ -373,7 +373,7 @@ }, "access_via": ["WoodsReserveShoreline"] }, - "gunsmith": { + "4e7ef752240141bca059b2ea": { "// mod integration for Gunsmith": true, "// Gunsmith is available after extracting from Tunnel (shoreline map) or Lighthouse Tunnel (lighthouse map)": true, "disable_warning": true, From 7cdd8db01f15d2bdc256c8b41c24fdcff35876ef Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 20 Dec 2024 18:42:25 +0100 Subject: [PATCH 097/203] chore: update types for spt 3.10.3 --- types/callbacks/SaveCallbacks.d.ts | 4 +- types/controllers/DialogueController.d.ts | 9 +- types/controllers/QuestController.d.ts | 2 +- .../RepeatableQuestController.d.ts | 14 ++- .../generators/RepeatableQuestGenerator.d.ts | 13 +-- .../RepeatableQuestRewardGenerator.d.ts | 8 +- types/helpers/ProfileHelper.d.ts | 19 ++++ types/models/eft/common/ILocationBase.d.ts | 13 +++ types/models/eft/common/tables/IQuest.d.ts | 7 ++ .../eft/common/tables/IRepeatableQuests.d.ts | 14 +++ .../eft/profile/ISearchFriendResponse.d.ts | 1 + types/models/eft/profile/ISptProfile.d.ts | 2 + types/models/eft/ws/IWsFriendsListAccept.d.ts | 5 + types/models/eft/ws/IWsNotificationEvent.d.ts | 2 +- types/models/enums/ConfigTypes.d.ts | 1 + types/models/spt/config/IBackupConfig.d.ts | 12 +++ types/models/spt/config/IItemConfig.d.ts | 2 + types/services/BackupService.d.ts | 98 +++++++++++++++++++ types/services/CircleOfCultistService.d.ts | 20 +++- types/services/ItemFilterService.d.ts | 5 + types/utils/RandomUtil.d.ts | 32 +++++- 21 files changed, 263 insertions(+), 20 deletions(-) create mode 100644 types/models/eft/ws/IWsFriendsListAccept.d.ts create mode 100644 types/models/spt/config/IBackupConfig.d.ts create mode 100644 types/services/BackupService.d.ts diff --git a/types/callbacks/SaveCallbacks.d.ts b/types/callbacks/SaveCallbacks.d.ts index 8f836cb7..3d5f2126 100644 --- a/types/callbacks/SaveCallbacks.d.ts +++ b/types/callbacks/SaveCallbacks.d.ts @@ -3,11 +3,13 @@ import { OnUpdate } from "@spt/di/OnUpdate"; import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { SaveServer } from "@spt/servers/SaveServer"; +import { BackupService } from "@spt/services/BackupService"; export declare class SaveCallbacks implements OnLoad, OnUpdate { protected saveServer: SaveServer; protected configServer: ConfigServer; + protected backupService: BackupService; protected coreConfig: ICoreConfig; - constructor(saveServer: SaveServer, configServer: ConfigServer); + constructor(saveServer: SaveServer, configServer: ConfigServer, backupService: BackupService); onLoad(): Promise; getRoute(): string; onUpdate(secondsSinceLastRun: number): Promise; diff --git a/types/controllers/DialogueController.d.ts b/types/controllers/DialogueController.d.ts index 2f00b131..ded87cf6 100644 --- a/types/controllers/DialogueController.d.ts +++ b/types/controllers/DialogueController.d.ts @@ -1,5 +1,8 @@ import { IDialogueChatBot } from "@spt/helpers/Dialogue/IDialogueChatBot"; import { DialogueHelper } from "@spt/helpers/DialogueHelper"; +import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper"; +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { IDeleteFriendRequest } from "@spt/models/eft/dialog/IDeleteFriendRequest"; import { IFriendRequestData } from "@spt/models/eft/dialog/IFriendRequestData"; import { IFriendRequestSendResponse } from "@spt/models/eft/dialog/IFriendRequestSendResponse"; import { IGetAllAttachmentsResponse } from "@spt/models/eft/dialog/IGetAllAttachmentsResponse"; @@ -20,11 +23,13 @@ export declare class DialogueController { protected saveServer: SaveServer; protected timeUtil: TimeUtil; protected dialogueHelper: DialogueHelper; + protected notificationSendHelper: NotificationSendHelper; + protected profileHelper: ProfileHelper; protected mailSendService: MailSendService; protected localisationService: LocalisationService; protected configServer: ConfigServer; protected dialogueChatBots: IDialogueChatBot[]; - constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]); + constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, profileHelper: ProfileHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]); registerChatBot(chatBot: IDialogueChatBot): void; /** Handle onUpdate spt event */ update(): void; @@ -151,4 +156,6 @@ export declare class DialogueController { protected messageHasExpired(message: IMessage): boolean; /** Handle client/friend/request/send */ sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse; + /** Handle client/friend/delete */ + deleteFriend(sessionID: string, request: IDeleteFriendRequest): void; } diff --git a/types/controllers/QuestController.d.ts b/types/controllers/QuestController.d.ts index ac486e38..85221d68 100644 --- a/types/controllers/QuestController.d.ts +++ b/types/controllers/QuestController.d.ts @@ -72,6 +72,7 @@ export declare class QuestController { */ protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void; /** + * TODO - Move this code into RepeatableQuestController * Handle the client accepting a repeatable quest and starting it * Send starting rewards if any to player and * Send start notification if any to player @@ -81,7 +82,6 @@ export declare class QuestController { * @returns IItemEventRouterResponse */ acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; - protected createAcceptedQuestClientResponse(sessionID: string, pmcData: IPmcData, repeatableQuestProfile: IRepeatableQuest): IItemEventRouterResponse; /** * Look for an accepted quest inside player profile, return matching * @param pmcData Profile to search through diff --git a/types/controllers/RepeatableQuestController.d.ts b/types/controllers/RepeatableQuestController.d.ts index 016f8c61..87257cae 100644 --- a/types/controllers/RepeatableQuestController.d.ts +++ b/types/controllers/RepeatableQuestController.d.ts @@ -147,6 +147,18 @@ export declare class RepeatableQuestController { * @returns IItemEventRouterResponse */ changeRepeatableQuest(pmcData: IPmcData, changeRequest: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse; + /** + * Remove the provided quest from pmc and scav character profiles + * @param fullProfile Profile to remove quest from + * @param questToReplaceId Quest id to remove from profile + */ + protected removeQuestFromProfile(fullProfile: ISptProfile, questToReplaceId: string): void; + /** + * Clean up the repeatables `changeRequirement` dictionary of expired data + * @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest + * @param replacedQuestId Id of the replaced quest + */ + protected cleanUpRepeatableChangeRequirements(repeatablesOfTypeInProfile: IPmcDataRepeatableQuest, replacedQuestId: string): void; /** * Find a repeatable (daily/weekly/scav) from a players profile by its id * @param questId Id of quest to find @@ -154,7 +166,7 @@ export declare class RepeatableQuestController { * @returns IGetRepeatableByIdResult */ protected getRepeatableById(questId: string, pmcData: IPmcData): IGetRepeatableByIdResult; - protected attemptToGenerateRepeatableQuest(pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + protected attemptToGenerateRepeatableQuest(sessionId: string, pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Some accounts have access to free repeatable quest refreshes * Track the usage of them inside players profile diff --git a/types/generators/RepeatableQuestGenerator.d.ts b/types/generators/RepeatableQuestGenerator.d.ts index 79a10fc3..802a68b6 100644 --- a/types/generators/RepeatableQuestGenerator.d.ts +++ b/types/generators/RepeatableQuestGenerator.d.ts @@ -33,13 +33,14 @@ export declare class RepeatableQuestGenerator { /** * This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json). * It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest + * @param sessionId Session id * @param pmcLevel Player's level for requested items and reward generation * @param pmcTraderInfo Players traper standing/rep levels * @param questTypePool Possible quest types pool * @param repeatableConfig Repeatable quest config * @returns IRepeatableQuest */ - generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + generateRepeatableQuest(sessionId: string, pmcLevel: number, pmcTraderInfo: Record, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Generate a randomised Elimination quest * @param pmcLevel Player's level for requested items and reward generation @@ -48,7 +49,7 @@ export declare class RepeatableQuestGenerator { * @param repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest * @returns Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json) */ - protected generateEliminationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + protected generateEliminationQuest(sessionid: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Get a number of kills neded to complete elimination quest * @param targetKey Target type desired e.g. anyPmc/bossBully/Savage @@ -83,7 +84,7 @@ export declare class RepeatableQuestGenerator { * @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest * @returns {object} object of quest type format for "Completion" (see assets/database/templates/repeatableQuests.json) */ - protected generateCompletionQuest(pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + protected generateCompletionQuest(sessionId: string, pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json) * This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many) @@ -102,7 +103,7 @@ export declare class RepeatableQuestGenerator { * @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest * @returns {object} object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json) */ - protected generateExplorationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + protected generateExplorationQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Filter a maps exits to just those for the desired side * @param locationKey Map id (e.g. factory4_day) @@ -110,7 +111,7 @@ export declare class RepeatableQuestGenerator { * @returns Array of Exit objects */ protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[]; - protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; + protected generatePickupQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest; /** * Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567) * @param locationKey e.g factory4_day @@ -135,5 +136,5 @@ export declare class RepeatableQuestGenerator { * @returns {object} Object which contains the base elements for repeatable quests of the requests type * (needs to be filled with reward and conditions by called to make a valid quest) */ - protected generateRepeatableTemplate(type: string, traderId: string, side: string): IRepeatableQuest; + protected generateRepeatableTemplate(type: string, traderId: string, side: string, sessionId: string): IRepeatableQuest; } diff --git a/types/generators/RepeatableQuestRewardGenerator.d.ts b/types/generators/RepeatableQuestRewardGenerator.d.ts index bc78ccad..f029974d 100644 --- a/types/generators/RepeatableQuestRewardGenerator.d.ts +++ b/types/generators/RepeatableQuestRewardGenerator.d.ts @@ -12,6 +12,7 @@ import { DatabaseService } from "@spt/services/DatabaseService"; import { ItemFilterService } from "@spt/services/ItemFilterService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { SeasonalEventService } from "@spt/services/SeasonalEventService"; +import { HashUtil } from "@spt/utils/HashUtil"; import { MathUtil } from "@spt/utils/MathUtil"; import { ObjectId } from "@spt/utils/ObjectId"; import { RandomUtil } from "@spt/utils/RandomUtil"; @@ -19,6 +20,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner"; export declare class RepeatableQuestRewardGenerator { protected logger: ILogger; protected randomUtil: RandomUtil; + protected hashUtil: HashUtil; protected mathUtil: MathUtil; protected databaseService: DatabaseService; protected itemHelper: ItemHelper; @@ -31,7 +33,7 @@ export declare class RepeatableQuestRewardGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected questConfig: IQuestConfig; - constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner); + constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner); /** * Generate the reward for a mission. A reward can consist of: * - Experience @@ -127,7 +129,7 @@ export declare class RepeatableQuestRewardGenerator { * @param preset Optional array of preset items * @returns {object} Object of "Reward"-item-type */ - protected generateItemReward(tpl: string, count: number, index: number): IQuestReward; + protected generateItemReward(tpl: string, count: number, index: number, foundInRaid?: boolean): IQuestReward; /** * Helper to create a reward item structured as required by the client * @@ -137,7 +139,7 @@ export declare class RepeatableQuestRewardGenerator { * @param preset Optional array of preset items * @returns {object} Object of "Reward"-item-type */ - protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward; + protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[], foundInRaid?: boolean): IQuestReward; /** * Picks rewardable items from items.json * This means they must: diff --git a/types/helpers/ProfileHelper.d.ts b/types/helpers/ProfileHelper.d.ts index c2871b44..f68c5809 100644 --- a/types/helpers/ProfileHelper.d.ts +++ b/types/helpers/ProfileHelper.d.ts @@ -2,6 +2,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; +import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse"; import { ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData"; import { BonusType } from "@spt/models/enums/BonusType"; @@ -90,6 +91,24 @@ export declare class ProfileHelper { * @returns ISptProfile object */ getFullProfile(sessionID: string): ISptProfile | undefined; + /** + * Get full representation of a players profile JSON by the account ID, or undefined if not found + * @param accountId Account ID to find + * @returns + */ + getFullProfileByAccountId(accountID: string): ISptProfile | undefined; + /** + * Retrieve a ChatRoomMember formatted profile for the given session ID + * @param sessionID The session ID to return the profile for + * @returns + */ + getChatRoomMemberFromSessionId(sessionID: string): ISearchFriendResponse | undefined; + /** + * Retrieve a ChatRoomMember formatted profile for the given PMC profile data + * @param pmcProfile The PMC profile data to format into a ChatRoomMember structure + * @returns + */ + getChatRoomMemberFromPmcProfile(pmcProfile: IPmcData): ISearchFriendResponse; /** * Get a PMC profile by its session id * @param sessionID Profile id to return diff --git a/types/models/eft/common/ILocationBase.d.ts b/types/models/eft/common/ILocationBase.d.ts index 75836b67..69000e1e 100644 --- a/types/models/eft/common/ILocationBase.d.ts +++ b/types/models/eft/common/ILocationBase.d.ts @@ -11,23 +11,36 @@ export interface ILocationBase { Banners: IBanner[]; BossLocationSpawn: IBossLocationSpawn[]; BotAssault: number; + /** Weighting on how likely a bot will be Easy difficulty */ BotEasy: number; + /** Weighting on how likely a bot will be Hard difficulty */ BotHard: number; + /** Weighting on how likely a bot will be Impossible difficulty */ BotImpossible: number; BotLocationModifier: IBotLocationModifier; BotMarksman: number; + /** Maximum Number of bots that are currently alive/loading/delayed */ BotMax: number; + /** Is not used in 33420 */ BotMaxPlayer: number; + /** Is not used in 33420 */ BotMaxTimePlayer: number; + /** Does not even exist in the client in 33420 */ BotMaxPvE: number; + /** Weighting on how likely a bot will be Normal difficulty */ BotNormal: number; + /** How many bot slots that need to be open before trying to spawn new bots. */ BotSpawnCountStep: number; + /** How often to check if bots are spawn-able. In seconds */ BotSpawnPeriodCheck: number; + /** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */ BotSpawnTimeOffMax: number; BotSpawnTimeOffMin: number; BotSpawnTimeOnMax: number; BotSpawnTimeOnMin: number; + /** How soon bots will be allowed to spawn */ BotStart: number; + /** After this long bots will no longer spawn */ BotStop: number; Description: string; DisabledForScav: boolean; diff --git a/types/models/eft/common/tables/IQuest.d.ts b/types/models/eft/common/tables/IQuest.d.ts index e9568562..3d1e9e3c 100644 --- a/types/models/eft/common/tables/IQuest.d.ts +++ b/types/models/eft/common/tables/IQuest.d.ts @@ -33,6 +33,11 @@ export interface IQuest { changeQuestMessageText: string; /** "Pmc" or "Scav" */ side: string; + acceptanceAndFinishingSource: string; + progressSource: string; + rankingModes: string[]; + gameModes: string[]; + arenaLocations: string[]; /** Status of quest to player */ sptStatus?: QuestStatus; } @@ -148,8 +153,10 @@ export interface IQuestReward { loyaltyLevel?: number; /** Hideout area id */ traderId?: string; + isEncoded?: boolean; unknown?: boolean; findInRaid?: boolean; + gameMode?: string[]; /** Game editions whitelisted to get reward */ availableInGameEditions?: string[]; /** Game editions blacklisted from getting reward */ diff --git a/types/models/eft/common/tables/IRepeatableQuests.d.ts b/types/models/eft/common/tables/IRepeatableQuests.d.ts index 37e582a6..b596c2b7 100644 --- a/types/models/eft/common/tables/IRepeatableQuests.d.ts +++ b/types/models/eft/common/tables/IRepeatableQuests.d.ts @@ -3,6 +3,12 @@ export interface IRepeatableQuest extends IQuest { changeCost: IChangeCost[]; changeStandingCost: number; sptRepatableGroupName: string; + acceptanceAndFinishingSource: string; + progressSource: string; + rankingModes: string[]; + gameModes: string[]; + arenaLocations: string[]; + questStatus: IRepeatableQuestStatus; } export interface IRepeatableQuestDatabase { templates: IRepeatableTemplates; @@ -10,6 +16,14 @@ export interface IRepeatableQuestDatabase { data: IOptions; samples: ISampleQuests[]; } +export interface IRepeatableQuestStatus { + id: string; + uid: string; + qid: string; + startTime: number; + status: number; + statusTimers: any; +} export interface IRepeatableTemplates { Elimination: IQuest; Completion: IQuest; diff --git a/types/models/eft/profile/ISearchFriendResponse.d.ts b/types/models/eft/profile/ISearchFriendResponse.d.ts index d3cc7dfd..628b82ce 100644 --- a/types/models/eft/profile/ISearchFriendResponse.d.ts +++ b/types/models/eft/profile/ISearchFriendResponse.d.ts @@ -8,4 +8,5 @@ export interface Info { Side: string; Level: number; MemberCategory: number; + SelectedMemberCategory: number; } diff --git a/types/models/eft/profile/ISptProfile.d.ts b/types/models/eft/profile/ISptProfile.d.ts index aba539b4..af8c92f3 100644 --- a/types/models/eft/profile/ISptProfile.d.ts +++ b/types/models/eft/profile/ISptProfile.d.ts @@ -19,6 +19,8 @@ export interface ISptProfile { traderPurchases?: Record>; /** Achievements earned by player */ achievements: Record; + /** List of friend profile IDs */ + friends: string[]; } export declare class ITraderPurchaseData { count: number; diff --git a/types/models/eft/ws/IWsFriendsListAccept.d.ts b/types/models/eft/ws/IWsFriendsListAccept.d.ts new file mode 100644 index 00000000..4a96db3c --- /dev/null +++ b/types/models/eft/ws/IWsFriendsListAccept.d.ts @@ -0,0 +1,5 @@ +import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent"; +import { ISearchFriendResponse } from "../profile/ISearchFriendResponse"; +export interface IWsFriendsListAccept extends IWsNotificationEvent { + profile: ISearchFriendResponse; +} diff --git a/types/models/eft/ws/IWsNotificationEvent.d.ts b/types/models/eft/ws/IWsNotificationEvent.d.ts index 5fc72f3a..de119c8d 100644 --- a/types/models/eft/ws/IWsNotificationEvent.d.ts +++ b/types/models/eft/ws/IWsNotificationEvent.d.ts @@ -1,4 +1,4 @@ export interface IWsNotificationEvent { type: string; - eventId: string; + eventId?: string; } diff --git a/types/models/enums/ConfigTypes.d.ts b/types/models/enums/ConfigTypes.d.ts index 2c4483a9..5bed6f17 100644 --- a/types/models/enums/ConfigTypes.d.ts +++ b/types/models/enums/ConfigTypes.d.ts @@ -1,5 +1,6 @@ export declare enum ConfigTypes { AIRDROP = "spt-airdrop", + BACKUP = "spt-backup", BOT = "spt-bot", PMC = "spt-pmc", CORE = "spt-core", diff --git a/types/models/spt/config/IBackupConfig.d.ts b/types/models/spt/config/IBackupConfig.d.ts new file mode 100644 index 00000000..06bb7475 --- /dev/null +++ b/types/models/spt/config/IBackupConfig.d.ts @@ -0,0 +1,12 @@ +import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig"; +export interface IBackupConfig extends IBaseConfig { + kind: "spt-backup"; + enabled: boolean; + maxBackups: number; + directory: string; + backupInterval: IBackupConfigInterval; +} +export interface IBackupConfigInterval { + enabled: boolean; + intervalMinutes: number; +} diff --git a/types/models/spt/config/IItemConfig.d.ts b/types/models/spt/config/IItemConfig.d.ts index a8833bf0..d516ba9b 100644 --- a/types/models/spt/config/IItemConfig.d.ts +++ b/types/models/spt/config/IItemConfig.d.ts @@ -7,6 +7,8 @@ export interface IItemConfig extends IBaseConfig { lootableItemBlacklist: string[]; /** items that should not be given as rewards */ rewardItemBlacklist: string[]; + /** Item base types that should not be given as rewards */ + rewardItemTypeBlacklist: string[]; /** Items that can only be found on bosses */ bossItems: string[]; handbookPriceOverride: Record; diff --git a/types/services/BackupService.d.ts b/types/services/BackupService.d.ts new file mode 100644 index 00000000..aeab6c14 --- /dev/null +++ b/types/services/BackupService.d.ts @@ -0,0 +1,98 @@ +import { PreSptModLoader } from "@spt/loaders/PreSptModLoader"; +import { IBackupConfig } from "@spt/models/spt/config/IBackupConfig"; +import { ILogger } from "@spt/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt/servers/ConfigServer"; +export declare class BackupService { + protected logger: ILogger; + protected preSptModLoader: PreSptModLoader; + protected configServer: ConfigServer; + protected backupConfig: IBackupConfig; + protected readonly activeServerMods: string[]; + protected readonly profileDir = "./user/profiles"; + constructor(logger: ILogger, preSptModLoader: PreSptModLoader, configServer: ConfigServer); + /** + * Initializes the backup process. + * + * This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning + * up old backups if the number exceeds the configured maximum. + * + * @returns A promise that resolves when the backup process is complete. + */ + init(): Promise; + /** + * Fetches the names of all JSON files in the profile directory. + * + * This method normalizes the profile directory path and reads all files within it. It then filters the files to + * include only those with a `.json` extension and returns their names. + * + * @returns A promise that resolves to an array of JSON file names. + */ + protected fetchProfileFiles(): Promise; + /** + * Check to see if the backup service is enabled via the config. + * + * @returns True if enabled, false otherwise. + */ + protected isEnabled(): boolean; + /** + * Generates the target directory path for the backup. The directory path is constructed using the `directory` from + * the configuration and the current backup date. + * + * @returns The target directory path for the backup. + */ + protected generateBackupTargetDir(): string; + /** + * Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`. + * + * @returns The formatted backup date string. + */ + protected generateBackupDate(): string; + /** + * Cleans up old backups in the backup directory. + * + * This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds + * the configured maximum, it deletes the oldest backups. + * + * @returns A promise that resolves when the cleanup is complete. + */ + protected cleanBackups(): Promise; + /** + * Retrieves and sorts the backup file paths from the specified directory. + * + * @param dir - The directory to search for backup files. + * @returns A promise that resolves to an array of sorted backup file paths. + */ + private getBackupPaths; + /** + * Compares two backup folder names based on their extracted dates. + * + * @param a - The name of the first backup folder. + * @param b - The name of the second backup folder. + * @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid. + */ + private compareBackupDates; + /** + * Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`. + * + * @param folderName - The name of the folder from which to extract the date. + * @returns A Date object if the folder name is in the correct format, otherwise null. + */ + private extractDateFromFolderName; + /** + * Removes excess backups from the backup directory. + * + * @param backups - An array of backup file names to be removed. + * @returns A promise that resolves when all specified backups have been removed. + */ + private removeExcessBackups; + /** + * Start the backup interval if enabled in the configuration. + */ + protected startBackupInterval(): void; + /** + * Get an array of active server mod details. + * + * @returns An array of mod names. + */ + protected getActiveServerMods(): string[]; +} diff --git a/types/services/CircleOfCultistService.d.ts b/types/services/CircleOfCultistService.d.ts index e8046178..7568261e 100644 --- a/types/services/CircleOfCultistService.d.ts +++ b/types/services/CircleOfCultistService.d.ts @@ -54,6 +54,16 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Attempt to add all rewards to cultist circle, if they dont fit remove one and try again until they fit + * @param sessionId Session id + * @param pmcData Player profile + * @param rewards Rewards to send to player + * @param containerGrid Cultist grid to add rewards to + * @param cultistCircleStashId Stash id + * @param output Client output + */ + protected addRewardsToCircleContainer(sessionId: string, pmcData: IPmcData, rewards: IItem[][], containerGrid: number[][], cultistCircleStashId: string, output: IItemEventRouterResponse): void; /** * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed * @param directRewards Direct rewards array from hideout config @@ -156,7 +166,7 @@ export declare class CircleOfCultistService { * @param itemRewardBlacklist Items not to add to pool * @param rewardPool Pool to add items to */ - protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: Set, rewardPool: Set): void; /** * Adds items the player needs to complete hideout crafts/upgrades to the reward pool * @param hideoutDbData Hideout area data @@ -164,7 +174,7 @@ export declare class CircleOfCultistService { * @param itemRewardBlacklist Items not to add to pool * @param rewardPool Pool to add items to */ - protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: Set, rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -174,11 +184,11 @@ export declare class CircleOfCultistService { /** * Get array of random reward items * @param rewardPool Reward pool to add to - * @param itemRewardBlacklist Reward Blacklist + * @param itemRewardBlacklist Item tpls to ignore * @param itemsShouldBeHighValue Should these items meet the valuable threshold - * @returns rewardPool + * @returns Set of item tpls */ - protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: Set, itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/types/services/ItemFilterService.d.ts b/types/services/ItemFilterService.d.ts index 7ff65324..120d44e8 100644 --- a/types/services/ItemFilterService.d.ts +++ b/types/services/ItemFilterService.d.ts @@ -36,6 +36,11 @@ export declare class ItemFilterService { * @returns string array of item tpls */ getItemRewardBlacklist(): string[]; + /** + * Get an array of item types that should never be given as a reward to player + * @returns string array of item base ids + */ + getItemRewardBaseTypeBlacklist(): string[]; /** * Return every template id blacklisted in config/item.json * @returns string array of blacklisted tempalte ids diff --git a/types/utils/RandomUtil.d.ts b/types/utils/RandomUtil.d.ts index 601300cc..a94c336d 100644 --- a/types/utils/RandomUtil.d.ts +++ b/types/utils/RandomUtil.d.ts @@ -106,6 +106,11 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * The IEEE-754 standard for double-precision floating-point numbers limits the number of digits (including both + * integer + fractional parts) to about 15–17 significant digits. 15 is a safe upper bound, so we'll use that. + */ + private static readonly MAX_SIGNIFICANT_DIGITS; /** * Generates a secure random number between 0 (inclusive) and 1 (exclusive). * @@ -116,6 +121,16 @@ export declare class RandomUtil { * @returns A secure random number between 0 (inclusive) and 1 (exclusive). */ private getSecureRandomNumber; + /** + * Determines the number of decimal places in a number. + * + * @param num - The number to analyze. + * @returns The number of decimal places, or 0 if none exist. + * @remarks There is a mathematical way to determine this, but it's not as simple as it seams due to floating point + * precision issues. This method is a simple workaround that converts the number to a string and splits it. + * It's not the most efficient but it *is* the most reliable and easy to understand. Come at me. + */ + private getNumberPrecision; /** * Generates a random integer between the specified minimum and maximum values, inclusive. * @@ -173,7 +188,7 @@ export declare class RandomUtil { /** * Returns a random string from the provided array of strings. * - * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * This method is separate from getArrayValue so we can use a generic inference with getArrayValue. * * @param arr - The array of strings to select a random value from. * @returns A randomly selected string from the array. @@ -225,12 +240,27 @@ export declare class RandomUtil { getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** * Generates a random integer between the specified range. + * Low and high parameters are floored to integers. + * + * TODO: v3.11 - This method should not accept non-integer numbers. * * @param low - The lower bound of the range (inclusive). * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; + /** + * Generates a random number between two given values with optional precision. + * + * @param value1 - The first value to determine the range. + * @param value2 - The second value to determine the range. If not provided, 0 is used. + * @param precision - The number of decimal places to round the result to. Must be a positive integer between 0 + * and MAX_PRECISION, inclusive. If not provided, precision is determined by the input values. + * @returns A random floating-point number between `value1` and `value2` (inclusive) with the specified precision. + * @throws Will throw an error if `precision` is not a positive integer, if `value1` or `value2` are not finite + * numbers, or if the precision exceeds the maximum allowed for the given values. + */ + randNum(value1: number, value2?: number, precision?: number | null): number; /** * Draws a specified number of random elements from a given list. * From d2948149b18176d5455f180ccdd83943b162f3fc Mon Sep 17 00:00:00 2001 From: Trap Date: Fri, 20 Dec 2024 18:42:57 +0100 Subject: [PATCH 098/203] fix!: breaking change in fix-repeatable-quests (SPT 3.10.3 is needed here) --- src/fix-repeatable-quests.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fix-repeatable-quests.ts b/src/fix-repeatable-quests.ts index 33320531..06d9c237 100644 --- a/src/fix-repeatable-quests.ts +++ b/src/fix-repeatable-quests.ts @@ -17,6 +17,7 @@ export const fixRepeatableQuests = (container: DependencyContainer): void => { repeatableQuestGenerator.generateRepeatableQuest.bind(repeatableQuestGenerator); repeatableQuestGenerator.generateRepeatableQuest = ( + sessionId: string, pmcLevel: number, pmcTradersInfo: Record, questTypePool: IQuestTypePool, @@ -32,6 +33,7 @@ export const fixRepeatableQuests = (container: DependencyContainer): void => { }); return originalGenerateRepeatableQuest( + sessionId, pmcLevel, clonedPmcTradersInfo, questTypePool, From 50151daf9b1049769a6d431ea108182d3d2a94a2 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 12 Dec 2024 21:49:08 +0100 Subject: [PATCH 099/203] chore(client): add some references just in case --- PTT-Plugin/PTT.csproj | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/PTT-Plugin/PTT.csproj b/PTT-Plugin/PTT.csproj index 24420e99..d32641b5 100644 --- a/PTT-Plugin/PTT.csproj +++ b/PTT-Plugin/PTT.csproj @@ -7,6 +7,7 @@ 1.1.0 true latest + ..\..\..\.. @@ -15,20 +16,35 @@ - - ..\..\..\..\BepInEx\plugins\spt\spt-reflection.dll + + $(PathToSPT)\BepInEx\plugins\spt\spt-common.dll - - ..\..\..\..\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll + + $(PathToSPT)\BepInEx\plugins\spt\spt-reflection.dll - ..\..\..\..\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll + + + $(PathToSPT)\BepInEx\core\BepInEx.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Comfort.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Comfort.Unity.dll - ..\..\..\..\EscapeFromTarkov_Data\Managed\UnityEngine.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.dll - ..\..\..\..\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Newtonsoft.Json.dll From 9d67575f3edc7a6db9c86f737c5d1e66729195b3 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 12 Dec 2024 21:49:45 +0100 Subject: [PATCH 100/203] fix(client): InitAllExfiltrationPointsPatch updated for 3.10 --- PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs b/PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs index db637e75..d550965f 100644 --- a/PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs +++ b/PTT-Plugin/Patches/InitAllExfiltrationPointsPatch.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using SPT.Reflection.Patching; +using EFT; using EFT.Interactive; using HarmonyLib; @@ -38,7 +39,7 @@ protected override MethodBase GetTargetMethod() } [PatchPrefix] - protected static bool PatchPrefix(ref ExfiltrationControllerClass __instance, LocationExitClass[] settings, bool justLoadSettings = false, bool giveAuthority = true) + protected static bool PatchPrefix(ref ExfiltrationControllerClass __instance, MongoID locationId, LocationExitClass[] settings, bool justLoadSettings = false, string disabledScavExits = "", bool giveAuthority = true) { ExfiltrationPoint[] source = LocationScene.GetAllObjects(false).ToArray(); ExfiltrationPoint[] scavExfilArr = source.Where(new Func(IsScavExfil)).ToArray(); @@ -87,9 +88,11 @@ protected static bool PatchPrefix(ref ExfiltrationControllerClass __instance, Lo Logger.LogWarning("PMC Exfil name = " + exfiltrationPoint.Settings.Name); exitName = exfiltrationPoint.Settings.Name; LocationExitClass locationExit = settings.FirstOrDefault(new Func(NameMatches)); + int num = Array.IndexOf(source, exfiltrationPoint) + 1; + MongoID mongoID = locationId.Add(num + 1); if (locationExit != null) { - exfiltrationPoint.LoadSettings(exfiltrationPoint.Id, locationExit, giveAuthority); + exfiltrationPoint.LoadSettings(mongoID, locationExit, giveAuthority); if (!justLoadSettings && !RandomRange(exfiltrationPoint)) { exfiltrationPoint.SetStatusLogged(EExfiltrationStatus.NotPresent, "ExfiltrationController.InitAllExfiltrationPoints-2"); From 540aa65099aeaff3a52fda2e3d7343c4ffc0911b Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 14 Dec 2024 11:44:40 +0100 Subject: [PATCH 101/203] build(client): remove AllowUnsafeBlocks compilation property --- PTT-Plugin/PTT.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/PTT-Plugin/PTT.csproj b/PTT-Plugin/PTT.csproj index d32641b5..50955515 100644 --- a/PTT-Plugin/PTT.csproj +++ b/PTT-Plugin/PTT.csproj @@ -5,7 +5,6 @@ Trap.PathToTarkov Client patches for Path to Tarkov 1.1.0 - true latest ..\..\..\.. From 3acf73dd4c62e59dff07cec00435b44289ff281e Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 14 Dec 2024 11:45:14 +0100 Subject: [PATCH 102/203] build(client): comment useless package reference --- PTT-Plugin/PTT.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PTT-Plugin/PTT.csproj b/PTT-Plugin/PTT.csproj index 50955515..6ab75840 100644 --- a/PTT-Plugin/PTT.csproj +++ b/PTT-Plugin/PTT.csproj @@ -47,7 +47,7 @@ - + From f43d8a89e84f0e58657e82b44c9e05cf60454586 Mon Sep 17 00:00:00 2001 From: Trap Date: Thu, 19 Dec 2024 19:07:38 +0100 Subject: [PATCH 103/203] chore: temporary first try with InteractableExfilsAPI --- PTT-Plugin/Examples.cs | 38 +++++++++++++++++++ PTT-Plugin/PTT.csproj | 4 ++ .../Patches/InitAllExfiltrationPointsPatch.cs | 1 + PTT-Plugin/Plugin.cs | 28 ++++++++++++-- package.json | 6 ++- 5 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 PTT-Plugin/Examples.cs diff --git a/PTT-Plugin/Examples.cs b/PTT-Plugin/Examples.cs new file mode 100644 index 00000000..3d828b02 --- /dev/null +++ b/PTT-Plugin/Examples.cs @@ -0,0 +1,38 @@ +using Comfort.Common; +using BepInEx; +using EFT.Interactive; +using EFT; +using InteractableExfilsAPI.Components; +using InteractableExfilsAPI.Singletons; +using InteractableExfilsAPI.Common; +using System.Collections.Generic; +using System; +using System.Linq; + +namespace PTT; + +public class Examples +{ + public static OnActionsAppliedResult SimpleExample(ExfiltrationPoint exfil, CustomExfilTrigger customExfilTrigger, bool exfilIsAvailableToPlayer) + { + if (!exfilIsAvailableToPlayer) + { + return null; + } + + return new OnActionsAppliedResult(new CustomExfilAction( + "Escape!", + false, + () => + { + customExfilTrigger.ToggleExfilZoneEnabled(); + } + )); + } + + public static OnActionsAppliedResult RequiresManualActivation(ExfiltrationPoint exfil, CustomExfilTrigger customExfilTrigger, bool exfilIsAvailableToPlayer) + { + customExfilTrigger.RequiresManualActivation = true; + return null; + } +} \ No newline at end of file diff --git a/PTT-Plugin/PTT.csproj b/PTT-Plugin/PTT.csproj index 6ab75840..11bac22d 100644 --- a/PTT-Plugin/PTT.csproj +++ b/PTT-Plugin/PTT.csproj @@ -45,6 +45,10 @@ $(PathToSPT)\EscapeFromTarkov_Data\Managed\Newtonsoft.Json.dll + + + $(PathToSPT)\BepInEx\plugins\InteractableExfilsAPI.dll + + + + + $(PathToSPT)\BepInEx\plugins\spt\spt-common.dll + + + $(PathToSPT)\BepInEx\plugins\spt\spt-reflection.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll + + + $(PathToSPT)\BepInEx\core\BepInEx.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Comfort.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Comfort.Unity.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UIModule.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll + + + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Newtonsoft.Json.dll + + + + $(PathToSPT)\BepInEx\plugins\Fika.Core.dll + + + + + diff --git a/PTT-Packets/Packets/PlayerChangedExitZonePacket.cs b/PTT-Packets/Packets/PlayerChangedExitZonePacket.cs new file mode 100644 index 00000000..bd19dc97 --- /dev/null +++ b/PTT-Packets/Packets/PlayerChangedExitZonePacket.cs @@ -0,0 +1,21 @@ +using LiteNetLib.Utils; + +namespace PTT.Packets; + +public struct PlayerChangedExitZonePacket : INetSerializable +{ + public string PlayerId; + public string ExitName; // will be null when player exit a zone + + public void Deserialize(NetDataReader reader) + { + PlayerId = reader.GetString(); + ExitName = reader.GetString(); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(PlayerId); + writer.Put(ExitName); + } +} \ No newline at end of file diff --git a/PTT-Plugin/PTT.csproj b/PTT-Plugin/PTT.csproj index d1c29e77..2c371d83 100644 --- a/PTT-Plugin/PTT.csproj +++ b/PTT-Plugin/PTT.csproj @@ -61,6 +61,13 @@ + + + {E4B8C5DB-7D40-49B5-9A4A-F4C1D3D7ADCB} + PTT-Packets + + + diff --git a/PTT.sln b/PTT.sln index 8e41e9db..c7a0d7b8 100644 --- a/PTT.sln +++ b/PTT.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.32106.194 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PTT", "PTT-Plugin\PTT.csproj", "{C1DE1108-5182-4676-AF15-8802E053494E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PTT-Packets", "PTT-Packets\PTT.csproj", "{E4B8C5DB-7D40-49B5-9A4A-F4C1D3D7ADCB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,11 @@ Global {C1DE1108-5182-4676-AF15-8802E053494E}.Debug|Any CPU.Build.0 = Debug|Any CPU {C1DE1108-5182-4676-AF15-8802E053494E}.Release|Any CPU.ActiveCfg = Release|Any CPU {C1DE1108-5182-4676-AF15-8802E053494E}.Release|Any CPU.Build.0 = Release|Any CPU + + {E4B8C5DB-7D40-49B5-9A4A-F4C1D3D7ADCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4B8C5DB-7D40-49B5-9A4A-F4C1D3D7ADCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4B8C5DB-7D40-49B5-9A4A-F4C1D3D7ADCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4B8C5DB-7D40-49B5-9A4A-F4C1D3D7ADCB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/scripts/prepare-files.js b/scripts/prepare-files.js index ef380168..6fbc650c 100644 --- a/scripts/prepare-files.js +++ b/scripts/prepare-files.js @@ -10,6 +10,9 @@ const { mkdirp } = require('mkdirp'); const PTTClientDir = 'PTT-Plugin'; const dllFileName = 'Trap.PathToTarkov.dll'; +const PTTPacketsClientDir = 'PTT-Packets'; +const packetsDllFileName = "Trap.PathToTarkov-Packets.dll"; + const main = async modName => { [ 'rimraf dist/user', @@ -17,6 +20,7 @@ const main = async modName => { () => mkdirp.sync(`./dist/user/mods/${modName}`), () => mkdirp.sync('./dist/BepInEx/plugins'), `cpr ./${PTTClientDir}/bin/Debug/net471/${dllFileName} ./dist/BepInEx/plugins/${dllFileName} -o`, + `cpr ./${PTTPacketsClientDir}/bin/Debug/net471/${packetsDllFileName} ./dist/BepInEx/plugins/${packetsDllFileName} -o`, `cpr package.json ./dist/user/mods/${modName}/package.json -o`, `cpr dist/src ./dist/user/mods/${modName}/src -o`, `cpr configs ./dist/user/mods/${modName}/configs -o`, From 19c4c0f030b335792b07f710a6c800a2505f9eb5 Mon Sep 17 00:00:00 2001 From: Trap Date: Sat, 4 Jan 2025 22:49:22 +0100 Subject: [PATCH 183/203] fix(fika): sync transits with simple vote mechanism --- PTT-Packets/Packets/PerformExfilPacket.cs | 14 + .../Packets/PlayerChangedExitZonePacket.cs | 21 -- .../PlayerVotedForExfilTargetPacket.cs | 26 ++ PTT-Packets/Packets/RawExfilTarget.cs | 40 +++ PTT-Plugin/Data/ExfilsTargets.cs | 27 +- PTT-Plugin/Helpers/Fika.cs | 53 ++++ PTT-Plugin/Helpers/Transit.cs | 4 +- PTT-Plugin/Patches/OnGameStartedPatch.cs | 6 + PTT-Plugin/Plugin.cs | 14 +- PTT-Plugin/Services/CustomExfilService.cs | 36 ++- PTT-Plugin/Services/CustomExfilServiceFika.cs | 16 +- PTT-Plugin/Services/ExfilsTargetsService.cs | 5 +- PTT-Plugin/Services/TransitVoteServiceFika.cs | 290 ++++++++++++++++++ PTT-Plugin/UI/ExfilPrompt.cs | 131 +++++--- scripts/install-files.js | 2 + scripts/prepare-files.js | 2 +- src/exfils-targets.ts | 2 + 17 files changed, 588 insertions(+), 101 deletions(-) create mode 100644 PTT-Packets/Packets/PerformExfilPacket.cs delete mode 100644 PTT-Packets/Packets/PlayerChangedExitZonePacket.cs create mode 100644 PTT-Packets/Packets/PlayerVotedForExfilTargetPacket.cs create mode 100644 PTT-Packets/Packets/RawExfilTarget.cs create mode 100644 PTT-Plugin/Helpers/Fika.cs create mode 100644 PTT-Plugin/Services/TransitVoteServiceFika.cs diff --git a/PTT-Packets/Packets/PerformExfilPacket.cs b/PTT-Packets/Packets/PerformExfilPacket.cs new file mode 100644 index 00000000..26c3ed53 --- /dev/null +++ b/PTT-Packets/Packets/PerformExfilPacket.cs @@ -0,0 +1,14 @@ +using LiteNetLib.Utils; + +namespace PTT.Packets; + +public struct PerformExfilPacket : INetSerializable +{ + public void Deserialize(NetDataReader reader) + { + } + + public void Serialize(NetDataWriter writer) + { + } +} \ No newline at end of file diff --git a/PTT-Packets/Packets/PlayerChangedExitZonePacket.cs b/PTT-Packets/Packets/PlayerChangedExitZonePacket.cs deleted file mode 100644 index bd19dc97..00000000 --- a/PTT-Packets/Packets/PlayerChangedExitZonePacket.cs +++ /dev/null @@ -1,21 +0,0 @@ -using LiteNetLib.Utils; - -namespace PTT.Packets; - -public struct PlayerChangedExitZonePacket : INetSerializable -{ - public string PlayerId; - public string ExitName; // will be null when player exit a zone - - public void Deserialize(NetDataReader reader) - { - PlayerId = reader.GetString(); - ExitName = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(PlayerId); - writer.Put(ExitName); - } -} \ No newline at end of file diff --git a/PTT-Packets/Packets/PlayerVotedForExfilTargetPacket.cs b/PTT-Packets/Packets/PlayerVotedForExfilTargetPacket.cs new file mode 100644 index 00000000..1fd0a926 --- /dev/null +++ b/PTT-Packets/Packets/PlayerVotedForExfilTargetPacket.cs @@ -0,0 +1,26 @@ +using LiteNetLib.Utils; + +namespace PTT.Packets; + +public struct PlayerVotedForExfilTargetPacket : INetSerializable +{ + public int NetId; + public RawExfilTarget RawExfilTarget; + + public void Deserialize(NetDataReader reader) + { + NetId = reader.GetInt(); + RawExfilTarget = reader.Get(); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(NetId); + writer.Put(RawExfilTarget); + } + + public readonly bool IsVoteCancelled() + { + return RawExfilTarget.ExitName == null || RawExfilTarget.ExitName == ""; + } +} \ No newline at end of file diff --git a/PTT-Packets/Packets/RawExfilTarget.cs b/PTT-Packets/Packets/RawExfilTarget.cs new file mode 100644 index 00000000..a009d750 --- /dev/null +++ b/PTT-Packets/Packets/RawExfilTarget.cs @@ -0,0 +1,40 @@ +using LiteNetLib.Utils; + +namespace PTT.Packets; + + +public struct RawExfilTarget : INetSerializable +{ + public string ExitName; // will be empty when player exit a zone + public bool IsTransit; + public string TransitMapId; // transit only + public string TransitSpawnPointId; // transit only + public string OffraidPosition; // empty on transit + + public void Deserialize(NetDataReader reader) + { + ExitName = EnsureNull(reader.GetString()); + IsTransit = reader.GetBool(); + TransitMapId = EnsureNull(reader.GetString()); + TransitSpawnPointId = EnsureNull(reader.GetString()); + OffraidPosition = EnsureNull(reader.GetString()); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(ExitName ?? ""); + writer.Put(IsTransit); + writer.Put(TransitMapId ?? ""); + writer.Put(TransitSpawnPointId ?? ""); + writer.Put(OffraidPosition ?? ""); + } + + private readonly string EnsureNull(string val) + { + if (val == "") + { + return null; + } + return val; + } +} \ No newline at end of file diff --git a/PTT-Plugin/Data/ExfilsTargets.cs b/PTT-Plugin/Data/ExfilsTargets.cs index 485ac31a..6efa2b16 100644 --- a/PTT-Plugin/Data/ExfilsTargets.cs +++ b/PTT-Plugin/Data/ExfilsTargets.cs @@ -1,12 +1,5 @@ -using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using SPT.Common.Http; -using Newtonsoft.Json; -using EFT.Interactive; using PTT.Settings; -using EFT; namespace PTT.Data; @@ -29,24 +22,28 @@ public class ExfilsTargetsResponse public class ExfilTarget { + public string exitName; public bool isTransit; public string transitMapId; // transit only public string transitSpawnPointId; // transit only public string offraidPosition; // empty on transit - public string GetCustomActionName() + public string GetCustomActionName(bool isDisabled = false) { + string disabledPrefix = isDisabled ? $"[{"Disabled".Localized()}] " : ""; + if (isTransit) { string transitTemplate = "PTT_TRANSITS_PROMPT_TEMPLATE".Localized(); string result = string.Format(transitTemplate, transitMapId.Localized()); + if (Config.DebugMode.Value && transitMapId.ToLower() == "sandbox_high") { - return $"{result}*"; + return $"{disabledPrefix}{result}*"; } - return result; + return $"{disabledPrefix}{result}"; } string extractTemplate = "PTT_EXTRACTS_PROMPT_TEMPLATE".Localized(); @@ -56,20 +53,20 @@ public string GetCustomActionName() // when the offraid position display name cannot be resolved if (offraidPositionDisplayName == offraidPositionDisplayNameKey) { - return string.Format(extractTemplate, offraidPosition); + return $"{disabledPrefix}{string.Format(extractTemplate, offraidPosition)}"; } - return string.Format(extractTemplate, offraidPositionDisplayName); + return $"{disabledPrefix}{string.Format(extractTemplate, offraidPositionDisplayName)}"; } - public string GetCustomExitName(ExfiltrationPoint exfil) + public string GetCustomExitName() { if (isTransit) { - return $"{exfil.Settings.Name}.{transitMapId}.{transitSpawnPointId}"; + return $"{exitName}.{transitMapId}.{transitSpawnPointId}"; } - return $"{exfil.Settings.Name}.{offraidPosition}"; + return $"{exitName}.{offraidPosition}"; } public bool IsAvailable() diff --git a/PTT-Plugin/Helpers/Fika.cs b/PTT-Plugin/Helpers/Fika.cs new file mode 100644 index 00000000..f8a9808d --- /dev/null +++ b/PTT-Plugin/Helpers/Fika.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Comfort.Common; +using Fika.Core.Coop.Components; +using Fika.Core.Coop.Players; +using Fika.Core.Networking; + +namespace PTT.Helpers; + +public static class Fika +{ + public static IFikaNetworkManager GetNetworkManager() + { + return Singleton.Instance; + } + + public static CoopHandler GetCoopHandler() + { + return GetNetworkManager()?.CoopHandler; + } + + public static List GetHumanPlayers() + { + return GetCoopHandler()?.HumanPlayers; + } + + public static CoopPlayer GetMyPlayer() + { + return GetCoopHandler()?.MyPlayer; + } + + public static int GetMyPlayerNetId() + { + CoopPlayer myPlayer = GetMyPlayer(); + + if (myPlayer == null) + { + Logger.Error("(FIKA) GetPlayerNetId: no CoopHandler.MyPlayer, fallback to 0"); + return 0; + } + + return myPlayer.NetId; + } + + public static bool IsHost() + { + return Singleton.Instantiated; + } + + public static bool IsClient() + { + return Singleton.Instantiated; + } +} \ No newline at end of file diff --git a/PTT-Plugin/Helpers/Transit.cs b/PTT-Plugin/Helpers/Transit.cs index 26205d57..08dda32e 100644 --- a/PTT-Plugin/Helpers/Transit.cs +++ b/PTT-Plugin/Helpers/Transit.cs @@ -5,10 +5,10 @@ namespace PTT.Helpers; internal static class Transit { - static public TransitPoint Create(ExfiltrationPoint exfil, ExfilTarget exfilTarget) + static public TransitPoint Create(ExfilTarget exfilTarget) { string locationId = exfilTarget.transitMapId; - string customTransitName = exfilTarget.GetCustomExitName(exfil); + string customTransitName = exfilTarget.GetCustomExitName(); return new TransitPoint { diff --git a/PTT-Plugin/Patches/OnGameStartedPatch.cs b/PTT-Plugin/Patches/OnGameStartedPatch.cs index 463c9960..8a045c81 100644 --- a/PTT-Plugin/Patches/OnGameStartedPatch.cs +++ b/PTT-Plugin/Patches/OnGameStartedPatch.cs @@ -1,4 +1,5 @@ using EFT; +using PTT.Services; using SPT.Reflection.Patching; using System.Reflection; @@ -14,6 +15,11 @@ protected override MethodBase GetTargetMethod() [PatchPrefix] public static bool PatchPrefix() { + if (Plugin.FikaIsInstalled) + { + TransitVoteServiceFika.InitRaid(); + } + InitExfilsTargetsService(); Plugin.DisplayInteractableExfilsAPIWarning(); return true; diff --git a/PTT-Plugin/Plugin.cs b/PTT-Plugin/Plugin.cs index c2c52475..c5ed7a72 100644 --- a/PTT-Plugin/Plugin.cs +++ b/PTT-Plugin/Plugin.cs @@ -22,20 +22,14 @@ protected void Awake() { Helpers.Logger.Init(Logger); Helpers.Logger.Info($"Plugin {PluginInfo.PLUGIN_GUID} is loading..."); + Settings.Config.Init(Config); FikaIsInstalled = Chainloader.PluginInfos.ContainsKey("com.fika.core"); InteractableExfilsApiIsInstalled = Chainloader.PluginInfos.ContainsKey(IE_API_PLUGIN_NAME); KaenoTraderScrollingIsInstalled = Chainloader.PluginInfos.ContainsKey("com.kaeno.TraderScrolling"); - Settings.Config.Init(Config); - ExfilsTargetsService = new ExfilsTargetsService(); - if (FikaIsInstalled) - { - Helpers.Logger.Info($"Fika.Core plugin detected"); - } - if (KaenoTraderScrollingIsInstalled) { Helpers.Logger.Info($"Kaeno-TraderScrolling detected"); @@ -56,6 +50,12 @@ protected void Awake() protected void Start() { + if (FikaIsInstalled) + { + Helpers.Logger.Info($"Fika.Core plugin detected"); + TransitVoteServiceFika.Init(); + } + if (InteractableExfilsApiIsInstalled) { Version apiVersion = Chainloader.PluginInfos[IE_API_PLUGIN_NAME].Metadata.Version; diff --git a/PTT-Plugin/Services/CustomExfilService.cs b/PTT-Plugin/Services/CustomExfilService.cs index 0999129b..17bcdec4 100644 --- a/PTT-Plugin/Services/CustomExfilService.cs +++ b/PTT-Plugin/Services/CustomExfilService.cs @@ -21,7 +21,7 @@ public static void ExtractTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) LocalGame localGame = Singleton.Instance as LocalGame; Player player = Singleton.Instance.MainPlayer; - Logger.Info($"started extraction on '{exfilTarget.GetCustomExitName(exfil)}'"); + Logger.Info($"started extraction on '{exfilTarget.GetCustomExitName()}'"); if (localGame == null) @@ -36,28 +36,32 @@ public static void ExtractTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) return; } - Plugin.ExfilsTargetsService.SaveExfil(exfil, exfilTarget); + Plugin.ExfilsTargetsService.SaveExfil(exfilTarget); // This is needed to validate extract quests like `Burning Rubber` // The ptt custom ptt exfil target name will be used to override the exitName in the LocalRaidEndedPatch - string exitName = exfil.Settings.Name; + string exitName = exfilTarget.exitName; float delay = 0f; localGame.Stop(player.ProfileId, ExitStatus.Survived, exitName, delay); Logger.Info($"local game stopped for profile '${player.ProfileId}'"); } - public static void TransitTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) + public static void TransitTo(ExfilTarget exfilTarget, Action onTransitDone) { if (Plugin.FikaIsInstalled) { - CustomExfilServiceFika.TransitTo(exfil, exfilTarget); + TransitVoteServiceFika.VoteForExfil(exfilTarget, () => + { + CustomExfilServiceFika.TransitTo(exfilTarget); + onTransitDone(); + }); return; } - TransitPoint transit = Transit.Create(exfil, exfilTarget); + TransitPoint transit = Transit.Create(exfilTarget); Logger.Info($"started transit on '{transit.parameters.name}'"); - Plugin.ExfilsTargetsService.SaveExfil(exfil, exfilTarget); + Plugin.ExfilsTargetsService.SaveExfil(exfilTarget); if (!TransitControllerAbstractClass.Exist(out GClass1642 vanillaTransitController)) { @@ -84,6 +88,24 @@ public static void TransitTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) int playersCount = 1; vanillaTransitController.Transit(transit, playersCount, transitHash, profiles, player); + onTransitDone(); Logger.Info($"transit done for profile '${player.ProfileId}'"); } + + public static void CancelTransitVote(string cancelMessage) + { + if (Plugin.FikaIsInstalled) + { + TransitVoteServiceFika.CancelVoteForExfil(cancelMessage); + } + } + + public static bool IsTransitDisabled(ExfilTarget exfilTarget) + { + if (Plugin.FikaIsInstalled && exfilTarget.isTransit) + { + return TransitVoteServiceFika.IsTransitDisabledByVote(exfilTarget); + } + return false; + } } diff --git a/PTT-Plugin/Services/CustomExfilServiceFika.cs b/PTT-Plugin/Services/CustomExfilServiceFika.cs index 19b580a9..2168a0bd 100644 --- a/PTT-Plugin/Services/CustomExfilServiceFika.cs +++ b/PTT-Plugin/Services/CustomExfilServiceFika.cs @@ -18,7 +18,7 @@ public static class CustomExfilServiceFika { public static void ExtractTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) { - Logger.Info($"(FIKA) started extraction on '{exfilTarget.GetCustomExitName(exfil)}'"); + Logger.Info($"(FIKA) started extraction on '{exfilTarget.GetCustomExitName()}'"); CoopGame coopGame = (CoopGame)Singleton.Instance; CoopPlayer coopPlayer = (CoopPlayer)Singleton.Instance.MainPlayer; @@ -36,10 +36,10 @@ public static void ExtractTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) } // 1. Save the exfil target - Plugin.ExfilsTargetsService.SaveExfil(exfil, exfilTarget); + Plugin.ExfilsTargetsService.SaveExfil(exfilTarget); // 2. Set the ExitLocation (needed to validate extract quests like `Burning Rubber`) - coopGame.ExitLocation = exfil.Settings.Name; + coopGame.ExitLocation = exfilTarget.exitName; // 3. Trigger extract coopGame.Extract(coopPlayer, exfil, null); @@ -47,9 +47,9 @@ public static void ExtractTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) Logger.Info($"(FIKA) extraction done for profile {coopPlayer.ProfileId}"); } - public static void TransitTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) + public static void TransitTo(ExfilTarget exfilTarget) { - Logger.Info($"started transit on '{exfilTarget.GetCustomExitName(exfil)}'"); + Logger.Info($"started transit on '{exfilTarget.GetCustomExitName()}'"); CoopGame coopGame = (CoopGame)Singleton.Instance; CoopPlayer coopPlayer = (CoopPlayer)Singleton.Instance.MainPlayer; @@ -67,7 +67,7 @@ public static void TransitTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) } // 1. Create the transit point - TransitPoint transit = Transit.Create(exfil, exfilTarget); + TransitPoint transit = Transit.Create(exfilTarget); // 2. Register the transit point if (!RegisterTransitPoint(transit)) @@ -77,10 +77,10 @@ public static void TransitTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) } // 3. Save the exfil target - Plugin.ExfilsTargetsService.SaveExfil(exfil, exfilTarget); + Plugin.ExfilsTargetsService.SaveExfil(exfilTarget); // 4. Set the ExitLocation - coopGame.ExitLocation = exfil.Settings.Name; + coopGame.ExitLocation = exfilTarget.exitName; // 5. Trigger extract with transit coopGame.Extract(coopPlayer, null, transit); diff --git a/PTT-Plugin/Services/ExfilsTargetsService.cs b/PTT-Plugin/Services/ExfilsTargetsService.cs index 562506ee..ec554d54 100644 --- a/PTT-Plugin/Services/ExfilsTargetsService.cs +++ b/PTT-Plugin/Services/ExfilsTargetsService.cs @@ -14,12 +14,13 @@ public class ExfilsTargetsService public void Init() { + UsedCustomExtractName = null; FetchExfilsTargetsForCurrentLocation(); } - public void SaveExfil(ExfiltrationPoint exfil, ExfilTarget exfilTarget) + public void SaveExfil(ExfilTarget exfilTarget) { - UsedCustomExtractName = exfilTarget.GetCustomExitName(exfil); + UsedCustomExtractName = exfilTarget.GetCustomExitName(); } public string ConsumeExtractName() diff --git a/PTT-Plugin/Services/TransitVoteServiceFika.cs b/PTT-Plugin/Services/TransitVoteServiceFika.cs new file mode 100644 index 00000000..976c5e29 --- /dev/null +++ b/PTT-Plugin/Services/TransitVoteServiceFika.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections.Generic; +using Comfort.Common; + +using LiteNetLib; +using Fika.Core.Coop.Components; +using Fika.Core.Coop.Players; +using Fika.Core.Networking; + +using PTT.Data; +using PTT.Helpers; +using PTT.Packets; +using Fika.Core.Modding; +using Fika.Core.Modding.Events; +using EFT.Communications; +using InteractableExfilsAPI.Singletons; + +namespace PTT.Services; + +public static class TransitVoteServiceFika +{ + private static Dictionary Votes = []; + private static Action ExfilAction = null; + + public static void Init() + { + FikaEventDispatcher.SubscribeEvent(RegisterPackets); + Logger.Info("Initialized Transit Vote service"); + } + + public static void InitRaid() + { + Votes = []; + ExfilAction = null; + } + + public static void VoteForExfil(ExfilTarget exfilTarget, Action exfilAction) + { + CoopHandler coopHandler = Helpers.Fika.GetCoopHandler(); + if (coopHandler == null) + { + Logger.Error("(FIKA) Cannot vote for exfil because no CoopHandler found"); + return; + } + + Logger.Info($"(FIKA) Vote for exfil {exfilTarget.GetCustomExitName()} with current player {coopHandler.MyPlayer.NetId}"); + NotificationManagerClass.DisplayMessageNotification($"Voted for exfil {exfilTarget.GetCustomActionName()}", ENotificationDurationType.Long); + + ExfilAction = exfilAction; + Votes.ForceAddValue(coopHandler.MyPlayer.NetId, exfilTarget); + InteractableExfilsService.RefreshPrompt(); + + if (Helpers.Fika.IsHost() && IsVoteSuccess()) + { + PerformAllExfil(); + return; + } + + var packet = CreateVotePacket(exfilTarget); + if (Helpers.Fika.IsClient()) + { + Singleton.Instance.SendData(ref packet, DeliveryMethod.ReliableSequenced); + } + else if (Helpers.Fika.IsHost()) + { + Singleton.Instance.SendDataToAll(ref packet, DeliveryMethod.ReliableSequenced); + } + } + + public static void CancelVoteForExfil(string cancelMessage) + { + CoopHandler coopHandler = Helpers.Fika.GetCoopHandler(); + if (coopHandler == null) + { + Logger.Error("(FIKA) Cannot vote for exfil because no CoopHandler found"); + return; + } + + if (ExfilAction == null && !Votes.ContainsKey(coopHandler.MyPlayer.NetId)) + { + Logger.Warning($"(FIKA) No vote to cancel with current player {coopHandler.MyPlayer.NetId}"); + return; + } + + Logger.Info($"(FIKA) Cancel vote with current player {coopHandler.MyPlayer.NetId}"); + + if (cancelMessage != null && cancelMessage != "") + { + NotificationManagerClass.DisplayMessageNotification(cancelMessage, ENotificationDurationType.Long); + } + + ExfilAction = null; + Votes.Remove(coopHandler.MyPlayer.NetId); + InteractableExfilsService.RefreshPrompt(); + + PlayerVotedForExfilTargetPacket packet = CreateCancelVotePacket(); + if (Helpers.Fika.IsClient()) + { + Singleton.Instance.SendData(ref packet, DeliveryMethod.ReliableSequenced); + } + else if (Helpers.Fika.IsHost()) + { + Singleton.Instance.SendDataToAll(ref packet, DeliveryMethod.ReliableSequenced); + } + } + + public static bool IsTransitDisabledByVote(ExfilTarget exfilTarget) + { + if (Votes.Count == 0) + { + return false; + } + + foreach (ExfilTarget votedExfilTarget in Votes.Values) + { + if (votedExfilTarget.GetCustomExitName() != exfilTarget.GetCustomExitName()) + { + return true; + } + } + + return false; + } + + private static void HandlePlayerVotedForExfil(PlayerVotedForExfilTargetPacket packet, NetPeer peer) + { + CoopHandler coopHandler = Helpers.Fika.GetCoopHandler(); + if (coopHandler == null) + { + Logger.Error("(FIKA) HandlePlayerVotedForExfil: cannot retrieve coopHandler"); + return; + } + + int playerNetId = packet.NetId; + + if (packet.IsVoteCancelled()) + { + Logger.Info($"(FIKA) Cancel vote packet received by peer {playerNetId}"); + NotificationManagerClass.DisplayMessageNotification($"Vote cancelled for player {playerNetId}", ENotificationDurationType.Long); + Votes.Remove(playerNetId); + InteractableExfilsService.RefreshPrompt(); + + if (Helpers.Fika.IsHost()) + { + // propagate change (for UI) + Singleton.Instance.SendDataToAll(ref packet, DeliveryMethod.ReliableSequenced, peer); + } + } + else + { + ExfilTarget exfilTarget = FromVotePacket(packet); + + Logger.Info($"(FIKA) Vote packet received by peer {playerNetId} for exfil {exfilTarget.GetCustomExitName()}"); + NotificationManagerClass.DisplayMessageNotification($"Player {playerNetId} voted for exfil {exfilTarget.GetCustomActionName()}", ENotificationDurationType.Long); + Votes.ForceAddValue(playerNetId, exfilTarget); + InteractableExfilsService.RefreshPrompt(); + + if (Helpers.Fika.IsHost()) + { + // propagate change (for UI) + Singleton.Instance.SendDataToAll(ref packet, DeliveryMethod.ReliableSequenced, peer); + } + } + + if (Helpers.Fika.IsHost() && IsVoteSuccess()) + { + PerformAllExfil(); + } + } + + private static void RegisterPackets(FikaNetworkManagerCreatedEvent createdEvent) + { + IFikaNetworkManager networkManager = createdEvent.Manager; + if (networkManager == null) + { + Logger.Error("(FIKA) Cannot register packets because networkManager is not found"); + return; + } + + networkManager.RegisterPacket(HandlePlayerVotedForExfil); + Logger.Info("(FIKA) Registered PlayerVotedForExfilTargetPacket"); + + if (Helpers.Fika.IsClient()) + { + networkManager.RegisterPacket(HandlePerformExfil); + Logger.Info("(FIKA) Registered PerformExfilPacket"); + } + } + + private static void PerformAllExfil() + { + if (!Singleton.Instantiated) + { + Logger.Error("(FIKA) Only the server can call PerformAllExfil"); + return; + } + + var fikaServer = Singleton.Instance; + var packet = new PerformExfilPacket(); + fikaServer.SendDataToAll(ref packet, DeliveryMethod.ReliableOrdered); + PerformLocalExfil(); + } + + private static void HandlePerformExfil(PerformExfilPacket packet, NetPeer peer) + { + PerformLocalExfil(); + } + + private static void PerformLocalExfil() + { + if (ExfilAction == null) + { + Logger.Error("(FIKA) Cannot perform exfil because no action has been set"); + return; + } + + ExfilAction(); + ExfilAction = null; + } + + private static bool IsVoteSuccess() + { + ExfilTarget votedExfilTarget = null; + List humans = Helpers.Fika.GetHumanPlayers(); + + if (humans == null || humans.Count == 0) + { + Logger.Error("(FIKA) No human players found"); + return false; + } + + foreach (CoopPlayer human in humans) + { + if (!Votes.TryGetValue(human.NetId, out ExfilTarget exfilTarget)) + { + return false; + } + + if (votedExfilTarget == null) + { + votedExfilTarget = exfilTarget; + } + else if (exfilTarget.GetCustomExitName() != votedExfilTarget.GetCustomExitName()) + { + return false; + } + } + + return votedExfilTarget != null; + } + + private static ExfilTarget FromVotePacket(PlayerVotedForExfilTargetPacket packet) + { + RawExfilTarget rawExfilTarget = packet.RawExfilTarget; + + return new ExfilTarget + { + exitName = rawExfilTarget.ExitName, + isTransit = rawExfilTarget.IsTransit, + transitMapId = rawExfilTarget.TransitMapId, + transitSpawnPointId = rawExfilTarget.TransitSpawnPointId, + offraidPosition = rawExfilTarget.OffraidPosition, + }; + } + + private static PlayerVotedForExfilTargetPacket CreateCancelVotePacket() + { + return new PlayerVotedForExfilTargetPacket + { + NetId = Helpers.Fika.GetMyPlayerNetId(), + RawExfilTarget = new RawExfilTarget() + }; + } + + private static PlayerVotedForExfilTargetPacket CreateVotePacket(ExfilTarget exfilTarget) + { + return new PlayerVotedForExfilTargetPacket + { + NetId = Helpers.Fika.GetMyPlayerNetId(), + RawExfilTarget = new RawExfilTarget + { + ExitName = exfilTarget.exitName, + IsTransit = exfilTarget.isTransit, + TransitMapId = exfilTarget.transitMapId, + TransitSpawnPointId = exfilTarget.transitSpawnPointId, + OffraidPosition = exfilTarget.offraidPosition, + } + }; + } +} \ No newline at end of file diff --git a/PTT-Plugin/UI/ExfilPrompt.cs b/PTT-Plugin/UI/ExfilPrompt.cs index 4c474b53..cc7a6178 100644 --- a/PTT-Plugin/UI/ExfilPrompt.cs +++ b/PTT-Plugin/UI/ExfilPrompt.cs @@ -12,57 +12,100 @@ namespace PTT.UI; public class ExfilPrompt(ExfiltrationPoint Exfil) { + private bool _exfiltrated = false; + private bool _voted = false; // when vote is confirmed + private ExfilTarget _selectedExfilTarget = null; // used to check is auto-cancel vote is needed private Action _actionToExecuteOnConfirm = null; private void InitPromptState() { + _exfiltrated = false; + _voted = false; + _selectedExfilTarget = null; _actionToExecuteOnConfirm = null; } - private void RunConfirm() + private Action CreateRunConfirm() { - if (_actionToExecuteOnConfirm != null) + return () => { - _actionToExecuteOnConfirm(); - _actionToExecuteOnConfirm = null; - } + if (_actionToExecuteOnConfirm != null) + { + _actionToExecuteOnConfirm(); + _actionToExecuteOnConfirm = null; + _voted = true; + } + }; } - private void RunCancel() + private Action CreateRunCancel() { - InitPromptState(); - Sound.PlayMenuCancel(); - SelectFirstPromptItem(); + return () => + { + CancelVote("Vote cancelled"); + InitPromptState(); + Sound.PlayMenuCancel(); + SelectFirstPromptItem(); + }; } private CustomExfilAction CreateCustomExfilAction(ExfiltrationPoint exfil, ExfilTarget exfilTarget) { - string customActionName = exfilTarget.GetCustomActionName(); - switch (exfilTarget.isTransit) { case true: - return new CustomExfilAction(customActionName, false, () => - { - _actionToExecuteOnConfirm = () => + bool isTransitDisabled = CustomExfilService.IsTransitDisabled(exfilTarget); + string customTransitActionName = exfilTarget.GetCustomActionName(isTransitDisabled); + + return new CustomExfilAction( + customTransitActionName, + isTransitDisabled, + () => { - CustomExfilService.TransitTo(exfil, exfilTarget); - Sound.PlayTransitConfirm(); - }; - Sound.PlayMenuEnter(); - SelectFirstPromptItem(); - }); + _actionToExecuteOnConfirm = () => + { + CustomExfilService.TransitTo(exfilTarget, () => + { + _exfiltrated = true; + }); + Sound.PlayTransitConfirm(); + }; + Sound.PlayMenuEnter(); + SelectFirstPromptItem(); + }); case false: - return new CustomExfilAction(customActionName, false, () => - { - _actionToExecuteOnConfirm = () => + bool isExtractDisabled = false; + string customExtractActionName = exfilTarget.GetCustomActionName(isExtractDisabled); + + return new CustomExfilAction( + customExtractActionName, + isExtractDisabled, + () => { - CustomExfilService.ExtractTo(exfil, exfilTarget); - Sound.PlayExtractConfirm(); - }; - Sound.PlayMenuEnter(); - SelectFirstPromptItem(); - }); + _actionToExecuteOnConfirm = () => + { + CustomExfilService.ExtractTo(exfil, exfilTarget); + _exfiltrated = true; + Sound.PlayExtractConfirm(); + }; + Sound.PlayMenuEnter(); + SelectFirstPromptItem(); + }); + } + } + + private void CancelVote(string cancelMessage) + { + _voted = false; + _selectedExfilTarget = null; + CustomExfilService.CancelTransitVote(cancelMessage); + } + + private void OnExitZone() + { + if (!_exfiltrated) + { + CancelVote("Vote cancelled (zone exited)"); } } @@ -86,27 +129,39 @@ public OnActionsAppliedResult Render() return null; } - // action selection step - if (_actionToExecuteOnConfirm == null) + // 1. action selection step + if (!_voted && _actionToExecuteOnConfirm == null) { List actions = exfilTargets .Where(exfilTarget => exfilTarget.IsAvailable()) .Select(exfilTarget => CreateCustomExfilAction(Exfil, exfilTarget)) .ToList(); - return new OnActionsAppliedResult(actions); + return new OnActionsAppliedResult(actions, OnExitZone); } - // confirmation step - var confirmAction = new CustomExfilAction("confirm".Localized(), false, RunConfirm); - var cancelAction = new CustomExfilAction("Cancel".Localized(), false, RunCancel); + var cancelAction = new CustomExfilAction("Cancel".Localized(), false, CreateRunCancel()); - if (Settings.Config.ExfilAutoselectCancel.Value) + // auto-cancel the vote when needed + if (_voted && _selectedExfilTarget != null && CustomExfilService.IsTransitDisabled(_selectedExfilTarget)) { - return new OnActionsAppliedResult([cancelAction, confirmAction]); + CancelVote("Vote cancelled because selected exfil transit don't match with the others"); + } + + // 3. confirmation step + if (!_voted) + { + var confirmAction = new CustomExfilAction("confirm".Localized(), false, CreateRunConfirm()); + + List actions = Settings.Config.ExfilAutoselectCancel.Value + ? [cancelAction, confirmAction] + : [confirmAction, cancelAction]; + + return new OnActionsAppliedResult(actions, OnExitZone); } - return new OnActionsAppliedResult([confirmAction, cancelAction]); + // 3. cancellation step + return new OnActionsAppliedResult([cancelAction], OnExitZone); } private static void SelectFirstPromptItem() diff --git a/scripts/install-files.js b/scripts/install-files.js index 1d2d50ce..49dd44f5 100644 --- a/scripts/install-files.js +++ b/scripts/install-files.js @@ -4,12 +4,14 @@ const { execSync } = require('child_process'); const packageJson = require('../package.json'); const dllFileName = 'Trap.PathToTarkov.dll'; +const packetsDllFileName = 'Trap.PathToTarkov-Packets.dll'; const cprFlags = '--overwrite'; const main = async modName => { [ `cpr ./dist/user/mods/${modName} ../../../user/mods/${modName} ${cprFlags}`, `cpr ./dist/BepInEx/plugins/${dllFileName} ../../../BepInEx/plugins/${dllFileName} ${cprFlags}`, + `cpr ./dist/BepInEx/plugins/${packetsDllFileName} ../../../BepInEx/plugins/${packetsDllFileName} ${cprFlags}`, 'echo "> Successfully installed files!"', ].forEach(cmd => { if (typeof cmd === 'string') { diff --git a/scripts/prepare-files.js b/scripts/prepare-files.js index 6fbc650c..474002b2 100644 --- a/scripts/prepare-files.js +++ b/scripts/prepare-files.js @@ -11,7 +11,7 @@ const PTTClientDir = 'PTT-Plugin'; const dllFileName = 'Trap.PathToTarkov.dll'; const PTTPacketsClientDir = 'PTT-Packets'; -const packetsDllFileName = "Trap.PathToTarkov-Packets.dll"; +const packetsDllFileName = 'Trap.PathToTarkov-Packets.dll'; const main = async modName => { [ diff --git a/src/exfils-targets.ts b/src/exfils-targets.ts index 84fa18e4..c53c2ee7 100644 --- a/src/exfils-targets.ts +++ b/src/exfils-targets.ts @@ -3,6 +3,7 @@ import { resolveLocationIdFromMapName, resolveMapNameFromLocation } from './map- // Warning: This type should be the same than the corresponding client type export type ExfilTarget = { + exitName: string; isTransit: boolean; transitMapId: string; // transit only transitSpawnPointId: string; // transit only @@ -39,6 +40,7 @@ export const getExfilsTargets = (config: Config, mapName: MapName): ExfilsTarget const parsed = parseExilTargetFromPTTConfig(targetValue); return { + exitName: exfilName, isTransit: Boolean(!parsed.targetOffraidPosition), offraidPosition: parsed.targetOffraidPosition ?? '', transitMapId: resolveLocationIdFromMapName(parsed.transitTargetMapName ?? ''), From 5697f465ab864142b81ffb8713566f4455896f3f Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 18:11:10 +0100 Subject: [PATCH 184/203] fix(fika): disable transits when host take an extract --- .../Packets/DisableTransitVotePacket.cs | 17 +++++++++++ PTT-Plugin/Services/CustomExfilServiceFika.cs | 6 ++++ PTT-Plugin/Services/TransitVoteServiceFika.cs | 29 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 PTT-Packets/Packets/DisableTransitVotePacket.cs diff --git a/PTT-Packets/Packets/DisableTransitVotePacket.cs b/PTT-Packets/Packets/DisableTransitVotePacket.cs new file mode 100644 index 00000000..c9e87713 --- /dev/null +++ b/PTT-Packets/Packets/DisableTransitVotePacket.cs @@ -0,0 +1,17 @@ +using LiteNetLib.Utils; + +namespace PTT.Packets; + +public struct DisableTransitVotePacket : INetSerializable +{ + public string Reason; + public void Deserialize(NetDataReader reader) + { + Reason = reader.GetString(); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(Reason); + } +} \ No newline at end of file diff --git a/PTT-Plugin/Services/CustomExfilServiceFika.cs b/PTT-Plugin/Services/CustomExfilServiceFika.cs index 2168a0bd..609905c6 100644 --- a/PTT-Plugin/Services/CustomExfilServiceFika.cs +++ b/PTT-Plugin/Services/CustomExfilServiceFika.cs @@ -44,6 +44,12 @@ public static void ExtractTo(ExfiltrationPoint exfil, ExfilTarget exfilTarget) // 3. Trigger extract coopGame.Extract(coopPlayer, exfil, null); + // 4. Disable transit vote if host has extracted + if (Helpers.Fika.IsHost()) + { + TransitVoteServiceFika.SendDisableTransitVotePacket("Host has extracted"); + } + Logger.Info($"(FIKA) extraction done for profile {coopPlayer.ProfileId}"); } diff --git a/PTT-Plugin/Services/TransitVoteServiceFika.cs b/PTT-Plugin/Services/TransitVoteServiceFika.cs index 976c5e29..b54142ac 100644 --- a/PTT-Plugin/Services/TransitVoteServiceFika.cs +++ b/PTT-Plugin/Services/TransitVoteServiceFika.cs @@ -21,6 +21,7 @@ public static class TransitVoteServiceFika { private static Dictionary Votes = []; private static Action ExfilAction = null; + private static bool Enabled = true; public static void Init() { @@ -32,6 +33,7 @@ public static void InitRaid() { Votes = []; ExfilAction = null; + Enabled = true; } public static void VoteForExfil(ExfilTarget exfilTarget, Action exfilAction) @@ -106,6 +108,11 @@ public static void CancelVoteForExfil(string cancelMessage) public static bool IsTransitDisabledByVote(ExfilTarget exfilTarget) { + if (!Enabled) + { + return true; + } + if (Votes.Count == 0) { return false; @@ -122,6 +129,19 @@ public static bool IsTransitDisabledByVote(ExfilTarget exfilTarget) return false; } + public static void SendDisableTransitVotePacket(string reason) + { + if (!Singleton.Instantiated) + { + Logger.Error("(FIKA) Only the server can call SendDisableTransitVotePacket"); + return; + } + + var fikaServer = Singleton.Instance; + var packet = new DisableTransitVotePacket { Reason = reason }; + fikaServer.SendDataToAll(ref packet, DeliveryMethod.ReliableOrdered); + } + private static void HandlePlayerVotedForExfil(PlayerVotedForExfilTargetPacket packet, NetPeer peer) { CoopHandler coopHandler = Helpers.Fika.GetCoopHandler(); @@ -184,6 +204,8 @@ private static void RegisterPackets(FikaNetworkManagerCreatedEvent createdEvent) { networkManager.RegisterPacket(HandlePerformExfil); Logger.Info("(FIKA) Registered PerformExfilPacket"); + networkManager.RegisterPacket(HandleDisableTransitVote); + Logger.Info("(FIKA) Registered DisableTransitVotePacket"); } } @@ -206,6 +228,13 @@ private static void HandlePerformExfil(PerformExfilPacket packet, NetPeer peer) PerformLocalExfil(); } + private static void HandleDisableTransitVote(DisableTransitVotePacket packet, NetPeer peer) + { + Enabled = false; + NotificationManagerClass.DisplayMessageNotification($"Transits disabled because {packet.Reason}", ENotificationDurationType.Long); + InteractableExfilsService.RefreshPrompt(); + } + private static void PerformLocalExfil() { if (ExfilAction == null) From eb6871a14e55bbf53fcb9b721900685896ac11ff Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 18:40:19 +0100 Subject: [PATCH 185/203] fix: ExfilPrompt should be reset when player exit the zone instead of first render --- PTT-Plugin/UI/ExfilPrompt.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/PTT-Plugin/UI/ExfilPrompt.cs b/PTT-Plugin/UI/ExfilPrompt.cs index cc7a6178..c45dd720 100644 --- a/PTT-Plugin/UI/ExfilPrompt.cs +++ b/PTT-Plugin/UI/ExfilPrompt.cs @@ -103,19 +103,19 @@ private void CancelVote(string cancelMessage) private void OnExitZone() { - if (!_exfiltrated) + if (!_exfiltrated) // we need to check if the player is not exfiltrated because OnExitZone will be call on exfil { - CancelVote("Vote cancelled (zone exited)"); + InitPromptState(); + + if (_voted) + { + CancelVote("Vote cancelled (zone exited)"); + } } } public OnActionsAppliedResult Render() { - if (InteractableExfilsService.IsFirstRender()) - { - InitPromptState(); - } - string exitName = Exfil.Settings.Name; if (!Plugin.ExfilsTargetsService.ExfilsTargets.data.TryGetValue(exitName, out List exfilTargets)) { From 89e4d677b4f577c2285f5e15c65ee508c6f421a5 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 18:43:58 +0100 Subject: [PATCH 186/203] fix(client): do not show the prompt on exfil --- PTT-Plugin/UI/ExfilPrompt.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PTT-Plugin/UI/ExfilPrompt.cs b/PTT-Plugin/UI/ExfilPrompt.cs index c45dd720..70973405 100644 --- a/PTT-Plugin/UI/ExfilPrompt.cs +++ b/PTT-Plugin/UI/ExfilPrompt.cs @@ -12,7 +12,7 @@ namespace PTT.UI; public class ExfilPrompt(ExfiltrationPoint Exfil) { - private bool _exfiltrated = false; + private bool _exfiltrated = false; // when player extracted or transited private bool _voted = false; // when vote is confirmed private ExfilTarget _selectedExfilTarget = null; // used to check is auto-cancel vote is needed private Action _actionToExecuteOnConfirm = null; @@ -116,6 +116,11 @@ private void OnExitZone() public OnActionsAppliedResult Render() { + if (_exfiltrated) + { + return null; + } + string exitName = Exfil.Settings.Name; if (!Plugin.ExfilsTargetsService.ExfilsTargets.data.TryGetValue(exitName, out List exfilTargets)) { From 3f73e2df349df5ab913f5f45b975d2f261204870 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 18:46:00 +0100 Subject: [PATCH 187/203] fix(client): IE_API v1.5.0 is needed --- PTT-Plugin/Plugin.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/PTT-Plugin/Plugin.cs b/PTT-Plugin/Plugin.cs index c5ed7a72..c7d8c8ff 100644 --- a/PTT-Plugin/Plugin.cs +++ b/PTT-Plugin/Plugin.cs @@ -17,6 +17,7 @@ public class Plugin : BaseUnityPlugin private static bool KaenoTraderScrollingIsInstalled { get; set; } public static ExfilsTargetsService ExfilsTargetsService; private const string IE_API_PLUGIN_NAME = "Jehree.InteractableExfilsAPI"; + private const string IE_API_MIN_VERSION = "1.5.0"; protected void Awake() { @@ -60,9 +61,9 @@ protected void Start() { Version apiVersion = Chainloader.PluginInfos[IE_API_PLUGIN_NAME].Metadata.Version; - if (apiVersion < new Version("1.4.1")) + if (apiVersion < new Version(IE_API_MIN_VERSION)) { - Helpers.Logger.Warning($"Jehree.InteractableExfilsAPI >= 1.4.1 is required"); + Helpers.Logger.Warning($"Jehree.InteractableExfilsAPI >= {IE_API_MIN_VERSION} is required"); InteractableExfilsApiIsOutdated = true; } @@ -83,7 +84,7 @@ public static void DisplayInteractableExfilsAPIWarning() } else if (InteractableExfilsApiIsOutdated) { - NotificationManagerClass.DisplayWarningNotification("Path To Tarkov: Your Interactable Exfils API mod is outdated. v1.4.1 or higher is required", ENotificationDurationType.Long); + NotificationManagerClass.DisplayWarningNotification($"Path To Tarkov: Your Interactable Exfils API mod is outdated. v{IE_API_MIN_VERSION} or higher is required", ENotificationDurationType.Long); } } } From a06ae59c4490f0816a9c3078f3516192ad0058b2 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 19:17:00 +0100 Subject: [PATCH 188/203] refactor!: added runUninstallProcedure on UserConfig + no more enabled field on config --- src/config-analysis.ts | 44 ++++++++++++++++++++++++++++++++++++++++++ src/config.ts | 20 +++++++++++++++---- src/mod.ts | 26 +++++++++++-------------- 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index d7cffa4d..dfaad279 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -325,6 +325,13 @@ const getErrorsForInfils = (config: Config, spawnConfig: SpawnConfig): string[] return errors; }; +const getWarningsForInfils = (config: Config, spawnConfig: SpawnConfig): string[] => { + const warnings: string[] = []; + void config; + void spawnConfig; + return warnings; +}; + const getErrorsForAdditionalSpawnpoints = (config: Config): string[] => { const errors: string[] = []; @@ -342,6 +349,12 @@ const getErrorsForAdditionalSpawnpoints = (config: Config): string[] => { return errors; }; +const getWarningsForAdditionalSpawnpoints = (config: Config): string[] => { + const warnings: string[] = []; + void config; + return warnings; +}; + const getErrorsForGeneralConfig = (config: Config): string[] => { const errors: string[] = []; @@ -358,9 +371,37 @@ const getErrorsForGeneralConfig = (config: Config): string[] => { errors.push('"vanilla_exfils_requirements" is no longer supported since version 6'); } + // check for usage of "enabled" (only when set to false) + if (config.enabled === false) { + errors.push( + 'passing the property "enabled" to false is no longer supported since version 6, please use runUninstallProcedure boolean on UserConfig.json5', + ); + } + + // check for usage of "bypass_uninstall_procedure" (only when set to true) + if (config.bypass_uninstall_procedure === true) { + errors.push('"bypass_uninstall_procedure" property is no longer supported since version 6'); + } + return errors; }; +const getWarningsForGeneralConfig = (config: Config): string[] => { + const warnings: string[] = []; + + // check for usage of "enabled" + if (config.enabled === true || config.enabled === false) { + warnings.push('"enabled" property on config is no longer supported since version 6'); + } + + // check for usage of "bypass_uninstall_procedure" (only when set to false) + if (config.bypass_uninstall_procedure === false) { + warnings.push('"bypass_uninstall_procedure" property is no longer supported since version 6'); + } + + return warnings; +}; + const getErrorsForSpawnConfig = (spawnConfig: SpawnConfig): string[] => { const errors: string[] = []; @@ -411,12 +452,15 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 7. check for infiltrations maps and spawn points errors.push(...getErrorsForInfils(config, spawnConfig)); + warnings.push(...getWarningsForInfils(config, spawnConfig)); // 8. check for additional spawnpoints errors.push(...getErrorsForAdditionalSpawnpoints(config)); + warnings.push(...getWarningsForAdditionalSpawnpoints(config)); // 9. check the rest of the config errors.push(...getErrorsForGeneralConfig(config)); + warnings.push(...getWarningsForGeneralConfig(config)); // 10. check the spawn config errors.push(...getErrorsForSpawnConfig(spawnConfig)); diff --git a/src/config.ts b/src/config.ts index b57be51f..dca5083f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -202,7 +202,7 @@ export type ExfiltrationConfig = { }; type RawConfig = { - enabled: boolean; + enabled?: boolean; // no longer supported debug?: boolean; debug_exfiltrations_tooltips_locale?: string; override_by_profiles?: OverrideByProfiles; @@ -216,7 +216,7 @@ type RawConfig = { bypass_exfils_override?: boolean; enable_automatic_transits_creation?: boolean; enable_all_vanilla_transits?: boolean; - bypass_uninstall_procedure: boolean; + bypass_uninstall_procedure?: boolean; // no longer supported enable_run_through?: boolean; enable_legacy_ptt_api?: boolean; restrictions_in_raid: Record; @@ -246,6 +246,7 @@ export type Config = Omit< export type UserConfig = { selectedConfig: string; + runUninstallProcedure?: false; }; export type Profile = ISptProfile & { @@ -261,6 +262,7 @@ export const PACKAGE_JSON_PATH = join(__dirname, '../package.json'); export const CONFIGS_DIR = join(__dirname, '../configs'); export const USER_CONFIG_PATH = join(CONFIGS_DIR, 'UserConfig.json5'); +export const DEFAULT_SELECTED_PTT_CONFIG = 'Default'; export const CONFIG_FILENAME = 'config.json5'; export const SPAWN_CONFIG_FILENAME = 'shared_player_spawnpoints.json5'; @@ -453,11 +455,21 @@ export const processSpawnConfig = (spawnConfig: SpawnConfig, config: Config): Sp export const getUserConfig = (jsonUtil: JsonUtil): UserConfig => { if (!fileExists(USER_CONFIG_PATH)) { const userConfig: UserConfig = { - selectedConfig: 'Default', + selectedConfig: DEFAULT_SELECTED_PTT_CONFIG, + runUninstallProcedure: false, }; writeJsonFile(USER_CONFIG_PATH, userConfig); return userConfig; } - return readJsonFile(USER_CONFIG_PATH, jsonUtil); + const res: UserConfig = readJsonFile(USER_CONFIG_PATH, jsonUtil); + + if (!res.selectedConfig) { + return { + ...res, + selectedConfig: DEFAULT_SELECTED_PTT_CONFIG, + }; + } + + return res; }; diff --git a/src/mod.ts b/src/mod.ts index dec82dcd..144c2c21 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -10,7 +10,7 @@ import type { SaveServer } from '@spt/servers/SaveServer'; import type { StaticRouterModService } from '@spt/services/mod/staticRouter/StaticRouterModService'; import { createPathToTarkovAPI } from './api'; -import type { Config, MapName, SpawnConfig } from './config'; +import type { Config, MapName, SpawnConfig, UserConfig } from './config'; import { CONFIG_FILENAME, CONFIGS_DIR, @@ -39,6 +39,7 @@ import type { JsonUtil } from '@spt/utils/JsonUtil'; class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { private packageJson: PackageJson; + private userConfig: UserConfig; private config: Config; private spawnConfig: SpawnConfig; public logger: ILogger; @@ -52,9 +53,12 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { const jsonUtil = container.resolve('JsonUtil'); this.packageJson = readJsonFile(PACKAGE_JSON_PATH, jsonUtil); - const userConfig = getUserConfig(jsonUtil); + this.userConfig = getUserConfig(jsonUtil); this.config = processConfig( - readJsonFile(path.join(CONFIGS_DIR, userConfig.selectedConfig, CONFIG_FILENAME), jsonUtil), + readJsonFile( + path.join(CONFIGS_DIR, this.userConfig.selectedConfig, CONFIG_FILENAME), + jsonUtil, + ), ); this.spawnConfig = processSpawnConfig( readJsonFile(path.join(CONFIGS_DIR, SPAWN_CONFIG_FILENAME), jsonUtil), @@ -66,7 +70,7 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { ? (data: string) => this.logger.debug(`Path To Tarkov: ${data}`, true) : noop; - if (!this.config.enabled) { + if (this.userConfig.runUninstallProcedure) { return; } @@ -88,7 +92,7 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { if (analysisResult.errors.length > 0) { throw new Error( - `Fatal Error when loading the selected Path To Tarkov config "${userConfig.selectedConfig}"`, + `Fatal Error when loading the selected Path To Tarkov config "${this.userConfig.selectedConfig}"`, ); } @@ -144,7 +148,7 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { } public postDBLoad(container: DependencyContainer): void { - if (!this.config.enabled) { + if (this.userConfig.runUninstallProcedure) { return; } @@ -161,16 +165,8 @@ class PathToTarkov implements IPreSptLoadMod, IPostSptLoadMod { throw new Error('cannot retrieve quests templates from db'); } - if (!this.config.enabled) { + if (this.userConfig.runUninstallProcedure) { this.logger.warning('=> Path To Tarkov is disabled!'); - - if (this.config.bypass_uninstall_procedure === true) { - this.logger.warning( - "=> PathToTarkov: uninstall process aborted because 'bypass_uninstall_procedure' field is true in config.json", - ); - return; - } - purgeProfiles(this.config, quests, saveServer, this.logger); return; } From 2ea911031fbbf1083b2388c9b21ed049e23ce267 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 19:33:59 +0100 Subject: [PATCH 189/203] chore: add some comment in default config --- configs/Default/config.json5 | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/configs/Default/config.json5 b/configs/Default/config.json5 index a49b650e..b5f486ef 100644 --- a/configs/Default/config.json5 +++ b/configs/Default/config.json5 @@ -1,16 +1,26 @@ { - enabled: true, - debug: true, - debug_exfiltrations_tooltips_locale: 'en', - initial_offraid_position: 'FactoryZB-1011', - respawn_at: ['FactoryZB-1011'], + // Those 3 options can highly change the difficulty, try to change them if PTT is too hardcore/grindy for you reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, - player_scav_move_offraid_position: false, + + // default offraid position when profile is created (or ptt installed for the first time) + initial_offraid_position: 'FactoryZB-1011', + + // offraid position when a player die (apply only when `reset_offraid_position_on_player_die` is true) + respawn_at: ['FactoryZB-1011'], + + // with this option, transit points will be created automatically according to offraid position definition enable_automatic_transits_creation: true, + + // vanilla compatible are officially not supported but you can still enable them here enable_all_vanilla_transits: false, + bypass_keep_found_in_raid_tweak: false, + player_scav_move_offraid_position: false, + debug: true, + debug_exfiltrations_tooltips_locale: 'en', + restrictions_in_raid: { // roubles '5449016a4bdc2d6f028b456f': { From c9978b54f56d7e26deca55bcb904c538d238d42a Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 19:38:15 +0100 Subject: [PATCH 190/203] chore: save configs --- configs/Default/config.json5 | 7 ++++++- configs/DevilFlippy/config.json5 | 8 ++------ configs/ExampleOverrideByProfiles/config.json5 | 10 ++++------ configs/LegacyPathToTarkovV4/config.json5 | 6 ++---- configs/LegacyPathToTarkovV5/config.json5 | 10 ++++------ configs/LinearPath/config.json5 | 6 ++---- configs/OriginalNarcoticsConfig/config.json5 | 6 ++---- configs/PathToTarkovReloaded/config.json5 | 6 ++---- 8 files changed, 24 insertions(+), 35 deletions(-) diff --git a/configs/Default/config.json5 b/configs/Default/config.json5 index b5f486ef..ba6beae8 100644 --- a/configs/Default/config.json5 +++ b/configs/Default/config.json5 @@ -8,16 +8,21 @@ initial_offraid_position: 'FactoryZB-1011', // offraid position when a player die (apply only when `reset_offraid_position_on_player_die` is true) + // you can put several offraid positions here so it will pick one randomly on death respawn_at: ['FactoryZB-1011'], // with this option, transit points will be created automatically according to offraid position definition enable_automatic_transits_creation: true, - // vanilla compatible are officially not supported but you can still enable them here + // vanilla transits are officially not supported but you can still enable them here enable_all_vanilla_transits: false, bypass_keep_found_in_raid_tweak: false, player_scav_move_offraid_position: false, + + // Check the `ExampleOverrideByProfiles` config for a full usage example + override_by_profiles: {}, + debug: true, debug_exfiltrations_tooltips_locale: 'en', diff --git a/configs/DevilFlippy/config.json5 b/configs/DevilFlippy/config.json5 index 70f7d1a4..a9e12f69 100644 --- a/configs/DevilFlippy/config.json5 +++ b/configs/DevilFlippy/config.json5 @@ -1,16 +1,12 @@ { - enabled: true, - debug: true, - initial_offraid_position: 'FactoryZB-1011', reset_offraid_position_on_player_die: true, traders_access_restriction: true, - flea_access_restriction: true, - flea_access_level: 1, hideout_multistash_enabled: true, + initial_offraid_position: 'FactoryZB-1011', player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, bypass_luas_Customs_spawn_points_tweak: false, + debug: true, restrictions_in_raid: { // roubles '5449016a4bdc2d6f028b456f': { diff --git a/configs/ExampleOverrideByProfiles/config.json5 b/configs/ExampleOverrideByProfiles/config.json5 index 771fbd74..7fe1e6bd 100644 --- a/configs/ExampleOverrideByProfiles/config.json5 +++ b/configs/ExampleOverrideByProfiles/config.json5 @@ -1,6 +1,7 @@ { - enabled: true, - debug: true, + reset_offraid_position_on_player_die: true, + traders_access_restriction: true, + hideout_multistash_enabled: true, override_by_profiles: { 'Stalker On Tarkov': { initial_offraid_position: 'TherapistStash', @@ -10,12 +11,9 @@ }, initial_offraid_position: 'MechanicStash', respawn_at: ['MechanicStash'], - reset_offraid_position_on_player_die: true, - traders_access_restriction: true, - hideout_multistash_enabled: true, player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, + debug: true, restrictions_in_raid: { // roubles '5449016a4bdc2d6f028b456f': { diff --git a/configs/LegacyPathToTarkovV4/config.json5 b/configs/LegacyPathToTarkovV4/config.json5 index 30fe7541..8edce302 100644 --- a/configs/LegacyPathToTarkovV4/config.json5 +++ b/configs/LegacyPathToTarkovV4/config.json5 @@ -1,13 +1,11 @@ { - enabled: true, - debug: true, - initial_offraid_position: 'FactoryZB-1011', reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, + initial_offraid_position: 'FactoryZB-1011', player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, + debug: true, restrictions_in_raid: { // roubles '5449016a4bdc2d6f028b456f': { diff --git a/configs/LegacyPathToTarkovV5/config.json5 b/configs/LegacyPathToTarkovV5/config.json5 index 5c8c05e9..eb364656 100644 --- a/configs/LegacyPathToTarkovV5/config.json5 +++ b/configs/LegacyPathToTarkovV5/config.json5 @@ -1,15 +1,13 @@ { - enabled: true, - debug: true, - override_by_profiles: {}, - initial_offraid_position: 'MechanicStash', - respawn_at: ['MechanicStash'], reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, + initial_offraid_position: 'MechanicStash', + respawn_at: ['MechanicStash'], player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, + debug: true, + override_by_profiles: {}, restrictions_in_raid: { // roubles '5449016a4bdc2d6f028b456f': { diff --git a/configs/LinearPath/config.json5 b/configs/LinearPath/config.json5 index 11f2d37c..5bed209e 100644 --- a/configs/LinearPath/config.json5 +++ b/configs/LinearPath/config.json5 @@ -1,13 +1,11 @@ { - enabled: true, - debug: true, - initial_offraid_position: 'MechanicStash', reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, + initial_offraid_position: 'MechanicStash', player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, + debug: true, restrictions_in_raid: { // roubles '5449016a4bdc2d6f028b456f': { diff --git a/configs/OriginalNarcoticsConfig/config.json5 b/configs/OriginalNarcoticsConfig/config.json5 index ca920133..e6cf7163 100644 --- a/configs/OriginalNarcoticsConfig/config.json5 +++ b/configs/OriginalNarcoticsConfig/config.json5 @@ -1,13 +1,11 @@ { - enabled: true, - debug: true, - initial_offraid_position: 'FactoryZB-1011', reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, + initial_offraid_position: 'FactoryZB-1011', player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, + debug: true, restrictions_in_raid: { '5449016a4bdc2d6f028b456f': { '// type = roubles': true, diff --git a/configs/PathToTarkovReloaded/config.json5 b/configs/PathToTarkovReloaded/config.json5 index 24da3ee4..39982fa0 100644 --- a/configs/PathToTarkovReloaded/config.json5 +++ b/configs/PathToTarkovReloaded/config.json5 @@ -1,13 +1,11 @@ { - enabled: true, - debug: true, - initial_offraid_position: 'PlayerHideout', reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, + initial_offraid_position: 'PlayerHideout', player_scav_move_offraid_position: false, bypass_keep_found_in_raid_tweak: false, - bypass_uninstall_procedure: false, + debug: true, restrictions_in_raid: { '5449016a4bdc2d6f028b456f': { '// type = roubles': true, From 9560df03330365cbd3df302e0129970b399de899 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 19:39:32 +0100 Subject: [PATCH 191/203] chore: bump the version of PTT-Packets to 1.0.0 --- PTT-Packets/PTT.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PTT-Packets/PTT.csproj b/PTT-Packets/PTT.csproj index 35c4a6ff..b0553061 100644 --- a/PTT-Packets/PTT.csproj +++ b/PTT-Packets/PTT.csproj @@ -4,7 +4,7 @@ net471 Trap.PathToTarkov-Packets Path To Tarkov Fika Packets - 6.0.0 + 1.0.0 latest ..\..\..\.. From 7145ba22f36c626a9ff4108c1e3033dde2ef91a3 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 21:07:33 +0100 Subject: [PATCH 192/203] feat(config-analysis): check offraid_positions.*.displayName --- src/config-analysis.ts | 34 +++++++++++++++++++++++++++++++--- src/config.ts | 2 +- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index dfaad279..4912d2c9 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -1,8 +1,8 @@ import { isValidExfilForMap } from './all-exfils'; -import type { ByMap } from './config'; +import type { ByLocale, ByMap } from './config'; import { EMPTY_STASH, - isLocalAvailable, + isLocaleAvailable, type Config, type MapName, type SpawnConfig, @@ -53,6 +53,18 @@ const checkAccessViaErrors = ( return errors; }; +const checkLocalesErrors = (byLocale: ByLocale, suffixMessage: string): string[] => { + const errors: string[] = []; + + Object.keys(byLocale).forEach(locale => { + if (!isLocaleAvailable(locale)) { + errors.push(`unknown locale "${locale}" found ${suffixMessage}`); + } + }); + + return errors; +}; + /** * This will also check ptt transit custom notation, e.g. "factory4_day.Gate 3" */ @@ -155,6 +167,15 @@ const getErrorsForOffraidPositions = (config: Config, spawnConfig: SpawnConfig): }); }); + // check offraidPosition displayName locales + Object.keys(config.offraid_positions ?? {}).forEach(offraidPositionName => { + const displayNameByLocale = config.offraid_positions?.[offraidPositionName]?.displayName ?? {}; + + errors.push( + ...checkLocalesErrors(displayNameByLocale, `for offraid position "${offraidPositionName}"`), + ); + }); + return errors; }; @@ -360,7 +381,7 @@ const getErrorsForGeneralConfig = (config: Config): string[] => { // check for wrong locale on `debug_exfiltrations_tooltips_locale` const debugTooltipsLocale = config.debug_exfiltrations_tooltips_locale; - if (debugTooltipsLocale && !isLocalAvailable(debugTooltipsLocale)) { + if (debugTooltipsLocale && !isLocaleAvailable(debugTooltipsLocale)) { errors.push( `wrong locale "${debugTooltipsLocale}" set to "debug_exfiltrations_tooltips_locale"`, ); @@ -419,6 +440,12 @@ const getErrorsForSpawnConfig = (spawnConfig: SpawnConfig): string[] => { return errors; }; +const getWarningsForSpawnConfig = (spawnConfig: SpawnConfig): string[] => { + const warnings: string[] = []; + void spawnConfig; + return warnings; +}; + export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigValidationResult => { const errors: string[] = []; const warnings: string[] = []; @@ -464,6 +491,7 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV // 10. check the spawn config errors.push(...getErrorsForSpawnConfig(spawnConfig)); + warnings.push(...getWarningsForSpawnConfig(spawnConfig)); return { errors, diff --git a/src/config.ts b/src/config.ts index dca5083f..89b780c0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -69,7 +69,7 @@ export const INDEXED_AVAILABLE_LOCALES: AvailableLocales = { tu: true, }; -export const isLocalAvailable = (givenLocale: string): boolean => { +export const isLocaleAvailable = (givenLocale: string): boolean => { const availableLocales: Record = INDEXED_AVAILABLE_LOCALES; const locale = givenLocale.trim().toLowerCase(); return Boolean(availableLocales[locale]); From 5106b708d3fddbf0884b0cf6124d443f6e0b4e9d Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 21:10:50 +0100 Subject: [PATCH 193/203] feat(config-analysis): check exfiltrations_config.*.displayName --- src/config-analysis.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 4912d2c9..0a57e1a9 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -213,15 +213,15 @@ const getErrorsForExfils = (config: Config): string[] => { const errors: string[] = []; Object.keys(config.exfiltrations).forEach(mapName => { - // 1. check all exfils maps are valid + // check all exfils maps are valid if (!ALLOWED_MAPS.includes(mapName)) { errors.push(`${mapName} is now allowed as a map name in "exfiltrations"`); } - // 2. check there is at least one exfil target + // check there is at least one exfil target const targetsByExfil = config.exfiltrations[mapName as MapName] ?? {}; Object.keys(targetsByExfil).forEach(extractName => { - // 2bis. check there is no "." characters in given extractName + // check there is no "." characters in given extractName if (extractName.indexOf('.') !== -1) { errors.push(`bad extract name "${extractName}": the "." character is forbidden`); } @@ -233,14 +233,14 @@ const getErrorsForExfils = (config: Config): string[] => { }); }); - // 3. check for missing maps + // check for missing maps MIN_NEEDED_MAPS.forEach(mapName => { if (!config.exfiltrations[mapName as MapName]) { errors.push(`${mapName} is missing in "exfiltrations"`); } }); - // 4. Check for extract point name validity + // Check for extract point name validity Object.keys(config.exfiltrations).forEach(mapName => { Object.keys(config.exfiltrations[mapName as MapName]).forEach(exfilName => { if (!isValidExfilForMap(mapName, exfilName)) { @@ -249,6 +249,13 @@ const getErrorsForExfils = (config: Config): string[] => { }); }); + // check exfiltrations_config displayName locales + Object.keys(config.exfiltrations_config ?? {}).forEach(extractName => { + const displayNameByLocale = config.exfiltrations_config?.[extractName]?.displayName ?? {}; + + errors.push(...checkLocalesErrors(displayNameByLocale, `for extract "${extractName}"`)); + }); + return errors; }; From a2999aae72fccc325292e2f64a0748aa2fe040db Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 21:17:05 +0100 Subject: [PATCH 194/203] feat(config-analysis): check extracts_prompt_template and transits_prompt_template locales --- src/config-analysis.ts | 48 ++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/config-analysis.ts b/src/config-analysis.ts index 0a57e1a9..bd3e175f 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -394,6 +394,28 @@ const getErrorsForGeneralConfig = (config: Config): string[] => { ); } + // check extracts_prompt_template locales + errors.push( + ...checkLocalesErrors(config.extracts_prompt_template ?? {}, `for extracts_prompt_template`), + ); + + // check transits_prompt_template locales + errors.push( + ...checkLocalesErrors(config.transits_prompt_template ?? {}, `for transits_prompt_template`), + ); + + return errors; +}; + +const getWarningsForGeneralConfig = (config: Config): string[] => { + const warnings: string[] = []; + void config; + return warnings; +}; + +const getErrorsForUnsupportedProperties = (config: Config): string[] => { + const errors: string[] = []; + // check for usage of "vanilla_exfils_requirements" if (config.vanilla_exfils_requirements) { errors.push('"vanilla_exfils_requirements" is no longer supported since version 6'); @@ -414,7 +436,7 @@ const getErrorsForGeneralConfig = (config: Config): string[] => { return errors; }; -const getWarningsForGeneralConfig = (config: Config): string[] => { +const getWarningsForUnsupportedProperties = (config: Config): string[] => { const warnings: string[] = []; // check for usage of "enabled" @@ -457,49 +479,53 @@ export const analyzeConfig = (config: Config, spawnConfig: SpawnConfig): ConfigV const errors: string[] = []; const warnings: string[] = []; - // 1. check there is at least one offraid position + // check there is at least one offraid position if (isEmpty(config.infiltrations)) { errors.push('no offraid position found in "infiltrations"'); } - // 2. check there is at least one map + // check there is at least one map if (isEmpty(config.exfiltrations)) { errors.push('no map found found in "exfiltrations"'); } - // 3. check initial_offraid_position + // check initial_offraid_position if (!config.infiltrations[config.initial_offraid_position]) { errors.push(`wrong initial_offraid_position "${config.initial_offraid_position}"`); } - // 4. check all offraid positions + // check all offraid positions errors.push(...getErrorsForOffraidPositions(config, spawnConfig)); warnings.push(...getWarningsForOffraidPositions(config)); - // 5. checks for exfil maps + // checks for exfil maps errors.push(...getErrorsForExfils(config)); warnings.push(...getWarningsForExfils(config)); - // 6. check for secondary stashes + // check for secondary stashes errors.push(...getErrorsSecondaryStashes(config)); warnings.push(...getWarningsSecondaryStashes(config)); - // 7. check for infiltrations maps and spawn points + // check for infiltrations maps and spawn points errors.push(...getErrorsForInfils(config, spawnConfig)); warnings.push(...getWarningsForInfils(config, spawnConfig)); - // 8. check for additional spawnpoints + // check for additional spawnpoints errors.push(...getErrorsForAdditionalSpawnpoints(config)); warnings.push(...getWarningsForAdditionalSpawnpoints(config)); - // 9. check the rest of the config + // check the rest of the config errors.push(...getErrorsForGeneralConfig(config)); warnings.push(...getWarningsForGeneralConfig(config)); - // 10. check the spawn config + // check the spawn config errors.push(...getErrorsForSpawnConfig(spawnConfig)); warnings.push(...getWarningsForSpawnConfig(spawnConfig)); + // check unsupported properties (old ptt configs) + errors.push(...getErrorsForUnsupportedProperties(config)); + warnings.push(...getWarningsForUnsupportedProperties(config)); + return { errors, warnings, From e3b4c494d42cb0087fd38d6042b52c3ea4b06751 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 21:30:21 +0100 Subject: [PATCH 195/203] feat(config-analysis): check exfiltrations_config extractName validity --- src/all-exfils.ts | 8 ++++++++ src/config-analysis.ts | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/all-exfils.ts b/src/all-exfils.ts index cc24a1a8..acabfd22 100644 --- a/src/all-exfils.ts +++ b/src/all-exfils.ts @@ -161,3 +161,11 @@ export const isValidExfilForMap = (mapName: string, exfilName: string): boolean const exfils = ALL_EXFILS[mapName] ?? []; return exfils.includes(exfilName); }; + +export const isValidExfil = (exfilName: string): boolean => { + const found = Object.keys(ALL_EXFILS).find(mapName => { + return isValidExfilForMap(mapName, exfilName); + }); + + return Boolean(found); +}; diff --git a/src/config-analysis.ts b/src/config-analysis.ts index bd3e175f..16e09700 100644 --- a/src/config-analysis.ts +++ b/src/config-analysis.ts @@ -1,4 +1,4 @@ -import { isValidExfilForMap } from './all-exfils'; +import { isValidExfil, isValidExfilForMap } from './all-exfils'; import type { ByLocale, ByMap } from './config'; import { EMPTY_STASH, @@ -252,10 +252,16 @@ const getErrorsForExfils = (config: Config): string[] => { // check exfiltrations_config displayName locales Object.keys(config.exfiltrations_config ?? {}).forEach(extractName => { const displayNameByLocale = config.exfiltrations_config?.[extractName]?.displayName ?? {}; - errors.push(...checkLocalesErrors(displayNameByLocale, `for extract "${extractName}"`)); }); + // check exfiltrations_config extractName validity + Object.keys(config.exfiltrations_config ?? {}).forEach(extractName => { + if (!isValidExfil(extractName)) { + errors.push(`invalid extract name "${extractName}" found in "exfiltrations_config'`); + } + }); + return errors; }; From 28ee6d2af21cccc7850297e90a1813e3e88cfcfb Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 21:30:47 +0100 Subject: [PATCH 196/203] fix(configs): broken configs --- configs/Default/config.json5 | 14 ++++++++- configs/DevilFlippy/config.json5 | 14 ++++----- configs/OriginalNarcoticsConfig/config.json5 | 10 +++---- configs/PathToTarkovReloaded/config.json5 | 31 +++++--------------- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/configs/Default/config.json5 b/configs/Default/config.json5 index ba6beae8..15193581 100644 --- a/configs/Default/config.json5 +++ b/configs/Default/config.json5 @@ -1,5 +1,5 @@ { - // Those 3 options can highly change the difficulty, try to change them if PTT is too hardcore/grindy for you + // Those 3 options can highly change the difficulty, try to change them if PTT is too hardcore/grindy for you reset_offraid_position_on_player_die: true, traders_access_restriction: true, hideout_multistash_enabled: true, @@ -1486,5 +1486,17 @@ 'Saferoom Exfil': { override_tooltips_template: '$exfilDisplayName', }, + ' V-Ex_light': { + displayName: { + en: 'Military Base SUV (Reserve)', + fr: 'Base militaire SUV (Réserve)', + }, + }, + EXFIL_Bunker_D2: { + displayName: { + en: 'D2 Bunker', + fr: 'Bunker D2', + }, + }, }, } diff --git a/configs/DevilFlippy/config.json5 b/configs/DevilFlippy/config.json5 index a9e12f69..209d9872 100644 --- a/configs/DevilFlippy/config.json5 +++ b/configs/DevilFlippy/config.json5 @@ -608,7 +608,7 @@ E4: 'LotusHideout', E7: 'ExpoCPFlea', E7_car: 'StreetsCarToLabs', - E8_yard: 'PainterHideout', + scav_e7: 'PainterHideout', E9_sniper: 'KlimovStreet', scav_e1: 'BasementDescent', scav_e5: 'RequisitionsHideout', @@ -848,7 +848,7 @@ fr: 'ZB-1012 vers Usine - Prapor/Svetlana/Evelyn (Planque)', }, }, - 'ZB-1013': { + EXFIL_ZB013: { displayName: { en: 'ZB-1013 to ZB-016', fr: 'ZB-1013 vers ZB-016', @@ -968,7 +968,7 @@ fr: "Bouche d'égout vers Littoral - Peacekeeper", }, }, - EXFIL_BUNKER_D2: { + EXFIL_Bunker_D2: { displayName: { en: 'D-2 to Shoreline - Peacekeeper', fr: 'D-2 vers Littoral - Peacekeeper', @@ -1058,7 +1058,7 @@ fr: 'Pont ferroviaire - Ref', }, }, - ' V-ex_light': { + ' V-Ex_light': { displayName: { en: 'Road to Military Base V-Ex', fr: 'Véhicule vers la base militaire', @@ -1070,7 +1070,7 @@ fr: 'Sentier vers litorral', }, }, - Coastal_South_road: { + Coastal_South_Road: { displayName: { en: 'Southern Road to Shoreline', fr: 'Éboulement route sud vers Littoral', @@ -1154,9 +1154,9 @@ fr: "Véhicule de l'avenue Primorsky vers labo", }, }, - E8: { + scav_e7: { displayName: { - en: 'Cardinal Apartment Complex - The Painter', + en: 'Cardinal Apartment Complex Parking - The Painter', fr: "Parking du complexe d'appartements Cardinal - The Painter", }, }, diff --git a/configs/OriginalNarcoticsConfig/config.json5 b/configs/OriginalNarcoticsConfig/config.json5 index e6cf7163..b4937611 100644 --- a/configs/OriginalNarcoticsConfig/config.json5 +++ b/configs/OriginalNarcoticsConfig/config.json5 @@ -1164,7 +1164,7 @@ en: 'North UN Roadblock (Customs, RUAF Roadblock*)', }, }, - 'Factory gate': { + 'Factory Gate': { displayName: { en: 'Factory Gate (Customs, Old Gas Gate)', }, @@ -1299,7 +1299,7 @@ en: 'Northern Checkpoint (Woods/Customs)', }, }, - ' V-ex_light': { + ' V-Ex_light': { displayName: { en: 'Military Base SUV (Reserve, CP Fence)', }, @@ -1309,7 +1309,7 @@ en: 'Path to Shoreline', }, }, - Coastal_South_road: { + Coastal_South_Road: { displayName: { en: 'Southern Road (Shoreline, Ruined Road)', }, @@ -1319,7 +1319,7 @@ en: 'Mountain Pass (Shoreline, Path to Shoreline*)', }, }, - Tunnel_Shared: { + tunnel_shared: { displayName: { en: 'Side Tunnel (Shoreline, Tunnel)', }, @@ -1434,7 +1434,7 @@ en: 'Ruined House (Hephaestus)', }, }, - EXFIL_Vent: { + EXFIL_vent: { displayName: { en: 'Manhole (Sally/Streets)', }, diff --git a/configs/PathToTarkovReloaded/config.json5 b/configs/PathToTarkovReloaded/config.json5 index 39982fa0..e32b0b15 100644 --- a/configs/PathToTarkovReloaded/config.json5 +++ b/configs/PathToTarkovReloaded/config.json5 @@ -774,7 +774,7 @@ en: 'UN Roadblock (to Customs, RUAF)', }, }, - 'Factory gate': { + 'Factory Gate': { displayName: { en: 'Factory Gate (to Factory, Med Tent)', }, @@ -879,7 +879,7 @@ en: 'Bunker Hermetic Door (to Shoreline, Checkpoint *1way)', }, }, - EXFIL_BUNKER_D2: { + EXFIL_Bunker_D2: { displayName: { en: 'D-2 (to Woods, Snip er Rock Bunker *1way)', }, @@ -909,17 +909,12 @@ en: 'Northern CP (to Woods, Outskirts)', }, }, - ' V-ex_light': { - displayName: { - en: 'Car Ride Home', - }, - }, Shorl_free: { displayName: { en: 'Path to Shoreline (I swear if you ask)', }, }, - Coastal_South_road: { + Coastal_South_Road: { displayName: { en: 'Southern Road (to Shoreline, Tunnel)', }, @@ -929,7 +924,7 @@ en: 'Mountain Pass (to Shoreline, Path to Shoreline)', }, }, - Tunnel_Shared: { + tunnel_shared: { displayName: { en: 'Side Tunnel (to Shoreline, Tunnel)', }, @@ -949,7 +944,7 @@ en: 'Main Elevator (to Streets, Basement)', }, }, - lab_Elevator_med: { + lab_Elevator_Med: { displayName: { en: 'Medical Block Elevator (to Streets, Basement)', }, @@ -1029,12 +1024,7 @@ en: 'Boat (Machine,Artem)', }, }, - WoodsFactoryGate: { - displayName: { - en: 'Gate 0 (Prapor)', - }, - }, - 'Hole Exfil': { + 'Hole Exfill': { displayName: { en: 'Crossroads (The Machine)', }, @@ -1049,12 +1039,12 @@ en: 'Zb-1011 to Factory, Cellars(Mechanic)', }, }, - 'ZB-1013': { + EXFIL_ZB013: { displayName: { en: 'ZB-1013 to Factory, Gate 3(Mechanic)', }, }, - 'ZB-1014': { + 'ZB-014': { displayName: { en: 'ZB-1014 to Factory, Gate 3(Mechanic)', }, @@ -1064,11 +1054,6 @@ en: 'Outskirts to Reserve and Shoreline (Priscillu)', }, }, - 'Checkpoint Fence': { - displayName: { - en: 'Checkpoint Fence to Woods and Shoreline (Priscillu)', - }, - }, Nakatani_stairs_free_exit: { displayName: { en: 'Nakatani Basement (Hideout)', From 751039aeeb16314c3f39703f7daa7c53527f2548 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 22:48:19 +0100 Subject: [PATCH 197/203] fix(client): InitPromptState after auto cancel vote --- PTT-Plugin/UI/ExfilPrompt.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/PTT-Plugin/UI/ExfilPrompt.cs b/PTT-Plugin/UI/ExfilPrompt.cs index 70973405..6ac1c978 100644 --- a/PTT-Plugin/UI/ExfilPrompt.cs +++ b/PTT-Plugin/UI/ExfilPrompt.cs @@ -151,6 +151,7 @@ public OnActionsAppliedResult Render() if (_voted && _selectedExfilTarget != null && CustomExfilService.IsTransitDisabled(_selectedExfilTarget)) { CancelVote("Vote cancelled because selected exfil transit don't match with the others"); + InitPromptState(); } // 3. confirmation step From 5d1c0d2b4df2226e40a8273dcfb9dd7916b42055 Mon Sep 17 00:00:00 2001 From: Trap Date: Sun, 5 Jan 2025 23:16:30 +0100 Subject: [PATCH 198/203] fix(client): autocancel vote wasn't fully implemented --- PTT-Plugin/UI/ExfilPrompt.cs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/PTT-Plugin/UI/ExfilPrompt.cs b/PTT-Plugin/UI/ExfilPrompt.cs index 6ac1c978..dd04f6e8 100644 --- a/PTT-Plugin/UI/ExfilPrompt.cs +++ b/PTT-Plugin/UI/ExfilPrompt.cs @@ -13,15 +13,15 @@ namespace PTT.UI; public class ExfilPrompt(ExfiltrationPoint Exfil) { private bool _exfiltrated = false; // when player extracted or transited - private bool _voted = false; // when vote is confirmed - private ExfilTarget _selectedExfilTarget = null; // used to check is auto-cancel vote is needed + private bool _transitVoted = false; // when vote is confirmed (transit only) + private ExfilTarget _selectedTransitExfilTarget = null; // used to check is auto-cancel vote is needed private Action _actionToExecuteOnConfirm = null; private void InitPromptState() { _exfiltrated = false; - _voted = false; - _selectedExfilTarget = null; + _transitVoted = false; + _selectedTransitExfilTarget = null; _actionToExecuteOnConfirm = null; } @@ -33,7 +33,7 @@ private Action CreateRunConfirm() { _actionToExecuteOnConfirm(); _actionToExecuteOnConfirm = null; - _voted = true; + _transitVoted = true; } }; } @@ -64,6 +64,7 @@ private CustomExfilAction CreateCustomExfilAction(ExfiltrationPoint exfil, Exfil { _actionToExecuteOnConfirm = () => { + _selectedTransitExfilTarget = exfilTarget; CustomExfilService.TransitTo(exfilTarget, () => { _exfiltrated = true; @@ -96,8 +97,8 @@ private CustomExfilAction CreateCustomExfilAction(ExfiltrationPoint exfil, Exfil private void CancelVote(string cancelMessage) { - _voted = false; - _selectedExfilTarget = null; + _transitVoted = false; + _selectedTransitExfilTarget = null; CustomExfilService.CancelTransitVote(cancelMessage); } @@ -107,7 +108,7 @@ private void OnExitZone() { InitPromptState(); - if (_voted) + if (_transitVoted) { CancelVote("Vote cancelled (zone exited)"); } @@ -135,7 +136,7 @@ public OnActionsAppliedResult Render() } // 1. action selection step - if (!_voted && _actionToExecuteOnConfirm == null) + if (!_transitVoted && _actionToExecuteOnConfirm == null) { List actions = exfilTargets .Where(exfilTarget => exfilTarget.IsAvailable()) @@ -148,14 +149,14 @@ public OnActionsAppliedResult Render() var cancelAction = new CustomExfilAction("Cancel".Localized(), false, CreateRunCancel()); // auto-cancel the vote when needed - if (_voted && _selectedExfilTarget != null && CustomExfilService.IsTransitDisabled(_selectedExfilTarget)) + if (_transitVoted && _selectedTransitExfilTarget != null && CustomExfilService.IsTransitDisabled(_selectedTransitExfilTarget)) { CancelVote("Vote cancelled because selected exfil transit don't match with the others"); InitPromptState(); } // 3. confirmation step - if (!_voted) + if (!_transitVoted) { var confirmAction = new CustomExfilAction("confirm".Localized(), false, CreateRunConfirm()); From e660e468ce0c082b042d2b176dea9ce0b5b1fc33 Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 6 Jan 2025 00:04:11 +0100 Subject: [PATCH 199/203] chore: update UserConfig.sample.json5 --- UserConfig.sample.json5 | 1 + 1 file changed, 1 insertion(+) diff --git a/UserConfig.sample.json5 b/UserConfig.sample.json5 index c04089b9..8fe6b1ca 100644 --- a/UserConfig.sample.json5 +++ b/UserConfig.sample.json5 @@ -1,3 +1,4 @@ { selectedConfig: 'Default', + runUninstallProcedure: false, } From 88d885b9f8e0d7ff2185532f6ed8bd891387189e Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 6 Jan 2025 00:04:23 +0100 Subject: [PATCH 200/203] docs: add HOW_TO_UNINSTALL.md documentation --- README.md | 6 +++--- docs/HOW_TO_UNINSTALL.md | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 docs/HOW_TO_UNINSTALL.md diff --git a/README.md b/README.md index a49ae385..db04b44f 100644 --- a/README.md +++ b/README.md @@ -44,12 +44,12 @@ The offraid position is stored in your profile in a dedicated field `PathToTarko ## UnInstallation -Before deleting the mod, you can set the `enabled` props to `false` in `config.json` and start the server once. +[How to Uninstall Path To Tarkov properly](./docs/HOW_TO_UNINSTALL.md) -It does 2 things in all existing profiles: +The uninstall process does 2 things for all existing profiles: 1. Ensure the main stash is selected -2. Unlock all traders listed in the config (Please note Jaeger will be unlocked only if the Introduction quest has been already completed) +2. Unlock all traders listed in the config (Please note Jaeger will be unlocked only if the Introduction quest has been already completed and this will work also for modded traders) ## More tweaks diff --git a/docs/HOW_TO_UNINSTALL.md b/docs/HOW_TO_UNINSTALL.md new file mode 100644 index 00000000..511ac197 --- /dev/null +++ b/docs/HOW_TO_UNINSTALL.md @@ -0,0 +1,44 @@ +# UnInstallation procedure + +## Why a special uninstall procedure ? + +Unlike other mods, Path To Tarkov need to be uninstalled properly. +This is because PTT made some changes to the profile in order to implement traders access restrictions and multistash system. + +With that in mind, you can create dedicated profiles for playing with PTT, so you don't have to care about this uninstall process. + +## How to uninstall + +Mandatory steps: + +1. edit the `user/mods/Trap-PathToTarkov/configs/UserConfig.json5` file in your spt directory. +2. pass the property `runUninstallProcedure` to `true` and save the file. +3. start your spt server (from here, PTT is uninstalled and disabled) + +Optional steps (cleanup): + +4. stop the spt server +5. remove the mod (don't forget `Trap-PathToTarkov.dll` in `BepInEx/plugins`) + +## FAQ + +> I don't have any `UserConfig.json5` file + +This file is automatically generated on first start of the spt server. +If it's missing, It probably means that you don't need to run the uninstall procedure. + +------ + +> What exactly does the uninstall procedure to my profile ? + +1. It will restore your main hideout stash items (otherwise you risk getting stuck on a secondary stash) +2. It will unlock all traders according to completed quests (this work for Jaeger Introduction quest but also for modded traders) + +When running your spt server with `runUninstallProcedure` set to true, it will restore back all profiles that need to be restored. +You can check PTT logs in the server console to see more details on what's going on. + +------ + +> I removed PTT without running the uninstall process, is it a problem ? + +Not especially, you can re-install and run the uninstall process if you have doubt or if one of your profile is broken. From e5aeb099aee8d247874de5a19298866fd847da51 Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 6 Jan 2025 00:06:17 +0100 Subject: [PATCH 201/203] docs: missing docs directory in the release zip --- scripts/prepare-files.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/prepare-files.js b/scripts/prepare-files.js index 474002b2..9015d246 100644 --- a/scripts/prepare-files.js +++ b/scripts/prepare-files.js @@ -28,6 +28,7 @@ const main = async modName => { `cpr ALL_EXFILS.md ./dist/user/mods/${modName}/ALL_EXFILS.md -o`, `cpr LOGO.jpg ./dist/user/mods/${modName}/LOGO.jpg -o`, `cpr README.md ./dist/user/mods/${modName}/README.md -o`, + `cpr ./docs ./dist/user/mods/${modName}/docs -o`, `cpr LICENSE ./dist/user/mods/${modName}/LICENSE -o`, 'echo "> Successfully prepared files!"', ].forEach(cmd => { From 4dc9967015558d88263fdff81ae47f39e8a10905 Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 6 Jan 2025 00:33:00 +0100 Subject: [PATCH 202/203] fix(client): no exfil prompt after first transit --- PTT-Plugin/UI/ExfilPrompt.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PTT-Plugin/UI/ExfilPrompt.cs b/PTT-Plugin/UI/ExfilPrompt.cs index dd04f6e8..3aa2a680 100644 --- a/PTT-Plugin/UI/ExfilPrompt.cs +++ b/PTT-Plugin/UI/ExfilPrompt.cs @@ -117,6 +117,11 @@ private void OnExitZone() public OnActionsAppliedResult Render() { + if (InteractableExfilsService.IsFirstRender()) + { + InitPromptState(); + } + if (_exfiltrated) { return null; From 0239eb33348e78d03f40c67326a31c35a4c59fba Mon Sep 17 00:00:00 2001 From: Trap Date: Mon, 6 Jan 2025 01:00:52 +0100 Subject: [PATCH 203/203] 6.0.0-rc.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4e5d7ce7..e066a90c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "path-to-tarkov", - "version": "6.0.0-rc.4", + "version": "6.0.0-rc.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "path-to-tarkov", - "version": "6.0.0-rc.4", + "version": "6.0.0-rc.5", "license": "MIT", "dependencies": { "atomically": "~1.7", diff --git a/package.json b/package.json index 030e1ea8..34a64815 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "path-to-tarkov", "displayName": "Path To Tarkov", "fullName": "Trap-PathToTarkov", - "version": "6.0.0-rc.4", + "version": "6.0.0-rc.5", "main": "src/mod.js", "license": "MIT", "author": "Trap",