Adding Mods w/Symlink

This commit is contained in:
2025-01-02 20:23:50 -05:00
parent 88fc2c3c93
commit 404890ecbb
10218 changed files with 3191380 additions and 0 deletions
@@ -0,0 +1,26 @@
[General]
modid=0
version=
newestVersion=
category="-1,"
installationFile=
ignoredVersion=
repository=Nexus
gameName=spt
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
nexusFileStatus=1
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-09-09T09:16:47Z
nexusCategory=0
converted=false
validated=false
color=@Variant(\0\0\0\x43\x1\xff\xff\x44\x44\x36\x36))\0\0)
tracked=0
[installedFiles]
size=0
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.21.0
newestVersion=
category="1,2"
nexusFileStatus=1
installationFile=WTT-Armory-Ak5C-1.0.3.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-22T04:12:41Z
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
@@ -0,0 +1,95 @@
{
"manifest": [
{
"key": "WeaponAK5C/ak5c.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle"
]
},
{
"key": "WeaponAK5C/ak5cbarrel.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5ccover.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5cfs.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5cgrip.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5chandguard.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5cmag.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5cmuzzle.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5crail.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5cstock.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
},
{
"key": "WeaponAK5C/ak5cstock_1.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/commonassets/physics/physicsmaterials.bundle"
]
}
]
}
@@ -0,0 +1,128 @@
{
"PEACEKEEPER": {
"items": [
{
"_id": "6671efb6acbb23fc7b97d066",
"_tpl": "6671ec0028088d829af1a668",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"StackObjectsCount": 1000
}
},
{
"_id": "6671efbac1e4261ab018d515",
"_tpl": "6671ecd0c978c594704b61f4",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"StackObjectsCount": 1000
}
},
{
"_id": "6671f0d35157784af2055255",
"_tpl": "6671ebcdd32bd95eb398e920",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"StackObjectsCount": 99805,
"Repairable": {
"Durability": 100,
"MaxDurability": 100
}
}
},
{
"_id": "6671f11665b0f49c45f19bf3",
"_tpl": "6671ee9490d3a9978a371da7",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_mount"
},
{
"_id": "6671f11420335e0bdd93c863",
"_tpl": "6671eca71020d64fb2240530",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_sight_front"
},
{
"_id": "6671f1115ea70dbd607d2aa7",
"_tpl": "6671ecb42225b07c8afc4ce3",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_stock"
},
{
"_id": "6671f10e062ffaf93fb65338",
"_tpl": "6671ec6e0bebf6ee2d5abf61",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_pistol_grip"
},
{
"_id": "6671f10a2e68b8c0ad1ff43d",
"_tpl": "6671ec0028088d829af1a668",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_magazine"
},
{
"_id": "6671f1307017899a8c8d4320",
"_tpl": "6671ece3365d10b3362eb40f",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_handguard"
},
{
"_id": "6671f0ffd993ff5c5c65dc59",
"_tpl": "6671ed4b45dbd54033e7bbb0",
"parentId": "6671f0d35157784af2055255",
"slotId": "mod_barrel"
},
{
"_id": "6671f192da41c7ae8fd07708",
"_tpl": "6671ed384a25cc51b3e8d8a7",
"parentId": "6671f1307017899a8c8d4320",
"slotId": "mod_tactical"
},
{
"_id": "6671f18f92e55b4c2e842ac3",
"_tpl": "6671ed384a25cc51b3e8d8a7",
"parentId": "6671f1307017899a8c8d4320",
"slotId": "mod_tactical_2"
},
{
"_id": "6671f106d133165140d4e524",
"_tpl": "6671ed5805ef46250c47e46a",
"parentId": "6671f0ffd993ff5c5c65dc59",
"slotId": "mod_muzzle"
}
],
"barter_scheme": {
"6671efb6acbb23fc7b97d066": [
[
{
"count": 25,
"_tpl": "5696686a4bdc2da3298b456a"
}
]
],
"6671efbac1e4261ab018d515": [
[
{
"count": 58,
"_tpl": "5696686a4bdc2da3298b456a"
}
]
],
"6671f0d35157784af2055255": [
[
{
"count": 785,
"_tpl": "5696686a4bdc2da3298b456a"
}
]
]
},
"loyal_level_items": {
"6671efb6acbb23fc7b97d066": 2,
"6671efbac1e4261ab018d515": 2,
"6671f0d35157784af2055255": 2
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
{
"name": "WTTArmoryAk5C",
"author": "Tron and MoxoPixel",
"version": "1.0.3",
"license": "NCSA",
"main": "src/mod.js",
"sptVersion": "~3.10",
"loadBefore": [],
"loadAfter": [],
"isBundleMod": true,
"incompatibilities": [],
"contributors": [],
"scripts": {
"setup": "npm i",
"build": "node ./build.mjs",
"buildinfo": "node ./build.mjs --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",
"os": "^0.1",
"tsyringe": "4.8.0",
"typescript": "5.4",
"winston": "3.12"
},
"dependencies": {
"jsonc": "^2.0.0"
}
}
@@ -0,0 +1,49 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { WTTInstanceManager } from "./WTTInstanceManager";
import customAssortSchemes from "../db/CustomAssortSchemes/CustomAssortSchemes.json";
import { traderIDs } from "./references/configConsts";
import type { ITraderAssort } from "@spt/models/eft/common/tables/ITrader";
export class CustomAssortSchemeService
{
private instanceManager: WTTInstanceManager;
public preSptLoad(instanceManager: WTTInstanceManager): void
{
this.instanceManager = instanceManager;
}
public postDBLoad(): void
{
const tables = this.instanceManager.database;
for (const traderId in customAssortSchemes)
{
const traderIdFromMap = traderIDs[traderId];
const finalTraderId = traderIdFromMap || traderId;
const trader = tables.traders[finalTraderId];
if (!trader)
{
return;
}
const newAssort : ITraderAssort = customAssortSchemes[traderId];
for (const item of newAssort.items)
{
trader.assort.items.push(item);
}
for (const [itemName, scheme] of Object.entries(newAssort.barter_scheme))
{
trader.assort.barter_scheme[itemName] = scheme;
}
for (const [itemName, count] of Object.entries(newAssort.loyal_level_items))
{
trader.assort.loyal_level_items[itemName] = count;
}
}
}
}
@@ -0,0 +1,856 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { NewItemFromCloneDetails } from "@spt/models/spt/mod/NewItemDetails";
import type { ConfigItem } from "./references/configConsts";
import { traderIDs } from "./references/configConsts";
import { currencyIDs } from "./references/configConsts";
import { inventorySlots } from "./references/configConsts";
import { ItemMap } from "./references/items";
import { ItemBaseClassMap } from "./references/itemBaseClasses";
import { ItemHandbookCategoryMap } from "./references/itemHandbookCategories";
import { LogTextColor } from "@spt/models/spt/logging/LogTextColor";
import fs from "node:fs";
import path from "node:path";
import type { WTTInstanceManager } from "./WTTInstanceManager";
import type { IDatabaseTables } from "@spt/models/spt/server/IDatabaseTables";
import type { ILocation } from "@spt/models/eft/common/ILocation";
import type { IPreset } from "@spt/models/eft/common/IGlobals";
import type { IItem } from "@spt/models/eft/common/tables/IItem";
import type { IInventory } from "@spt/models/eft/common/tables/IBotType";
import type { IProps } from "@spt/models/eft/common/tables/ITemplateItem";
export class CustomItemService {
private instanceManager: WTTInstanceManager;
public preSptLoad(instanceManager: WTTInstanceManager): void {
this.instanceManager = instanceManager;
}
public postDBLoad(): void {
const configPath = path.join(__dirname, "../db/Items");
const configFiles = fs
.readdirSync(configPath)
.filter((file) => !file.includes("BaseItemReplacement"));
let numItemsAdded = 0;
for (const file of configFiles) {
const filePath = path.join(configPath, file);
try {
const fileContents = fs.readFileSync(filePath, "utf-8");
const config = JSON.parse(fileContents) as ConfigItem;
for (const itemId in config) {
const itemConfig = config[itemId];
try {
const { exampleCloneItem, finalItemTplToClone } =
this.createExampleCloneItem(itemConfig, itemId);
if (this.instanceManager.debug) {
console.log(`Processing file: ${file}, Item ID: ${itemId}`);
console.log(
`Prefab Path: ${exampleCloneItem.overrideProperties?.Prefab.path}`
);
}
this.instanceManager.customItem.createItemFromClone(exampleCloneItem);
this.processStaticLootContainers(itemConfig, itemId);
this.processModSlots(itemConfig, [finalItemTplToClone], itemId);
this.processInventorySlots(itemConfig, itemId);
this.processMasterySections(itemConfig, itemId);
this.processWeaponPresets(itemConfig, itemId);
this.processTraders(itemConfig, itemId);
this.addtoHallofFame(itemConfig, itemId);
this.addtoSpecialSlots(itemConfig, itemId);
numItemsAdded++;
} catch (itemError) {
console.error(`Error processing item ID: ${itemId} in file: ${file}`);
console.error(itemError);
}
}
} catch (fileError) {
console.error(`Error processing config file: ${file}`);
console.error(fileError);
}
}
if (numItemsAdded > 0) {
this.instanceManager.logger.log(
`[${this.instanceManager.modName}] Database: Loaded ${numItemsAdded} custom items.`,
LogTextColor.GREEN
);
} else {
this.instanceManager.logger.log(
`[${this.instanceManager.modName}] Database: No custom items loaded.`,
LogTextColor.GREEN
);
}
// Post-item processing (e.g., bot inventories, quest modifications)
for (const file of configFiles) {
const filePath = path.join(configPath, file);
try {
const fileContents = fs.readFileSync(filePath, "utf-8");
const config = JSON.parse(fileContents) as ConfigItem;
for (const itemId in config) {
const itemConfig = config[itemId];
this.processBotInventories(itemConfig, itemConfig.itemTplToClone, itemId);
}
} catch (fileError) {
console.error(`Error processing bot inventories for file: ${file}`);
console.error(fileError);
}
}
}
/**
* Creates an example clone item with the provided item configuration and item ID.
*
* @param {any} itemConfig - The configuration of the item to clone.
* @param {string} itemId - The ID of the item.
* @return {{ exampleCloneItem: NewItemFromCloneDetails, finalItemTplToClone: string }} The created example clone item and the final item template to clone.
*/
private createExampleCloneItem(
itemConfig: ConfigItem[string],
itemId: string
): {
exampleCloneItem: NewItemFromCloneDetails;
finalItemTplToClone: string;
} {
const itemTplToCloneFromMap =
ItemMap[itemConfig.itemTplToClone] || itemConfig.itemTplToClone;
const finalItemTplToClone = itemTplToCloneFromMap;
const parentIdFromMap =
ItemBaseClassMap[itemConfig.parentId] || itemConfig.parentId;
const finalParentId = parentIdFromMap;
const handbookParentIdFromMap =
ItemHandbookCategoryMap[itemConfig.handbookParentId] ||
itemConfig.handbookParentId;
const finalHandbookParentId = handbookParentIdFromMap;
const itemPrefabPath = `customItems/${itemId}.bundle`;
const exampleCloneItem: NewItemFromCloneDetails = {
itemTplToClone: finalItemTplToClone,
overrideProperties: itemConfig.overrideProperties
? {
...itemConfig.overrideProperties,
Prefab: {
path:
itemConfig.overrideProperties.Prefab?.path || itemPrefabPath,
rcid: ""
}
}
: undefined,
parentId: finalParentId,
newId: itemId,
fleaPriceRoubles: itemConfig.fleaPriceRoubles,
handbookPriceRoubles: itemConfig.handbookPriceRoubles,
handbookParentId: finalHandbookParentId,
locales: itemConfig.locales
};
if (this.instanceManager.debug) {
console.log(`Cloning item ${finalItemTplToClone} for itemID: ${itemId}`);
}
return { exampleCloneItem, finalItemTplToClone };
}
/**
* Adds an item to a static loot container with a given probability.
*
* @param {string} containerID - The ID of the loot container.
* @param {string} itemToAdd - The item to add to the loot container.
* @param {number} probability - The probability of the item being added.
* @return {void} This function does not return anything.
*/
private addToStaticLoot(
containerID: string,
itemToAdd: string,
probability: number
): void {
const locations = this.instanceManager.database.locations;
for (const locationID in locations) {
if (!Object.prototype.hasOwnProperty.call(locations, locationID)) {
continue; // Skip invalid locations
}
const location: ILocation = locations[locationID];
if (!location.staticLoot) {
if (this.instanceManager.debug) {
console.warn(`Warning: No static loot found in location: ${locationID}`);
}
continue;
}
const staticLoot = location.staticLoot;
if (!Object.prototype.hasOwnProperty.call(staticLoot, containerID)) {
if (this.instanceManager.debug) {
console.log(`Error: Loot container ID ${containerID} not found in location: ${locationID}`);
}
continue;
}
const lootContainer = staticLoot[containerID];
if (!lootContainer) {
if (this.instanceManager.debug) {
console.log(`Error: Loot container ID ${containerID} is null in location: ${locationID}`);
}
continue;
}
const templateFromMap = ItemMap[itemToAdd];
const finalTemplate = templateFromMap || itemToAdd;
const newLoot = [
{
tpl: finalTemplate,
relativeProbability: probability,
},
];
lootContainer.itemDistribution.push(...newLoot);
if (this.instanceManager.debug) {
console.log(`Added ${itemToAdd} to loot container: ${containerID} in location: ${locationID}`);
}
}
}
/**
* Processes the static loot containers for a given item.
*
* @param {any} itemConfig - The configuration object for the item.
* @param {string} itemId - The ID of the item.
* @return {void} This function does not return a value.
*/
private processStaticLootContainers(itemConfig: ConfigItem[string], itemId: string): void {
if (itemConfig.addtoStaticLootContainers) {
if (this.instanceManager.debug) {
console.log("Processing static loot containers for item:", itemId);
}
if (Array.isArray(itemConfig.StaticLootContainers)) {
if (this.instanceManager.debug) {
console.log("Adding item to multiple static loot containers:");
}
for (const container of itemConfig.StaticLootContainers) {
const staticLootContainer =
ItemMap[container.ContainerName] || container.ContainerName;
this.addToStaticLoot(
staticLootContainer,
itemId,
container.Probability
);
if (this.instanceManager.debug) {
console.log(
` - Added to container '${staticLootContainer}' with probability ${container.Probability}`
);
}
}
}
else {
const staticLootContainer =
ItemMap[itemConfig.StaticLootContainers] ||
itemConfig.StaticLootContainers;
this.addToStaticLoot(
staticLootContainer,
itemId,
itemConfig.Probability
);
if (this.instanceManager.debug) {
console.log(`Added to container '${staticLootContainer}' with probability ${itemConfig.Probability}`);
}
}
}
}
/**
* Processes the mod slots of an item.
*
* @param {any} itemConfig - The configuration of the item.
* @param {string[]} finalItemTplToClone - The final item template to clone.
* @param {string} itemId - The ID of the item.
* @returns {void}
*/
private processModSlots(
itemConfig: ConfigItem[string],
finalItemTplToClone: string[],
itemId: string
): void {
const tables = this.instanceManager.database;
const moddableItemWhitelistIds = Array.isArray(
itemConfig.ModdableItemWhitelist
)
? itemConfig.ModdableItemWhitelist.map((shortname) => ItemMap[shortname])
: itemConfig.ModdableItemWhitelist
? [ItemMap[itemConfig.ModdableItemWhitelist]]
: [];
const moddableItemBlacklistIds = Array.isArray(
itemConfig.ModdableItemBlacklist
)
? itemConfig.ModdableItemBlacklist.map((shortname) => ItemMap[shortname])
: itemConfig.ModdableItemBlacklist
? [ItemMap[itemConfig.ModdableItemBlacklist]]
: [];
const modSlots = Array.isArray(itemConfig.modSlot)
? itemConfig.modSlot
: itemConfig.modSlot
? [itemConfig.modSlot]
: [];
const lowercaseModSlots = modSlots.map((modSlotName) =>
modSlotName.toLowerCase()
);
if (itemConfig.addtoModSlots) {
if (this.instanceManager.debug) {
console.log("Processing mod slots for item:", itemId);
}
for (const parentItemId in tables.templates.items) {
const parentItem = tables.templates.items[parentItemId];
if (!parentItem._props.Slots) {
continue;
}
const isBlacklisted = moddableItemBlacklistIds.includes(parentItemId);
const isWhitelisted = moddableItemWhitelistIds.includes(parentItemId);
if (isBlacklisted) {
continue;
}
let addToModSlots = false;
if (isWhitelisted && itemConfig.modSlot) {
addToModSlots = true;
}
else if (!isBlacklisted && itemConfig.modSlot) {
for (const modSlot of parentItem._props.Slots) {
if (
modSlot._props.filters?.[0].Filter.some((filterItem) =>
finalItemTplToClone.includes(filterItem)
)
) {
if (lowercaseModSlots.includes(modSlot._name.toLowerCase())) {
addToModSlots = true;
break;
}
}
}
}
if (addToModSlots) {
for (const modSlot of parentItem._props.Slots) {
if (lowercaseModSlots.includes(modSlot._name.toLowerCase())) {
if (!modSlot._props.filters) {
modSlot._props.filters = [
{
AnimationIndex: 0,
Filter: []
}
];
}
if (!modSlot._props.filters[0].Filter.includes(itemId)) {
modSlot._props.filters[0].Filter.push(itemId);
if (this.instanceManager.debug) {
console.log(`Successfully added item ${itemId} to the filter of mod slot ${modSlot._name} for parent item ${parentItemId}`);
}
}
}
}
}
}
}
}
/**
* Processes the inventory slots for a given item.
*
* @param {any} itemConfig - The configuration object for the item.
* @param {string} itemId - The ID of the item.
* @param {any} defaultInventorySlots - The default inventory slots.
* @return {void} This function does not return a value.
*/
private processInventorySlots(
itemConfig: ConfigItem[string],
itemId: string
): void {
const tables = this.instanceManager.database;
if (itemConfig.addtoInventorySlots) {
if (this.instanceManager.debug) {
console.log("Processing inventory slots for item:", itemId);
}
const defaultInventorySlots =
tables.templates.items["55d7217a4bdc2d86028b456d"]._props.Slots;
const allowedSlots = Array.isArray(itemConfig.addtoInventorySlots)
? itemConfig.addtoInventorySlots
: [itemConfig.addtoInventorySlots];
// Iterate over the slots and push the item into the filters per the config
for (const slot of defaultInventorySlots) {
const slotName = inventorySlots[slot._name];
const slotId = Object.keys(inventorySlots).find(
(key) => inventorySlots[key] === slot._name
);
if (
allowedSlots.includes(slot._name) ||
allowedSlots.includes(slotName) ||
allowedSlots.includes(slotId)
) {
if (!slot._props.filters[0].Filter.includes(itemId)) {
slot._props.filters[0].Filter.push(itemId);
if (this.instanceManager.debug) {
console.log(`Successfully added item ${itemId} to the filter of slot ${slot._name}`);
}
}
}
}
}
}
/**
* Processes the mastery sections for an item.
*
* @param {any} itemConfig - The configuration object for the item.
* @param {string} itemId - The ID of the item.
* @param {any} tables - The tables object containing global configuration.
* @return {void} This function does not return a value.
*/
private processMasterySections(
itemConfig: ConfigItem[string],
itemId: string
): void {
const tables = this.instanceManager.database;
if (itemConfig.masteries) {
if (this.instanceManager.debug) {
console.log("Processing mastery sections for item:", itemId);
}
const masterySections = Array.isArray(itemConfig.masterySections)
? itemConfig.masterySections
: [itemConfig.masterySections];
for (const mastery of masterySections) {
const existingMastery = tables.globals.config.Mastering.find(
(existing) => existing.Name === mastery.Name
);
if (existingMastery) {
existingMastery.Templates.push(...mastery.Templates);
if (this.instanceManager.debug) {
console.log(` - Adding to existing mastery section for item: ${itemId}`);
}
}
else {
tables.globals.config.Mastering.push(mastery);
if (this.instanceManager.debug) {
console.log(` - Adding new mastery section for item: ${itemId}`);
}
}
}
}
}
/**
* Processes weapon presets based on the provided item configuration and tables.
*
* @param {any} itemConfig - The item configuration.
* @return {void} This function does not return anything.
*/
private processWeaponPresets(
itemConfig: ConfigItem[string],
itemId: string
): void {
const tables = this.instanceManager.database;
const { addweaponpreset, weaponpresets } = itemConfig;
const itemPresets = tables.globals.ItemPresets;
if (addweaponpreset) {
if (this.instanceManager.debug) {
console.log("Processing weapon presets for item:", itemId);
}
for (const presetData of weaponpresets) {
const preset: IPreset = {
_changeWeaponName: presetData._changeWeaponName,
_encyclopedia: presetData._encyclopedia || undefined,
_id: presetData._id,
_items: presetData._items.map((itemData: IItem) => {
const item: IItem = {
_id: itemData._id,
_tpl: itemData._tpl
};
// Add parentId and slotId only if they are present in itemData
if (itemData.parentId) {
item.parentId = itemData.parentId;
}
if (itemData.slotId) {
item.slotId = itemData.slotId;
}
return item;
}),
_name: presetData._name,
_parent: presetData._parent,
_type: "Preset"
};
itemPresets[preset._id] = preset;
if (this.instanceManager.debug) {
console.log(` - Added weapon preset: ${preset._name}`);
console.log(` - Preset: ${JSON.stringify(preset)}`);
}
}
}
}
/**
* Processes traders based on the item configuration.
*
* @param {any} itemConfig - The configuration of the item.
* @param {string} itemId - The ID of the item.
* @return {void} This function does not return a value.
*/
private processTraders(
itemConfig: ConfigItem[string],
itemId: string
): void {
const tables = this.instanceManager.database;
if (!itemConfig.addtoTraders) {
return;
}
const { traderId, traderItems, barterScheme } = itemConfig;
const traderIdFromMap = traderIDs[traderId];
const finalTraderId = traderIdFromMap || traderId;
const trader = tables.traders[finalTraderId];
if (!trader) {
return;
}
for (const item of traderItems) {
if (this.instanceManager.debug) {
console.log("Processing traders for item:", itemId);
}
const newItem = {
_id: itemId,
_tpl: itemId,
parentId: "hideout",
slotId: "hideout",
upd: {
UnlimitedCount: item.unlimitedCount,
StackObjectsCount: item.stackObjectsCount
}
};
trader.assort.items.push(newItem);
if (this.instanceManager.debug) {
console.log(`Successfully added item ${itemId} to the trader ${traderId}`);
}
}
trader.assort.barter_scheme[itemId] = [];
for (const scheme of barterScheme) {
if (this.instanceManager.debug) {
console.log("Processing trader barter scheme for item:", itemId);
}
const count = scheme.count;
const tpl = currencyIDs[scheme._tpl] || ItemMap[scheme._tpl];
if (!tpl) {
throw new Error(
`Invalid _tpl value in barterScheme for item: ${itemId}`
);
}
trader.assort.barter_scheme[itemId].push([
{
count: count,
_tpl: tpl
}
]);
if (this.instanceManager.debug) {
console.log(`Successfully added item ${itemId} to the barter scheme of trader ${traderId}`);
}
}
trader.assort.loyal_level_items[itemId] = itemConfig.loyallevelitems;
}
private addtoHallofFame(itemConfig: ConfigItem[string], itemId: string) {
const hallofFame1 = this.instanceManager.database.templates.items["63dbd45917fff4dee40fe16e"];
const hallofFame2 = this.instanceManager.database.templates.items["65424185a57eea37ed6562e9"];
const hallofFame3 = this.instanceManager.database.templates.items["6542435ea57eea37ed6562f0"];
// Add to Hall of Fame filters
if (itemConfig.addtoHallOfFame) {
const hallOfFames = [hallofFame1, hallofFame2, hallofFame3];
for (const hall of hallOfFames) {
for (const slot of hall._props.Slots) {
for (const filter of slot._props.filters) {
if (!filter.Filter.includes(itemId)) {
filter.Filter.push(itemId);
if (this.instanceManager.debug) {
console.log(`Added item ${itemId} to filter Hall of Fame ${hall._name}`);
}
}
}
}
}
}
}
private addtoSpecialSlots(itemConfig: ConfigItem[string], itemId: string) {
const tables = this.instanceManager.database;
if (itemConfig.addtoSpecialSlots) {
const pockets = tables.templates.items["627a4e6b255f7527fb05a0f6"];
for (const slot of pockets._props.Slots) {
if (!slot._props.filters[0].Filter.includes(itemId)) {
slot._props.filters[0].Filter.push(itemId);
}
}
}
}
/**
* Processes the bot inventories based on the given item configuration.
*
* @param {ConfigItem[string]} itemConfig - The item configuration.
* @param {string} finalItemTplToClone - The final item template to clone.
* @param {string} itemId - The item ID.
* @return {void} This function does not return anything.
*/
private processBotInventories(
itemConfig: ConfigItem[string],
finalItemTplToClone: string,
itemId: string
): void {
const tables = this.instanceManager.database;
if (!itemConfig.addtoBots) return;
if (this.instanceManager.debug) {
console.log("Processing bot inventories for item:", itemId);
}
// Iterate through bot types
for (const botId in tables.bots.types) {
const botType = botId;
const botInventory = tables.bots.types[botId].inventory;
botInventory.Ammo = botInventory.Ammo || {};
// Process items and equipment
this.processInventoryType(botInventory.items, finalItemTplToClone, itemId, botType, "items");
this.processInventoryType(botInventory.equipment, finalItemTplToClone, itemId, botType, "equipment");
// Process mods if applicable
if (itemConfig.addtoModSlots && itemConfig.modSlot) {
this.processBotModSlots(finalItemTplToClone, itemId, botType, itemConfig.modSlot);
}
}
}
/**
* Processes inventory type (items or equipment) and gathers mods based on Slots.
*
* @param {any} inventoryType - The inventory type to process.
* @param {string} finalTplToClone - The final item template to clone.
* @param {string} itemId - The item ID.
* @param {string} botType - The bot type identifier.
* @param {string} typeLabel - Label indicating items or equipment.
* @return {void} This function does not return anything.
*/
private processInventoryType(
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
inventoryType: any,
finalTplToClone: string,
itemId: string,
botType: string,
typeLabel: string
): void {
const tables = this.instanceManager.database;
if (typeLabel === "equipment" && (
(inventoryType.FirstPrimaryWeapon?.[finalTplToClone]) ||
(inventoryType.SecondPrimaryWeapon?.[finalTplToClone]) ||
(inventoryType.Holster?.[finalTplToClone])
)) {
if (!this.ensureValidWeaponPreset(itemId)) {
return;
}
this.processAmmoAndChambers(tables.bots.types[botType].inventory, tables.templates.items[itemId]._props, itemId, botType);
}
for (const lootSlot in inventoryType) {
const items = inventoryType[lootSlot];
if (items && items[finalTplToClone] !== undefined) {
const weight = items[finalTplToClone];
if (this.instanceManager.debug) {
console.log(` - Adding item to bot ${typeLabel} for bot type: ${botType} in loot slot: ${lootSlot} with weight: ${weight}`);
}
items[itemId] = weight;
this.addModsToItem(tables, itemId, botType);
}
}
}
/**
* Adds mods to an item based on its Slots configuration.
*
* @param {any} tables - The database tables.
* @param {string} itemId - The item ID.
* @param {string} botType - The bot type identifier.
* @return {void} This function does not return anything.
*/
private addModsToItem(tables: IDatabaseTables, itemId: string, botType: string): void {
const itemProps = tables.templates.items[itemId]._props;
if (itemProps?.Slots) {
for (const slot of itemProps.Slots) {
const slotName = slot._name;
const filters = slot._props.filters;
if (filters && filters.length > 0) {
for (const filter of filters) {
for (const modId of filter.Filter) {
if (modId && tables.templates.items[modId]) {
tables.bots.types[botType].inventory.mods[itemId] = tables.bots.types[botType].inventory.mods[itemId] || {};
tables.bots.types[botType].inventory.mods[itemId][slotName] = tables.bots.types[botType].inventory.mods[itemId][slotName] || [];
if (!tables.bots.types[botType].inventory.mods[itemId][slotName].includes(modId)) {
tables.bots.types[botType].inventory.mods[itemId][slotName].push(modId);
if (tables.templates.items[modId]._props) {
if (tables.templates.items[modId]._props.Slots.length > 0) {
this.addModsToItem(tables, modId, botType);
}
}
}
if (this.instanceManager.debug) {
console.log(` - Added mod ${modId} to ${itemId}'s ${slotName} of bot type ${botType}`);
}
}
}
}
}
}
}
}
/**
* Processes mod slots and adds itemId to specified slots if finalItemTplToClone is present.
*
* @param {any} mods - The mods inventory.
* @param {string} finalItemTplToClone - The final item template to clone.
* @param {string} itemId - The item ID.
* @param {string} botType - The bot type identifier.
* @param {string[]} modSlots - The list of mod slots to process.
* @return {void} This function does not return anything.
*/
private processBotModSlots(
finalItemTplToClone: string,
itemId: string,
botType: string,
modSlots: string[]
): void {
const mods = this.instanceManager.database.bots.types[botType].inventory.mods;
for (const item in mods) {
const itemMods = mods[item];
for (const modSlot of modSlots) {
if (itemMods[modSlot]?.includes(finalItemTplToClone)) {
itemMods[modSlot].push(itemId);
if (this.instanceManager.debug) {
console.log(` - Added item ${itemId} to mod slot ${modSlot} for bot type ${botType} in item ${item}`);
}
// Adding nested mods for the new item
this.addModsToItem(this.instanceManager.database, itemId, botType);
}
}
}
}
/**
* Processes ammo and chambers, adding calibers and chamber filters if needed.
*
* @param {any} botInventory - The bot's inventory.
* @param {any} itemProps - The properties of the item.
* @param {string} itemId - The item ID.
* @param {string} botType - The bot type identifier.
* @return {void} This function does not return anything.
*/
private processAmmoAndChambers(
botInventory: IInventory,
itemProps: IProps,
itemId: string,
botType: string
): void {
const ammoCaliber = itemProps.ammoCaliber;
if (!ammoCaliber) return;
botInventory.Ammo[ammoCaliber] = botInventory.Ammo[ammoCaliber] || {};
if (this.instanceManager.debug) {
console.log(` - Added new caliber ${ammoCaliber} to bot inventory for bot type ${botType}`);
}
if (itemProps.Chambers) {
for (const chamber of itemProps.Chambers) {
const filters = chamber._props.filters;
if (filters && filters.length > 0) {
for (const filter of filters) {
for (const filterItem of filter.Filter) {
botInventory.Ammo[ammoCaliber][filterItem] = botInventory.Ammo[ammoCaliber][filterItem] || 0;
if (this.instanceManager.debug) {
console.log(` - Added filter item ${filterItem} to caliber ${ammoCaliber} in bot inventory for bot type ${botType}`);
}
}
}
}
}
}
}
/**
* Ensures the weapon has a valid preset in the global ItemPresets.
*
* @param {string} itemId - The item ID.
* @return {boolean} True if the weapon has a valid preset, false otherwise.
*/
private ensureValidWeaponPreset(itemId: string): boolean {
const db = this.instanceManager.database;
const presets: Record<string, IPreset> = db.globals.ItemPresets;
for (const presetObj of Object.values(presets)) {
if (presetObj._items[0]._tpl === itemId) {
if (this.instanceManager.debug) {
console.log(` - Valid preset found for item ${itemId}`);
}
return true;
}
}
if (this.instanceManager.debug) {
console.warn(`No valid preset found for item ${itemId} in globals.ItemPresets`);
}
return false;
}
}
@@ -0,0 +1,119 @@
import path from "node:path";
import type { ILogger } from "@spt/models/spt/utils/ILogger";
import type { ProfileController } from "@spt/controllers/ProfileController";
import type { ProfileCallbacks } from "@spt/callbacks/ProfileCallbacks";
import type { EventOutputHolder } from "@spt/routers/EventOutputHolder";
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 { DynamicRouterModService } from "@spt/services/mod/dynamicRouter/DynamicRouterModService";
import type { TraderAssortService } from "@spt/services/TraderAssortService";
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 { ApplicationContext } from "@spt/context/ApplicationContext";
import type { VFS } from "@spt/utils/VFS";
export class WTTInstanceManager
{
//#region Accessible in or after preSptLoad
public modName: string;
public debug: boolean;
// Useful Paths
public profilePath: string = path.join(process.cwd(), "\\user\\profiles");
// Instances
public container: DependencyContainer;
public PreSptModLoader: PreSptModLoader;
public configServer: ConfigServer;
public saveServer: SaveServer;
public itemHelper: ItemHelper;
public logger: ILogger;
public staticRouter: StaticRouterModService;
public dynamicRouter: DynamicRouterModService;
public profileController: ProfileController;
public profileCallbacks: ProfileCallbacks;
//#endregion
//#region Acceessible in or after postDBLoad
public database: IDatabaseTables;
public customItem: CustomItemService;
public imageRouter: ImageRouter;
public jsonUtil: JsonUtil;
public profileHelper: ProfileHelper;
public eventOutputHolder: EventOutputHolder;
public ragfairPriceService: RagfairPriceService;
public importerUtil: ImporterUtil;
public traderAssortService: TraderAssortService;
public applicationContext: ApplicationContext;
public vfs: VFS;
//#endregion
// Call at the start of the mods postDBLoad method
public preSptLoad(container: DependencyContainer, mod: string): void
{
this.modName = mod;
this.container = container;
this.PreSptModLoader = container.resolve<PreSptModLoader>("PreSptModLoader");
this.imageRouter = container.resolve<ImageRouter>("ImageRouter");
this.configServer = container.resolve<ConfigServer>("ConfigServer");
this.saveServer = container.resolve<SaveServer>("SaveServer");
this.itemHelper = container.resolve<ItemHelper>("ItemHelper");
this.eventOutputHolder = container.resolve<EventOutputHolder>("EventOutputHolder");
this.profileController = container.resolve<ProfileController>("ProfileController");
this.profileCallbacks = container.resolve<ProfileCallbacks>("ProfileCallbacks");
this.logger = container.resolve<ILogger>("WinstonLogger");
this.staticRouter = container.resolve<StaticRouterModService>("StaticRouterModService");
this.dynamicRouter = container.resolve<DynamicRouterModService>("DynamicRouterModService");
this.traderAssortService = container.resolve<TraderAssortService>("TraderAssortService");
this.vfs = container.resolve<VFS>("VFS");
}
public postDBLoad(container: DependencyContainer): void
{
this.database = container.resolve<DatabaseServer>("DatabaseServer").getTables();
this.customItem = container.resolve<CustomItemService>("CustomItemService");
this.jsonUtil = container.resolve<JsonUtil>("JsonUtil");
this.profileHelper = container.resolve<ProfileHelper>("ProfileHelper");
this.ragfairPriceService = container.resolve<RagfairPriceService>("RagfairPriceService");
this.importerUtil = container.resolve<ImporterUtil>("ImporterUtil");
this.applicationContext = container.resolve<ApplicationContext>("ApplicationContext");
}
public colorLog(message: string, color: string) {
const colorCodes = {
red: "\x1b[31m",
green: "\x1b[32m",
yellow: "\x1b[33m",
blue: "\x1b[34m",
magenta: "\x1b[35m",
cyan: "\x1b[36m",
white: "\x1b[37m",
gray: "\x1b[90m",
brightRed: "\x1b[91m",
brightGreen: "\x1b[92m",
brightYellow: "\x1b[93m",
brightBlue: "\x1b[94m",
brightMagenta: "\x1b[95m",
brightCyan: "\x1b[96m",
brightWhite: "\x1b[97m"
};
const resetCode = "\x1b[0m";
const colorCode = colorCodes[color as keyof typeof colorCodes] || "\x1b[37m"; // Default to white if color is invalid.
console.log(`${colorCode}${message}${resetCode}`); // Log the colored message here
}
}
@@ -0,0 +1,94 @@
/* eslint-disable @typescript-eslint/naming-convention */
import fs from "node:fs";
import path from "node:path";
import type { DependencyContainer } from "tsyringe";
import type { IPostDBLoadMod } from "@spt/models/external/IPostDBLoadMod";
import type { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod";
import { LogTextColor } from "@spt/models/spt/logging/LogTextColor";
// WTT imports
import { WTTInstanceManager } from "./WTTInstanceManager";
// Boss imports
import { CustomItemService } from "./CustomItemService";
// Custom Trader Assort Items
import { CustomAssortSchemeService } from "./CustomAssortSchemeService";
class WTTArmoryAk5C
implements IPreSptLoadMod, IPostDBLoadMod
{
private instanceManager: WTTInstanceManager = new WTTInstanceManager();
private version: string;
private modName = "WTTArmoryAk5C";
private customItemService: CustomItemService = new CustomItemService();
private customAssortSchemeService: CustomAssortSchemeService = new CustomAssortSchemeService();
debug = false;
// Anything that needs done on preSptLoad, place here.
public preSptLoad(container: DependencyContainer): void
{
// Initialize the instance manager DO NOTHING ELSE BEFORE THIS
this.instanceManager.preSptLoad(container, this.modName);
this.instanceManager.debug = this.debug;
// EVERYTHING AFTER HERE MUST USE THE INSTANCE
this.getVersionFromJson();
this.displayCreditBanner();
this.customItemService.preSptLoad(this.instanceManager);
this.customAssortSchemeService.preSptLoad(this.instanceManager);
}
// Anything that needs done on postDBLoad, place here.
postDBLoad(container: DependencyContainer): void
{
// Initialize the instance manager DO NOTHING ELSE BEFORE THIS
this.instanceManager.postDBLoad(container);
// EVERYTHING AFTER HERE MUST USE THE INSTANCE
this.customItemService.postDBLoad();
this.customAssortSchemeService.postDBLoad();
this.instanceManager.logger.log(
`[${this.modName}] Database: Loading complete.`,
LogTextColor.GREEN
);
}
private getVersionFromJson(): void
{
const packageJsonPath = path.join(__dirname, "../package.json");
fs.readFile(packageJsonPath, "utf-8", (err, data) =>
{
if (err)
{
console.error("Error reading file:", err);
return;
}
const jsonData = JSON.parse(data);
this.version = jsonData.version;
});
}
private displayCreditBanner(): void
{
this.instanceManager.colorLog
(`[${this.modName}] Developers: Tron, MoxoPixel, and the WTT Team
Swede dreams are made of this`, "green");
}
}
module.exports = { mod: new WTTArmoryAk5C() };
@@ -0,0 +1,296 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { IPreset } from "@spt/models/eft/common/IGlobals";
import type { Ixyz } from "@spt/models/eft/common/Ixyz";
import type { IPrefab } from "@spt/models/eft/common/tables/ICustomizationItem";
export interface ConfigItem
{
[itemId: string]: {
itemTplToClone: string;
overrideProperties: {
Prefab: {
path: string;
rcid: string;
};
ReverbVolume: number;
};
parentId: string;
fleaPriceRoubles: number;
handbookPriceRoubles: number;
handbookParentId: string;
locales: {
[locale: string]: {
name: string;
shortName: string;
description: string;
};
};
clearClonedProps: boolean;
addtoInventorySlots: string[];
addtoModSlots: boolean;
modSlot: string[];
ModdableItemWhitelist: string;
ModdableItemBlacklist: string;
addtoTraders: boolean;
traderId: traderIDs;
traderItems: {
unlimitedCount: boolean;
stackObjectsCount: number;
}[];
barterScheme: {
count: number;
_tpl: string;
}[];
loyallevelitems: number;
addtoBots: boolean;
addtoStaticLootContainers: boolean;
StaticLootContainers: string;
Probability: number;
masteries: boolean;
masterySections: {
Name: string;
Templates: string[];
Level2: number;
Level3: number;
};
addweaponpreset: boolean;
weaponpresets: IPreset[];
addtoHallOfFame: boolean;
addtoSpecialSlots: boolean;
};
};
export interface HeadConfig {
path: string;
addHeadToPlayer: boolean;
side: string[];
locales: {
[key: string]: string; // This allows dynamic locale keys, such as "en", "ru", etc.
};
}
export interface VoiceConfig
{
[voiceId: string]: {
locales: {
[key: string]: string; // This allows dynamic locale keys, such as "en", "ru", etc.
};
name: string;
addVoiceToPlayer: boolean;
sideSpecificVoice: string;
addToBotTypes: Record<string, number>;
};
}
export interface ClothingConfig {
type: string; // The type of clothing item, e.g., "bottom"
suiteId: string; // ID of the clothing item's suite
outfitId: string; // Unique identifier for the outfit
bottomId?: string; // ID of the clothing item's bottom
locales: {
[key: string]: string; // This allows dynamic locale keys, such as "en", "ru", etc.
};
topId?: string; // ID of the clothing item's top
handsId?: string; // ID of the clothing item's hands
side: string[]; // Side of the clothing item, e.g., ["usec", "bear"]
bottomBundlePath?: string; // Path to the clothing item's asset bundle
topBundlePath?: string; // Path to the clothing item's top asset bundle
handsBundlePath?: string; // Path to the clothing item's hands asset bundle
watchPrefab?: IPrefab; // Path to the watch prefab asset bundle
watchPosition?: Ixyz; // Position of the watch on the clothing item
watchRotation?: Ixyz; // Rotation of the watch on the clothing item
handsBaseID?: string; // ID of the clothing item's hands base
traderId: string; // Trader who sells this item, e.g., "RAGMAN"
loyaltyLevel: number; // Loyalty level required to purchase the item
profileLevel: number; // Player profile level required to purchase the item
standing: number; // Minimum standing required with the trader
currencyId: string; // Currency type for the item's price, e.g., "ROUBLES"
price: number; // Cost of the clothing item in the specified currency
}
export enum traderIDs
{
MECHANIC = "5a7c2eca46aef81a7ca2145d",
SKIER = "58330581ace78e27b8b10cee",
PEACEKEEPER = "5935c25fb3acc3127c3d8cd9",
THERAPIST = "54cb57776803fa99248b456e",
PRAPOR = "54cb50c76803fa8b248b4571",
JAEGAR = "5c0647fdd443bc2504c2d371",
RAGMAN = "5ac3b934156ae10c4430e83c",
FENCE = "579dc571d53a0658a154fbec",
BADGER = "bd3a8b28356d9c6509966546"
}
export enum currencyIDs
{
ROUBLES = "5449016a4bdc2d6f028b456f",
EUROS = "569668774bdc2da2298b4568",
DOLLARS = "5696686a4bdc2da3298b456a"
}
export enum allBotTypes
{
// Arena Fighters
ARENAFIGHTER = "arenafighter",
ARENAFIGHTEREVENT = "arenafighterevent",
// Scavs
ASSAULT = "assault",
ASSAULTGROUP = "assaultgroup",
MARKSMAN = "marksman",
CRAZYASSAULTEVENT = "crazyassaultevent",
CURSEDASSAULT = "cursedassault",
// PMC's
BEAR = "bear",
USEC = "usec",
PMCBEAR = "pmcbear",
PMCUSEC = "pmcusec",
PMC = "pmcbot",
// ExUsec
EXUSEC = "exusec",
// Cultists
CULTISTPRIEST = "sectantpriest",
CULTISTWARRIOR = "sectantwarrior",
CULTISTONI = "sectantoni",
CULTISTPRIESTEVENT = "sectantpriestevent",
CULTISTPREDVESTNIK = "sectantpredvestnik",
CULTISTPRIZRAK = "sectantprizrak",
// BTR
BTR = "btrshooter",
// Spirits
SPIRITSPRING = "spiritspring",
SPIRITWINTER = "spiritwinter",
// Zombies
INFECTEDASSAULT = "infectedassault",
INFECTEDCIVIL = "infectedcivil",
INFECTEDLABORANT = "infectedlaborant",
INFECTEDPMC = "infectedpmc",
INFECTEDTAGILLA = "infectedtagilla",
// Santa
GIFTER = "gifter",
// Bosses & Followers
// Kaban
KABAN = "bossboar",
KABANSNIPER = "bossboarsniper",
FOLLOWERBOAR = "followerboar",
FOLLOWERBOARCLOSE1 = "followerboarclose1",
FOLLOWERBOARCLOSE2 = "followerboarclose2",
// Killa
KILLA = "bosskilla",
// Kolontay
KOLONTAY = "bosskolontay",
FOLLOWERKOLONTAYASSAULT = "followerkolontayassault",
FOLLOWERKOLONTAYSECURITY = "followerkolontaysecurity",
// Partisan
PARTISAN = "bosspartisan",
// Reshala
RESHALA = "bossbully",
FOLLOWERRESHALA = "followerbully",
// Gluhar
GLUHAR = "bossgluhar",
FOLLOWERGLUHARASSAULT = "followergluharassault",
FOLLOWERGLUHARSCOUT = "followergluharscout",
FOLLOWERGLUHARSECURITY = "followergluharsecurity",
FOLLOWERGLUHARSNIPER = "followergluharsnipe",
// Goons
KNIGHT = "bossknight",
FOLLOWERBIGPIPE = "followerbigpipe",
FOLLOWERBIRDEYE = "followerbirdeye",
// Shturman
SHTURMAN = "bosskojaniy",
FOLLOWERSHTURMAN = "followerkojaniy",
// Sanitar
SANITAR = "bosssanitar",
FOLLOWERSANITAR = "followersanitar",
// Tagilla
TAGILLA = "bosstagilla",
FOLLOWERTAGILLA = "followertagilla",
// Zryachiy
ZRYACHIY = "bosszryachiy",
FOLLOWERZRYACHIY = "followerzryachiy",
PEACEFULZRYACHIYEVENT = "peacefulzryachiyevent",
RAVANGEZRYACHIYEVENT = "ravengezryachiyevent",
// Traders
// Peacemaker
PEACEMAKER = "peacemaker",
// Skier
SKIER = "skier",
}
export enum inventorySlots
{
FirstPrimaryWeapon = "55d729c64bdc2d89028b4570",
SecondPrimaryWeapon = "55d729d14bdc2d86028b456e",
Holster = "55d729d84bdc2de3098b456b",
Scabbard = "55d729e34bdc2d1b198b456d",
FaceCover = "55d729e84bdc2d8a028b4569",
Headwear = "55d729ef4bdc2d3a168b456c",
TacticalVest = "55d729f74bdc2d87028b456e",
SecuredContainer = "55d72a054bdc2d88028b456e",
Backpack = "55d72a104bdc2d89028b4571",
ArmorVest = "55d72a194bdc2d86028b456f",
Pockets = "55d72a274bdc2de3098b456c",
Earpiece = "5665b7164bdc2d144c8b4570",
Dogtag = "59f0be1e86f77453be490939",
Eyewear = "5a0ad9313f1241000e072755",
ArmBand = "5b3f583786f77411d552fb2b"
}
export enum Stashes
{
LEVEL1 = "566abbc34bdc2d92178b4576",
LEVEL2 = "5811ce572459770cba1a34ea",
LEVEL3 = "5811ce662459770f6f490f32",
LEVEL4 = "5811ce772459770e9e5f9532"
}
export interface QuestZone
{
zoneId: string;
zoneName: string;
zoneType: string;
flareType?: string;
zoneLocation: string;
position: {
x: string;
y: string;
z: string;
};
rotation: {
x: string;
y: string;
z: string;
};
scale: {
x: string;
y: string;
z: string;
};
}
@@ -0,0 +1,79 @@
export const ItemBaseClassMap: { [itemName: string]: string } = {
"AMMO": "5485a8684bdc2da71d8b4567",
"AMMO_CONTAINER": "543be5cb4bdc2deb348b4568",
"ARMORED_EQUIPMENT": "57bef4c42459772e8d35a53b",
"ARMBAND": "5b3f15d486f77432d0509248",
"ARMOR": "5448e54d4bdc2dcc718b4568",
"ARMORPLATE": "644120aa86ffbe10ee032b6f",
"ASSAULT_CARBINE": "5447b5fc4bdc2d87278b4567",
"ASSAULT_RIFLE": "5447b5f14bdc2d61278b4567",
"ASSAULT_SCOPE": "55818add4bdc2d5b648b456f",
"BACKPACK": "5448e53e4bdc2d60728b4567",
"BARREL": "555ef6e44bdc2de9068b457e",
"BATTERY": "57864ee62459775490116fc1",
"BIPOD": "55818afb4bdc2dde698b456d",
"BUILDING_MATERIAL": "57864ada245977548638de91",
"CHARGING_HANDLE": "55818a6f4bdc2db9688b456b",
"CHEST_RIG": "5448e5284bdc2dcb718b4567",
"COMMON_CONTAINER": "5795f317245977243854e041",
"COMPACT_REFLEX_SIGHT": "55818acf4bdc2dde698b456b",
"COMPASS": "5f4fbaaca5573a5ac31db429",
"DRINK": "5448e8d64bdc2dce718b4568",
"DRUG": "5448f3a14bdc2d27728b4569",
"ELECTRONICS": "57864a66245977548f04a81f",
"FACECOVER": "5a341c4686f77469e155819e",
"FLASHLIGHT": "55818b084bdc2d5b648b4571",
"FLASHHIDER": "550aa4bf4bdc2dd6348b456b",
"FOOD": "5448e8d04bdc2ddf718b4569",
"FOREGRIP": "55818af64bdc2d5b648b4570",
"FUEL": "5d650c3e815116009f6201d2",
"GAS_BLOCK": "56ea9461d2720b67698b456f",
"GRENADE_LAUNCHER": "5447bedf4bdc2d87278b4568",
"HANDGUN": "5447b5cf4bdc2d65278b4567",
"HANDGUARD": "55818a104bdc2db9688b4569",
"HEADPHONES": "5645bcb74bdc2ded0b8b4578",
"HEADWEAR": "5a341c4086f77401f2541505",
"INFO": "5448ecbe4bdc2d60728b4568",
"INVENTORY": "55d720f24bdc2d88028b456d",
"IRON_SIGHT": "55818ac54bdc2d5b648b456e",
"KEYCARD": "5c164d2286f774194c5e69fa",
"KEYMECHANICAL": "5c99f98d86f7745c314214b3",
"KEY_CARD": "5c164d2286f774194c5e69fa",
"KNIFE": "5447e1d04bdc2dff2f8b4567",
"LOCKING_CONTAINER": "5671435f4bdc2d96058b4569",
"LOOT_CONTAINER": "566965d44bdc2d814c8b4571",
"LUBRICANT": "57864e4c24597754843f8723",
"MACHINEGUN": "5447bed64bdc2d97278b4568",
"MAGAZINE": "5448bc234bdc2d3c308b4569",
"MAP": "567849dd4bdc2d150f8b456e",
"MARKSMAN_RIFLE": "5447b6194bdc2d67278b4567",
"MEDICAL_ITEM": "5448f3ac4bdc2dce718b4569",
"MEDICAL_SUPPLIES": "57864c8c245977548867e7f1",
"MEDITKIT": "5448f39d4bdc2d0a728b4568",
"MONEY": "543be5dd4bdc2deb348b4569",
"MUZZLECOMBO": "550aa4dd4bdc2dc9348b4569",
"MOUNT": "55818b224bdc2dde698b456f",
"NIGHTVISION": "5a2c3a9486f774688b05e574",
"OTHER": "590c745b86f7743cc433c5f2",
"PISTOLGRIP": "55818a684bdc2ddd698b456d",
"POCKETS": "557596e64bdc2dc2118b4571",
"PORTABLE_RANGEFINDER": "61605ddea09d851a0a0c1bbc",
"RANDOMLOOTCONTAINER": "62f109593b54472778797866",
"RECEIVER": "55818a304bdc2db5418b457d",
"REFLEX_SIGHT": "55818ad54bdc2ddc698b4569",
"REPAIRKITS": "616eb7aea207f41933308f46",
"SCOPE": "55818ae44bdc2dde698b456c",
"SHOTGUN": "5447b6094bdc2dc3278b4567",
"SILENCER": "550aa4cd4bdc2dd8348b456c",
"SNIPER_RIFLE": "5447b6254bdc2dc3278b4568",
"SPECIAL_ITEM": "5447e0e74bdc2d3c308b4567",
"STASH": "566abbb64bdc2d144c8b457d",
"STATIONARY_CONT.": "567583764bdc2d98058b456e",
"STIMULANT": "5448f3a64bdc2d60728b456a",
"STOCK": "55818a594bdc2db9688b456a",
"THROWABLE_WEAPON": "543be6564bdc2df4348b4568",
"THERMALVISION": "5d21f59b6dbe99052b54ef83",
"TOOL": "57864bb7245977548b3b66c2",
"UBGL": "55818b014bdc2ddc698b456b",
"VIS_OBSERV_DEVICE": "5448e5724bdc2ddf718b4568",
};
@@ -0,0 +1,81 @@
export const ItemHandbookCategoryMap: { [itemName: string]: string } = {
"AMMO": "5b47574386f77428ca22b346",
"AMMO_BOXES": "5b47574386f77428ca22b33c",
"AMMO_ROUNDS": "5b47574386f77428ca22b33b",
"BARTER": "5b47574386f77428ca22b33e",
"BARTER_BUILDING": "5b47574386f77428ca22b2ee",
"BARTER_ELECTRONICS": "5b47574386f77428ca22b2ef",
"BARTER_ENERGY": "5b47574386f77428ca22b2ed",
"BARTER_FLAMMABLE": "5b47574386f77428ca22b2f2",
"BARTER_HOUSEHOLD": "5b47574386f77428ca22b2f0",
"BARTER_MEDICAL": "5b47574386f77428ca22b2f3",
"BARTER_OTHERS": "5b47574386f77428ca22b2f4",
"BARTER_TOOLS": "5b47574386f77428ca22b2f6",
"BARTER_VALUABLES": "5b47574386f77428ca22b2f1",
"GEAR": "5b47574386f77428ca22b33f",
"GEAR_ARMOR": "5b5f701386f774093f2ecf0f",
"GEAR_BACKPACKS": "5b5f6f6c86f774093f2ecf0b",
"GEAR_CASES": "5b5f6fa186f77409407a7eb7",
"GEAR_COMPONENTS": "5b5f704686f77447ec5d76d7",
"GEAR_FACECOVERS": "5b47574386f77428ca22b32f",
"GEAR_HEADSETS": "5b5f6f3c86f774094242ef87",
"GEAR_HEADWEAR": "5b47574386f77428ca22b330",
"GEAR_RIGS": "5b5f6f8786f77447ed563642",
"GEAR_SECURED": "5b5f6fd286f774093f2ecf0d",
"GEAR_VISORS": "5b47574386f77428ca22b331",
"INFO": "5b47574386f77428ca22b341",
"KEYS": "5b47574386f77428ca22b342",
"KEYS_ELECTRONIC": "5c518ed586f774119a772aee",
"KEYS_MECHANIC": "5c518ec986f7743b68682ce2",
"MAPS": "5b47574386f77428ca22b343",
"MEDICAL": "5b47574386f77428ca22b344",
"MEDICAL_INJECTORS": "5b47574386f77428ca22b33a",
"MEDICAL_INJURY": "5b47574386f77428ca22b339",
"MEDICAL_MEDKITS": "5b47574386f77428ca22b338",
"MEDICAL_PILLS": "5b47574386f77428ca22b337",
"MODS": "5b5f71a686f77447ed5636ab",
"MODS_FUNCTIONAL": "5b5f71b386f774093f2ecf11",
"MODS_GEAR": "5b5f750686f774093e6cb503",
"MODS_VITAL": "5b5f75b986f77447ec5d7710",
"MOD_ASSAULT_SCOPE": "5b5f740a86f77447ec5d7706",
"MOD_AUX": "5b5f74cc86f77447ec5d770a",
"MOD_BARREL": "5b5f75c686f774094242f19f",
"MOD_BIPOD": "5b5f71c186f77409407a7ec0",
"MOD_CHARGE": "5b5f751486f77447ec5d770c",
"MOD_FLASHHIDER": "5b5f724c86f774093f2ecf15",
"MOD_FOREGRIP": "5b5f71de86f774093f2ecf13",
"MOD_GASBLOCK": "5b5f760586f774093e6cb509",
"MOD_HANDGUARD": "5b5f75e486f77447ec5d7712",
"MOD_IRON_SIGHT": "5b5f746686f77447ec5d7708",
"MOD_LAUNCHER": "5b5f752e86f774093e6cb505",
"MOD_LIGHTLASER": "5b5f736886f774094242f193",
"MOD_MAGAZINE": "5b5f754a86f774094242f19b",
"MOD_MOUNT": "5b5f755f86f77447ec5d770e",
"MOD_MICRO_DOT": "5b5f744786f774094242f197",
"MOD_MUZZLE": "5b5f724186f77447ed5636ad",
"MOD_OPTIC": "5b5f748386f774093e6cb501",
"MOD_PISTOLGRIP": "5b5f761f86f774094242f1a1",
"MOD_RECEIVER": "5b5f764186f77447ec5d7714",
"MOD_SIGHT": "5b5f73ec86f774093e6cb4fd",
"MOD_STOCK": "5b5f757486f774093e6cb507",
"MOD_SUPPRESSOR": "5b5f731a86f774093e6cb4f9",
"MONEY": "5b5f78b786f77447ed5636af",
"PROVISIONS": "5b47574386f77428ca22b340",
"PROVISIONS_DRINKS": "5b47574386f77428ca22b335",
"PROVISIONS_FOOD": "5b47574386f77428ca22b336",
"QUEST": "5b619f1a86f77450a702a6f3",
"SPEC": "5b47574386f77428ca22b345",
"WEAPONS": "5b5f78dc86f77409407a7f8e",
"WEAPONS_ASSAULTRIFLES": "5b5f78fc86f77409407a7f90",
"WEAPONS_BOLTACTION": "5b5f798886f77447ed5636b5",
"WEAPONS_CARBINES": "5b5f78e986f77447ed5636b1",
"WEAPONS_DMR": "5b5f791486f774093f2ed3be",
"WEAPONS_GL": "5b5f79d186f774093f2ed3c2",
"WEAPONS_MG": "5b5f79a486f77409407a7f94",
"WEAPONS_MELEE": "5b5f7a0886f77409407a7f96",
"WEAPONS_PISTOLS": "5b5f792486f77447ed5636b3",
"WEAPONS_SHOTGUNS": "5b5f794b86f77409407a7f92",
"WEAPONS_SMG": "5b5f796a86f774093f2ed3c0",
"WEAPONS_SPECIAL": "5b5f79eb86f77447ed5636b7",
"WEAPONS_THROW": "5b5f7a2386f774093f2ed3c4",
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
© 2024 SSH_ All Rights Reserved.
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.16.0
newestVersion=
category="-1,"
nexusFileStatus=1
installationFile=AlphaRestorations.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-16T07:07:13Z
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
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.16.0
newestVersion=
category="2,"
nexusFileStatus=1
installationFile=AmandsGraphics.1.6.5.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-16T06:48:35Z
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
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.21.0
newestVersion=
category="1,2"
nexusFileStatus=1
installationFile=choccy-striker-1.0.5.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-22T04:01:36Z
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
@@ -0,0 +1,67 @@
{
"manifest": [
{
"key": "assets/weapons/striker12/client_assets.bundle",
"dependencyKeys": [
"shaders",
"cubemaps",
"assets/weapons/striker12/textures.bundle"
]
},
{
"key": "assets/weapons/striker12/weapon_striker_12_container.bundle",
"dependencyKeys": [
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"assets/weapons/striker12/client_assets.bundle",
"assets/weapons/striker12/striker12_bank.bundle",
"assets/content/audio/weapons/generic"
]
},
{
"key": "assets/weapons/striker12/striker12_bank.bundle",
"dependencyKeys": [
"assets/content/audio/blendoptions/assets.bundle"
]
},
{
"key": "assets/weapons/striker12/textures.bundle",
"dependencyKeys": [
]
},
{
"key": "assets/weapons/striker12/mod_stock_foldable_striker_12.bundle",
"dependencyKeys": [
"assets/weapons/striker12/client_assets.bundle"
]
},
{
"key": "assets/weapons/striker12/mod_mount_piccatiny_rail_striker_12.bundle",
"dependencyKeys": [
"assets/weapons/striker12/client_assets.bundle"
]
},
{
"key": "assets/weapons/striker12/mod_magazine_striker_12.bundle",
"dependencyKeys": [
"assets/weapons/striker12/client_assets.bundle"
]
},
{
"key": "assets/weapons/striker12/mod_front_sight_striker_12.bundle",
"dependencyKeys": [
"assets/weapons/striker12/client_assets.bundle"
]
},
{
"key": "assets/weapons/striker12/mod_rear_sight_striker_12.bundle",
"dependencyKeys": [
"assets/weapons/striker12/client_assets.bundle"
]
}
]
}
@@ -0,0 +1,30 @@
{
"name": "Striker",
"version": "1.0.5",
"main": "src/mod.js",
"license": "CC-BY 3.0",
"author": "Choccy",
"isBundleMod": true,
"sptVersion": "~3.10",
"loadBefore": [],
"loadAfter": [],
"incompatibilities": [],
"contributors": [],
"scripts": {
"setup": "npm i",
"build": "node ./build.mjs",
"buildinfo": "node ./build.mjs --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"
}
}
@@ -0,0 +1,72 @@
#!/usr/bin/env node
// This is a simple script used to build a mod package. The script will copy necessary files to the build directory
// and compress the build directory into a zip file that can be easily shared.
const fs = require("fs-extra");
const glob = require("glob");
const zip = require('bestzip');
const path = require("path");
// Load the package.json file to get some information about the package so we can name things appropriately. This is
// atypical, and you would never do this in a production environment, but this script is only used for development so
// it's fine in this case. Some of these values are stored in environment variables, but those differ between node
// versions; the 'author' value is not available after node v14.
const { author, name:packageName, version } = require("./package.json");
// Generate the name of the package, stripping out all non-alphanumeric characters in the 'author' and 'name'.
const modName = `${author.replace(/[^a-z0-9]/gi, "")}-${packageName.replace(/[^a-z0-9]/gi, "")}-${version}`;
console.log(`Generated package name: ${modName}`);
// Delete the old build directory and compressed package file.
fs.rmSync(`${__dirname}/dist`, { force: true, recursive: true });
console.log("Previous build files deleted.");
// Generate a list of files that should not be copied over into the distribution directory. This is a blacklist to ensure
// we always copy over additional files and directories that authors may have added to their project. This may need to be
// expanded upon by the mod author to allow for node modules that are used within the mod; example commented out below.
const ignoreList = [
"node_modules/",
// "node_modules/!(weighted|glob)", // Instead of excluding the entire node_modules directory, allow two node modules.
"src/**/*.js",
"types/",
".git/",
".gitea/",
".eslintignore",
".eslintrc.json",
".gitignore",
".DS_Store",
"packageBuild.ts",
"mod.code-workspace",
"package-lock.json",
"tsconfig.json"
];
const exclude = glob.sync(`{${ignoreList.join(",")}}`, { realpath: true, dot: true });
// For some reason these basic-bitch functions won't allow us to copy a directory into itself, so we have to resort to
// using a temporary directory, like an idiot. Excuse the normalize spam; some modules cross-platform, some don't...
fs.copySync(__dirname, path.normalize(`${__dirname}/../~${modName}`), {filter:(filePath) =>
{
return !exclude.includes(filePath);
}});
fs.moveSync(path.normalize(`${__dirname}/../~${modName}`), path.normalize(`${__dirname}/${modName}`), { overwrite: true });
fs.copySync(path.normalize(`${__dirname}/${modName}`), path.normalize(`${__dirname}/dist`));
console.log("Build files copied.");
// Compress the files for easy distribution. The compressed file is saved into the dist directory. When uncompressed we
// need to be sure that it includes a directory that the user can easily copy into their game mods directory.
zip({
source: modName,
destination: `dist/${modName}.zip`,
cwd: __dirname
}).catch(function(err)
{
console.error("A bestzip error has occurred: ", err.stack);
}).then(function()
{
console.log(`Compressed mod package to: /dist/${modName}.zip`);
// Now that we're done with the compression we can delete the temporary build directory.
fs.rmSync(`${__dirname}/${modName}`, { force: true, recursive: true });
console.log("Build successful! your zip file has been created and is ready to be uploaded to hub.sp-tarkov.com/files/");
});
@@ -0,0 +1,177 @@
{
"items": [
{
"_id": "668c697ec56e7663bf2f1005",
"_tpl": "668c68adb49c8d5089331ec9",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"UnlimitedCount": true,
"StackObjectsCount": 9999,
"FireMode": {
"FireMode": "single"
}
}
},
{
"_id": "e3ef88f46d8e285227cffe45",
"_tpl": "668c68b1e0d0f96066595fa2",
"parentId": "668c697ec56e7663bf2f1005",
"slotId": "mod_magazine"
},
{
"_id": "a702db60f496efd45f8e9483",
"_tpl": "668c68b33a252358c049a4c8",
"parentId": "668c697ec56e7663bf2f1005",
"slotId": "mod_stock"
},
{
"_id": "655e58f4b381ee68321dd08c",
"_tpl": "668c68aa2e09beec5a6e9154",
"parentId": "668c697ec56e7663bf2f1005",
"slotId": "mod_mount"
},
{
"_id": "00db83f6f4337583dfc1fa4d",
"_tpl": "668c68b67096754b726a9734",
"parentId": "668c697ec56e7663bf2f1005",
"slotId": "mod_sight_front",
"upd": {
"Sight": {
"ScopesCurrentCalibPointIndexes": [
0
],
"ScopesSelectedModes": [
0
],
"SelectedScope": 0
}
}
},
{
"_id": "2854917141d662e500787806",
"_tpl": "668c68b90986da08fccc3b88",
"parentId": "655e58f4b381ee68321dd08c",
"slotId": "mod_sight_rear",
"upd": {
"Sight": {
"ScopesCurrentCalibPointIndexes": [
0
],
"ScopesSelectedModes": [
0
],
"SelectedScope": 0
}
}
},
{
"_id": "668c69b6c986e289e9c1f4b1",
"_tpl": "668c68b1e0d0f96066595fa2",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"UnlimitedCount": true,
"StackObjectsCount": 9999
}
},
{
"_id": "668c69bc007d83bcac51cd44",
"_tpl": "668c68b33a252358c049a4c8",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"UnlimitedCount": true,
"StackObjectsCount": 9999
}
},
{
"_id": "668c69c0532752d86230b1c8",
"_tpl": "668c68aa2e09beec5a6e9154",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"UnlimitedCount": true,
"StackObjectsCount": 9999
}
},
{
"_id": "668c69c481b7ccb3b40a0260",
"_tpl": "668c68b67096754b726a9734",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"UnlimitedCount": true,
"StackObjectsCount": 9999
}
},
{
"_id": "668c69c8b08861ab464577d6",
"_tpl": "668c68b90986da08fccc3b88",
"parentId": "hideout",
"slotId": "hideout",
"upd": {
"UnlimitedCount": true,
"StackObjectsCount": 9999
}
}
],
"barter_scheme": {
"668c697ec56e7663bf2f1005": [
[
{
"_tpl": "5449016a4bdc2d6f028b456f",
"count": 23165
}
]
],
"668c69b6c986e289e9c1f4b1": [
[
{
"_tpl": "5449016a4bdc2d6f028b456f",
"count": 3341
}
]
],
"668c69bc007d83bcac51cd44": [
[
{
"_tpl": "5449016a4bdc2d6f028b456f",
"count": 9621
}
]
],
"668c69c0532752d86230b1c8": [
[
{
"_tpl": "5449016a4bdc2d6f028b456f",
"count": 8754
}
]
],
"668c69c481b7ccb3b40a0260": [
[
{
"_tpl": "5449016a4bdc2d6f028b456f",
"count": 871
}
]
],
"668c69c8b08861ab464577d6": [
[
{
"_tpl": "5449016a4bdc2d6f028b456f",
"count": 871
}
]
]
},
"loyal_level_items":{
"668c697ec56e7663bf2f1005": 1,
"668c69b6c986e289e9c1f4b1": 1,
"668c69bc007d83bcac51cd44": 1,
"668c69c0532752d86230b1c8": 1,
"668c69c481b7ccb3b40a0260": 1,
"668c69c8b08861ab464577d6": 1
}
}
@@ -0,0 +1,75 @@
{
"ItemPresets": {
"65f59db05d59d765e8cef3d7": {
"_changeWeaponName": false,
"_encyclopedia": "668c68adb49c8d5089331ec9",
"_id": "65f59db05d59d765e8cef3d7",
"_items": [
{
"_id": "65f59dbd1da2c4564a057192",
"_tpl": "668c68adb49c8d5089331ec9",
"upd": {
"FireMode": {
"FireMode": "single"
}
}
},
{
"_id": "e3ef88f46d8e285227cffe45",
"_tpl": "668c68b1e0d0f96066595fa2",
"parentId": "65f59dbd1da2c4564a057192",
"slotId": "mod_magazine"
},
{
"_id": "a702db60f496efd45f8e9483",
"_tpl": "668c68b33a252358c049a4c8",
"parentId": "65f59dbd1da2c4564a057192",
"slotId": "mod_stock"
},
{
"_id": "655e58f4b381ee68321dd08c",
"_tpl": "668c68aa2e09beec5a6e9154",
"parentId": "65f59dbd1da2c4564a057192",
"slotId": "mod_mount"
},
{
"_id": "00db83f6f4337583dfc1fa4d",
"_tpl": "668c68b67096754b726a9734",
"parentId": "65f59dbd1da2c4564a057192",
"slotId": "mod_sight_front",
"upd": {
"Sight": {
"ScopesCurrentCalibPointIndexes": [
0
],
"ScopesSelectedModes": [
0
],
"SelectedScope": 0
}
}
},
{
"_id": "2854917141d662e500787806",
"_tpl": "668c68b90986da08fccc3b88",
"parentId": "655e58f4b381ee68321dd08c",
"slotId": "mod_sight_rear",
"upd": {
"Sight": {
"ScopesCurrentCalibPointIndexes": [
0
],
"ScopesSelectedModes": [
0
],
"SelectedScope": 0
}
}
}
],
"_name": "Armsel Striker",
"_parent": "65f59dbd1da2c4564a057192",
"_type": "Preset"
}
}
}
@@ -0,0 +1,735 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mod = exports.WeapID = void 0;
const ItemTpl_1 = require("C:/snapshot/project/obj/models/enums/ItemTpl");
const Traders_1 = require("C:/snapshot/project/obj/models/enums/Traders");
const Item_Preset_json_1 = __importDefault(require("../src/Item_Preset.json"));
const global_item_preset_json_1 = __importDefault(require("../src/global_item_preset.json"));
var WeapID;
(function (WeapID) {
WeapID["MOUNT_STRIKER12_PICATINY"] = "668c68aa2e09beec5a6e9154";
WeapID["WEAP_STRIKER12"] = "668c68adb49c8d5089331ec9";
WeapID["MAG_STRIKER12"] = "668c68b1e0d0f96066595fa2";
WeapID["STOCK_STRIKER12"] = "668c68b33a252358c049a4c8";
WeapID["SIGHT_FRONT_STRIKER12"] = "668c68b67096754b726a9734";
WeapID["SIGHT_REAR_STRIKER12"] = "668c68b90986da08fccc3b88";
})(WeapID || (exports.WeapID = WeapID = {}));
class Mod {
postDBLoad(container) {
const customitem = container.resolve("CustomItemService");
const databaseserver = container.resolve("DatabaseServer");
const db = databaseserver.getTables();
const globals = db.globals;
const MC = db.traders[Traders_1.Traders.MECHANIC].assort;
//---WEAPON LISTING AND ATTACHMENT---
const Piccatiny_Mount = {
itemTplToClone: "591ee00d86f774592f7b841e",
overrideProperties: {
Weight: 0.036,
ExaminedByDefault: false,
RaidModdable: false,
Width: 2,
Prefab: {
path: "assets/weapons/striker12/mod_mount_piccatiny_rail_striker_12.bundle",
rcid: ""
},
Slots: [
{
"_id": "picatinny_mod_scope",
"_mergeSlotWithChildren": false,
"_name": "mod_scope",
"_parent": WeapID.MOUNT_STRIKER12_PICATINY,
"_props": {
"filters": [
{
"Filter": [
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"544a3f024bdc2d1d388b4568",
"544a3a774bdc2d3a388b4567",
"5d2dc3e548f035404a1a4798",
"57adff4f24597737f373b6e6",
"5c0517910db83400232ffee5",
"591c4efa86f7741030027726",
"570fd79bd2720bc7458b4583",
"570fd6c2d2720bc6458b457f",
"558022b54bdc2dac148b458d",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"58491f3324597764bc48fa02",
"584924ec24597768f12ae244",
"5b30b0dc5acfc400153b7124",
"6165ac8c290d254f5e6b2f6c",
"60a23797a37c940de7062d02",
"5d2da1e948f035477b1ce2ba",
"5c0505e00db834001b735073",
"609a63b6e2ff132951242d09",
"584984812459776a704a82a6",
"59f9d81586f7744c7506ee62",
"570fd721d2720bc5458b4596",
"57ae0171245977343c27bfcf",
"5d1b5e94d7ad1a2b865a96b0",
"609bab8b455afd752b2e6138",
"58d39d3d86f77445bb794ae7",
"616554fe50224f204c1da2aa",
"5c7d55f52e221644f31bff6a",
"616584766ef05c2ce828ef57",
"5b3b6dc75acfc47a8773fb1e",
"615d8d878004cc50514c3233",
"577d128124597739d65d0e56",
"5c064c400db834001d23f468",
"58d2664f86f7747fec5834f6",
"5c1cdd302e221602b3137250",
"61714b2467085e45ef140b2c",
"5b31163c5acfc400153b71cb",
"5a33b652c4a28232996e407c",
"5a33b2c9c4a282000c5a9511",
"59db7eed86f77461f8380365",
"5a1ead28fcdbcb001912fa9f",
"626bb8532c923541184624b4",
"63fc449f5bd61c6cf3784a88",
"6477772ea8a38bb2050ed4db",
"6478641c19d732620e045e17",
"64785e7c19d732620e045e15"
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
},
{
"_id": "picatinny_rear_sight",
"_mergeSlotWithChildren": false,
"_name": "mod_sight_rear",
"_parent": WeapID.MOUNT_STRIKER12_PICATINY,
"_props": {
"filters": [
{
"Filter": [
WeapID.SIGHT_REAR_STRIKER12,
"5bb20e49d4351e3bac1212de",
"5ba26b17d4351e00367f9bdd",
"5dfa3d7ac41b2312ea33362a",
"5c1780312e221602b66cc189",
"5fb6564947ce63734e3fa1da",
"5bc09a18d4351e003562b68e",
"5c18b9192e2216398b5a8104",
"5fc0fa957283c4046c58147e",
"5894a81786f77427140b8347",
"55d5f46a4bdc2d1b198b4567",
"5ae30bad5acfc400185c2dc4"
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
}
]
},
parentId: "55818b224bdc2dde698b456f",
newId: WeapID.MOUNT_STRIKER12_PICATINY,
handbookParentId: "5b5f755f86f77447ec5d770e",
handbookPriceRoubles: 6775,
fleaPriceRoubles: 9881,
locales: {
"en": {
name: "StrikeRail Picatinny Mount",
shortName: "SR-Picatinny Mount",
description: "A specialized accessory crafted specifically for the Armsel Striker shotgun, offering a wide range of optic customization options. This mount attaches securely to the shotgun's receiver, providing a standardized Picatinny rail interface. "
}
}
};
customitem.createItemFromClone(Piccatiny_Mount);
const striker_12 = {
itemTplToClone: "5a7828548dc32e5a9c28b516",
overrideProperties: {
Prefab: {
path: "assets/weapons/striker12/weapon_striker_12_container.bundle",
rcid: ""
},
aimingSensitivity: 0.54,
Width: 3,
Height: 2,
AllowFeed: false,
AllowJam: false,
AllowMisfire: false,
AllowSlide: false,
AimPlane: 0.05,
CenterOfImpact: 0.11,
shotgunDispersion: 1,
ShotgunDispersion: 1,
SingleFireRate: 500,
bFirerate: 500,
Velocity: 3.2,
DeviationMax: 8,
Ergonomics: 67,
isChamberLoad: true,
TacticalReloadFixation: 95,
TacticalReloadStiffnes: {
x: 0.85,
y: 0.80,
z: 0.95
},
ExaminedByDefault: false,
ExamineExperience: 18,
HeatFactorGun: 0.76,
IronSightRange: 50,
LootExperience: 25,
RecoilAngle: 87,
RecoilCenter: {
x: 0.007,
y: -0.26,
z: -0.068
},
RecoilForceUp: 520,
RecoilForceBack: 320,
RecoilCamera: 0.0087,
RecoilDampingHandRotation: 0.76,
RecoilReturnSpeedHandRotation: 4.75,
RecoilReturnPathDampingHandRotation: 0.47,
RecoilStableIndexShot: 6,
RecoilPosZMult: 1,
PostRecoilHorizontalRangeHandRotation: {
x: -2,
y: 0,
z: 0
},
PostRecoilVerticalRangeHandRotation: {
x: -2,
y: 1,
z: 0
},
RotationCenter: {
x: 0,
y: -0,
z: -0
},
RotationCenterNoStock: {
x: 0.007,
y: -0.26,
z: -0.068
},
Slots: [
{
"_id": "668c68c7a69b2dde82553d82",
"_mergeSlotWithChildren": false,
"_name": "mod_magazine",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"AnimationIndex": 0,
"Filter": [
WeapID.MAG_STRIKER12
]
}
]
},
"_proto": "55d30c394bdc2dae468b4577",
"_required": true
},
{
"_id": "668c68e88a65124cff33dbbf",
"_mergeSlotWithChildren": false,
"_name": "mod_stock",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
WeapID.STOCK_STRIKER12
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
},
{
"_id": "668c68f746bfb7ea6a7700c5",
"_mergeSlotWithChildren": false,
"_name": "mod_mount",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
WeapID.MOUNT_STRIKER12_PICATINY
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
},
{
"_id": "668c69275fc4527c8c0a9ddb",
"_mergeSlotWithChildren": false,
"_name": "mod_sight_front",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
WeapID.SIGHT_FRONT_STRIKER12
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
}
],
Weight: 4.2,
ammoCaliber: "Caliber12g",
defAmmo: "560d5e524bdc2d25448b4571",
defMagType: WeapID.MAG_STRIKER12,
durabSpawnMax: 100,
durabSpawnMin: 35,
weapFireType: ["single"]
},
parentId: "5447b6094bdc2dc3278b4567",
newId: WeapID.WEAP_STRIKER12,
handbookParentId: "5b5f794b86f77409407a7f92",
handbookPriceRoubles: 23665,
fleaPriceRoubles: 28775,
locales: {
"en": {
name: "Armsel Striker 12 Gauge Cylinder Shotgun",
shortName: "Striker 12",
description: "Armsel Striker, also known by its nickname the \"Street Swiper\", was developed Hilton R. Walker, a Zimbabwean (formerly Rhodesian) citizen, in 1981. The shotgun is designed for riot control and combat while featuring a revolving cylinder mechanism. His shotgun became a success and was exported to various parts of the world, despite some drawbacks. The rotary cylinder was bulky, had a long reload time, and the basic action was not without certain flaws."
}
}
};
customitem.createItemFromClone(striker_12);
const armsel_mag = {
itemTplToClone: ItemTpl_1.ItemTpl.MAGAZINE_12G_M870X4_4RND,
overrideProperties: {
Cartridges: [
{
"_id": "5a7882dcc5856700177af663",
"_max_count": 11,
"_name": "cartridges",
"_parent": WeapID.MAG_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845",
"64b8ee384b75259c590fa89b"
]
}
]
},
"_proto": "5748538b2459770af276a261"
}
],
ExaminedByDefault: false,
Ergonomics: -8,
Weight: 0.01,
ExamineExperience: 12,
Prefab: {
path: "assets/weapons/striker12/mod_magazine_striker_12.bundle",
rcid: ""
}
},
parentId: "5448bc234bdc2d3c308b4569",
newId: WeapID.MAG_STRIKER12,
handbookParentId: "5b5f754a86f774094242f19b",
handbookPriceRoubles: 2584,
fleaPriceRoubles: 3112,
locales: {
"en": {
name: "Armsel Striker 12-Round Cylinder Magazine",
shortName: "12-CM",
description: "A big and bulky internal revolving cylinder for the Armsel Striker. It can support up to 12 rounds (1 in chamber + 11 in magazine). It will take a while to reload such thing given the mechanism for it."
}
}
};
customitem.createItemFromClone(armsel_mag);
const striker_stock = {
itemTplToClone: "56083cba4bdc2de22e8b456f",
overrideProperties: {
Ergonomics: -10,
Weight: 0.33,
Width: 2,
Height: 1,
ExtraSizeRight: 1,
Recoil: -54,
ExamineExperience: 12,
Prefab: {
path: "assets/weapons/striker12/mod_stock_foldable_striker_12.bundle",
rcid: ""
},
ExaminedByDefault: false
},
parentId: "55818a594bdc2db9688b456a",
newId: WeapID.STOCK_STRIKER12,
handbookParentId: "5b5f757486f774093e6cb507",
handbookPriceRoubles: 2874,
fleaPriceRoubles: 3100,
locales: {
"en": {
name: "Armsel Striker Metal Stock",
shortName: "Striker Stock",
description: "A strong and robust metal stock fitted for the Armsel Striker. Provides good recoil control and stabilization, it can be a bit clunky with how long it is."
}
}
};
customitem.createItemFromClone(striker_stock);
const armsel_clamp_sight = {
itemTplToClone: "5bc09a30d4351e00367fb7c8",
overrideProperties: {
Ergonomics: -2,
Weight: 0.024,
Width: 1,
ConflictingItems: [
"570fd6c2d2720bc6458b457f",
"570fd79bd2720bc7458b4583",
"591c4efa86f7741030027726",
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"59db7e1086f77448be30ddf3",
"5b30b0dc5acfc400153b7124",
"5b3b6dc75acfc47a8773fb1e",
"5c0505e00db834001b735073",
"5c0517910db83400232ffee5",
"5c064c400db834001d23f468",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"5d1b5e94d7ad1a2b865a96b0",
"609a63b6e2ff132951242d09",
"63fc449f5bd61c6cf3784a88"
],
Height: 1,
Prefab: {
path: "assets/weapons/striker12/mod_front_sight_striker_12.bundle",
rcid: ""
},
ExaminedByDefault: false
},
parentId: "55818ac54bdc2d5b648b456e",
newId: WeapID.SIGHT_FRONT_STRIKER12,
handbookParentId: "5b5f73ec86f774093e6cb4fd",
handbookPriceRoubles: 885,
fleaPriceRoubles: 910,
locales: {
"en": {
name: "Armsel Striker Front Sight Clamp",
shortName: "Striker Clamp",
description: "Front sight that can be clamped on the barrel where the receiver meet."
}
}
};
customitem.createItemFromClone(armsel_clamp_sight);
const armsel_rear_sight = {
itemTplToClone: "5894a81786f77427140b8347",
overrideProperties: {
Ergonomics: -1,
Weight: 0.018,
Width: 1,
Height: 1,
ConflictingItems: [
"59db7e1086f77448be30ddf3",
"5d1b5e94d7ad1a2b865a96b0"
],
Prefab: {
path: "assets/weapons/striker12/mod_rear_sight_striker_12.bundle",
rcid: ""
},
ExaminedByDefault: false
},
parentId: "55818ac54bdc2d5b648b456e",
newId: WeapID.SIGHT_REAR_STRIKER12,
handbookParentId: "5b5f73ec86f774093e6cb4fd",
handbookPriceRoubles: 885,
fleaPriceRoubles: 910,
locales: {
"en": {
name: "Armsel Striker Rear Sight",
shortName: "Striker Rear",
description: "Rear sight for the Armsel Striker, requires picatinny rail to be mounted."
}
}
};
customitem.createItemFromClone(armsel_rear_sight);
//---MASTERY AND TRADER---
//Global Weapon Preset
for (const itemPreset in global_item_preset_json_1.default.ItemPresets) {
globals.ItemPresets[itemPreset] = global_item_preset_json_1.default.ItemPresets[itemPreset];
}
//Trader Assort
MC.items.push(...Item_Preset_json_1.default.items);
for (const bsc in Item_Preset_json_1.default.barter_scheme) {
MC.barter_scheme[bsc] = Item_Preset_json_1.default.barter_scheme[bsc];
}
for (const llv in Item_Preset_json_1.default.loyal_level_items) {
MC.loyal_level_items[llv] = Item_Preset_json_1.default.loyal_level_items[llv];
}
//---For Other tidbits of manipulation---
db.templates.items[ItemTpl_1.ItemTpl.INVENTORY_DEFAULT]._props.Slots[0]._props.filters[0].Filter.push(WeapID.WEAP_STRIKER12);
db.templates.items[ItemTpl_1.ItemTpl.INVENTORY_DEFAULT]._props.Slots[1]._props.filters[0].Filter.push(WeapID.WEAP_STRIKER12);
/* const usec = db.bots.types["usec"];
const bear = db.bots.types["bear"];
usec.inventory.equipment.FirstPrimaryWeapon[WeapID.WEAP_STRIKER12] = 5;
usec.inventory.mods[WeapID.WEAP_STRIKER12] =
{
mod_stock: [WeapID.STOCK_STRIKER12],
mod_mount: [WeapID.MOUNT_STRIKER12_PICATINY],
mod_sight_front: [WeapID.SIGHT_FRONT_STRIKER12],
mod_magazine: [WeapID.MAG_STRIKER12],
patron_in_weapon: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
};
usec.inventory.mods[WeapID.MOUNT_STRIKER12_PICATINY] =
{
mod_scope: [
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"544a3f024bdc2d1d388b4568",
"544a3a774bdc2d3a388b4567",
"5d2dc3e548f035404a1a4798",
"57adff4f24597737f373b6e6",
"5c0517910db83400232ffee5",
"591c4efa86f7741030027726",
"570fd79bd2720bc7458b4583",
"570fd6c2d2720bc6458b457f",
"558022b54bdc2dac148b458d",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"58491f3324597764bc48fa02",
"584924ec24597768f12ae244",
"5b30b0dc5acfc400153b7124",
"6165ac8c290d254f5e6b2f6c",
"60a23797a37c940de7062d02",
"5d2da1e948f035477b1ce2ba",
"5c0505e00db834001b735073",
"609a63b6e2ff132951242d09",
"584984812459776a704a82a6",
"59f9d81586f7744c7506ee62",
"570fd721d2720bc5458b4596",
"57ae0171245977343c27bfcf",
"5d1b5e94d7ad1a2b865a96b0",
"609bab8b455afd752b2e6138",
"58d39d3d86f77445bb794ae7",
"616554fe50224f204c1da2aa",
"5c7d55f52e221644f31bff6a",
"616584766ef05c2ce828ef57",
"5b3b6dc75acfc47a8773fb1e",
"615d8d878004cc50514c3233",
"577d128124597739d65d0e56",
"5c064c400db834001d23f468",
"58d2664f86f7747fec5834f6",
"5c1cdd302e221602b3137250",
"61714b2467085e45ef140b2c",
"5b31163c5acfc400153b71cb",
"5a33b652c4a28232996e407c",
"5a33b2c9c4a282000c5a9511",
"59db7eed86f77461f8380365",
"5a1ead28fcdbcb001912fa9f",
"626bb8532c923541184624b4",
"63fc449f5bd61c6cf3784a88",
"6477772ea8a38bb2050ed4db",
"6478641c19d732620e045e17",
"64785e7c19d732620e045e15"
],
mod_sight_rear: [
WeapID.SIGHT_REAR_STRIKER12,
"5bb20e49d4351e3bac1212de",
"5ba26b17d4351e00367f9bdd",
"5dfa3d7ac41b2312ea33362a",
"5c1780312e221602b66cc189",
"5fb6564947ce63734e3fa1da",
"5bc09a18d4351e003562b68e",
"5c18b9192e2216398b5a8104",
"5fc0fa957283c4046c58147e",
"5894a81786f77427140b8347",
"55d5f46a4bdc2d1b198b4567",
"5ae30bad5acfc400185c2dc4"
]
};
usec.inventory.mods[WeapID.MAG_STRIKER12] =
{
cartridges: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
};
bear.inventory.equipment.FirstPrimaryWeapon[WeapID.WEAP_STRIKER12] = 5;
bear.inventory.mods[WeapID.WEAP_STRIKER12] =
{
mod_stock: [WeapID.STOCK_STRIKER12],
mod_mount: [WeapID.MOUNT_STRIKER12_PICATINY],
mod_sight_front: [WeapID.SIGHT_FRONT_STRIKER12],
mod_magazine: [WeapID.MAG_STRIKER12],
patron_in_weapon: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
};
bear.inventory.mods[WeapID.MOUNT_STRIKER12_PICATINY] =
{
mod_scope: [
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"544a3f024bdc2d1d388b4568",
"544a3a774bdc2d3a388b4567",
"5d2dc3e548f035404a1a4798",
"57adff4f24597737f373b6e6",
"5c0517910db83400232ffee5",
"591c4efa86f7741030027726",
"570fd79bd2720bc7458b4583",
"570fd6c2d2720bc6458b457f",
"558022b54bdc2dac148b458d",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"58491f3324597764bc48fa02",
"584924ec24597768f12ae244",
"5b30b0dc5acfc400153b7124",
"6165ac8c290d254f5e6b2f6c",
"60a23797a37c940de7062d02",
"5d2da1e948f035477b1ce2ba",
"5c0505e00db834001b735073",
"609a63b6e2ff132951242d09",
"584984812459776a704a82a6",
"59f9d81586f7744c7506ee62",
"570fd721d2720bc5458b4596",
"57ae0171245977343c27bfcf",
"5d1b5e94d7ad1a2b865a96b0",
"609bab8b455afd752b2e6138",
"58d39d3d86f77445bb794ae7",
"616554fe50224f204c1da2aa",
"5c7d55f52e221644f31bff6a",
"616584766ef05c2ce828ef57",
"5b3b6dc75acfc47a8773fb1e",
"615d8d878004cc50514c3233",
"577d128124597739d65d0e56",
"5c064c400db834001d23f468",
"58d2664f86f7747fec5834f6",
"5c1cdd302e221602b3137250",
"61714b2467085e45ef140b2c",
"5b31163c5acfc400153b71cb",
"5a33b652c4a28232996e407c",
"5a33b2c9c4a282000c5a9511",
"59db7eed86f77461f8380365",
"5a1ead28fcdbcb001912fa9f",
"626bb8532c923541184624b4",
"63fc449f5bd61c6cf3784a88",
"6477772ea8a38bb2050ed4db",
"6478641c19d732620e045e17",
"64785e7c19d732620e045e15"
],
mod_sight_rear: [
WeapID.SIGHT_REAR_STRIKER12,
"5bb20e49d4351e3bac1212de",
"5ba26b17d4351e00367f9bdd",
"5dfa3d7ac41b2312ea33362a",
"5c1780312e221602b66cc189",
"5fb6564947ce63734e3fa1da",
"5bc09a18d4351e003562b68e",
"5c18b9192e2216398b5a8104",
"5fc0fa957283c4046c58147e",
"5894a81786f77427140b8347",
"55d5f46a4bdc2d1b198b4567",
"5ae30bad5acfc400185c2dc4"
]
};
bear.inventory.mods[WeapID.MAG_STRIKER12] =
{
cartridges: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
}; */
//For next AKi update
customitem.addCustomWeaponToPMCs(WeapID.WEAP_STRIKER12, 6, "FirstPrimaryWeapon");
db.templates.quests["5a03153686f77442d90e2171"].conditions.AvailableForFinish[0].counter.conditions[0].weapon.push(WeapID.WEAP_STRIKER12);
}
}
exports.mod = new Mod();
//# sourceMappingURL=mod.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,774 @@
/* eslint-disable @typescript-eslint/indent */
/* eslint-disable @typescript-eslint/naming-convention */
import { DependencyContainer } from "tsyringe";
import { IPostDBLoadMod } from "@spt/models/external/IPostDBLoadMod";
import { CustomItemService } from "@spt/services/mod/CustomItemService";
import { NewItemFromCloneDetails } from "@spt/models/spt/mod/NewItemDetails";
import { DatabaseServer } from "@spt/servers/DatabaseServer";
import { ItemTpl } from "@spt/models/enums/ItemTpl";
import { Traders } from "@spt/models/enums/Traders";
import preset_file from "../src/Item_Preset.json";
import global_preset_file from "../src/global_item_preset.json";
export enum WeapID {
MOUNT_STRIKER12_PICATINY = "668c68aa2e09beec5a6e9154",
WEAP_STRIKER12 = "668c68adb49c8d5089331ec9",
MAG_STRIKER12 = "668c68b1e0d0f96066595fa2",
STOCK_STRIKER12 = "668c68b33a252358c049a4c8",
SIGHT_FRONT_STRIKER12 = "668c68b67096754b726a9734",
SIGHT_REAR_STRIKER12 = "668c68b90986da08fccc3b88"
}
class Mod implements IPostDBLoadMod
{
public postDBLoad(container: DependencyContainer): void
{
const customitem = container.resolve<CustomItemService>("CustomItemService");
const databaseserver = container.resolve<DatabaseServer>("DatabaseServer");
const db = databaseserver.getTables()
const globals = db.globals;
const MC = db.traders[Traders.MECHANIC].assort;
//---WEAPON LISTING AND ATTACHMENT---
const Piccatiny_Mount: NewItemFromCloneDetails ={
itemTplToClone: "591ee00d86f774592f7b841e",
overrideProperties: {
Weight: 0.036,
ExaminedByDefault: false,
RaidModdable: false,
Width: 2,
Prefab: {
path: "assets/weapons/striker12/mod_mount_piccatiny_rail_striker_12.bundle",
rcid: ""
},
Slots: [
{
"_id": "picatinny_mod_scope",
"_mergeSlotWithChildren": false,
"_name": "mod_scope",
"_parent": WeapID.MOUNT_STRIKER12_PICATINY,
"_props": {
"filters": [
{
"Filter":
[
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"544a3f024bdc2d1d388b4568",
"544a3a774bdc2d3a388b4567",
"5d2dc3e548f035404a1a4798",
"57adff4f24597737f373b6e6",
"5c0517910db83400232ffee5",
"591c4efa86f7741030027726",
"570fd79bd2720bc7458b4583",
"570fd6c2d2720bc6458b457f",
"558022b54bdc2dac148b458d",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"58491f3324597764bc48fa02",
"584924ec24597768f12ae244",
"5b30b0dc5acfc400153b7124",
"6165ac8c290d254f5e6b2f6c",
"60a23797a37c940de7062d02",
"5d2da1e948f035477b1ce2ba",
"5c0505e00db834001b735073",
"609a63b6e2ff132951242d09",
"584984812459776a704a82a6",
"59f9d81586f7744c7506ee62",
"570fd721d2720bc5458b4596",
"57ae0171245977343c27bfcf",
"5d1b5e94d7ad1a2b865a96b0",
"609bab8b455afd752b2e6138",
"58d39d3d86f77445bb794ae7",
"616554fe50224f204c1da2aa",
"5c7d55f52e221644f31bff6a",
"616584766ef05c2ce828ef57",
"5b3b6dc75acfc47a8773fb1e",
"615d8d878004cc50514c3233",
"577d128124597739d65d0e56",
"5c064c400db834001d23f468",
"58d2664f86f7747fec5834f6",
"5c1cdd302e221602b3137250",
"61714b2467085e45ef140b2c",
"5b31163c5acfc400153b71cb",
"5a33b652c4a28232996e407c",
"5a33b2c9c4a282000c5a9511",
"59db7eed86f77461f8380365",
"5a1ead28fcdbcb001912fa9f",
"626bb8532c923541184624b4",
"63fc449f5bd61c6cf3784a88",
"6477772ea8a38bb2050ed4db",
"6478641c19d732620e045e17",
"64785e7c19d732620e045e15"
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
},
{
"_id": "picatinny_rear_sight",
"_mergeSlotWithChildren": false,
"_name": "mod_sight_rear",
"_parent": WeapID.MOUNT_STRIKER12_PICATINY,
"_props": {
"filters": [
{
"Filter":
[
WeapID.SIGHT_REAR_STRIKER12,
"5bb20e49d4351e3bac1212de",
"5ba26b17d4351e00367f9bdd",
"5dfa3d7ac41b2312ea33362a",
"5c1780312e221602b66cc189",
"5fb6564947ce63734e3fa1da",
"5bc09a18d4351e003562b68e",
"5c18b9192e2216398b5a8104",
"5fc0fa957283c4046c58147e",
"5894a81786f77427140b8347",
"55d5f46a4bdc2d1b198b4567",
"5ae30bad5acfc400185c2dc4"
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
}
]
},
parentId: "55818b224bdc2dde698b456f",
newId: WeapID.MOUNT_STRIKER12_PICATINY,
handbookParentId: "5b5f755f86f77447ec5d770e",
handbookPriceRoubles: 6775,
fleaPriceRoubles: 9881,
locales: {
"en": {
name: "StrikeRail Picatinny Mount",
shortName: "SR-Picatinny Mount",
description: "A specialized accessory crafted specifically for the Armsel Striker shotgun, offering a wide range of optic customization options. This mount attaches securely to the shotgun's receiver, providing a standardized Picatinny rail interface. "
}
}
}
customitem.createItemFromClone(Piccatiny_Mount);
const striker_12: NewItemFromCloneDetails = {
itemTplToClone: "5a7828548dc32e5a9c28b516",
overrideProperties: {
Prefab: {
path: "assets/weapons/striker12/weapon_striker_12_container.bundle",
rcid: ""
},
aimingSensitivity: 0.54,
Width: 3,
Height: 2,
AllowFeed: false,
AllowJam: false,
AllowMisfire: false,
AllowSlide: false,
AimPlane: 0.05,
CenterOfImpact: 0.11,
shotgunDispersion: 1,
ShotgunDispersion: 1,
SingleFireRate: 500,
bFirerate: 500,
Velocity: 3.2,
DeviationMax: 8,
Ergonomics: 67,
isChamberLoad: true,
TacticalReloadFixation: 95,
TacticalReloadStiffnes:
{
x: 0.85,
y: 0.80,
z: 0.95
},
ExaminedByDefault: false,
ExamineExperience: 18,
HeatFactorGun: 0.76,
IronSightRange: 50,
LootExperience: 25,
RecoilAngle: 87,
RecoilCenter:
{
x: 0.007,
y: -0.26,
z: -0.068
},
RecoilForceUp: 520,
RecoilForceBack: 320,
RecoilCamera: 0.0087,
RecoilDampingHandRotation: 0.76,
RecoilReturnSpeedHandRotation: 4.75,
RecoilReturnPathDampingHandRotation: 0.47,
RecoilStableIndexShot: 6,
RecoilPosZMult: 1,
PostRecoilHorizontalRangeHandRotation:
{
x: -2,
y: 0,
z: 0
},
PostRecoilVerticalRangeHandRotation:
{
x: -2,
y: 1,
z: 0
},
RotationCenter:
{
x: 0,
y: -0,
z: -0
},
RotationCenterNoStock:
{
x: 0.007,
y: -0.26,
z: -0.068
},
Slots: [
{
"_id": "668c68c7a69b2dde82553d82",
"_mergeSlotWithChildren": false,
"_name": "mod_magazine",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"AnimationIndex": 0,
"Filter": [
WeapID.MAG_STRIKER12
]
}
]
},
"_proto": "55d30c394bdc2dae468b4577",
"_required": true
},
{
"_id": "668c68e88a65124cff33dbbf",
"_mergeSlotWithChildren": false,
"_name": "mod_stock",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
WeapID.STOCK_STRIKER12
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
},
{
"_id": "668c68f746bfb7ea6a7700c5",
"_mergeSlotWithChildren": false,
"_name": "mod_mount",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
WeapID.MOUNT_STRIKER12_PICATINY
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
},
{
"_id": "668c69275fc4527c8c0a9ddb",
"_mergeSlotWithChildren": false,
"_name": "mod_sight_front",
"_parent": WeapID.WEAP_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
WeapID.SIGHT_FRONT_STRIKER12
],
"Shift": 0
}
]
},
"_proto": "55d30c4c4bdc2db4468b457e",
"_required": false
}
],
Weight: 4.2,
ammoCaliber: "Caliber12g",
defAmmo: "560d5e524bdc2d25448b4571",
defMagType: WeapID.MAG_STRIKER12,
durabSpawnMax: 100,
durabSpawnMin: 35,
weapFireType: ["single"]
},
parentId: "5447b6094bdc2dc3278b4567",
newId: WeapID.WEAP_STRIKER12,
handbookParentId: "5b5f794b86f77409407a7f92",
handbookPriceRoubles: 23665,
fleaPriceRoubles: 28775,
locales: {
"en": {
name: "Armsel Striker 12 Gauge Cylinder Shotgun",
shortName: "Striker 12",
description: "Armsel Striker, also known by its nickname the \"Street Swiper\", was developed Hilton R. Walker, a Zimbabwean (formerly Rhodesian) citizen, in 1981. The shotgun is designed for riot control and combat while featuring a revolving cylinder mechanism. His shotgun became a success and was exported to various parts of the world, despite some drawbacks. The rotary cylinder was bulky, had a long reload time, and the basic action was not without certain flaws."
}
}
}
customitem.createItemFromClone(striker_12);
const armsel_mag: NewItemFromCloneDetails= {
itemTplToClone: ItemTpl.MAGAZINE_12G_M870X4_4RND,
overrideProperties: {
Cartridges: [
{
"_id": "5a7882dcc5856700177af663",
"_max_count": 11,
"_name": "cartridges",
"_parent": WeapID.MAG_STRIKER12,
"_props": {
"filters": [
{
"Filter": [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845",
"64b8ee384b75259c590fa89b"
]
}
]
},
"_proto": "5748538b2459770af276a261"
}
],
ExaminedByDefault: false,
Ergonomics: -8,
Weight: 0.01,
ExamineExperience: 12,
Prefab:
{
path: "assets/weapons/striker12/mod_magazine_striker_12.bundle",
rcid: ""
}
},
parentId: "5448bc234bdc2d3c308b4569",
newId: WeapID.MAG_STRIKER12,
handbookParentId: "5b5f754a86f774094242f19b",
handbookPriceRoubles: 2584,
fleaPriceRoubles: 3112,
locales: {
"en": {
name: "Armsel Striker 12-Round Cylinder Magazine",
shortName: "12-CM",
description: "A big and bulky internal revolving cylinder for the Armsel Striker. It can support up to 12 rounds (1 in chamber + 11 in magazine). It will take a while to reload such thing given the mechanism for it."
}
}
}
customitem.createItemFromClone(armsel_mag);
const striker_stock: NewItemFromCloneDetails= {
itemTplToClone: "56083cba4bdc2de22e8b456f",
overrideProperties: {
Ergonomics: -10,
Weight: 0.33,
Width: 2,
Height: 1,
ExtraSizeRight: 1,
Recoil: -54,
ExamineExperience: 12,
Prefab:
{
path: "assets/weapons/striker12/mod_stock_foldable_striker_12.bundle",
rcid: ""
},
ExaminedByDefault: false
},
parentId: "55818a594bdc2db9688b456a",
newId: WeapID.STOCK_STRIKER12,
handbookParentId: "5b5f757486f774093e6cb507",
handbookPriceRoubles: 2874,
fleaPriceRoubles: 3100,
locales: {
"en": {
name: "Armsel Striker Metal Stock",
shortName: "Striker Stock",
description: "A strong and robust metal stock fitted for the Armsel Striker. Provides good recoil control and stabilization, it can be a bit clunky with how long it is."
}
}
}
customitem.createItemFromClone(striker_stock);
const armsel_clamp_sight: NewItemFromCloneDetails= {
itemTplToClone: "5bc09a30d4351e00367fb7c8",
overrideProperties: {
Ergonomics: -2,
Weight: 0.024,
Width: 1,
ConflictingItems: [
"570fd6c2d2720bc6458b457f",
"570fd79bd2720bc7458b4583",
"591c4efa86f7741030027726",
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"59db7e1086f77448be30ddf3",
"5b30b0dc5acfc400153b7124",
"5b3b6dc75acfc47a8773fb1e",
"5c0505e00db834001b735073",
"5c0517910db83400232ffee5",
"5c064c400db834001d23f468",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"5d1b5e94d7ad1a2b865a96b0",
"609a63b6e2ff132951242d09",
"63fc449f5bd61c6cf3784a88"
],
Height: 1,
Prefab:
{
path: "assets/weapons/striker12/mod_front_sight_striker_12.bundle",
rcid: ""
},
ExaminedByDefault: false
},
parentId: "55818ac54bdc2d5b648b456e",
newId: WeapID.SIGHT_FRONT_STRIKER12,
handbookParentId: "5b5f73ec86f774093e6cb4fd",
handbookPriceRoubles: 885,
fleaPriceRoubles: 910,
locales: {
"en": {
name: "Armsel Striker Front Sight Clamp",
shortName: "Striker Clamp",
description: "Front sight that can be clamped on the barrel where the receiver meet."
}
}
}
customitem.createItemFromClone(armsel_clamp_sight);
const armsel_rear_sight: NewItemFromCloneDetails= {
itemTplToClone: "5894a81786f77427140b8347",
overrideProperties: {
Ergonomics: -1,
Weight: 0.018,
Width: 1,
Height: 1,
ConflictingItems: [
"59db7e1086f77448be30ddf3",
"5d1b5e94d7ad1a2b865a96b0"
],
Prefab:
{
path: "assets/weapons/striker12/mod_rear_sight_striker_12.bundle",
rcid: ""
},
ExaminedByDefault: false
},
parentId: "55818ac54bdc2d5b648b456e",
newId: WeapID.SIGHT_REAR_STRIKER12,
handbookParentId: "5b5f73ec86f774093e6cb4fd",
handbookPriceRoubles: 885,
fleaPriceRoubles: 910,
locales: {
"en": {
name: "Armsel Striker Rear Sight",
shortName: "Striker Rear",
description: "Rear sight for the Armsel Striker, requires picatinny rail to be mounted."
}
}
}
customitem.createItemFromClone(armsel_rear_sight);
//---MASTERY AND TRADER---
//Global Weapon Preset
for (const itemPreset in global_preset_file.ItemPresets)
{
globals.ItemPresets[itemPreset] = global_preset_file.ItemPresets[itemPreset];
}
//Trader Assort
MC.items.push(...preset_file.items);
for (const bsc in preset_file.barter_scheme)
{
MC.barter_scheme[bsc] = preset_file.barter_scheme[bsc];
}
for (const llv in preset_file.loyal_level_items)
{
MC.loyal_level_items[llv] = preset_file.loyal_level_items[llv];
}
//---For Other tidbits of manipulation---
db.templates.items[ItemTpl.INVENTORY_DEFAULT]._props.Slots[0]._props.filters[0].Filter.push(WeapID.WEAP_STRIKER12);
db.templates.items[ItemTpl.INVENTORY_DEFAULT]._props.Slots[1]._props.filters[0].Filter.push(WeapID.WEAP_STRIKER12);
/* const usec = db.bots.types["usec"];
const bear = db.bots.types["bear"];
usec.inventory.equipment.FirstPrimaryWeapon[WeapID.WEAP_STRIKER12] = 5;
usec.inventory.mods[WeapID.WEAP_STRIKER12] =
{
mod_stock: [WeapID.STOCK_STRIKER12],
mod_mount: [WeapID.MOUNT_STRIKER12_PICATINY],
mod_sight_front: [WeapID.SIGHT_FRONT_STRIKER12],
mod_magazine: [WeapID.MAG_STRIKER12],
patron_in_weapon: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
};
usec.inventory.mods[WeapID.MOUNT_STRIKER12_PICATINY] =
{
mod_scope: [
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"544a3f024bdc2d1d388b4568",
"544a3a774bdc2d3a388b4567",
"5d2dc3e548f035404a1a4798",
"57adff4f24597737f373b6e6",
"5c0517910db83400232ffee5",
"591c4efa86f7741030027726",
"570fd79bd2720bc7458b4583",
"570fd6c2d2720bc6458b457f",
"558022b54bdc2dac148b458d",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"58491f3324597764bc48fa02",
"584924ec24597768f12ae244",
"5b30b0dc5acfc400153b7124",
"6165ac8c290d254f5e6b2f6c",
"60a23797a37c940de7062d02",
"5d2da1e948f035477b1ce2ba",
"5c0505e00db834001b735073",
"609a63b6e2ff132951242d09",
"584984812459776a704a82a6",
"59f9d81586f7744c7506ee62",
"570fd721d2720bc5458b4596",
"57ae0171245977343c27bfcf",
"5d1b5e94d7ad1a2b865a96b0",
"609bab8b455afd752b2e6138",
"58d39d3d86f77445bb794ae7",
"616554fe50224f204c1da2aa",
"5c7d55f52e221644f31bff6a",
"616584766ef05c2ce828ef57",
"5b3b6dc75acfc47a8773fb1e",
"615d8d878004cc50514c3233",
"577d128124597739d65d0e56",
"5c064c400db834001d23f468",
"58d2664f86f7747fec5834f6",
"5c1cdd302e221602b3137250",
"61714b2467085e45ef140b2c",
"5b31163c5acfc400153b71cb",
"5a33b652c4a28232996e407c",
"5a33b2c9c4a282000c5a9511",
"59db7eed86f77461f8380365",
"5a1ead28fcdbcb001912fa9f",
"626bb8532c923541184624b4",
"63fc449f5bd61c6cf3784a88",
"6477772ea8a38bb2050ed4db",
"6478641c19d732620e045e17",
"64785e7c19d732620e045e15"
],
mod_sight_rear: [
WeapID.SIGHT_REAR_STRIKER12,
"5bb20e49d4351e3bac1212de",
"5ba26b17d4351e00367f9bdd",
"5dfa3d7ac41b2312ea33362a",
"5c1780312e221602b66cc189",
"5fb6564947ce63734e3fa1da",
"5bc09a18d4351e003562b68e",
"5c18b9192e2216398b5a8104",
"5fc0fa957283c4046c58147e",
"5894a81786f77427140b8347",
"55d5f46a4bdc2d1b198b4567",
"5ae30bad5acfc400185c2dc4"
]
};
usec.inventory.mods[WeapID.MAG_STRIKER12] =
{
cartridges: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
};
bear.inventory.equipment.FirstPrimaryWeapon[WeapID.WEAP_STRIKER12] = 5;
bear.inventory.mods[WeapID.WEAP_STRIKER12] =
{
mod_stock: [WeapID.STOCK_STRIKER12],
mod_mount: [WeapID.MOUNT_STRIKER12_PICATINY],
mod_sight_front: [WeapID.SIGHT_FRONT_STRIKER12],
mod_magazine: [WeapID.MAG_STRIKER12],
patron_in_weapon: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
};
bear.inventory.mods[WeapID.MOUNT_STRIKER12_PICATINY] =
{
mod_scope: [
"57ac965c24597706be5f975c",
"57aca93d2459771f2c7e26db",
"544a3f024bdc2d1d388b4568",
"544a3a774bdc2d3a388b4567",
"5d2dc3e548f035404a1a4798",
"57adff4f24597737f373b6e6",
"5c0517910db83400232ffee5",
"591c4efa86f7741030027726",
"570fd79bd2720bc7458b4583",
"570fd6c2d2720bc6458b457f",
"558022b54bdc2dac148b458d",
"5c07dd120db834001c39092d",
"5c0a2cec0db834001b7ce47d",
"58491f3324597764bc48fa02",
"584924ec24597768f12ae244",
"5b30b0dc5acfc400153b7124",
"6165ac8c290d254f5e6b2f6c",
"60a23797a37c940de7062d02",
"5d2da1e948f035477b1ce2ba",
"5c0505e00db834001b735073",
"609a63b6e2ff132951242d09",
"584984812459776a704a82a6",
"59f9d81586f7744c7506ee62",
"570fd721d2720bc5458b4596",
"57ae0171245977343c27bfcf",
"5d1b5e94d7ad1a2b865a96b0",
"609bab8b455afd752b2e6138",
"58d39d3d86f77445bb794ae7",
"616554fe50224f204c1da2aa",
"5c7d55f52e221644f31bff6a",
"616584766ef05c2ce828ef57",
"5b3b6dc75acfc47a8773fb1e",
"615d8d878004cc50514c3233",
"577d128124597739d65d0e56",
"5c064c400db834001d23f468",
"58d2664f86f7747fec5834f6",
"5c1cdd302e221602b3137250",
"61714b2467085e45ef140b2c",
"5b31163c5acfc400153b71cb",
"5a33b652c4a28232996e407c",
"5a33b2c9c4a282000c5a9511",
"59db7eed86f77461f8380365",
"5a1ead28fcdbcb001912fa9f",
"626bb8532c923541184624b4",
"63fc449f5bd61c6cf3784a88",
"6477772ea8a38bb2050ed4db",
"6478641c19d732620e045e17",
"64785e7c19d732620e045e15"
],
mod_sight_rear: [
WeapID.SIGHT_REAR_STRIKER12,
"5bb20e49d4351e3bac1212de",
"5ba26b17d4351e00367f9bdd",
"5dfa3d7ac41b2312ea33362a",
"5c1780312e221602b66cc189",
"5fb6564947ce63734e3fa1da",
"5bc09a18d4351e003562b68e",
"5c18b9192e2216398b5a8104",
"5fc0fa957283c4046c58147e",
"5894a81786f77427140b8347",
"55d5f46a4bdc2d1b198b4567",
"5ae30bad5acfc400185c2dc4"
]
};
bear.inventory.mods[WeapID.MAG_STRIKER12] =
{
cartridges: [
"560d5e524bdc2d25448b4571",
"5d6e6772a4b936088465b17c",
"5d6e67fba4b9361bc73bc779",
"5d6e6806a4b936088465b17e",
"5d6e68dea4b9361bcc29e659",
"5d6e6911a4b9361bd5780d52",
"5c0d591486f7744c505b416f",
"58820d1224597753c90aeb13",
"5d6e68c4a4b9361b93413f79",
"5d6e68a8a4b9360b6c0d54e2",
"5d6e68e6a4b9361c140bcfe0",
"5d6e6869a4b9361c140bcfde",
"5d6e68b3a4b9361bca7e50b5",
"5d6e6891a4b9361bd473feea",
"5d6e689ca4b9361bc8618956",
"5d6e68d1a4b93622fe60e845"
]
}; */
//For next AKi update
customitem.addCustomWeaponToPMCs(WeapID.WEAP_STRIKER12, 6, "FirstPrimaryWeapon");
db.templates.quests["5a03153686f77442d90e2171"].conditions.AvailableForFinish[0].counter.conditions[0].weapon.push(WeapID.WEAP_STRIKER12);
}
}
export const mod = new Mod();
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.30.0
newestVersion=
category="2,"
nexusFileStatus=1
installationFile=Tyfon-AutoDeposit-3.0.1.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-30T11:47:05Z
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
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.18.0
newestVersion=
category="2,"
nexusFileStatus=1
installationFile=ProvocatorMods.Cruise-1.0.0.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-18T07:04:25Z
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
+26
View File
@@ -0,0 +1,26 @@
[General]
modid=0
version=
newestVersion=
category="-1,"
installationFile=
ignoredVersion=
repository=Nexus
gameName=spt
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
nexusFileStatus=1
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-18T07:04:34Z
nexusCategory=0
converted=false
validated=false
color=@Variant(\0\0\0\x43\x1\xff\xff\x44\x44\x36\x36))\0\0)
tracked=0
[installedFiles]
size=0
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.16.0
newestVersion=
category="2,"
nexusFileStatus=1
installationFile=stckytwl.BetterBulletCracks-3.10-1.0.1.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-16T06:21:47Z
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
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=spt
modid=0
version=d2024.12.16.0
newestVersion=
category="1,"
nexusFileStatus=1
installationFile=flir-betterkeysng.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-16T06:54: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
@@ -0,0 +1,33 @@
---
stages:
- build
- upload
build:
stage: build
image: node:22
artifacts:
paths:
- build
script:
- npm install
- npm run build
upload:
image: curlimages/curl:latest
stage: upload
cache:
key: tooling
paths:
- build
rules:
- if: '$CI_COMMIT_TAG'
script:
- |
OUTPUT_FILE=$(mktemp)
HTTP_CODE=$(curl --silent --output $OUTPUT_FILE --write-out "%{http_code}" --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/flir-betterkeysng.zip "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/betterkeys-ng/${CI_COMMIT_TAG}/flir-betterkeysng.zip")
echo "return $HTTP_CODE"
cat $OUTPUT_FILE
if [[ ${HTTP_CODE} -lt 200 || ${HTTP_CODE} -gt 299 ]] ; then
exit 1
fi

Some files were not shown because too many files have changed in this diff Show More