From 31d7301bfbd7be7f2e62c7a5e5f9169851594ff6 Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 16 May 2025 01:43:49 -0400 Subject: [PATCH] Updated Profiles Again & Added Server-Side Dynamic Maps --- mods/Dynamic Maps - Server/meta.ini | 28 +++ .../user/mods/SPTDynamicMaps/.buildignore | 20 ++ .../user/mods/SPTDynamicMaps/package.json | 37 ++++ .../SPTDynamicMaps/src/InstanceManager.ts | 82 +++++++ .../user/mods/SPTDynamicMaps/src/mod.ts | 208 ++++++++++++++++++ .../meta.ini | 0 profiles/Multiplayer/modlist.txt | 3 +- profiles/Server/modlist.txt | 30 +-- 8 files changed, 393 insertions(+), 15 deletions(-) create mode 100644 mods/Dynamic Maps - Server/meta.ini create mode 100644 mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/.buildignore create mode 100644 mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/package.json create mode 100644 mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/InstanceManager.ts create mode 100644 mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/mod.ts rename mods/{Version 2.0.0_separator => Version 2.0.4_separator}/meta.ini (100%) diff --git a/mods/Dynamic Maps - Server/meta.ini b/mods/Dynamic Maps - Server/meta.ini new file mode 100644 index 0000000..933145b --- /dev/null +++ b/mods/Dynamic Maps - Server/meta.ini @@ -0,0 +1,28 @@ +[General] +gameName=spt +modid=0 +version=d2025.5.14.0 +newestVersion= +category="-1," +nexusFileStatus=1 +installationFile=DynamicMaps-0.5.7-ba475092.zip +repository= +ignoredVersion= +comments= +notes= +nexusDescription= +url= +hasCustomURL=false +lastNexusQuery= +lastNexusUpdate= +nexusLastModified=2025-05-16T05:41:38Z +nexusCategory=0 +converted=false +validated=false +color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0) +tracked=0 + +[installedFiles] +1\modid=0 +1\fileid=0 +size=1 diff --git a/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/.buildignore b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/.buildignore new file mode 100644 index 0000000..2cbde65 --- /dev/null +++ b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/.buildignore @@ -0,0 +1,20 @@ +/.buildignore +/.DS_Store +/.editorconfig +/.eslintignore +/.eslintrc.json +/.git +/.github +/.gitignore +/.gitlab +/.nvmrc +/.prettierrc +/.vscode +/build.mjs +/dist +/images +/mod.code-workspace +/node_modules +/package-lock.json +/tsconfig.json +/types diff --git a/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/package.json b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/package.json new file mode 100644 index 0000000..a00d68c --- /dev/null +++ b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/package.json @@ -0,0 +1,37 @@ +{ + "name": "SPT-DynamicMaps", + "version": "0.5.7", + "sptVersion": "~3.11", + "loadBefore": [], + "loadAfter": [], + "incompatibilities": [], + "isBundleMod": false, + "main": "src/mod.js", + "scripts": { + "setup": "npm i", + "build": "node ./packageBuild.ts", + "buildinfo": "node ./packageBuild.ts --verbose" + }, + "devDependencies": { + "@types/node": "20.11", + "@typescript-eslint/eslint-plugin": "7.2", + "@typescript-eslint/parser": "7.2", + "archiver": "^6.0", + "eslint": "8.57", + "fs-extra": "11.2", + "ignore": "^5.2", + "tsyringe": "4.8.0", + "typescript": "5.4", + "winston": "3.12", + "bestzip": "^2.2.1" + }, + "author": "mpstark", + "contributors": [ + "dirtbikercj", + "AcidPhantasm" + ], + "license": "MIT", + "dependencies": { + + } +} diff --git a/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/InstanceManager.ts b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/InstanceManager.ts new file mode 100644 index 0000000..76be7be --- /dev/null +++ b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/InstanceManager.ts @@ -0,0 +1,82 @@ +import type { ILogger } from "@spt/models/spt/utils/ILogger"; +import type { DatabaseServer } from "@spt/servers/DatabaseServer"; +import type { IDatabaseTables } from "@spt/models/spt/server/IDatabaseTables"; +import type { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService"; +import type { DependencyContainer } from "tsyringe"; +import type { CustomItemService } from "@spt/services/mod/CustomItemService"; +import type { ImageRouter } from "@spt/routers/ImageRouter"; +import type { PreSptModLoader } from "@spt/loaders/PreSptModLoader"; +import type { ConfigServer } from "@spt/servers/ConfigServer"; +import type { JsonUtil } from "@spt/utils/JsonUtil"; +import type { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import type { RagfairPriceService } from "@spt/services/RagfairPriceService"; +import type { ImporterUtil } from "@spt/utils/ImporterUtil"; +import type { SaveServer } from "@spt/servers/SaveServer"; +import type { ItemHelper } from "@spt/helpers/ItemHelper"; +import type { MailSendService } from "@spt/services/MailSendService"; +import type { HashUtil } from "@spt/utils/HashUtil"; +import type { TraderHelper } from "@spt/helpers/TraderHelper"; +import type { HttpResponseUtil } from "@spt/utils/HttpResponseUtil"; +import type { FileSystemSync } from "@spt/utils/FileSystemSync"; + +export class InstanceManager +{ + //#region Accessible in or after preAkiLoad + private alpha = false; + private version = ""; + + // Instances + public container: DependencyContainer; + public preSptModLoader: PreSptModLoader; + public configServer: ConfigServer; + public saveServer: SaveServer; + public itemHelper: ItemHelper; + public logger: ILogger; + public staticRouter: StaticRouterModService; + public fs: FileSystemSync; + public hashUtil: HashUtil; + public httpResponseUtil: HttpResponseUtil; + //#endregion + + //#region Acceessible in or after postDBLoad + public database: IDatabaseTables; + public customItem: CustomItemService; + public imageRouter: ImageRouter; + public jsonUtil: JsonUtil; + public profileHelper: ProfileHelper; + public ragfairPriceService: RagfairPriceService; + public importerUtil: ImporterUtil; + public customItemService: CustomItemService; + public mailSendService: MailSendService; + public traderHelper: TraderHelper; + //#endregion + + // Call at the start of the mods postDBLoad method + public preSptLoad(container: DependencyContainer): void + { + this.container = container; + this.preSptModLoader = container.resolve("PreSptModLoader"); + this.imageRouter = container.resolve("ImageRouter"); + this.configServer = container.resolve("ConfigServer"); + this.saveServer = container.resolve("SaveServer"); + this.itemHelper = container.resolve("ItemHelper"); + this.logger = container.resolve("WinstonLogger"); + this.staticRouter = container.resolve("StaticRouterModService"); + this.fs = container.resolve("FileSystemSync"); + this.hashUtil = container.resolve("HashUtil"); + this.httpResponseUtil = container.resolve("HttpResponseUtil"); + } + + public postDBLoad(container: DependencyContainer): void + { + this.database = container.resolve("DatabaseServer").getTables(); + this.customItem = container.resolve("CustomItemService"); + this.jsonUtil = container.resolve("JsonUtil"); + this.profileHelper = container.resolve("ProfileHelper"); + this.ragfairPriceService = container.resolve("RagfairPriceService"); + this.importerUtil = container.resolve("ImporterUtil"); + this.customItemService = container.resolve("CustomItemService"); + this.mailSendService = container.resolve("MailSendService"); + this.traderHelper = container.resolve("TraderHelper"); + } +} \ No newline at end of file diff --git a/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/mod.ts b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/mod.ts new file mode 100644 index 0000000..be0886a --- /dev/null +++ b/mods/Dynamic Maps - Server/user/mods/SPTDynamicMaps/src/mod.ts @@ -0,0 +1,208 @@ +import type { DependencyContainer } from "tsyringe"; +import type { IPostDBLoadMod } from "@spt/models/external/IPostDBLoadMod"; +import type { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod"; +import type { Item } from "@spt/models/eft/common/tables/IItem"; +import type { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; +import type { NewItemFromCloneDetails } from "@spt/models/spt/mod/NewItemDetails"; +import { Traders } from "@spt/models/enums/Traders"; +import { InstanceManager } from "./InstanceManager"; + +class DynamicMaps implements IPreSptLoadMod, IPostDBLoadMod +{ + // eslint-disable-next-line @typescript-eslint/naming-convention + protected InstanceManager: InstanceManager = new InstanceManager(); + + public preSptLoad(container: DependencyContainer): void + { + this.InstanceManager.preSptLoad(container); + } + + public postDBLoad(container: DependencyContainer): void + { + this.InstanceManager.postDBLoad(container); + + this.createNewMaps(); + } + + private createNewMaps(): void + { + this.createGroundZeroMap(); + this.createStreetsMap(); + this.createReserveMap(); + this.createLabsMap(); + this.createLighthouseMap(); + } + + private createGroundZeroMap(): void + { + const gzMap: NewItemFromCloneDetails = + { + itemTplToClone: "5900b89686f7744e704a8747", + parentId: "567849dd4bdc2d150f8b456e", + newId: "6738033eb7305d3bdafe9518", + fleaPriceRoubles: 25000, + handbookPriceRoubles: 32500, + handbookParentId: "5b47574386f77428ca22b343", + overrideProperties: { + + }, + locales: { + en: { + name: "Ground Zero plan map", + shortName: "Ground Zero", + description: "" + } + } + } + + const assortId = "6738076415fd9232e8dae982"; + + this.InstanceManager.customItemService.createItemFromClone(gzMap); + this.pushToTraderAssort(Traders.THERAPIST, gzMap.newId, gzMap.handbookPriceRoubles, assortId); + } + + private createStreetsMap(): void + { + const streetsMap: NewItemFromCloneDetails = + { + itemTplToClone: "5900b89686f7744e704a8747", + parentId: "567849dd4bdc2d150f8b456e", + newId: "673803448cb3819668d77b1b", + fleaPriceRoubles: 25000, + handbookPriceRoubles: 32500, + handbookParentId: "5b47574386f77428ca22b343", + overrideProperties: { + + }, + locales: { + en: { + name: "Streets of Tarkov plan", + shortName: "Streets", + description: "" + } + } + } + + const assortId = "67380769ebda082cf01c3fd7"; + + this.InstanceManager.customItemService.createItemFromClone(streetsMap); + this.pushToTraderAssort(Traders.THERAPIST, streetsMap.newId, streetsMap.handbookPriceRoubles, assortId); + } + + private createReserveMap(): void + { + const reserveMap: NewItemFromCloneDetails = + { + itemTplToClone: "5900b89686f7744e704a8747", + parentId: "567849dd4bdc2d150f8b456e", + newId: "6738034a9713b5f42b4a8b78", + fleaPriceRoubles: 25000, + handbookPriceRoubles: 32500, + handbookParentId: "5b47574386f77428ca22b343", + overrideProperties: { + + }, + locales: { + en: { + name: "Reserve plan", + shortName: "Reserve", + description: "" + } + } + } + + const assortId = "6738076e704fef20a1a580e6"; + + this.InstanceManager.customItemService.createItemFromClone(reserveMap); + this.pushToTraderAssort(Traders.THERAPIST, reserveMap.newId, reserveMap.handbookPriceRoubles, assortId); + } + + private createLabsMap(): void + { + const labsMap: NewItemFromCloneDetails = + { + itemTplToClone: "5900b89686f7744e704a8747", + parentId: "567849dd4bdc2d150f8b456e", + newId: "6738034e9d22459ad7cd1b81", + fleaPriceRoubles: 25000, + handbookPriceRoubles: 32500, + handbookParentId: "5b47574386f77428ca22b343", + overrideProperties: { + + }, + locales: { + en: { + name: "Labs plan", + shortName: "Labs", + description: "" + } + } + } + + const assortId = "673807742ef49729b9dd1b0a"; + + this.InstanceManager.customItemService.createItemFromClone(labsMap); + this.pushToTraderAssort(Traders.THERAPIST, labsMap.newId, labsMap.handbookPriceRoubles, assortId); + } + + private createLighthouseMap(): void + { + const lighthouseMap: NewItemFromCloneDetails = + { + itemTplToClone: "5900b89686f7744e704a8747", + parentId: "567849dd4bdc2d150f8b456e", + newId: "6738035350b24a4ae4a57997", + fleaPriceRoubles: 25000, + handbookPriceRoubles: 32500, + handbookParentId: "5b47574386f77428ca22b343", + overrideProperties: { + + }, + locales: { + en: { + name: "Lighthouse plan", + shortName: "Lighthouse", + description: "" + } + } + } + + const assortId = "6738077be5a03fda63c9917d"; + + this.InstanceManager.customItemService.createItemFromClone(lighthouseMap); + this.pushToTraderAssort(Traders.THERAPIST, lighthouseMap.newId, lighthouseMap.handbookPriceRoubles, assortId); + } + + private pushToTraderAssort(traderId: Traders, itemId: string, price: number, assortId: string): void + { + const assort = this.InstanceManager.database.traders[traderId].assort; + + const item: Item = { + _id: assortId, + _tpl: itemId, + parentId: "hideout", + slotId: "hideout", + upd: { + UnlimitedCount: false, + StackObjectsCount: 4, + BuyRestrictionMax: 10, + BuyRestrictionCurrent: 0 + } + } + + const scheme: IBarterScheme[][] = [ + [ + { + count: price, + _tpl: "5449016a4bdc2d6f028b456f" + } + ] + ]; + + assort.items.push(item); + assort.barter_scheme[assortId] = scheme; + assort.loyal_level_items[assortId] = 1; + } +} + +export const mod = new DynamicMaps(); diff --git a/mods/Version 2.0.0_separator/meta.ini b/mods/Version 2.0.4_separator/meta.ini similarity index 100% rename from mods/Version 2.0.0_separator/meta.ini rename to mods/Version 2.0.4_separator/meta.ini diff --git a/profiles/Multiplayer/modlist.txt b/profiles/Multiplayer/modlist.txt index 4fc4039..827b6f7 100644 --- a/profiles/Multiplayer/modlist.txt +++ b/profiles/Multiplayer/modlist.txt @@ -1,6 +1,6 @@ # This file was automatically generated by Mod Organizer. +Unsorted_separator -+Version 2.0.0_separator ++Version 2.0.4_separator +Backburner_separator +Config Files +Modlist Addons_separator @@ -58,6 +58,7 @@ +Player Encumbrance Bar +Quick Move To Container +Quest Tracker +-Dynamic Maps - Server +Dynamic Maps +Custom Interactions +Item Context Menu Extended diff --git a/profiles/Server/modlist.txt b/profiles/Server/modlist.txt index 8ec4975..39dc116 100644 --- a/profiles/Server/modlist.txt +++ b/profiles/Server/modlist.txt @@ -1,14 +1,15 @@ +# This file was automatically generated by Mod Organizer. +Unsorted_separator -+Version 2.0.0_separator ++Version 2.0.4_separator +Backburner_separator -Config Files +Modlist Addons_separator +Tools & Debugging_separator -+Headshot Darkness -+Smoke Rework +-Headshot Darkness +-Smoke Rework +Bright Lasers +Borkels Realistic NVGs -+HollywoodFX +-HollywoodFX +VFX & Atmosphere_separator +Vocal Player +Agony SFX @@ -48,18 +49,19 @@ +Skeleton Key +New Items & Keys_separator +SFX & Music_separator -+Trader Scrolling -+Auto Deposit -+Use Loose Loot -+Quicksell -+Equip From Weapon Rack +-Trader Scrolling +-Auto Deposit +-Use Loose Loot +-Quicksell +-Equip From Weapon Rack +Better Trader Modding -+Player Encumbrance Bar -+Quick Move To Container -+Quest Tracker +-Player Encumbrance Bar +-Quick Move To Container +-Quest Tracker +-Dynamic Maps - Server +Dynamic Maps -+Custom Interactions -+Item Context Menu Extended +-Custom Interactions +-Item Context Menu Extended -Menu Overhaul +UI Fixes +Interface & HUD_separator