Compare commits
3 commits
af5fcc9115
...
3755d6e2a6
| Author | SHA1 | Date | |
|---|---|---|---|
| 3755d6e2a6 | |||
| 57c563a139 | |||
| d5ece8e9b7 |
30 changed files with 1862 additions and 0 deletions
BIN
user/mods/BepInEx/plugins/VCQLQuestZones.dll
Normal file
BIN
user/mods/BepInEx/plugins/VCQLQuestZones.dll
Normal file
Binary file not shown.
413
user/mods/MoxoPixel-TacticalGearComponent/src/mod.js
Normal file
413
user/mods/MoxoPixel-TacticalGearComponent/src/mod.js
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const itemTemplate = require("../templates/item_template.json");
|
||||
const configJson = require("../config.json");
|
||||
const modTGC_items_json_1 = __importDefault(require("../database/modTGC_items.json"));
|
||||
const modTGC_clothes_json_1 = __importDefault(require("../database/modTGC_clothes.json"));
|
||||
const globals_json_1 = __importDefault(require("../database/globals.json"));
|
||||
const assort_json_1 = __importDefault(require("../database/traders/668aaff35fd574b6dcc4a686/assort.json"));
|
||||
const suits_json_1 = __importDefault(require("../database/traders/668aaff35fd574b6dcc4a686/suits.json"));
|
||||
class TGCItems {
|
||||
db;
|
||||
mydb;
|
||||
logger;
|
||||
jsonUtil;
|
||||
async postDBLoad(container) {
|
||||
this.logger = container.resolve("WinstonLogger");
|
||||
this.jsonUtil = container.resolve("JsonUtil");
|
||||
const databaseServer = container.resolve("DatabaseServer");
|
||||
const modLoader = container.resolve("PreSptModLoader");
|
||||
//Mod Info
|
||||
const modFolderName = "MoxoPixel-TacticalGearComponent";
|
||||
const modFullName = "Tactical Gear Component";
|
||||
//Trader IDs
|
||||
const traders = {
|
||||
"PAINTERSHOP": "668aaff35fd574b6dcc4a686"
|
||||
};
|
||||
//Currency IDs
|
||||
const currencies = {
|
||||
"roubles": "5449016a4bdc2d6f028b456f",
|
||||
"dollars": "5696686a4bdc2da3298b456a",
|
||||
"euros": "569668774bdc2da2298b4568",
|
||||
"bitcoin": "59faff1d86f7746c51718c9c",
|
||||
"gp": "5d235b4d86f7742e017bc88a"
|
||||
};
|
||||
//Get the server database and our custom database
|
||||
this.db = databaseServer.getTables();
|
||||
this.mydb = {
|
||||
modTgcItems: modTGC_items_json_1.default,
|
||||
modTgcClothes: modTGC_clothes_json_1.default,
|
||||
globals: globals_json_1.default,
|
||||
traders: {
|
||||
"668aaff35fd574b6dcc4a686": {
|
||||
assort: assort_json_1.default,
|
||||
suits: suits_json_1.default
|
||||
}
|
||||
}
|
||||
};
|
||||
this.logger.info("Loading: " + modFullName);
|
||||
const secureContainerIds = [
|
||||
"665ee77ccf2d642e98220bca",
|
||||
"5857a8bc2459772bad15db29",
|
||||
"64f6f4c5911bcdfe8b03b0dc",
|
||||
"544a11ac4bdc2d470e8b456a",
|
||||
"5857a8b324597729ab0a0e7d",
|
||||
"59db794186f77448bc595262",
|
||||
"664a55d84a90fc2c8a6305c9",
|
||||
"5c093ca986f7740a1867ab12",
|
||||
"676008db84e242067d0dc4c9"
|
||||
];
|
||||
const armbandId = "55d7217a4bdc2d86028b456d";
|
||||
//Items
|
||||
if (this.mydb.modTgcItems && typeof this.mydb.modTgcItems === "object" && Object.keys(this.mydb.modTgcItems).length > 0) {
|
||||
for (const [modTGCID, modTGCItem] of Object.entries(this.mydb.modTgcItems)) {
|
||||
//Items + Handbook
|
||||
if (typeof modTGCItem === 'object' && "clone" in modTGCItem) {
|
||||
this.cloneItem(modTGCItem.clone, modTGCID);
|
||||
this.copyToFilters(modTGCItem.clone, modTGCID);
|
||||
if ("PutInArmband" in modTGCItem && this.db.templates.items[armbandId]) {
|
||||
this.db.templates.items[armbandId]._props.Slots[14]._props.filters[0].Filter.push(modTGCID);
|
||||
}
|
||||
if (configJson.PouchesInSecureContainer && "putInSecureContainer" in modTGCItem) {
|
||||
for (const id of secureContainerIds) {
|
||||
const item = this.db.templates.items[id];
|
||||
if (item && item._props && item._props.Grids && item._props.Grids[0] && item._props.Grids[0]._props && item._props.Grids[0]._props.filters && item._props.Grids[0]._props.filters[0] && item._props.Grids[0]._props.filters[0].Filter) {
|
||||
item._props.Grids[0]._props.filters[0].Filter.push(modTGCID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this.createItem(modTGCID);
|
||||
//Locales (Languages)
|
||||
this.addLocales(modTGCID, modTGCItem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.warning("modTgcItems is missing or not an object in the mod database.");
|
||||
}
|
||||
//Item Filters
|
||||
if (this.mydb.modTgcItems && typeof this.mydb.modTgcItems === "object" && Object.keys(this.mydb.modTgcItems).length > 0) {
|
||||
for (const modTGCID in this.mydb.modTgcItems)
|
||||
this.addToFilters(modTGCID);
|
||||
}
|
||||
//Clothing
|
||||
if (this.mydb.modTgcClothes && typeof this.mydb.modTgcClothes === "object" && Object.keys(this.mydb.modTgcClothes).length > 0) {
|
||||
for (const [modTGCID, modTGCArticle] of Object.entries(this.mydb.modTgcClothes)) {
|
||||
//Articles + Handbook
|
||||
if (typeof modTGCArticle === 'object' && "clone" in modTGCArticle) {
|
||||
this.cloneClothing(modTGCArticle.clone, modTGCID);
|
||||
}
|
||||
//Locales (Languages)
|
||||
this.addLocales(modTGCID, undefined, modTGCArticle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.warning("modTgcClothes is missing or not an object in the mod database.");
|
||||
}
|
||||
//Presets
|
||||
if (this.mydb.globals && this.mydb.globals.ItemPresets) {
|
||||
for (const preset in this.mydb.globals.ItemPresets) {
|
||||
this.db.globals.ItemPresets[preset] = this.mydb.globals.ItemPresets[preset];
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.warning("modTGC: globals.ItemPresets is missing in the mod database.");
|
||||
}
|
||||
//Traders
|
||||
for (const trader in traders) {
|
||||
if (this.mydb.traders[traders[trader]] && this.mydb.traders[traders[trader]].suits) {
|
||||
this.addTraderSuits(traders[trader]);
|
||||
}
|
||||
else {
|
||||
this.logger.warning(`No suits for trader ${trader}`);
|
||||
}
|
||||
if (this.mydb.traders[traders[trader]] && this.mydb.traders[traders[trader]].assort) {
|
||||
this.addTraderAssort(traders[trader]);
|
||||
}
|
||||
else {
|
||||
this.logger.warning(`No assort for trader ${trader}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
cloneItem(itemToClone, modTGCID) {
|
||||
//If the item is enabled in the json
|
||||
if (this.mydb.modTgcItems[modTGCID].enable == true) {
|
||||
//Get a clone of the original item from the database
|
||||
let modTGCItemOut = this.jsonUtil.clone(this.db.templates.items[itemToClone]);
|
||||
//Change the necessary item attributes using the info in our database file modTgcItems.json
|
||||
modTGCItemOut._id = modTGCID;
|
||||
modTGCItemOut = this.compareAndReplace(modTGCItemOut, this.mydb.modTgcItems[modTGCID]["item"]);
|
||||
//Add the new item to the database
|
||||
this.db.templates.items[modTGCID] = modTGCItemOut;
|
||||
//Create the handbook entry for the items
|
||||
const handbookEntry = {
|
||||
"Id": modTGCID,
|
||||
"ParentId": this.mydb.modTgcItems[modTGCID]["handbook"]["ParentId"],
|
||||
"Price": this.mydb.modTgcItems[modTGCID]["handbook"]["Price"]
|
||||
};
|
||||
//Add the handbook entry to the database
|
||||
this.db.templates.handbook.Items.push(handbookEntry);
|
||||
}
|
||||
}
|
||||
createItem(itemToCreate) {
|
||||
//Create an item from scratch instead of cloning it
|
||||
//Requires properly formatted entry in modTgcItems.json with NO "clone" attribute
|
||||
//Get the new item object from the json
|
||||
const newItem = this.mydb.modTgcItems[itemToCreate];
|
||||
//If the item is enabled in the json
|
||||
if (newItem.enable) {
|
||||
//Check the structure of the new item in modTgcItems
|
||||
const [pass, checkedItem] = this.checkItem(newItem);
|
||||
if (!pass)
|
||||
return;
|
||||
//Add the new item to the database
|
||||
this.db.templates.items[itemToCreate] = checkedItem;
|
||||
//Create the handbook entry for the items
|
||||
const handbookEntry = {
|
||||
"Id": itemToCreate,
|
||||
"ParentId": newItem["handbook"]["ParentId"],
|
||||
"Price": newItem["handbook"]["Price"]
|
||||
};
|
||||
//Add the handbook entry to the database
|
||||
this.db.templates.handbook.Items.push(handbookEntry);
|
||||
}
|
||||
}
|
||||
checkItem(itemToCheck) {
|
||||
let pass = true;
|
||||
for (const level1 in itemTemplate) {
|
||||
if (itemTemplate.hasOwnProperty(level1) && !(level1 in itemToCheck.item)) {
|
||||
this.logger.error("ERROR - Missing attribute: \"" + level1 + "\" in your item entry!");
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
for (const prop in itemToCheck.item._props) {
|
||||
if (itemToCheck.item._props.hasOwnProperty(prop) && !(prop in itemTemplate._props)) {
|
||||
this.logger.warning("WARNING - Attribute: \"" + prop + "\" not found in item template!");
|
||||
}
|
||||
}
|
||||
const itemOUT = {
|
||||
"_id": itemToCheck.item._id,
|
||||
"_name": itemToCheck.item._name,
|
||||
"_parent": itemToCheck.item._parent,
|
||||
"_props": itemToCheck.item._props,
|
||||
"_type": itemToCheck.item._type,
|
||||
"_proto": itemToCheck.item._proto
|
||||
};
|
||||
return [pass, itemOUT];
|
||||
}
|
||||
compareAndReplace(originalItem, attributesToChange) {
|
||||
for (const key in attributesToChange) {
|
||||
if (attributesToChange.hasOwnProperty(key)) {
|
||||
if ((["boolean", "string", "number"].includes(typeof attributesToChange[key])) || Array.isArray(attributesToChange[key])) {
|
||||
if (key in originalItem) {
|
||||
originalItem[key] = attributesToChange[key];
|
||||
}
|
||||
else {
|
||||
this.logger.warning("(Item: " + originalItem._id + ") WARNING: Could not find the attribute: \"" + key + "\" in the original item, make sure this is intended!");
|
||||
originalItem[key] = attributesToChange[key];
|
||||
}
|
||||
}
|
||||
else {
|
||||
originalItem[key] = this.compareAndReplace(originalItem[key], attributesToChange[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return originalItem;
|
||||
}
|
||||
getFilters(item) {
|
||||
//Get the slots, chambers, cartridges, and conflicting items objects and return them.
|
||||
const slots = (typeof this.db.templates.items[item]._props.Slots === "undefined") ? [] : this.db.templates.items[item]._props.Slots;
|
||||
const chambers = (typeof this.db.templates.items[item]._props.Chambers === "undefined") ? [] : this.db.templates.items[item]._props.Chambers;
|
||||
const cartridges = (typeof this.db.templates.items[item]._props.Cartridges === "undefined") ? [] : this.db.templates.items[item]._props.Cartridges;
|
||||
const filters = slots.concat(chambers, cartridges);
|
||||
const conflictingItems = (typeof this.db.templates.items[item]._props.ConflictingItems === "undefined") ? [] : this.db.templates.items[item]._props.ConflictingItems;
|
||||
return [filters, conflictingItems];
|
||||
}
|
||||
copyToFilters(itemClone, modTGCID) {
|
||||
//Find the original item in all compatible and conflict filters and add the clone to those filters as well
|
||||
for (const item in this.db.templates.items) {
|
||||
if (item in this.mydb.modTgcItems)
|
||||
continue;
|
||||
const [filters, conflictingItems] = this.getFilters(item);
|
||||
for (const filter of filters) {
|
||||
for (const id of filter._props.filters[0].Filter) {
|
||||
if (id === itemClone)
|
||||
filter._props.filters[0].Filter.push(modTGCID);
|
||||
}
|
||||
}
|
||||
for (const conflictID of conflictingItems)
|
||||
if (conflictID === itemClone)
|
||||
conflictingItems.push(modTGCID);
|
||||
}
|
||||
}
|
||||
addToFilters(modTGCID) {
|
||||
//Add a new item to compatibility & conflict filters of pre-existing items
|
||||
//Add additional compatible and conflicting items to new item filters (manually adding more than the ones that were cloned)
|
||||
const modTGCNewItem = this.mydb.modTgcItems[modTGCID];
|
||||
//If the item is enabled in the json
|
||||
if (modTGCNewItem.enable) {
|
||||
this.logger.debug("addToFilters: " + modTGCID);
|
||||
//Manually add items into an THISMOD item's filters
|
||||
if ("addToThisItemsFilters" in modTGCNewItem) {
|
||||
const modTGCItemFilters = this.getFilters(modTGCID)[0];
|
||||
let modTGCConflictingItems = this.getFilters(modTGCID)[1];
|
||||
for (const modSlotName in modTGCNewItem.addToThisItemsFilters) {
|
||||
if (modSlotName === "conflicts")
|
||||
modTGCConflictingItems = modTGCConflictingItems.concat(modTGCNewItem.addToThisItemsFilters.conflicts);
|
||||
else {
|
||||
for (const filter in modTGCItemFilters) {
|
||||
if (modSlotName === modTGCItemFilters[filter]._name) {
|
||||
const slotFilter = modTGCItemFilters[filter]._props.filters[0].Filter;
|
||||
const newFilter = slotFilter.concat(modTGCNewItem.addToThisItemsFilters[modSlotName]);
|
||||
modTGCItemFilters[filter]._props.filters[0].Filter = newFilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Manually add THISMOD items to pre-existing item filters.
|
||||
if ("addToExistingItemFilters" in modTGCNewItem) {
|
||||
for (const modSlotName in modTGCNewItem.addToExistingItemFilters) {
|
||||
if (modSlotName === "conflicts") {
|
||||
for (const conflictingItem of modTGCNewItem.addToExistingItemFilters[modSlotName]) {
|
||||
const conflictingItems = this.getFilters(conflictingItem)[1];
|
||||
conflictingItems.push(modTGCID);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const compatibleItem of modTGCNewItem.addToExistingItemFilters[modSlotName]) {
|
||||
const filters = this.getFilters(compatibleItem)[0];
|
||||
for (const filter of filters) {
|
||||
if (modSlotName === filter._name)
|
||||
filter._props.filters[0].Filter.push(modTGCID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cloneClothing(itemToClone, modTGCID) {
|
||||
if (this.mydb.modTgcClothes[modTGCID].enable || !("enable" in this.mydb.modTgcClothes[modTGCID])) {
|
||||
//Get a clone of the original item from the database
|
||||
let tgcClothingOut = this.jsonUtil.clone(this.db.templates.customization[itemToClone]);
|
||||
//Change the necessary clothing item attributes using the info in our database file modTgcClothes.json
|
||||
tgcClothingOut._id = modTGCID;
|
||||
tgcClothingOut._name = modTGCID;
|
||||
tgcClothingOut = this.compareAndReplace(tgcClothingOut, this.mydb.modTgcClothes[modTGCID]["customization"]);
|
||||
//Add the new item to the database
|
||||
this.db.templates.customization[modTGCID] = tgcClothingOut;
|
||||
this.logger.debug("Clothing item " + modTGCID + " created as a clone of " + itemToClone + " and added to database.");
|
||||
}
|
||||
}
|
||||
addTraderAssort(trader) {
|
||||
if (this.mydb.traders[trader] &&
|
||||
this.mydb.traders[trader].assort &&
|
||||
this.db.traders[trader] &&
|
||||
this.db.traders[trader].assort) {
|
||||
// Merge items
|
||||
if (Array.isArray(this.mydb.traders[trader].assort.items)) {
|
||||
for (const item of this.mydb.traders[trader].assort.items) {
|
||||
this.db.traders[trader].assort.items.push(item);
|
||||
}
|
||||
}
|
||||
// Merge barter_scheme
|
||||
if (typeof this.mydb.traders[trader].assort.barter_scheme === "object") {
|
||||
Object.assign(this.db.traders[trader].assort.barter_scheme, this.mydb.traders[trader].assort.barter_scheme);
|
||||
}
|
||||
// Merge loyal_level_items
|
||||
if (typeof this.mydb.traders[trader].assort.loyal_level_items === "object") {
|
||||
Object.assign(this.db.traders[trader].assort.loyal_level_items, this.mydb.traders[trader].assort.loyal_level_items);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.warning(`Trader ${trader} does not exist in SPT database or has no assort property. Cannot add assort.`);
|
||||
}
|
||||
}
|
||||
addTraderSuits(trader) {
|
||||
// Only do anything if a suits.json file is included for trader in this mod
|
||||
if (this.mydb.traders[trader] &&
|
||||
typeof this.mydb.traders[trader].suits !== "undefined" &&
|
||||
this.db.traders[trader] &&
|
||||
this.db.traders[trader].base) {
|
||||
// Enable customization for that trader
|
||||
this.db.traders[trader].base.customization_seller = true;
|
||||
// Create the suits array if it doesn't already exist in SPT database so we can push to it
|
||||
if (typeof this.db.traders[trader].suits === "undefined")
|
||||
this.db.traders[trader].suits = [];
|
||||
// Push all suits
|
||||
for (const suit of this.mydb.traders[trader].suits)
|
||||
this.db.traders[trader].suits.push(suit);
|
||||
}
|
||||
else {
|
||||
this.logger.warning(`Trader ${trader} does not exist in SPT database or has no base property. Cannot add suits.`);
|
||||
}
|
||||
}
|
||||
addLocales(modTGCID, modTGCItem, modTGCArticle) {
|
||||
const name = modTGCID + " Name";
|
||||
const shortname = modTGCID + " ShortName";
|
||||
const description = modTGCID + " Description";
|
||||
const isItem = typeof modTGCItem !== "undefined";
|
||||
const modTGCEntry = isItem ? modTGCItem : modTGCArticle;
|
||||
for (const localeID in this.db.locales.global) //For each possible locale/language in SPT's database
|
||||
{
|
||||
let localeEntry;
|
||||
if (isItem && "locales" in modTGCEntry) {
|
||||
if (localeID in modTGCEntry.locales) //If the language is entered in modTgcItems, use that
|
||||
{
|
||||
localeEntry = {
|
||||
"Name": modTGCEntry.locales[localeID].Name,
|
||||
"ShortName": modTGCEntry.locales[localeID].ShortName,
|
||||
"Description": modTGCEntry.locales[localeID].Description
|
||||
};
|
||||
}
|
||||
else //Otherwise use english as the default
|
||||
{
|
||||
localeEntry = {
|
||||
"Name": modTGCEntry.locales.en.Name,
|
||||
"ShortName": modTGCEntry.locales.en.ShortName,
|
||||
"Description": modTGCEntry.locales.en.Description
|
||||
};
|
||||
}
|
||||
this.db.locales.global[localeID][name] = localeEntry.Name;
|
||||
this.db.locales.global[localeID][shortname] = localeEntry.ShortName;
|
||||
this.db.locales.global[localeID][description] = localeEntry.Description;
|
||||
}
|
||||
else if (!isItem && "locales" in modTGCEntry) {
|
||||
const locales = modTGCEntry.locales;
|
||||
if (localeID in locales) {
|
||||
localeEntry = {
|
||||
"Name": locales[localeID].Name,
|
||||
"Description": locales[localeID].Description || ""
|
||||
};
|
||||
}
|
||||
else {
|
||||
localeEntry = {
|
||||
"Name": locales.en.Name,
|
||||
"Description": locales.en.Description || ""
|
||||
};
|
||||
}
|
||||
this.db.locales.global[localeID][name] = localeEntry.Name;
|
||||
this.db.locales.global[localeID][description] = localeEntry.Description;
|
||||
}
|
||||
else {
|
||||
if (isItem)
|
||||
this.logger.warning("WARNING: Missing locale entry for item: " + modTGCID);
|
||||
else
|
||||
this.logger.debug("No locale entries for item/clothing: " + modTGCID);
|
||||
}
|
||||
//Also add the necessary preset locale entries if they exist
|
||||
if (isItem && modTGCItem.presets) {
|
||||
for (const preset in modTGCItem.presets) {
|
||||
this.db.locales.global[localeID][preset] = modTGCItem.presets[preset];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = { mod: new TGCItems() };
|
||||
//# sourceMappingURL=mod.js.map
|
||||
10
user/mods/MoxoPixel-TacticalGearComponent/src/mod.js.map
Normal file
10
user/mods/MoxoPixel-TacticalGearComponent/src/mod.js.map
Normal file
File diff suppressed because one or more lines are too long
438
user/mods/aMoxoPixel-Painter/src/CustomItemsManager.js
Normal file
438
user/mods/aMoxoPixel-Painter/src/CustomItemsManager.js
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CustomItemsManager = void 0;
|
||||
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
|
||||
/**
|
||||
* Manages creation of custom items for the Painter mod
|
||||
*/
|
||||
class CustomItemsManager {
|
||||
logger;
|
||||
constructor(logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
/**
|
||||
* Create all custom items for the Painter mod
|
||||
*/
|
||||
createCustomItems(customItemService, configServer, tables, inventoryConfig, enableLootBoxes) {
|
||||
// Create figurines
|
||||
this.createFigurines(customItemService, configServer, tables);
|
||||
// Create loot boxes if enabled
|
||||
if (enableLootBoxes) {
|
||||
this.createLootBoxes(customItemService, tables, inventoryConfig);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create Batman and Golden Turd figurines
|
||||
*/
|
||||
createFigurines(customItemService, configServer, tables) {
|
||||
const batmanFigurine = {
|
||||
itemTplToClone: "655c67782a1356436041c9c5",
|
||||
overrideProperties: {
|
||||
Name: "Batman figurine",
|
||||
ShortName: "Batman",
|
||||
Description: "Rare larger figurine of Batman, a superhero of the American comic book publisher DC Comics, Batman.",
|
||||
Prefab: {
|
||||
"path": "figurine_batman.bundle",
|
||||
"rcid": ""
|
||||
},
|
||||
CanRequireOnRagfair: false,
|
||||
CanSellOnRagfair: true
|
||||
},
|
||||
parentId: "57864a3d24597754843f8721",
|
||||
newId: "672e2e75d78fe9e90c8cb393",
|
||||
fleaPriceRoubles: 154000,
|
||||
handbookPriceRoubles: 154000,
|
||||
handbookParentId: "5b47574386f77428ca22b2f1",
|
||||
locales: {
|
||||
en: {
|
||||
name: "Batman figurine",
|
||||
shortName: "Batman",
|
||||
description: "Rare larger figurine of Batman, a superhero of the American comic book publisher DC Comics, Batman."
|
||||
}
|
||||
}
|
||||
};
|
||||
const dodoFigurine = {
|
||||
itemTplToClone: "59e3647686f774176a362507",
|
||||
overrideProperties: {
|
||||
Name: "Golden Turd figurine",
|
||||
ShortName: "Turd",
|
||||
Description: "Awarded to the master of annoying tasks, it is said that it was made from the golden poop of a dodo bird.",
|
||||
Prefab: {
|
||||
"path": "dodo338383899.bundle",
|
||||
"rcid": ""
|
||||
},
|
||||
CanRequireOnRagfair: false,
|
||||
CanSellOnRagfair: false,
|
||||
Weight: 69,
|
||||
ExaminedByDefault: false
|
||||
},
|
||||
parentId: "57864a3d24597754843f8721",
|
||||
newId: "684db00229850b2f1f7832c1",
|
||||
fleaPriceRoubles: 69,
|
||||
handbookPriceRoubles: 69,
|
||||
handbookParentId: "5b47574386f77428ca22b2f1",
|
||||
locales: {
|
||||
en: {
|
||||
name: "Golden Turd figurine",
|
||||
shortName: "Turd",
|
||||
description: "Awarded to the master of annoying tasks, it is said that it was made from the golden poop of a dodo bird."
|
||||
}
|
||||
}
|
||||
};
|
||||
const mosFigurine = {
|
||||
itemTplToClone: "59e3647686f774176a362507",
|
||||
overrideProperties: {
|
||||
Name: "Moscovium (Material 115)",
|
||||
ShortName: "MC-115",
|
||||
Description: "Sealed compound made from Moscovium, a synthetic element with atomic number 115, known for its unique properties. Does it bend space and time? Who knows.",
|
||||
Prefab: {
|
||||
"path": "mos115.bundle",
|
||||
"rcid": ""
|
||||
},
|
||||
CanRequireOnRagfair: false,
|
||||
CanSellOnRagfair: false,
|
||||
Weight: 69,
|
||||
ExaminedByDefault: false
|
||||
},
|
||||
parentId: "57864a3d24597754843f8721",
|
||||
newId: "685867727d49afb420c2b29e",
|
||||
fleaPriceRoubles: 69,
|
||||
handbookPriceRoubles: 69,
|
||||
handbookParentId: "5b47574386f77428ca22b2f1",
|
||||
locales: {
|
||||
en: {
|
||||
name: "Moscovium (Material 115)",
|
||||
shortName: "MC-115",
|
||||
description: "Sealed compound made from Moscovium, a synthetic element with atomic number 115, known for its unique properties. Does it bend space and time? Who knows."
|
||||
}
|
||||
}
|
||||
};
|
||||
customItemService.createItemFromClone(batmanFigurine);
|
||||
customItemService.createItemFromClone(dodoFigurine);
|
||||
customItemService.createItemFromClone(mosFigurine);
|
||||
this.logger.info("Painter custom items added");
|
||||
// Add figurines to Hall of Fame
|
||||
this.addToHallOfFame(tables, "672e2e75d78fe9e90c8cb393", "655c67782a1356436041c9c5", "Batman figurine");
|
||||
this.addToHallOfFame(tables, "684db00229850b2f1f7832c1", "59e3647686f774176a362507", "Golden Turd figurine");
|
||||
this.addToHallOfFame(tables, "685867727d49afb420c2b29e", "59e3647686f774176a362507", "Moscovium (Material 115)");
|
||||
// Prevent dodoFigurine from being lootable
|
||||
this.preventDodoFromBeingLootable(configServer);
|
||||
this.preventMosFromBeingLootable(configServer);
|
||||
}
|
||||
/**
|
||||
* Create mystery loot boxes
|
||||
*/
|
||||
createLootBoxes(customItemService, tables, inventoryConfig) {
|
||||
const mysteryBoxOne = {
|
||||
itemTplToClone: "6489b2b131a2135f0d7d0fcb",
|
||||
overrideProperties: {
|
||||
Name: "Painter's Special Delivery",
|
||||
ShortName: "Painter Lootbox",
|
||||
Description: "A lootbox filled with various items, including some of the most sought after barter items.",
|
||||
Weight: 25,
|
||||
Prefab: {
|
||||
"path": "mysterybox.bundle",
|
||||
"rcid": ""
|
||||
},
|
||||
Width: 4,
|
||||
Height: 4,
|
||||
BackgroundColor: "blue",
|
||||
CanRequireOnRagfair: false,
|
||||
CanSellOnRagfair: false
|
||||
},
|
||||
parentId: "62f109593b54472778797866",
|
||||
newId: "668ff5bde41a0cce3b142464",
|
||||
fleaPriceRoubles: 500000,
|
||||
handbookPriceRoubles: 500000,
|
||||
handbookParentId: "5b5f6fa186f77409407a7eb7",
|
||||
locales: {
|
||||
en: {
|
||||
name: "Painter's Special Delivery",
|
||||
shortName: "Painter Lootbox",
|
||||
description: "A lootbox filled with 20 items, including some of the most sought after barter items. Get a LEDX or go broke. The choise is yours."
|
||||
}
|
||||
}
|
||||
};
|
||||
customItemService.createItemFromClone(mysteryBoxOne);
|
||||
// Change item _name to remove it from the *actual* sealed weapon crate logic, this removes it from airdrops and allows easier access to change the contents
|
||||
const customIteminDB = tables.templates.items["668ff5bde41a0cce3b142464"];
|
||||
customIteminDB._name = "668ff5bde41a0cce3b142464";
|
||||
// Configure loot pool for mystery box
|
||||
this.configureMysteryBoxLoot(inventoryConfig);
|
||||
const mysteryBoxTwo = {
|
||||
itemTplToClone: "6489981f7063b903ff4b8565",
|
||||
overrideProperties: {
|
||||
Name: "Painter's War Box",
|
||||
ShortName: "Painter Warbox",
|
||||
Description: "A lootbox filled with various items, some of the most sought after military items.",
|
||||
Weight: 30,
|
||||
Prefab: {
|
||||
"path": "mysterybox_2.bundle",
|
||||
"rcid": ""
|
||||
},
|
||||
Width: 4,
|
||||
Height: 3,
|
||||
BackgroundColor: "blue",
|
||||
CanRequireOnRagfair: false,
|
||||
CanSellOnRagfair: false
|
||||
},
|
||||
parentId: "62f109593b54472778797866",
|
||||
newId: "6699546547ad52e0fccf6da9",
|
||||
fleaPriceRoubles: 500000,
|
||||
handbookPriceRoubles: 500000,
|
||||
handbookParentId: "5b5f6fa186f77409407a7eb7",
|
||||
locales: {
|
||||
en: {
|
||||
name: "Painter's War Box",
|
||||
shortName: "Painter Warbox",
|
||||
description: "A lootbox filled with various items, some of the most sought after military items."
|
||||
}
|
||||
}
|
||||
};
|
||||
customItemService.createItemFromClone(mysteryBoxTwo);
|
||||
this.logger.info("Painter loot boxes added");
|
||||
}
|
||||
/**
|
||||
* Configure the mystery box loot pool with various high-value items
|
||||
*/
|
||||
configureMysteryBoxLoot(inventoryConfig) {
|
||||
inventoryConfig.randomLootContainers["668ff5bde41a0cce3b142464"] = {
|
||||
rewardCount: 20,
|
||||
foundInRaid: true,
|
||||
rewardTplPool: {
|
||||
"5bc9be8fd4351e00334cae6e": 5,
|
||||
"5d03794386f77420415576f5": 1,
|
||||
"5672cb124bdc2d1a0f8b4568": 10,
|
||||
"6389c85357baa773a825b356": 1,
|
||||
"59faf98186f774067b6be103": 5,
|
||||
"5d1b32c186f774252167a530": 5,
|
||||
"590de71386f774347051a052": 5,
|
||||
"590de7e986f7741b096e5f32": 5,
|
||||
"573475fb24597737fb1379e1": 10,
|
||||
"6389c6c7dbfd5e4b95197e68": 5,
|
||||
"5e2af4d286f7746d4159f07a": 5,
|
||||
"62a0a098de7ac8199358053b": 5,
|
||||
"62a091170b9d3c46de5b6cf2": 5,
|
||||
"5bc9c049d4351e44f824d360": 5,
|
||||
"62a08f4c4f842e1bd12d9d62": 5,
|
||||
"57347c5b245977448d35f6e1": 10,
|
||||
"59e361e886f774176c10a2a5": 5,
|
||||
"62a0a043cf4a99369e2624a5": 5,
|
||||
"59e3606886f77417674759a5": 5,
|
||||
"56742c324bdc2d150f8b456d": 10,
|
||||
"5c1265fc86f7743f896a21c2": 5,
|
||||
"5d1b309586f77425227d1676": 10,
|
||||
"59e3639286f7741777737013": 1,
|
||||
"619cbfeb6b8a1b37a54eebfa": 5,
|
||||
"5c06779c86f77426e00dd782": 10,
|
||||
"5e54f6af86f7742199090bf3": 5,
|
||||
"5af0484c86f7740f02001f7f": 10,
|
||||
"60391a8b3364dc22b04d0ce5": 5,
|
||||
"62a09ee4cf4a99369e262453": 10,
|
||||
"5c06782b86f77426df5407d2": 10,
|
||||
"5733279d245977289b77ec24": 5,
|
||||
"59e3658a86f7741776641ac4": 5,
|
||||
"573474f924597738002c6174": 5,
|
||||
"5c1267ee86f77416ec610f72": 5,
|
||||
"57347b8b24597737dd42e192": 10,
|
||||
"59e358a886f7741776641ac3": 5,
|
||||
"590c2c9c86f774245b1f03f2": 10,
|
||||
"5e2af41e86f774755a234b67": 5,
|
||||
"59e35cbb86f7741778269d83": 5,
|
||||
"5734779624597737e04bf329": 10,
|
||||
"56742c284bdc2d98058b456d": 10,
|
||||
"5e2aee0a86f774755a234b62": 5,
|
||||
"590a386e86f77429692b27ab": 5,
|
||||
"5bc9b9ecd4351e3bac122519": 5,
|
||||
"5d1b3f2d86f774253763b735": 5,
|
||||
"590a373286f774287540368b": 5,
|
||||
"57347c1124597737fb1379e3": 10,
|
||||
"5734781f24597737e04bf32a": 5,
|
||||
"5672cb304bdc2dc2088b456a": 5,
|
||||
"59e35de086f7741778269d84": 5,
|
||||
"5d1b2fa286f77425227d1674": 5,
|
||||
"6389c70ca33d8c4cdf4932c6": 5,
|
||||
"590a3cd386f77436f20848cb": 10,
|
||||
"5d1b371186f774253763a656": 5,
|
||||
"6389c7f115805221fb410466": 1,
|
||||
"63a0b208f444d32d6f03ea1e": 1,
|
||||
"5bc9b355d4351e6d1509862a": 5,
|
||||
"5d63d33b86f7746ea9275524": 10,
|
||||
"5d4042a986f7743185265463": 10,
|
||||
"5e2af47786f7746d404f3aaa": 5,
|
||||
"5d1b2f3f86f774252167a52c": 1,
|
||||
"5b43575a86f77424f443fe62": 5,
|
||||
"590a3efd86f77437d351a25b": 5,
|
||||
"590c595c86f7747884343ad7": 5,
|
||||
"5672cb724bdc2dc2088b456b": 5,
|
||||
"5bc9b720d4351e450201234b": 5,
|
||||
"62a09cfe4f842e1bd12da3e4": 5,
|
||||
"5734758f24597738025ee253": 5,
|
||||
"5bc9bc53d4351e00367fbcee": 5,
|
||||
"5d235a5986f77443f6329bc6": 5,
|
||||
"57347ca924597744596b4e71": 1,
|
||||
"5e2aedd986f7746d404f3aa4": 5,
|
||||
"5d6fc78386f77449d825f9dc": 5,
|
||||
"5d6fc87386f77449db3db94e": 5,
|
||||
"590c5a7286f7747884343aea": 5,
|
||||
"5d1b317c86f7742523398392": 5,
|
||||
"573478bc24597738002c6175": 5,
|
||||
"5e2af2bc86f7746d3f3c33fc": 5,
|
||||
"5734795124597738002c6176": 10,
|
||||
"5d0377ce86f774186372f689": 1,
|
||||
"5e2af29386f7746d4159f077": 5,
|
||||
"5c0530ee86f774697952d952": 1,
|
||||
"5d1b392c86f77425243e98fe": 10,
|
||||
"60b0f7057897d47c5b04ab94": 5,
|
||||
"60b0f561c4449e4cb624c1d7": 5,
|
||||
"590a391c86f774385a33c404": 5,
|
||||
"573476d324597737da2adc13": 10,
|
||||
"5b4335ba86f7744d2837a264": 5,
|
||||
"619cc01e0a7c3a1a2731940c": 5,
|
||||
"5d40419286f774318526545f": 10,
|
||||
"5d1b36a186f7742523398433": 1,
|
||||
"61bf7b6302b3924be92fa8c3": 10,
|
||||
"6389c7750ef44505c87f5996": 1,
|
||||
"5d0375ff86f774186372f685": 1,
|
||||
"5d0376a486f7747d8050965c": 1,
|
||||
"5c052f6886f7746b1e3db148": 1,
|
||||
"619cbf476b8a1b37a54eebf8": 5,
|
||||
"5d03784a86f774203e7e0c4d": 1,
|
||||
"5d0378d486f77420421a5ff4": 1,
|
||||
"5d40425986f7743185265461": 10,
|
||||
"5d1b2ffd86f77425243e8d17": 10,
|
||||
"5d0379a886f77420407aa271": 1,
|
||||
"5bc9c377d4351e3bac12251b": 5,
|
||||
"5af0534a86f7743b6f354284": 5,
|
||||
"5d4041f086f7743cac3f22a7": 5,
|
||||
"59e3556c86f7741776641ac2": 10,
|
||||
"5e2af02c86f7746d420957d4": 10,
|
||||
"590c31c586f774245e3141b2": 10,
|
||||
"59e35ef086f7741777737012": 10,
|
||||
"59e35abd86f7741778269d82": 5,
|
||||
"59e3596386f774176c10a2a2": 5,
|
||||
"5c12688486f77426843c7d32": 5,
|
||||
"573477e124597737dd42e191": 10,
|
||||
"5d03775b86f774203e7e0c4b": 1,
|
||||
"5d1b313086f77425227d1678": 10,
|
||||
"59faff1d86f7746c51718c9c": 1,
|
||||
"59e366c186f7741778269d85": 10,
|
||||
"5d1b3a5d86f774252167ba22": 5,
|
||||
"619cbfccbedcde2f5b3f7bdd": 5,
|
||||
"590c2b4386f77425357b6123": 10,
|
||||
"5af04b6486f774195a3ebb49": 10,
|
||||
"5c052e6986f7746b207bc3c9": 1,
|
||||
"5af0561e86f7745f5f3ad6ac": 5,
|
||||
"59e36c6f86f774176c10a2a7": 5,
|
||||
"57347c2e24597744902c94a1": 5,
|
||||
"5d1b327086f7742525194449": 5,
|
||||
"62a09cb7a04c0c5c6e0a84f8": 5,
|
||||
"590a3b0486f7743954552bdb": 1,
|
||||
"577e1c9d2459773cd707c525": 5,
|
||||
"59fafb5d86f774067a6f2084": 1,
|
||||
"5d1c774f86f7746d6620f8db": 10,
|
||||
"57347baf24597738002c6178": 10,
|
||||
"60391afc25aff57af81f7085": 1,
|
||||
"5e54f62086f774219b0f1937": 5,
|
||||
"590a358486f77429692b2790": 5,
|
||||
"5e2aef7986f7746d3f3c33f5": 5,
|
||||
"5e2af4a786f7746d3f3c3400": 5,
|
||||
"59faf7ca86f7740dbe19f6c2": 5,
|
||||
"5d1b31ce86f7742523398394": 10,
|
||||
"5d40412b86f7743cb332ac3a": 5,
|
||||
"590c2d8786f774245b1f03f3": 10,
|
||||
"57347c77245977448d35f6e2": 10,
|
||||
"62a0a0bb621468534a797ad5": 5,
|
||||
"61bf83814088ec1a363d7097": 5,
|
||||
"590c35a486f774273531c822": 10,
|
||||
"5d1b39a386f774252339976f": 10,
|
||||
"5bc9bdb8d4351e003562b8a1": 5,
|
||||
"5e2af00086f7746d3f3c33f7": 10,
|
||||
"5c13cd2486f774072c757944": 10,
|
||||
"590a3c0a86f774385a33c450": 10,
|
||||
"5734770f24597738025ee254": 10,
|
||||
"5e2af37686f774755a234b65": 10,
|
||||
"5c12620d86f7743f8b198b72": 1,
|
||||
"5c13cef886f774072e618e82": 10,
|
||||
"590c2e1186f77425357b6124": 5,
|
||||
"57347c93245977448d35f6e3": 10,
|
||||
"60391b0fb847c71012789415": 5,
|
||||
"57347cd0245977445a2d6ff1": 10,
|
||||
"5e2af22086f7746d3f3c33fa": 10,
|
||||
"5c052fb986f7746b2101e909": 1,
|
||||
"590a3d9c86f774385926e510": 10,
|
||||
"5909e99886f7740c983b9984": 10,
|
||||
"5f745ee30acaeb0d490d8c5b": 5,
|
||||
"5c05308086f7746b2101e90b": 1,
|
||||
"5c05300686f7746dce784e5d": 1,
|
||||
"5d1b385e86f774252167b98a": 5,
|
||||
"590c5bbd86f774785762df04": 10,
|
||||
"590c5c9f86f77477c91c36e7": 10,
|
||||
"5d1c819a86f774771b0acd6c": 5,
|
||||
"573476f124597737e04bf328": 10,
|
||||
"59e3647686f774176a362507": 5,
|
||||
"5d1b304286f774253763a528": 5,
|
||||
"590c311186f77424d1667482": 5,
|
||||
"590c346786f77423e50ed342": 10,
|
||||
"56742c2e4bdc2d95058b456d": 10
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Add custom figurines to Hall of Fame filters
|
||||
*/
|
||||
addToHallOfFame(tables, newItemId, originalItemId, itemName) {
|
||||
const hallOfFame1 = tables.templates.items["63dbd45917fff4dee40fe16e"];
|
||||
const hallOfFame2 = tables.templates.items["65424185a57eea37ed6562e9"];
|
||||
const hallOfFame3 = tables.templates.items["6542435ea57eea37ed6562f0"];
|
||||
const hallOfFames = [hallOfFame1, hallOfFame2, hallOfFame3];
|
||||
let totalAdditions = 0;
|
||||
hallOfFames.forEach((hall) => {
|
||||
if (hall && hall._props && hall._props.Slots) {
|
||||
let additionsThisHall = 0;
|
||||
for (const slot of hall._props.Slots) {
|
||||
if (slot._props && slot._props.filters) {
|
||||
for (const filter of slot._props.filters) {
|
||||
// Only add the new item if the original cloned item is already in this filter
|
||||
if (filter.Filter && filter.Filter.includes(originalItemId) && !filter.Filter.includes(newItemId)) {
|
||||
filter.Filter.push(newItemId);
|
||||
additionsThisHall++;
|
||||
totalAdditions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (additionsThisHall > 0) {
|
||||
this.logger.debug(`Added ${itemName} to ${additionsThisHall} slot(s) in ${hall._name}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (totalAdditions > 0) {
|
||||
this.logger.debug(`Successfully added ${itemName} (${newItemId}) to ${totalAdditions} total Hall of Fame slot(s)`);
|
||||
}
|
||||
else {
|
||||
this.logger.debug(`WARNING: No Hall of Fame slots found for ${itemName} - original item ${originalItemId} may not be in any Hall of Fame filters`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Prevent the Golden Turd figurine from being lootable
|
||||
*/
|
||||
preventDodoFromBeingLootable(configServer) {
|
||||
const itemConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.ITEM);
|
||||
const dodoFigurineId = "684db00229850b2f1f7832c1";
|
||||
// Add to lootable item blacklist to prevent it from spawning in any loot containers or loose loot
|
||||
if (!itemConfig.lootableItemBlacklist.includes(dodoFigurineId)) {
|
||||
itemConfig.lootableItemBlacklist.push(dodoFigurineId);
|
||||
}
|
||||
}
|
||||
preventMosFromBeingLootable(configServer) {
|
||||
const itemConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.ITEM);
|
||||
const mosFigurineId = "685867727d49afb420c2b29e";
|
||||
// Add to lootable item blacklist to prevent it from spawning in any loot containers or loose loot
|
||||
if (!itemConfig.lootableItemBlacklist.includes(mosFigurineId)) {
|
||||
itemConfig.lootableItemBlacklist.push(mosFigurineId);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.CustomItemsManager = CustomItemsManager;
|
||||
//# sourceMappingURL=CustomItemsManager.js.map
|
||||
10
user/mods/aMoxoPixel-Painter/src/CustomItemsManager.js.map
Normal file
10
user/mods/aMoxoPixel-Painter/src/CustomItemsManager.js.map
Normal file
File diff suppressed because one or more lines are too long
236
user/mods/aMoxoPixel-Painter/src/mod.js
Normal file
236
user/mods/aMoxoPixel-Painter/src/mod.js
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
|
||||
const Traders_1 = require("C:/snapshot/project/obj/models/enums/Traders");
|
||||
const CustomItemsManager_1 = require("./CustomItemsManager");
|
||||
const configJson = __importStar(require("../config.json"));
|
||||
const baseJson = __importStar(require("../db/base.json"));
|
||||
const assortJson = __importStar(require("../db/assort.json"));
|
||||
const path = __importStar(require("path"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const modPath = path.normalize(path.join(__dirname, ".."));
|
||||
class PainterTrader {
|
||||
mod;
|
||||
logger;
|
||||
configServer;
|
||||
ragfairConfig;
|
||||
constructor() {
|
||||
this.mod = "aMoxoPixel-Painter";
|
||||
}
|
||||
preSptLoad(container) {
|
||||
this.logger = container.resolve("WinstonLogger");
|
||||
const PreSptModLoader = container.resolve("PreSptModLoader");
|
||||
const imageRouter = container.resolve("ImageRouter");
|
||||
const configServer = container.resolve("ConfigServer");
|
||||
const traderConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.TRADER);
|
||||
const questConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.QUEST);
|
||||
if (!traderConfig.moddedTraders) {
|
||||
traderConfig.moddedTraders = { clothingService: [] };
|
||||
}
|
||||
if (configJson.enableRepeatableQuests) {
|
||||
const PainterRepeatQuests = {
|
||||
traderId: "668aaff35fd574b6dcc4a686",
|
||||
name: "painter",
|
||||
questTypes: ["Completion", "Exploration", "Elimination"],
|
||||
rewardBaseWhitelist: [
|
||||
"543be6564bdc2df4348b4568",
|
||||
"5448e5284bdc2dcb718b4567",
|
||||
"5485a8684bdc2da71d8b4567",
|
||||
"57864a3d24597754843f8721",
|
||||
"55818af64bdc2d5b648b4570",
|
||||
"57864e4c24597754843f8723",
|
||||
"57864a66245977548f04a81f",
|
||||
"57864ee62459775490116fc1",
|
||||
"590c745b86f7743cc433c5f2"
|
||||
],
|
||||
rewardCanBeWeapon: true,
|
||||
weaponRewardChancePercent: 20
|
||||
};
|
||||
questConfig.repeatableQuests[0].traderWhitelist.push(PainterRepeatQuests); // Daily quests
|
||||
questConfig.repeatableQuests[1].traderWhitelist.push(PainterRepeatQuests); // Weekly quests
|
||||
this.logger.info("Painter repeatable quests added to quest config");
|
||||
}
|
||||
this.registerProfileImage(PreSptModLoader, imageRouter);
|
||||
this.setupTraderUpdateTime(traderConfig);
|
||||
this.setupTraderServices(traderConfig);
|
||||
Traders_1.Traders["668aaff35fd574b6dcc4a686"] = "668aaff35fd574b6dcc4a686";
|
||||
}
|
||||
postDBLoad(container) {
|
||||
this.configServer = container.resolve("ConfigServer");
|
||||
this.ragfairConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.RAGFAIR);
|
||||
const configServer = container.resolve("ConfigServer");
|
||||
const imageRouter = container.resolve("ImageRouter");
|
||||
const jsonUtil = container.resolve("JsonUtil");
|
||||
const databaseServer = container.resolve("DatabaseServer");
|
||||
const databaseService = container.resolve("DatabaseService");
|
||||
const customItem = container.resolve("CustomItemService");
|
||||
const inventoryConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.INVENTORY);
|
||||
const tables = databaseService.getTables();
|
||||
if (configJson.enableRepeatableQuests) {
|
||||
const repeatableQuests = databaseServer.getTables().templates.repeatableQuests;
|
||||
const rqLocales = databaseServer.getTables().locales.global.en;
|
||||
if (repeatableQuests.templates.Elimination) {
|
||||
repeatableQuests.templates.Elimination.successMessageText = "A damn beast you are, hehe. Good work, here's your share.";
|
||||
repeatableQuests.templates.Elimination.description = "I have a mission for you. I need you to eliminate some trash from Tarkov's streets. You up for it?";
|
||||
}
|
||||
if (repeatableQuests.templates.Completion) {
|
||||
repeatableQuests.templates.Completion.successMessageText = "There you are! You got everything? Good stuff.";
|
||||
repeatableQuests.templates.Completion.description = "I have a mission for you. I need you to gather some items for me. You up for it?";
|
||||
}
|
||||
if (repeatableQuests.templates.Exploration) {
|
||||
repeatableQuests.templates.Exploration.successMessageText = "Marvelous, young man. Thank you for some fine work.";
|
||||
repeatableQuests.templates.Exploration.description = "Ah, mercenary, do you want to do a good deed? My clients are asking to ensure a safe area to conduct a specific secret operation. I would like to appoint you for this, as you are the most competent of the local workers. You will have to survey the area and report back to me. Good luck.";
|
||||
}
|
||||
// Update localization files
|
||||
rqLocales["616041eb031af660100c9967 successMessageText 668aaff35fd574b6dcc4a686 0"] = "Marvelous, young man. Thank you for the work.";
|
||||
rqLocales["616041eb031af660100c9967 description 668aaff35fd574b6dcc4a686 0"] = "Ah, mercenary, do you want to do a good deed? My clients are asking to ensure a safe area to conduct a specific secret operation. I would like to appoint you for this, as you are the most competent of the local workers. You will have to survey the area and report back to me. Good luck.";
|
||||
rqLocales["61604635c725987e815b1a46 successMessageText 668aaff35fd574b6dcc4a686 0"] = "There you are! You got everything? Good stuff.";
|
||||
rqLocales["61604635c725987e815b1a46 description 668aaff35fd574b6dcc4a686 0"] = "I have a mission for you. I need you to gather some items for me. You up for it?";
|
||||
rqLocales["616052ea3054fc0e2c24ce6e successMessageText 668aaff35fd574b6dcc4a686 0"] = "A damn beast you are, hehe. Good work, here's your share.";
|
||||
rqLocales["616052ea3054fc0e2c24ce6e description 668aaff35fd574b6dcc4a686 0"] = "I have a mission for you. I need you to eliminate some trash from Tarkov's streets. You up for it?";
|
||||
this.logger.info("Painter repeatable quest messages added to localization files");
|
||||
}
|
||||
this.addTraderToDb(baseJson, tables, jsonUtil);
|
||||
this.addTraderToLocales(tables, baseJson.name, "Ivan Samoylov", baseJson.nickname, baseJson.location, "Ivan Samoylov is a master craftsman renowned for his exceptional skill in creating exquisite weapon cosmetics. With an innate talent for blending artistry and functionality, he transforms ordinary weapons into mesmerizing works of art.");
|
||||
this.ragfairConfig.traders[baseJson._id] = true;
|
||||
this.importQuests(tables);
|
||||
this.importQuestLocales(tables);
|
||||
this.routeQuestImages(imageRouter);
|
||||
// Create all custom items using the CustomItemsManager
|
||||
const customItemsManager = new CustomItemsManager_1.CustomItemsManager(this.logger);
|
||||
customItemsManager.createCustomItems(customItem, configServer, tables, inventoryConfig, configJson.enableLootBoxes);
|
||||
}
|
||||
registerProfileImage(preSptModLoader, imageRouter) {
|
||||
const imageFilepath = `./${preSptModLoader.getModPath(this.mod)}res`;
|
||||
imageRouter.addRoute(baseJson.avatar.replace(".jpg", ""), `${imageFilepath}/painter.jpg`);
|
||||
}
|
||||
setupTraderUpdateTime(traderConfig) {
|
||||
const traderRefreshRecord = { traderId: baseJson._id, seconds: { min: 2000, max: 6600 } };
|
||||
traderConfig.updateTime.push(traderRefreshRecord);
|
||||
}
|
||||
setupTraderServices(traderConfig) {
|
||||
const traderId = baseJson._id;
|
||||
if (!traderConfig.moddedTraders) {
|
||||
traderConfig.moddedTraders = { clothingService: [] };
|
||||
}
|
||||
traderConfig.moddedTraders.clothingService.push(traderId);
|
||||
}
|
||||
addTraderToDb(traderDetailsToAdd, tables, jsonUtil) {
|
||||
tables.traders[traderDetailsToAdd._id] = {
|
||||
assort: jsonUtil.deserialize(jsonUtil.serialize(assortJson)),
|
||||
base: jsonUtil.deserialize(jsonUtil.serialize(traderDetailsToAdd)),
|
||||
questassort: {
|
||||
started: {},
|
||||
success: {
|
||||
"672e2804a0529208b4e10e18": "668aad3c3ff8f5b258e3a65b",
|
||||
"672e284a363b798192b802af": "668c18eb12542b3c3ff6e20f",
|
||||
"672e289bb4096716fcb918a7": "668c18eb12542b3c3ff6e20f"
|
||||
},
|
||||
fail: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
addTraderToLocales(tables, fullName, firstName, nickName, location, description) {
|
||||
const locales = Object.values(tables.locales.global);
|
||||
for (const locale of locales) {
|
||||
locale[`${baseJson._id} FullName`] = fullName;
|
||||
locale[`${baseJson._id} FirstName`] = firstName;
|
||||
locale[`${baseJson._id} Nickname`] = nickName;
|
||||
locale[`${baseJson._id} Location`] = location;
|
||||
locale[`${baseJson._id} Description`] = description;
|
||||
}
|
||||
}
|
||||
loadFiles(dirPath, extName, cb) {
|
||||
if (!fs.existsSync(dirPath))
|
||||
return;
|
||||
const dir = fs.readdirSync(dirPath, { withFileTypes: true });
|
||||
dir.forEach(item => {
|
||||
const itemPath = path.normalize(`${dirPath}/${item.name}`);
|
||||
if (item.isDirectory())
|
||||
this.loadFiles(itemPath, extName, cb);
|
||||
else if (extName.includes(path.extname(item.name)))
|
||||
cb(itemPath);
|
||||
});
|
||||
}
|
||||
importQuests(tables) {
|
||||
this.loadFiles(`${modPath}/db/quests/`, [".json"], function (filePath) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const item = require(filePath);
|
||||
if (Object.keys(item).length < 1)
|
||||
return;
|
||||
for (const quest in item) {
|
||||
tables.templates.quests[quest] = item[quest];
|
||||
}
|
||||
});
|
||||
}
|
||||
importQuestLocales(tables) {
|
||||
const serverLocales = ["ch", "cz", "en", "es", "es-mx", "fr", "ge", "hu", "it", "jp", "pl", "po", "ru", "sk", "tu"];
|
||||
const addedLocales = {};
|
||||
for (const locale of serverLocales) {
|
||||
this.loadFiles(`${modPath}/db/locales/${locale}`, [".json"], function (filePath) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const localeFile = require(filePath);
|
||||
if (Object.keys(localeFile).length < 1)
|
||||
return;
|
||||
for (const currentItem in localeFile) {
|
||||
tables.locales.global[locale][currentItem] = localeFile[currentItem];
|
||||
if (!Object.keys(addedLocales).includes(locale))
|
||||
addedLocales[locale] = {};
|
||||
addedLocales[locale][currentItem] = localeFile[currentItem];
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const locale of serverLocales) {
|
||||
if (locale == "en")
|
||||
continue;
|
||||
for (const englishItem in addedLocales["en"]) {
|
||||
if (locale in addedLocales) {
|
||||
if (englishItem in addedLocales[locale])
|
||||
continue;
|
||||
}
|
||||
if (tables.locales.global[locale] != undefined)
|
||||
tables.locales.global[locale][englishItem] = addedLocales["en"][englishItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
routeQuestImages(imageRouter) {
|
||||
this.loadFiles(`${modPath}/res/quests/`, [".png", ".jpg"], function (filePath) {
|
||||
imageRouter.addRoute(`/files/quest/icon/${path.basename(filePath, path.extname(filePath))}`, filePath);
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = { mod: new PainterTrader() };
|
||||
//# sourceMappingURL=mod.js.map
|
||||
10
user/mods/aMoxoPixel-Painter/src/mod.js.map
Normal file
10
user/mods/aMoxoPixel-Painter/src/mod.js.map
Normal file
File diff suppressed because one or more lines are too long
41
user/mods/acidphantasm-bosseshavelegamedals/src/mod.js
Normal file
41
user/mods/acidphantasm-bosseshavelegamedals/src/mod.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mod = void 0;
|
||||
const tsyringe_1 = require("C:/snapshot/project/node_modules/tsyringe");
|
||||
const jsonc_1 = require("C:/snapshot/project/node_modules/jsonc");
|
||||
const path_1 = __importDefault(require("path"));
|
||||
class BossesHaveLegaMedals {
|
||||
logger;
|
||||
static fileSystemSync = tsyringe_1.container.resolve("FileSystemSync");
|
||||
static config = jsonc_1.jsonc.parse(BossesHaveLegaMedals.fileSystemSync.read(path_1.default.resolve(__dirname, "../config/config.jsonc")));
|
||||
postDBLoad(container) {
|
||||
const databaseService = container.resolve("DatabaseService");
|
||||
this.logger = container.resolve("WinstonLogger");
|
||||
const tables = databaseService.getTables();
|
||||
let chance = BossesHaveLegaMedals.config.legaMedalChance;
|
||||
if (chance <= 0)
|
||||
chance = 1;
|
||||
for (const botType in tables.bots.types) {
|
||||
if (!botType.includes("boss") || botType == "bosstest") {
|
||||
continue;
|
||||
}
|
||||
const bossPockets = tables.bots.types[botType].inventory.items.Pockets;
|
||||
const bossTotal = Object.values(bossPockets).reduce((a, b) => a + b, 0);
|
||||
let value = 0;
|
||||
let guess = 0;
|
||||
let rollChance = 0;
|
||||
guess = chance / 100 * bossTotal;
|
||||
value = Math.round((chance / 100) * (bossTotal + guess));
|
||||
rollChance = value / (bossTotal + value);
|
||||
//this.logger.debug(`[BossesHaveLegaMedals] ${botType}: ${(bossTotal + value)} --- if value: ${value} then chance is ${rollChance}`);
|
||||
if (BossesHaveLegaMedals.config.debugLogging)
|
||||
this.logger.debug(`[BossesHaveLegaMedals] ${botType}: Chance is ${Number(rollChance).toLocaleString(undefined, { style: 'percent', minimumFractionDigits: 2 })}`);
|
||||
bossPockets["6656560053eaaa7a23349c86"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.mod = new BossesHaveLegaMedals();
|
||||
//# sourceMappingURL=mod.js.map
|
||||
10
user/mods/acidphantasm-bosseshavelegamedals/src/mod.js.map
Normal file
10
user/mods/acidphantasm-bosseshavelegamedals/src/mod.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "mod.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"mod.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;;;;AAAA,wEAA2F;AAM3F,kEAA+D;AAC/D,gDAAwB;AAGxB,MAAM,oBAAoB;IAEd,MAAM,CAAS;IAEf,MAAM,CAAC,cAAc,GAAG,oBAAS,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;IAC5E,MAAM,CAAC,MAAM,GAAW,aAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,cAAc,CAAC,IAAI,CAAC,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC;IAElI,UAAU,CAAC,SAA8B;QAE5C,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAkB,iBAAiB,CAAC,CAAC;QAC9E,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAoB,eAAe,CAAC,SAAS,EAAE,CAAC;QAE5D,IAAI,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,eAAe,CAAC;QACzD,IAAI,MAAM,IAAI,CAAC;YAAE,MAAM,GAAG,CAAC,CAAC;QAE5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EACvC,CAAC;YACG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,IAAI,UAAU,EACtD,CAAC;gBACG,SAAS;YACb,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YACvE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAExE,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,UAAU,GAAG,CAAC,CAAC;YAEnB,KAAK,GAAG,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;YACjC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;YACzD,UAAU,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,CAAA;YACxC,qIAAqI;YACrI,IAAI,oBAAoB,CAAC,MAAM,CAAC,YAAY;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,OAAO,eAAe,MAAM,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC,SAAS,EAAC,EAAC,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAC,CAAC,EAAC,CAAC,EAAE,CAAC,CAAC;YAC5M,WAAW,CAAC,0BAA0B,CAAC,GAAG,KAAK,CAAC;QACpD,CAAC;IACL,CAAC;;AASQ,QAAA,GAAG,GAAG,IAAI,oBAAoB,EAAE,CAAC"
|
||||
}
|
||||
29
user/mods/acidphantasm-refsptfriendlyquests/src/mod.js
Normal file
29
user/mods/acidphantasm-refsptfriendlyquests/src/mod.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mod = void 0;
|
||||
class RefSPTFriendlyQuests {
|
||||
customQuestTable = require("../db/Ref_quests.json");
|
||||
postDBLoad(container) {
|
||||
const databaseService = container.resolve("DatabaseService");
|
||||
const tables = databaseService.getTables();
|
||||
const localeTable = tables.locales.global;
|
||||
const questTable = tables.templates.quests;
|
||||
const refTraderID = "6617beeaa9cfa777ca915b7c";
|
||||
const refBase = tables.traders[refTraderID].base;
|
||||
const refQuestAssort = tables.traders[refTraderID].questassort;
|
||||
//Update assort to have quest reward
|
||||
refQuestAssort["success"]["66c1beaefa6e5a0c120f0d08"] = "668caeedbdb70c05d702f1b6";
|
||||
questTable["66058cc1da30b620a34e6e86"] = this.customQuestTable["66058cc1da30b620a34e6e86"]; //tgh p1
|
||||
questTable["66058cc208308761cf390993"] = this.customQuestTable["66058cc208308761cf390993"]; //tgh p2
|
||||
questTable["66058cc5bb83da7ba474aba9"] = this.customQuestTable["66058cc5bb83da7ba474aba9"]; //tgh p3
|
||||
for (const language in localeTable) {
|
||||
localeTable[language]["668caeedbdb70c05d702f0fc"] = "Eliminate PMCs"; // tgh p1
|
||||
localeTable[language]["662ba78e19c86d3199ae0a93"] = "Eliminate PMCs"; // tgh p2
|
||||
localeTable[language]["662ba61d3ed61b6b78187b71"] = "Eliminate PMCs"; // tgh p3
|
||||
}
|
||||
// Change LL4 requirements for Ref to be 1.00
|
||||
refBase.loyaltyLevels[3].minStanding = 1.0;
|
||||
}
|
||||
}
|
||||
exports.mod = new RefSPTFriendlyQuests();
|
||||
//# sourceMappingURL=mod.js.map
|
||||
10
user/mods/acidphantasm-refsptfriendlyquests/src/mod.js.map
Normal file
10
user/mods/acidphantasm-refsptfriendlyquests/src/mod.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "mod.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"mod.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;AAOA,MAAM,oBAAoB;IAEd,gBAAgB,GAA2B,OAAO,CAAC,uBAAuB,CAAC,CAAA;IAE5E,UAAU,CAAC,SAA8B;QAE5C,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAkB,iBAAiB,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAoB,eAAe,CAAC,SAAS,EAAE,CAAC;QAC5D,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;QAC3C,MAAM,WAAW,GAAG,0BAA0B,CAAC;QAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC;QACjD,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC;QAE/D,oCAAoC;QACpC,cAAc,CAAC,SAAS,CAAC,CAAC,0BAA0B,CAAC,GAAG,0BAA0B,CAAE;QAEpF,UAAU,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAC,CAAC,QAAQ;QACpG,UAAU,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAC,CAAC,QAAQ;QACpG,UAAU,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAC,CAAC,QAAQ;QAEpG,KAAK,MAAM,QAAQ,IAAI,WAAW,EAClC,CAAC;YACG,WAAW,CAAC,QAAQ,CAAC,CAAC,0BAA0B,CAAC,GAAG,gBAAgB,CAAA,CAAC,SAAS;YAC9E,WAAW,CAAC,QAAQ,CAAC,CAAC,0BAA0B,CAAC,GAAG,gBAAgB,CAAA,CAAC,SAAS;YAC9E,WAAW,CAAC,QAAQ,CAAC,CAAC,0BAA0B,CAAC,GAAG,gBAAgB,CAAA,CAAC,SAAS;QAClF,CAAC;QAED,6CAA6C;QAC7C,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC;IAC/C,CAAC;CACJ;AAEY,QAAA,GAAG,GAAG,IAAI,oBAAoB,EAAE,CAAC"
|
||||
}
|
||||
65
user/mods/redlaser42- Better Headset Descriptions/src/mod.js
Normal file
65
user/mods/redlaser42- Better Headset Descriptions/src/mod.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mod = void 0;
|
||||
const jsonc_1 = require("C:/snapshot/project/node_modules/jsonc");
|
||||
const path = __importStar(require("path"));
|
||||
class Mod {
|
||||
postDBLoad(container) {
|
||||
const LocaleHelper = container.resolve("LocaleService");
|
||||
const locale = LocaleHelper.getDesiredGameLocale();
|
||||
const localeDB = LocaleHelper.getLocaleDb();
|
||||
const fileSystem = container.resolve("FileSystemSync");
|
||||
//Config Variables
|
||||
const hearingColor = "#598559";
|
||||
const ambientColor = "#f59542";
|
||||
//load config file
|
||||
const headsetConfigs = jsonc_1.jsonc.parse(fileSystem.read(path.resolve(__dirname, "../config/headset-config.json")));
|
||||
//Update function
|
||||
const headsetDescUpdate = (itemID, Hearing, Ambient) => {
|
||||
const headsetDesc = localeDB[`${itemID} Description`];
|
||||
const headsetDescNew = headsetDesc +
|
||||
`\n\n <color=${hearingColor}>Rated Hearing Distance: ${Hearing} meters</color>\n` +
|
||||
` <color=${ambientColor}>Ambient Noise Canceling: -${Ambient}db</color>`;
|
||||
localeDB[`${itemID} Description`] = headsetDescNew;
|
||||
};
|
||||
// Loop and apply
|
||||
for (const [itemID, hearing, ambient] of headsetConfigs) {
|
||||
headsetDescUpdate(itemID, hearing, ambient);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.mod = new Mod();
|
||||
//# sourceMappingURL=mod.js.map
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "mod.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"mod.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,kEAA+D;AAC/D,2CAA6B;AAE7B,MAAM,GAAG;IAEE,UAAU,CAAC,SAA8B;QAC5C,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAgB,eAAe,CAAC,CAAC;QACvE,MAAM,MAAM,GAAkB,YAAY,CAAC,oBAAoB,EAAE,CAAC;QAClE,MAAM,QAAQ,GAA2B,YAAY,CAAC,WAAW,EAAE,CAAC;QACpE,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;QAEvE,kBAAkB;QAClB,MAAM,YAAY,GAAG,SAAS,CAAC;QAC/B,MAAM,YAAY,GAAG,SAAS,CAAC;QAC/B,kBAAkB;QAClB,MAAM,cAAc,GAA+B,aAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC,CAAC,CAAC;QAE1I,iBAAiB;QACjB,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAE,OAAe,EAAE,OAAe,EAAQ,EAAE;YACjF,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,MAAM,cAAc,CAAC,CAAC;YACtD,MAAM,cAAc,GAAG,WAAW;gBAC9B,eAAe,YAAY,4BAA4B,OAAO,mBAAmB;gBACjF,WAAW,YAAY,8BAA8B,OAAO,YAAY,CAAC;YAC7E,QAAQ,CAAC,GAAG,MAAM,cAAc,CAAC,GAAG,cAAc,CAAC;QACvD,CAAC,CAAA;QAED,iBAAiB;QACjB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,cAAc,EAAE,CAAC;YACtD,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;IAEL,CAAC;CACJ;AAEY,QAAA,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC"
|
||||
}
|
||||
43
user/mods/tyfon-uifixes/src/assortUnlocks.js
Normal file
43
user/mods/tyfon-uifixes/src/assortUnlocks.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.assortUnlocks = void 0;
|
||||
const assortUnlocks = (container) => {
|
||||
const logger = container.resolve("PrimaryLogger");
|
||||
const staticRouterModService = container.resolve("StaticRouterModService");
|
||||
const databaseService = container.resolve("DatabaseService");
|
||||
const loadAssortmentUnlocks = () => {
|
||||
const traders = databaseService.getTraders();
|
||||
const quests = databaseService.getQuests();
|
||||
const result = {};
|
||||
for (const traderId in traders) {
|
||||
const trader = traders[traderId];
|
||||
if (trader.questassort) {
|
||||
for (const questStatus in trader.questassort) {
|
||||
// Explicitly check that quest status is an expected value - some mods accidently import in such a way that adds a "default" value
|
||||
if (!["started", "success", "fail"].includes(questStatus)) {
|
||||
continue;
|
||||
}
|
||||
for (const assortId in trader.questassort[questStatus]) {
|
||||
const questId = trader.questassort[questStatus][assortId];
|
||||
if (!quests[questId]) {
|
||||
logger.warning(`UIFixes: Trader ${traderId} questassort references unknown quest ${JSON.stringify(questId)}! Check that whatever mod added that trader and/or quest is installed correctly.`);
|
||||
continue;
|
||||
}
|
||||
result[assortId] = quests[questId].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
staticRouterModService.registerStaticRouter("UIFixesRoutes", [
|
||||
{
|
||||
url: "/uifixes/assortUnlocks",
|
||||
action: async (url, info, sessionId, output) => {
|
||||
return JSON.stringify(loadAssortmentUnlocks());
|
||||
}
|
||||
}
|
||||
], "custom-static-ui-fixes");
|
||||
};
|
||||
exports.assortUnlocks = assortUnlocks;
|
||||
//# sourceMappingURL=assortUnlocks.js.map
|
||||
10
user/mods/tyfon-uifixes/src/assortUnlocks.js.map
Normal file
10
user/mods/tyfon-uifixes/src/assortUnlocks.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "assortUnlocks.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"assortUnlocks.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;AAMO,MAAM,aAAa,GAAG,CAAC,SAA8B,EAAE,EAAE;IAC5D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;IAC3D,MAAM,sBAAsB,GAAG,SAAS,CAAC,OAAO,CAAyB,wBAAwB,CAAC,CAAC;IACnG,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAkB,iBAAiB,CAAC,CAAC;IAE9E,MAAM,qBAAqB,GAAG,GAAG,EAAE;QAC/B,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,MAAM,GAA2B,EAAE,CAAC;QAE1C,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBAC3C,kIAAkI;oBAClI,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;wBACxD,SAAS;oBACb,CAAC;oBAED,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;wBACrD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC;wBAE1D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;4BACnB,MAAM,CAAC,OAAO,CACV,mBAAmB,QAAQ,yCAAyC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,kFAAkF,CAChL,CAAC;4BACF,SAAS;wBACb,CAAC;wBAED,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;oBAC5C,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;IAEF,sBAAsB,CAAC,oBAAoB,CACvC,eAAe,EACf;QACI;YACI,GAAG,EAAE,wBAAwB;YAC7B,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;gBAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC,CAAC;YACnD,CAAC;SACJ;KACJ,EACD,wBAAwB,CAC3B,CAAC;AACN,CAAC,CAAC;AAlDW,QAAA,aAAa,iBAkDxB"
|
||||
}
|
||||
30
user/mods/tyfon-uifixes/src/keepQuickBinds.js
Normal file
30
user/mods/tyfon-uifixes/src/keepQuickBinds.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.keepQuickBinds = void 0;
|
||||
const keepQuickBinds = (container) => {
|
||||
const logger = container.resolve("PrimaryLogger");
|
||||
const cloner = container.resolve("RecursiveCloner");
|
||||
container.afterResolution("InRaidHelper", (_, inRaidHelper) => {
|
||||
const original = inRaidHelper.deleteInventory;
|
||||
inRaidHelper.deleteInventory = (pmcData, sessionId) => {
|
||||
// Copy the existing quickbinds
|
||||
const fastPanel = cloner.clone(pmcData.Inventory.fastPanel);
|
||||
// Nukes the inventory and the fastpanel
|
||||
const result = original.call(inRaidHelper, pmcData, sessionId);
|
||||
// Restore the quickbinds for items that still exist
|
||||
try {
|
||||
for (const index in fastPanel) {
|
||||
if (pmcData.Inventory.items.find(i => i._id == fastPanel[index])) {
|
||||
pmcData.Inventory.fastPanel[index] = fastPanel[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
logger.error(`UIFixes: Failed to restore quickbinds\n ${error}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}, { frequency: "Always" });
|
||||
};
|
||||
exports.keepQuickBinds = keepQuickBinds;
|
||||
//# sourceMappingURL=keepQuickBinds.js.map
|
||||
10
user/mods/tyfon-uifixes/src/keepQuickBinds.js.map
Normal file
10
user/mods/tyfon-uifixes/src/keepQuickBinds.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "keepQuickBinds.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"keepQuickBinds.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;AAMO,MAAM,cAAc,GAAG,CAAC,SAA8B,EAAE,EAAE;IAC7D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,iBAAiB,CAAC,CAAC;IAE7D,SAAS,CAAC,eAAe,CACrB,cAAc,EACd,CAAC,CAAC,EAAE,YAA0B,EAAE,EAAE;QAC9B,MAAM,QAAQ,GAAG,YAAY,CAAC,eAAe,CAAC;QAE9C,YAAY,CAAC,eAAe,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE;YAClD,+BAA+B;YAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAE5D,wCAAwC;YACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YAE/D,oDAAoD;YACpD,IAAI,CAAC;gBACD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;oBAC5B,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAC/D,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;oBAC1D,CAAC;gBACL,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,2CAA2C,KAAK,EAAE,CAAC,CAAC;YACrE,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC,CAAC;IACN,CAAC,EACD,EAAE,SAAS,EAAE,QAAQ,EAAE,CAC1B,CAAC;AACN,CAAC,CAAC;AAhCW,QAAA,cAAc,kBAgCzB"
|
||||
}
|
||||
43
user/mods/tyfon-uifixes/src/linkedSlotSearch.js
Normal file
43
user/mods/tyfon-uifixes/src/linkedSlotSearch.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.linkedSlotSearch = void 0;
|
||||
const linkedSlotSearch = (container) => {
|
||||
const logger = container.resolve("PrimaryLogger");
|
||||
const itemHelper = container.resolve("ItemHelper");
|
||||
const databaseService = container.resolve("DatabaseService");
|
||||
container.afterResolution("RagfairLinkedItemService", (_, linkedItemService) => {
|
||||
const original = linkedItemService.getLinkedItems;
|
||||
linkedItemService.getLinkedItems = linkedSearchId => {
|
||||
const [tpl, slotName] = linkedSearchId.split(":", 2);
|
||||
if (slotName) {
|
||||
logger.info(`UIFixes: Finding items for specific slot ${tpl}:${slotName}`);
|
||||
const allItems = databaseService.getItems();
|
||||
const resultSet = getSpecificFilter(allItems[tpl], slotName);
|
||||
// Default Inventory, for equipment slots
|
||||
if (tpl === "55d7217a4bdc2d86028b456d") {
|
||||
const categories = [...resultSet];
|
||||
const items = Object.keys(allItems).filter(tpl => itemHelper.isOfBaseclasses(tpl, categories));
|
||||
// Send the categories along too, some of them might actually be items
|
||||
return new Set(items.concat(categories));
|
||||
}
|
||||
return resultSet;
|
||||
}
|
||||
return original.call(linkedItemService, tpl);
|
||||
};
|
||||
}, { frequency: "Always" });
|
||||
};
|
||||
exports.linkedSlotSearch = linkedSlotSearch;
|
||||
const getSpecificFilter = (item, slotName) => {
|
||||
const results = new Set();
|
||||
// For whatever reason, all chamber slots have the name "patron_in_weapon"
|
||||
const groupName = slotName === "patron_in_weapon" ? "Chambers" : "Slots";
|
||||
const group = item._props[groupName] ?? [];
|
||||
const sub = group.find(slot => slot._name === slotName);
|
||||
for (const filter of sub?._props?.filters ?? []) {
|
||||
for (const f of filter.Filter) {
|
||||
results.add(f);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
//# sourceMappingURL=linkedSlotSearch.js.map
|
||||
10
user/mods/tyfon-uifixes/src/linkedSlotSearch.js.map
Normal file
10
user/mods/tyfon-uifixes/src/linkedSlotSearch.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "linkedSlotSearch.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"linkedSlotSearch.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;AAQO,MAAM,gBAAgB,GAAG,CAAC,SAA8B,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAa,YAAY,CAAC,CAAC;IAC/D,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAkB,iBAAiB,CAAC,CAAC;IAE9E,SAAS,CAAC,eAAe,CACrB,0BAA0B,EAC1B,CAAC,CAAC,EAAE,iBAA2C,EAAE,EAAE;QAC/C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,cAAc,CAAC;QAElD,iBAAiB,CAAC,cAAc,GAAG,cAAc,CAAC,EAAE;YAChD,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAErD,IAAI,QAAQ,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,4CAA4C,GAAG,IAAI,QAAQ,EAAE,CAAC,CAAC;gBAC3E,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC;gBAC5C,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;gBAE7D,yCAAyC;gBACzC,IAAI,GAAG,KAAK,0BAA0B,EAAE,CAAC;oBACrC,MAAM,UAAU,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;oBAClC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;oBAE/F,sEAAsE;oBACtE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;gBAC7C,CAAC;gBAED,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC,CAAC;IACN,CAAC,EACD,EAAE,SAAS,EAAE,QAAQ,EAAE,CAC1B,CAAC;AACN,CAAC,CAAC;AAnCW,QAAA,gBAAgB,oBAmC3B;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAmB,EAAE,QAAgB,EAAe,EAAE;IAC7E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,0EAA0E;IAC1E,MAAM,SAAS,GAAG,QAAQ,KAAK,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAE3C,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;IACxD,KAAK,MAAM,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC"
|
||||
}
|
||||
27
user/mods/tyfon-uifixes/src/mod.js
Normal file
27
user/mods/tyfon-uifixes/src/mod.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mod = void 0;
|
||||
const assortUnlocks_1 = require("./assortUnlocks");
|
||||
const keepQuickBinds_1 = require("./keepQuickBinds");
|
||||
const linkedSlotSearch_1 = require("./linkedSlotSearch");
|
||||
const putToolsBack_1 = require("./putToolsBack");
|
||||
const config_json_1 = __importDefault(require("../config/config.json"));
|
||||
class UIFixes {
|
||||
preSptLoad(container) {
|
||||
// Keep quickbinds for items that aren't actually lost on death
|
||||
(0, keepQuickBinds_1.keepQuickBinds)(container);
|
||||
// Better tool return - starting production
|
||||
if (config_json_1.default.putToolsBack) {
|
||||
(0, putToolsBack_1.putToolsBack)(container);
|
||||
}
|
||||
// Slot-specific linked search
|
||||
(0, linkedSlotSearch_1.linkedSlotSearch)(container);
|
||||
// Show unlocking quest on locked offers
|
||||
(0, assortUnlocks_1.assortUnlocks)(container);
|
||||
}
|
||||
}
|
||||
exports.mod = new UIFixes();
|
||||
//# sourceMappingURL=mod.js.map
|
||||
10
user/mods/tyfon-uifixes/src/mod.js.map
Normal file
10
user/mods/tyfon-uifixes/src/mod.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "mod.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"mod.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;;;;AAIA,mDAAgD;AAChD,qDAAkD;AAClD,yDAAsD;AACtD,iDAA8C;AAE9C,wEAA2C;AAE3C,MAAM,OAAO;IACF,UAAU,CAAC,SAA8B;QAC5C,+DAA+D;QAC/D,IAAA,+BAAc,EAAC,SAAS,CAAC,CAAC;QAE1B,2CAA2C;QAC3C,IAAI,qBAAM,CAAC,YAAY,EAAE,CAAC;YACtB,IAAA,2BAAY,EAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;QAED,8BAA8B;QAC9B,IAAA,mCAAgB,EAAC,SAAS,CAAC,CAAC;QAE5B,wCAAwC;QACxC,IAAA,6BAAa,EAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;CACJ;AAEY,QAAA,GAAG,GAAG,IAAI,OAAO,EAAE,CAAC"
|
||||
}
|
||||
95
user/mods/tyfon-uifixes/src/putToolsBack.js
Normal file
95
user/mods/tyfon-uifixes/src/putToolsBack.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.putToolsBack = void 0;
|
||||
const returnToProperty = "uifixes.returnTo";
|
||||
const putToolsBack = (container) => {
|
||||
const logger = container.resolve("PrimaryLogger");
|
||||
const cloner = container.resolve("RecursiveCloner");
|
||||
const itemHelper = container.resolve("ItemHelper");
|
||||
container.afterResolution("HideoutHelper", (_, hideoutHelper) => {
|
||||
const original = hideoutHelper.registerProduction;
|
||||
hideoutHelper.registerProduction = (pmcData, body, sessionID) => {
|
||||
const result = original.call(hideoutHelper, pmcData, body, sessionID);
|
||||
// The items haven't been deleted yet, augment the list with their parentId
|
||||
try {
|
||||
const bodyAsSingle = body;
|
||||
if (bodyAsSingle && bodyAsSingle.tools?.length > 0) {
|
||||
const requestTools = bodyAsSingle.tools;
|
||||
const tools = pmcData.Hideout.Production[body.recipeId].sptRequiredTools;
|
||||
for (let i = 0; i < tools.length; i++) {
|
||||
const originalTool = pmcData.Inventory.items.find(x => x._id === requestTools[i].id);
|
||||
// If the tool is in the stash itself, skip it. Same check as InventoryHelper.isItemInStash
|
||||
if (originalTool.parentId === pmcData.Inventory.stash &&
|
||||
originalTool.slotId === "hideout") {
|
||||
continue;
|
||||
}
|
||||
tools[i][returnToProperty] = [originalTool.parentId, originalTool.slotId];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
logger.error(`UIFixes: Failed to save tool origin\n ${error}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}, { frequency: "Always" });
|
||||
// Better tool return - returning the tool
|
||||
container.afterResolution("InventoryHelper", (_, inventoryHelper) => {
|
||||
const original = inventoryHelper.addItemToStash;
|
||||
inventoryHelper.addItemToStash = (sessionId, request, pmcData, output) => {
|
||||
const itemWithModsToAddClone = cloner.clone(request.itemWithModsToAdd);
|
||||
// If a tool marked with uifixes is there, try to return it to its original container
|
||||
const tool = itemWithModsToAddClone[0];
|
||||
if (tool[returnToProperty]) {
|
||||
try {
|
||||
const [containerId, slotId] = tool[returnToProperty];
|
||||
// Clean the item
|
||||
delete tool[returnToProperty];
|
||||
const [foundContainerFS2D, foundSlotId] = findGridFS2DForItems(inventoryHelper, containerId, slotId, itemWithModsToAddClone, pmcData);
|
||||
if (foundContainerFS2D) {
|
||||
// At this point everything should succeed
|
||||
inventoryHelper.placeItemInContainer(foundContainerFS2D, itemWithModsToAddClone, containerId, foundSlotId);
|
||||
// protected function, bypass typescript
|
||||
inventoryHelper["setFindInRaidStatusForItem"](itemWithModsToAddClone, request.foundInRaid);
|
||||
// Add item + mods to output and profile inventory
|
||||
output.profileChanges[sessionId].items.new.push(...itemWithModsToAddClone);
|
||||
pmcData.Inventory.items.push(...itemWithModsToAddClone);
|
||||
logger.debug(`Added ${itemWithModsToAddClone[0].upd?.StackObjectsCount ?? 1} item: ${itemWithModsToAddClone[0]._tpl} with: ${itemWithModsToAddClone.length - 1} mods to ${containerId}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
logger.error(`UIFixes: Encounted an error trying to put tool back.\n ${error}`);
|
||||
}
|
||||
logger.info("UIFixes: Unable to put tool back in its original container, returning it to stash.");
|
||||
}
|
||||
return original.call(inventoryHelper, sessionId, request, pmcData, output);
|
||||
};
|
||||
}, { frequency: "Always" });
|
||||
function findGridFS2DForItems(inventoryHelper, containerId, startingGrid, items, pmcData) {
|
||||
const container = pmcData.Inventory.items.find(x => x._id === containerId);
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
const [foundTemplate, containerTemplate] = itemHelper.getItem(container._tpl);
|
||||
if (!foundTemplate || !containerTemplate) {
|
||||
return;
|
||||
}
|
||||
let originalGridIndex = containerTemplate._props.Grids.findIndex(g => g._name === startingGrid);
|
||||
if (originalGridIndex < 0) {
|
||||
originalGridIndex = 0;
|
||||
}
|
||||
// Loop through grids, starting from the original grid
|
||||
for (let gridIndex = originalGridIndex; gridIndex < containerTemplate._props.Grids.length + originalGridIndex; gridIndex++) {
|
||||
const grid = containerTemplate._props.Grids[gridIndex % containerTemplate._props.Grids.length];
|
||||
const gridItems = pmcData.Inventory.items.filter(x => x.parentId === containerId && x.slotId === grid._name);
|
||||
const containerFS2D = inventoryHelper.getContainerMap(grid._props.cellsH, grid._props.cellsV, gridItems, containerId);
|
||||
// will change the array so clone it
|
||||
if (inventoryHelper.canPlaceItemInContainer(cloner.clone(containerFS2D), items)) {
|
||||
return [containerFS2D, grid._name];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
exports.putToolsBack = putToolsBack;
|
||||
//# sourceMappingURL=putToolsBack.js.map
|
||||
10
user/mods/tyfon-uifixes/src/putToolsBack.js.map
Normal file
10
user/mods/tyfon-uifixes/src/putToolsBack.js.map
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 3,
|
||||
"file": "putToolsBack.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"putToolsBack.ts"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": "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"
|
||||
}
|
||||
23
user/mods/user/mods/Virtual's Custom Quest Loader/LICENSE
Normal file
23
user/mods/user/mods/Virtual's Custom Quest Loader/LICENSE
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Virtual (https://hub.sp-tarkov.com/user/26520-virtual/)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
This license refers to the files included within the folder that it resides in from the original download. Any other modification or assets surrounding the use of said files created and maintained by another entity are to be processed under a seperate license and are not the product from this copyright individual.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"enableLogging": true,
|
||||
"enableDebugLogging": false,
|
||||
"ignoreSideExclusive": false
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Locales files need to be placed into the correct folder so they are loaded to the correct language setting. Locales are loaded from the server, so if a locale folder doesn't exist, you can create it.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Here is where you place all .json files that contain the contents of the quests. They should have the same format as quests.json in aki-data/server/database/templates/. There is no required name and you can call them whatever you like.
|
||||
|
||||
The only additional properties that can be added are
|
||||
|
||||
"startMonth": 12,
|
||||
"startDay": 1,
|
||||
"endDay": 31
|
||||
|
||||
This allows you to create seasonal quests (The values here for example would only have the task available during the month of december.)
|
||||
|
||||
Quests can be accross multiple files and you can have each json with 20 quests for example.
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "Virtuals Custom Quest Loader",
|
||||
"version":"2.0.4",
|
||||
"main": "src/mod.js",
|
||||
"license": "MIT",
|
||||
"author": "Virtual",
|
||||
"sptVersion": "3.11.x",
|
||||
"scripts": {
|
||||
"setup": "npm i",
|
||||
"build": "node ./packageBuild.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "16.11.62",
|
||||
"@typescript-eslint/eslint-plugin": "5.38.1",
|
||||
"@typescript-eslint/parser": "5.38.1",
|
||||
"bestzip": "2.2.1",
|
||||
"eslint": "8.24.0",
|
||||
"fs-extra": "10.1.0",
|
||||
"glob": "8.0.3",
|
||||
"tsyringe": "4.7.0",
|
||||
"typescript": "4.8.4"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
All images need to be 314 x 177 AND need to be either a .png or .jpg.
|
||||
After placing them in this folder, you can select the image in the database/quests/ file and change it to the name of the image you placed in this folder.
|
||||
227
user/mods/user/mods/Virtual's Custom Quest Loader/src/mod.ts
Normal file
227
user/mods/user/mods/Virtual's Custom Quest Loader/src/mod.ts
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
import { DependencyContainer} from "tsyringe";
|
||||
import { IPostDBLoadMod } from "@spt/models/external/IPostDBLoadMod";
|
||||
import { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod"
|
||||
import type {StaticRouterModService} from "@spt/services/mod/staticRouter/StaticRouterModService";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||
import { DatabaseServer } from "@spt/servers/DatabaseServer";
|
||||
import { ImageRouter } from "@spt/routers/ImageRouter";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import * as path from "path";
|
||||
const fs = require('fs');
|
||||
const modPath = path.normalize(path.join(__dirname, '..'));
|
||||
|
||||
class VCQL implements IPostDBLoadMod, IPreSptLoadMod {
|
||||
private enableLogging;
|
||||
private enableDebugLogging;
|
||||
private ignoreSideExclusive;
|
||||
private zones;
|
||||
|
||||
public preSptLoad(container: DependencyContainer): void {
|
||||
const staticRouterModService: StaticRouterModService = container.resolve<StaticRouterModService>("StaticRouterModService")
|
||||
const logger = container.resolve<ILogger>("WinstonLogger")
|
||||
|
||||
this.loadZones()
|
||||
staticRouterModService.registerStaticRouter(
|
||||
"vcql-get-zones",
|
||||
[
|
||||
{
|
||||
url: "/vcql/zones/get",
|
||||
action: (url, info, sessionId, output) =>
|
||||
{
|
||||
if (this.enableDebugLogging) logger.success("[VCQL-DEBUG] Zone router hit.")
|
||||
return JSON.stringify(this.zones);
|
||||
}
|
||||
}
|
||||
],
|
||||
"vcql-get"
|
||||
)
|
||||
}
|
||||
|
||||
public postDBLoad(container: DependencyContainer): void
|
||||
{
|
||||
const database = container.resolve<DatabaseServer>("DatabaseServer").getTables()
|
||||
const imageRouter = container.resolve< ImageRouter >("ImageRouter")
|
||||
const logger = container.resolve<ILogger>("WinstonLogger")
|
||||
const config = container.resolve<ConfigServer>("ConfigServer").getConfig(ConfigTypes.QUEST)
|
||||
|
||||
this.importConfig()
|
||||
this.importQuests(database, logger, config)
|
||||
this.importAssorts(database, logger)
|
||||
this.importLocales(database)
|
||||
this.routeImages(imageRouter, logger)
|
||||
}
|
||||
|
||||
public loadFiles(dirPath, extName, cb) {
|
||||
if (!fs.existsSync(dirPath)) return
|
||||
const dir = fs.readdirSync(dirPath, { withFileTypes: true })
|
||||
dir.forEach(item => {
|
||||
const itemPath = path.normalize(`${dirPath}/${item.name}`)
|
||||
if (item.isDirectory()) this.loadFiles(itemPath, extName, cb)
|
||||
else if (extName.includes(path.extname(item.name))) cb(itemPath)
|
||||
});
|
||||
}
|
||||
|
||||
public loadZones() {
|
||||
let zones = []
|
||||
this.loadFiles(`${modPath}/database/zones/`, [".json"], function(filePath) {
|
||||
const zoneFile = require(filePath)
|
||||
if (Object.keys(zoneFile).length > 0)
|
||||
zones.push(... zoneFile)
|
||||
})
|
||||
this.zones = zones
|
||||
}
|
||||
|
||||
public importConfig() {
|
||||
let config = require(`${modPath}/database/config/config.json`)
|
||||
this.enableLogging = config.enableLogging
|
||||
this.enableDebugLogging = config.enableDebugLogging
|
||||
this.ignoreSideExclusive = config.ignoreSideExclusive
|
||||
}
|
||||
|
||||
public importQuests(database, logger, config) {
|
||||
let questCount = 0
|
||||
let prunedCount = 0
|
||||
let debugLogging = this.enableDebugLogging
|
||||
let ignoreSideExclusive = this.ignoreSideExclusive
|
||||
this.loadFiles(`${modPath}/database/quests/`, [".json"], function(filePath) {
|
||||
const item = require(filePath)
|
||||
if (Object.keys(item).length < 1) return
|
||||
for (const quest in item) {
|
||||
// Date check
|
||||
if (item[quest].startMonth && item[quest].startMonth > 0) {
|
||||
let currentDate = new Date()
|
||||
|
||||
let questStartDate = new Date(currentDate.getFullYear(), item[quest].startMonth - 1, item[quest].startDay)
|
||||
let questEndDate = new Date(currentDate.getFullYear(), item[quest].endMonth - 1, item[quest].endDay)
|
||||
|
||||
if (currentDate < questStartDate || currentDate > questEndDate) {
|
||||
if (debugLogging) logger.success(`[VCQL-DEBUG] Removing quest ${item[quest]._id} because it is outside the date range`)
|
||||
prunedCount++
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
delete item[quest].startMonth; delete item[quest].endMonth; delete item[quest].startDay; delete item[quest].endDay
|
||||
// Push
|
||||
if (item[quest].sideExclusive) {
|
||||
if (item[quest].sideExclusive == "Usec" && !ignoreSideExclusive) {
|
||||
config.usecOnlyQuests.push(quest)
|
||||
if (debugLogging) logger.success(`[VCQL-DEBUG] Adding quest ${item[quest]._id} as a Usec exclusive quest.`)
|
||||
}
|
||||
if (item[quest].sideExclusive == "Bear" && !ignoreSideExclusive) {
|
||||
config.bearOnlyQuests.push(quest)
|
||||
if (debugLogging) logger.success(`[VCQL-DEBUG] Adding quest ${item[quest]._id} as a Bear exclusive quest.`)
|
||||
}
|
||||
delete item[quest].sideExclusive
|
||||
}
|
||||
database.templates.quests[quest] = item[quest]
|
||||
questCount++
|
||||
}
|
||||
})
|
||||
|
||||
if (this.enableLogging) {
|
||||
logger.success(`[VCQL] Loaded ${questCount} custom quests.`)
|
||||
logger.success(`[VCQL] ${prunedCount} custom quests were pruned due to date settings.`)
|
||||
}
|
||||
}
|
||||
|
||||
public importAssorts(database, logger) {
|
||||
let debugLogging = this.enableDebugLogging
|
||||
this.loadFiles(`${modPath}/database/assorts/`, [".json"], function(filePath) {
|
||||
const assorts = require(filePath)
|
||||
if (assorts.items == undefined || assorts.traderID == undefined || assorts.barter_scheme == undefined || assorts.loyal_level_items == undefined) return
|
||||
|
||||
let traderID = assorts.traderID
|
||||
let databaseTrader = database.traders[traderID]
|
||||
|
||||
// If assort is for a custom trader, ensure that they have the appropriate assort tables
|
||||
if (databaseTrader.questassort == undefined) databaseTrader.questassort = {
|
||||
started: {},
|
||||
success: {},
|
||||
fail: {}
|
||||
}
|
||||
|
||||
if (databaseTrader.assort == undefined) databaseTrader.assort = {
|
||||
items: [],
|
||||
barter_scheme: {},
|
||||
loyal_level_items: {}
|
||||
}
|
||||
|
||||
// Add barter scheme, loyalty level, quest assort and general assort, where applicable
|
||||
for (const assort of assorts.items) {
|
||||
if (assorts.barter_scheme[assort._id] != undefined) {
|
||||
databaseTrader.assort.barter_scheme[assort._id] = assorts.barter_scheme[assort._id]
|
||||
} else {
|
||||
if (assort.parentId == "hideout") logger.error(`[VCQL] Parent assort ${assort._id} has no associated barter scheme.`)
|
||||
}
|
||||
|
||||
if (assorts.loyal_level_items[assort._id] != undefined) {
|
||||
databaseTrader.assort.loyal_level_items[assort._id] = assorts.loyal_level_items[assort._id]
|
||||
} else {
|
||||
if (assort.parentId == "hideout") logger.error(`[VCQL] Parent assort ${assort._id} has no associated loyalty level`)
|
||||
}
|
||||
|
||||
if (assort.unlockedOn != undefined && assort.questID != undefined) {
|
||||
databaseTrader.questassort[assort.unlockedOn][assort._id] = assort.questID
|
||||
delete assort.unlockedOn
|
||||
delete assort.questID
|
||||
}
|
||||
|
||||
databaseTrader.assort.items.push(assort)
|
||||
if (debugLogging) logger.success(`[VCQL-DEBUG] Adding assort ${assort._id} to the trader ${traderID}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public importLocales(database) {
|
||||
const serverLocales = ['ch','cz','en','es','es-mx','fr','ge','hu','it','jp','kr','pl','po','ru','sk','tu']
|
||||
const addedLocales = {}
|
||||
for (const locale of serverLocales) {
|
||||
this.loadFiles(`${modPath}/database/locales/${locale}`, [".json"], function(filePath) {
|
||||
const localeFile = require(filePath)
|
||||
if (Object.keys(localeFile).length < 1) return
|
||||
for (const currentItem in localeFile) {
|
||||
database.locales.global[locale][currentItem] = localeFile[currentItem]
|
||||
if (!Object.keys(addedLocales).includes(locale)) addedLocales[locale] = {}
|
||||
addedLocales[locale][currentItem] = localeFile[currentItem]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// placeholders
|
||||
for (const locale of serverLocales) {
|
||||
if (locale == "en") continue
|
||||
for (const englishItem in addedLocales["en"]) {
|
||||
if (locale in addedLocales) {
|
||||
if (englishItem in addedLocales[locale]) continue
|
||||
}
|
||||
if (database.locales.global[locale] != undefined) database.locales.global[locale][englishItem] = addedLocales["en"][englishItem]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public routeImages(imageRouter, logger) {
|
||||
let questImageCount = 0
|
||||
let debugLogging = this.enableDebugLogging
|
||||
this.loadFiles(`${modPath}/res/quests/`, [".png", ".jpg"], function(filePath) {
|
||||
imageRouter.addRoute(`/files/quest/icon/${path.basename(filePath, path.extname(filePath))}`, filePath)
|
||||
if (debugLogging) logger.success(`[VCQL-DEBUG] Adding quest image ${path.basename(filePath)}`)
|
||||
questImageCount++
|
||||
})
|
||||
|
||||
let traderImageCount = 0
|
||||
this.loadFiles(`${modPath}/res/traders/`, [".png", ".jpg"], function(filePath) {
|
||||
imageRouter.addRoute(`/files/trader/avatar/${path.basename(filePath, path.extname(filePath))}`, filePath)
|
||||
if (debugLogging) logger.success(`[VCQL-DEBUG] Adding quest image ${path.basename(filePath)}`)
|
||||
traderImageCount++
|
||||
})
|
||||
|
||||
if (this.enableLogging) {
|
||||
logger.success(`[VCQL] Loaded ${questImageCount} custom quest images.`)
|
||||
logger.success(`[VCQL] Loaded ${traderImageCount} custom trader images.`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { mod: new VCQL() }
|
||||
Loading…
Add table
Add a link
Reference in a new issue