Mod init
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 acidphantasm
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Welcome to Harry Hideout by acidphantasm
|
||||
|
||||
This mod is designed and built to ease constructing and upgrading your hideout pre-flea market. You can continue to use it post-flea as Harry contains all items used in construction & upgrades.
|
||||
|
||||
## **Configuration options**
|
||||
|
||||
- itemPriceMultiplier
|
||||
- useFleaPrices
|
||||
- useBarters
|
||||
|
||||
Adjust itemPriceMultiplier to adjust item value for both flea & non-flea price.
|
||||
If you disable useFleaPrices, the item price will revert to values in items.json
|
||||
If you disable useBarters, the high end items will be available for Roubles
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"itemPriceMultiplier": 1,
|
||||
"useFleaPrices": true,
|
||||
"useBarters": true,
|
||||
|
||||
"enableConsoleDebug": false
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
{
|
||||
"nonBarterItems": [
|
||||
{
|
||||
"itemID": "569668774bdc2da2298b4568",
|
||||
"price": 140
|
||||
},
|
||||
{
|
||||
"itemID": "5696686a4bdc2da3298b456a",
|
||||
"price": 130
|
||||
},
|
||||
{
|
||||
"itemID": "57347b8b24597737dd42e192",
|
||||
"price": 17000
|
||||
},
|
||||
{
|
||||
"itemID": "590c2c9c86f774245b1f03f2",
|
||||
"price": 8000
|
||||
},
|
||||
{
|
||||
"itemID": "5c13cef886f774072e618e82",
|
||||
"price": 6000
|
||||
},
|
||||
{
|
||||
"itemID": "57347c93245977448d35f6e3",
|
||||
"price": 35000
|
||||
},
|
||||
{
|
||||
"itemID": "5c13cd2486f774072c757944",
|
||||
"price": 8000
|
||||
},
|
||||
{
|
||||
"itemID": "62a0a098de7ac8199358053b",
|
||||
"price": 18000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b3f2d86f774253763b735",
|
||||
"price": 28000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b3a5d86f774252167ba22",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "544fb25a4bdc2dfb738b4567",
|
||||
"price": 2000
|
||||
},
|
||||
{
|
||||
"itemID": "62a0a043cf4a99369e2624a5",
|
||||
"price": 25000
|
||||
},
|
||||
{
|
||||
"itemID": "57347c77245977448d35f6e2",
|
||||
"price": 22000
|
||||
},
|
||||
{
|
||||
"itemID": "57347c5b245977448d35f6e1",
|
||||
"price": 29000
|
||||
},
|
||||
{
|
||||
"itemID": "544fb5454bdc2df8738b456a",
|
||||
"price": 19000
|
||||
},
|
||||
{
|
||||
"itemID": "56742c284bdc2d98058b456d",
|
||||
"price": 12000
|
||||
},
|
||||
{
|
||||
"itemID": "590a3c0a86f774385a33c450",
|
||||
"price": 13000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b2fa286f77425227d1674",
|
||||
"price": 87000
|
||||
},
|
||||
{
|
||||
"itemID": "5733279d245977289b77ec24",
|
||||
"price": 43000
|
||||
},
|
||||
{
|
||||
"itemID": "5734779624597737e04bf329",
|
||||
"price": 17000
|
||||
},
|
||||
{
|
||||
"itemID": "61bf7b6302b3924be92fa8c3",
|
||||
"price": 27000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b317c86f7742523398392",
|
||||
"price": 38000
|
||||
},
|
||||
{
|
||||
"itemID": "59e35ef086f7741777737012",
|
||||
"price": 16000
|
||||
},
|
||||
{
|
||||
"itemID": "590c5bbd86f774785762df04",
|
||||
"price": 11000
|
||||
},
|
||||
{
|
||||
"itemID": "590c31c586f774245e3141b2",
|
||||
"price": 24000
|
||||
},
|
||||
{
|
||||
"itemID": "57347c1124597737fb1379e3",
|
||||
"price": 21000
|
||||
},
|
||||
{
|
||||
"itemID": "5e2af2bc86f7746d3f3c33fc",
|
||||
"price": 12000
|
||||
},
|
||||
{
|
||||
"itemID": "590a373286f774287540368b",
|
||||
"price": 28000
|
||||
},
|
||||
{
|
||||
"itemID": "5af04b6486f774195a3ebb49",
|
||||
"price": 22000
|
||||
},
|
||||
{
|
||||
"itemID": "60391b0fb847c71012789415",
|
||||
"price": 20000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b313086f77425227d1678",
|
||||
"price": 20000
|
||||
},
|
||||
{
|
||||
"itemID": "59e36c6f86f774176c10a2a7",
|
||||
"price": 27000
|
||||
},
|
||||
{
|
||||
"itemID": "62a09ee4cf4a99369e262453",
|
||||
"price": 7000
|
||||
},
|
||||
{
|
||||
"itemID": "5b4335ba86f7744d2837a264",
|
||||
"price": 14000
|
||||
},
|
||||
{
|
||||
"itemID": "5e831507ea0a7c419c2f9bd9",
|
||||
"price": 59000
|
||||
},
|
||||
{
|
||||
"itemID": "59e3606886f77417674759a5",
|
||||
"price": 30000
|
||||
},
|
||||
{
|
||||
"itemID": "619cc01e0a7c3a1a2731940c",
|
||||
"price": 17000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b392c86f77425243e98fe",
|
||||
"price": 19000
|
||||
},
|
||||
{
|
||||
"itemID": "5c06779c86f77426e00dd782",
|
||||
"price": 13000
|
||||
},
|
||||
{
|
||||
"itemID": "59e35cbb86f7741778269d83",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "59e35de086f7741778269d84",
|
||||
"price": 44000
|
||||
},
|
||||
{
|
||||
"itemID": "5e2af29386f7746d4159f077",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "61bf83814088ec1a363d7097",
|
||||
"price": 24000
|
||||
},
|
||||
{
|
||||
"itemID": "590c2e1186f77425357b6124",
|
||||
"price": 44000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1c819a86f774771b0acd6c",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "62a0a0bb621468534a797ad5",
|
||||
"price": 25000
|
||||
},
|
||||
{
|
||||
"itemID": "62a0a124de7ac81993580542",
|
||||
"price": 45000
|
||||
},
|
||||
{
|
||||
"itemID": "574eb85c245977648157eec3",
|
||||
"price": 24000
|
||||
},
|
||||
{
|
||||
"itemID": "619cbfeb6b8a1b37a54eebfa",
|
||||
"price": 61000
|
||||
},
|
||||
{
|
||||
"itemID": "63a0b208f444d32d6f03ea1e",
|
||||
"price": 145000
|
||||
},
|
||||
{
|
||||
"itemID": "590a3b0486f7743954552bdb",
|
||||
"price": 23000
|
||||
},
|
||||
{
|
||||
"itemID": "590c311186f77424d1667482",
|
||||
"price": 16000
|
||||
},
|
||||
{
|
||||
"itemID": "59faf98186f774067b6be103",
|
||||
"price": 17000
|
||||
},
|
||||
{
|
||||
"itemID": "5d40419286f774318526545f",
|
||||
"price": 18000
|
||||
},
|
||||
{
|
||||
"itemID": "590c346786f77423e50ed342",
|
||||
"price": 32000
|
||||
},
|
||||
{
|
||||
"itemID": "590a3cd386f77436f20848cb",
|
||||
"price": 24000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b304286f774253763a528",
|
||||
"price": 30000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b2ffd86f77425243e8d17",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "590c392f86f77444754deb29",
|
||||
"price": 38000
|
||||
},
|
||||
{
|
||||
"itemID": "5734781f24597737e04bf32a",
|
||||
"price": 24000
|
||||
},
|
||||
{
|
||||
"itemID": "590a391c86f774385a33c404",
|
||||
"price": 25000
|
||||
},
|
||||
{
|
||||
"itemID": "5bc9b355d4351e6d1509862a",
|
||||
"price": 24000
|
||||
},
|
||||
{
|
||||
"itemID": "60391a8b3364dc22b04d0ce5",
|
||||
"price": 45000
|
||||
},
|
||||
{
|
||||
"itemID": "5734795124597738002c6176",
|
||||
"price": 19000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1c774f86f7746d6620f8db",
|
||||
"price": 14000
|
||||
},
|
||||
{
|
||||
"itemID": "619cbf476b8a1b37a54eebf8",
|
||||
"price": 19000
|
||||
},
|
||||
{
|
||||
"itemID": "57347c2e24597744902c94a1",
|
||||
"price": 60000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b327086f7742525194449",
|
||||
"price": 45000
|
||||
},
|
||||
{
|
||||
"itemID": "5af0534a86f7743b6f354284",
|
||||
"price": 89000
|
||||
},
|
||||
{
|
||||
"itemID": "5e2af22086f7746d3f3c33fa",
|
||||
"price": 12000
|
||||
},
|
||||
{
|
||||
"itemID": "5c06782b86f77426df5407d2",
|
||||
"price": 15000
|
||||
},
|
||||
{
|
||||
"itemID": "590c639286f774151567fa95",
|
||||
"price": 22000
|
||||
},
|
||||
{
|
||||
"itemID": "5d0378d486f77420421a5ff4",
|
||||
"price": 340000
|
||||
},
|
||||
{
|
||||
"itemID": "590c595c86f7747884343ad7",
|
||||
"price": 48000
|
||||
},
|
||||
{
|
||||
"itemID": "5d0375ff86f774186372f685",
|
||||
"price": 34000
|
||||
},
|
||||
{
|
||||
"itemID": "5d03775b86f774203e7e0c4b",
|
||||
"price": 100000
|
||||
},
|
||||
{
|
||||
"itemID": "5af0484c86f7740f02001f7f",
|
||||
"price": 12000
|
||||
},
|
||||
{
|
||||
"itemID": "59e35abd86f7741778269d82",
|
||||
"price": 25000
|
||||
},
|
||||
{
|
||||
"itemID": "5e2af00086f7746d3f3c33f7",
|
||||
"price": 13000
|
||||
},
|
||||
{
|
||||
"itemID": "590c35a486f774273531c822",
|
||||
"price": 35000
|
||||
},
|
||||
{
|
||||
"itemID": "60391afc25aff57af81f7085",
|
||||
"price": 74000
|
||||
},
|
||||
{
|
||||
"itemID": "5e2aedd986f7746d404f3aa4",
|
||||
"price": 180000
|
||||
},
|
||||
{
|
||||
"itemID": "573478bc24597738002c6175",
|
||||
"price": 19000
|
||||
},
|
||||
{
|
||||
"itemID": "573474f924597738002c6174",
|
||||
"price": 5000
|
||||
},
|
||||
{
|
||||
"itemID": "590c645c86f77412b01304d9",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "590c651286f7741e566b6461",
|
||||
"price": 38000
|
||||
},
|
||||
{
|
||||
"itemID": "62a09e73af34e73a266d932a",
|
||||
"price": 26000
|
||||
},
|
||||
{
|
||||
"itemID": "590c621186f774138d11ea29",
|
||||
"price": 19000
|
||||
},
|
||||
{
|
||||
"itemID": "590a386e86f77429692b27ab",
|
||||
"price": 13000
|
||||
},
|
||||
{
|
||||
"itemID": "59e3639286f7741777737013",
|
||||
"price": 105000
|
||||
},
|
||||
{
|
||||
"itemID": "5d235a5986f77443f6329bc6",
|
||||
"price": 50000
|
||||
},
|
||||
{
|
||||
"itemID": "5734758f24597738025ee253",
|
||||
"price": 28000
|
||||
},
|
||||
{
|
||||
"itemID": "59faf7ca86f7740dbe19f6c2",
|
||||
"price": 55000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b376e86f774252519444e",
|
||||
"price": 325000
|
||||
},
|
||||
{
|
||||
"itemID": "5bc9bc53d4351e00367fbcee",
|
||||
"price": 57000
|
||||
},
|
||||
{
|
||||
"itemID": "57347cd0245977445a2d6ff1",
|
||||
"price": 12000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b39a386f774252339976f",
|
||||
"price": 15000
|
||||
},
|
||||
{
|
||||
"itemID": "5d1b32c186f774252167a530",
|
||||
"price": 27000
|
||||
},
|
||||
{
|
||||
"itemID": "619cbfccbedcde2f5b3f7bdd",
|
||||
"price": 75000
|
||||
},
|
||||
{
|
||||
"itemID": "5c052f6886f7746b1e3db148",
|
||||
"price": 90000
|
||||
},
|
||||
{
|
||||
"itemID": "62a0a16d0b9d3c46de5b6e97",
|
||||
"price": 155000
|
||||
},
|
||||
{
|
||||
"itemID": "61bf7c024770ee6f9c6b8b53",
|
||||
"price": 65000
|
||||
},
|
||||
{
|
||||
"itemID": "5c12613b86f7743bbe2c3f76",
|
||||
"price": 375000
|
||||
},
|
||||
{
|
||||
"itemID": "5c05300686f7746dce784e5d",
|
||||
"price": 125000
|
||||
}
|
||||
],
|
||||
"barterItems": [
|
||||
{
|
||||
"itemID": "5c0530ee86f774697952d952",
|
||||
"price": 1290504,
|
||||
"barterAmount": 3,
|
||||
"barterItemID": "59faff1d86f7746c51718c9c"
|
||||
},
|
||||
{
|
||||
"itemID": "6389c85357baa773a825b356",
|
||||
"price": 4596724,
|
||||
"barterAmount": 8,
|
||||
"barterItemID": "59faff1d86f7746c51718c9c"
|
||||
},
|
||||
{
|
||||
"itemID": "6389c7f115805221fb410466",
|
||||
"price": 1932786,
|
||||
"barterAmount": 4,
|
||||
"barterItemID": "59faff1d86f7746c51718c9c"
|
||||
},
|
||||
{
|
||||
"itemID": "5d03794386f77420415576f5",
|
||||
"price": 217169,
|
||||
"barterAmount": 1,
|
||||
"barterItemID": "59faff1d86f7746c51718c9c"
|
||||
},
|
||||
{
|
||||
"itemID": "5b4391a586f7745321235ab2",
|
||||
"price": 37189,
|
||||
"barterAmount": 3,
|
||||
"barterItemID": "5991b51486f77447b112d44f"
|
||||
},
|
||||
{
|
||||
"itemID": "5b7c710788a4506dec015957",
|
||||
"price": 1081368,
|
||||
"barterAmount": 2,
|
||||
"barterItemID": "59faff1d86f7746c51718c9c"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"_id": "HarryHideout",
|
||||
"working": true,
|
||||
"availableInRaid": false,
|
||||
"items_buy": {
|
||||
"category": [
|
||||
"5448eb774bdc2d0a728b4567"
|
||||
],
|
||||
"id_list": []
|
||||
},
|
||||
"items_buy_prohibited": {},
|
||||
"customization_seller": false,
|
||||
"name": "Harry",
|
||||
"surname": "Hideout",
|
||||
"nickname": "Hideout Harry",
|
||||
"location": "I'm sellin', what are you buyin'?",
|
||||
"avatar": "/files/trader/avatar/harry.jpg",
|
||||
"balance_rub": 5000000,
|
||||
"balance_dol": 0,
|
||||
"balance_eur": 0,
|
||||
"unlockedByDefault": true,
|
||||
"discount": 0,
|
||||
"discount_end": 0,
|
||||
"buyer_up": true,
|
||||
"currency": "RUB",
|
||||
"nextResupply": 1615141448,
|
||||
"repair": {
|
||||
"availability": false,
|
||||
"quality": "2",
|
||||
"excluded_id_list": [],
|
||||
"excluded_category": [],
|
||||
"currency": "5449016a4bdc2d6f028b456f",
|
||||
"currency_coefficient": 1,
|
||||
"price_rate": 10
|
||||
},
|
||||
"insurance": {
|
||||
"availability": false,
|
||||
"min_payment": 0,
|
||||
"min_return_hour": 0,
|
||||
"max_return_hour": 0,
|
||||
"max_storage_time": 99,
|
||||
"excluded_category": []
|
||||
},
|
||||
"gridHeight": 150,
|
||||
"loyaltyLevels": [{
|
||||
"minLevel": 1,
|
||||
"minSalesSum": 0,
|
||||
"minStanding": 0,
|
||||
"buy_price_coef": 38,
|
||||
"repair_price_coef": 175,
|
||||
"insurance_price_coef": 10,
|
||||
"exchange_price_coef": 0,
|
||||
"heal_price_coef": 0
|
||||
}
|
||||
],
|
||||
"sell_category": [
|
||||
"82e7fac0b7495d72d4083356",
|
||||
"ac705d3440c1407645e33579",
|
||||
"dc97aee367144dc03389405d",
|
||||
"7ffcc96aa06c7e90940330c5",
|
||||
"e8f46e3ad74b9d862121f9dc",
|
||||
"5b47574386f77428ca22b33e",
|
||||
"5b47574386f77428ca22b33f",
|
||||
"5b5f78dc86f77409407a7f8e",
|
||||
"5b47574386f77428ca22b346",
|
||||
"5b47574386f77428ca22b340",
|
||||
"5b47574386f77428ca22b344",
|
||||
"5b47574386f77428ca22b342",
|
||||
"5b47574386f77428ca22b341",
|
||||
"5b47574386f77428ca22b345",
|
||||
"5b47574386f77428ca22b343",
|
||||
"5b5f71b386f774093f2ecf11",
|
||||
"5b5f71c186f77409407a7ec0",
|
||||
"5b5f71de86f774093f2ecf13",
|
||||
"5b5f724186f77447ed5636ad",
|
||||
"5b5f736886f774094242f193",
|
||||
"5b5f73ec86f774093e6cb4fd",
|
||||
"5b5f74cc86f77447ec5d770a",
|
||||
"5b5f750686f774093e6cb503",
|
||||
"5b5f751486f77447ec5d770c",
|
||||
"5b5f752e86f774093e6cb505",
|
||||
"5b5f754a86f774094242f19b",
|
||||
"5b5f755f86f77447ec5d770e",
|
||||
"5b5f757486f774093e6cb507",
|
||||
"5b5f75b986f77447ec5d7710",
|
||||
"5b5f75c686f774094242f19f",
|
||||
"5b5f75e486f77447ec5d7712",
|
||||
"5b5f760586f774093e6cb509",
|
||||
"5b5f761f86f774094242f1a1",
|
||||
"5b5f764186f77447ec5d7714"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "HarryHideout",
|
||||
"version": "1.0.3",
|
||||
"main": "src/mod.js",
|
||||
"license": "MIT",
|
||||
"author": "acidphantasm",
|
||||
"akiVersion": "~3.8",
|
||||
"loadBefore": [],
|
||||
"loadAfter": [],
|
||||
"incompatibilities": [],
|
||||
"contributors": [],
|
||||
"scripts": {
|
||||
"setup": "npm i",
|
||||
"build": "node ./build.mjs",
|
||||
"buildinfo": "node ./build.mjs --verbose"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "20.11",
|
||||
"@typescript-eslint/eslint-plugin": "7.2",
|
||||
"@typescript-eslint/parser": "7.2",
|
||||
"archiver": "^6.0",
|
||||
"eslint": "8.57",
|
||||
"fs-extra": "11.2",
|
||||
"ignore": "^5.2",
|
||||
"os": "^0.1",
|
||||
"tsyringe": "4.8.0",
|
||||
"typescript": "5.4",
|
||||
"winston": "3.12"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
@@ -0,0 +1,126 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FluentAssortConstructor = void 0;
|
||||
class FluentAssortConstructor {
|
||||
itemsToSell = [];
|
||||
barterScheme = {};
|
||||
loyaltyLevel = {};
|
||||
hashUtil;
|
||||
logger;
|
||||
constructor(hashutil, logger) {
|
||||
this.hashUtil = hashutil;
|
||||
this.logger = logger;
|
||||
}
|
||||
/**
|
||||
* Start selling item with tpl
|
||||
* @param itemTpl Tpl id of the item you want trader to sell
|
||||
* @param itemId Optional - set your own Id, otherwise unique id will be generated
|
||||
*/
|
||||
createSingleAssortItem(itemTpl, itemId = undefined) {
|
||||
// Create item ready for insertion into assort table
|
||||
const newItemToAdd = {
|
||||
_id: !itemId ? this.hashUtil.generate() : itemId,
|
||||
_tpl: itemTpl,
|
||||
parentId: "hideout", // Should always be "hideout"
|
||||
slotId: "hideout", // Should always be "hideout"
|
||||
upd: {
|
||||
UnlimitedCount: false,
|
||||
StackObjectsCount: 100
|
||||
}
|
||||
};
|
||||
this.itemsToSell.push(newItemToAdd);
|
||||
return this;
|
||||
}
|
||||
createComplexAssortItem(items) {
|
||||
items[0].parentId = "hideout";
|
||||
items[0].slotId = "hideout";
|
||||
if (!items[0].upd) {
|
||||
items[0].upd = {};
|
||||
}
|
||||
items[0].upd.UnlimitedCount = false;
|
||||
items[0].upd.StackObjectsCount = 100;
|
||||
this.itemsToSell.push(...items);
|
||||
return this;
|
||||
}
|
||||
addStackCount(stackCount) {
|
||||
this.itemsToSell[0].upd.StackObjectsCount = stackCount;
|
||||
return this;
|
||||
}
|
||||
addUnlimitedStackCount() {
|
||||
this.itemsToSell[0].upd.StackObjectsCount = 999999;
|
||||
this.itemsToSell[0].upd.UnlimitedCount = true;
|
||||
return this;
|
||||
}
|
||||
makeStackCountUnlimited() {
|
||||
this.itemsToSell[0].upd.StackObjectsCount = 999999;
|
||||
return this;
|
||||
}
|
||||
addBuyRestriction(maxBuyLimit) {
|
||||
this.itemsToSell[0].upd.BuyRestrictionMax = maxBuyLimit;
|
||||
this.itemsToSell[0].upd.BuyRestrictionCurrent = 0;
|
||||
return this;
|
||||
}
|
||||
addLoyaltyLevel(level) {
|
||||
this.loyaltyLevel[this.itemsToSell[0]._id] = level;
|
||||
return this;
|
||||
}
|
||||
addMoneyCost(currencyType, amount) {
|
||||
this.barterScheme[this.itemsToSell[0]._id] = [
|
||||
[
|
||||
{
|
||||
count: amount,
|
||||
_tpl: currencyType
|
||||
}
|
||||
]
|
||||
];
|
||||
return this;
|
||||
}
|
||||
addBarterCost(itemTpl, count) {
|
||||
const sellableItemId = this.itemsToSell[0]._id;
|
||||
// No data at all, create
|
||||
if (Object.keys(this.barterScheme).length === 0) {
|
||||
this.barterScheme[sellableItemId] = [[
|
||||
{
|
||||
count: count,
|
||||
_tpl: itemTpl
|
||||
}
|
||||
]];
|
||||
}
|
||||
else {
|
||||
// Item already exists, add to
|
||||
const existingData = this.barterScheme[sellableItemId][0].find(x => x._tpl === itemTpl);
|
||||
if (existingData) {
|
||||
// itemtpl already a barter for item, add to count
|
||||
existingData.count += count;
|
||||
}
|
||||
else {
|
||||
// No barter for item, add it fresh
|
||||
this.barterScheme[sellableItemId][0].push({
|
||||
count: count,
|
||||
_tpl: itemTpl
|
||||
});
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Reset objet ready for reuse
|
||||
* @returns
|
||||
*/
|
||||
export(data) {
|
||||
const itemBeingSoldId = this.itemsToSell[0]._id;
|
||||
if (data.assort.items.find(x => x._id === itemBeingSoldId)) {
|
||||
this.logger.error(`Unable to add complex item with item key ${this.itemsToSell[0]._id}, key already used`);
|
||||
return;
|
||||
}
|
||||
data.assort.items.push(...this.itemsToSell);
|
||||
data.assort.barter_scheme[itemBeingSoldId] = this.barterScheme[itemBeingSoldId];
|
||||
data.assort.loyal_level_items[itemBeingSoldId] = this.loyaltyLevel[itemBeingSoldId];
|
||||
this.itemsToSell = [];
|
||||
this.barterScheme = {};
|
||||
this.loyaltyLevel = {};
|
||||
return this;
|
||||
}
|
||||
}
|
||||
exports.FluentAssortConstructor = FluentAssortConstructor;
|
||||
//# sourceMappingURL=fluentTraderAssortCreator.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"fluentTraderAssortCreator.js","sourceRoot":"","sources":["fluentTraderAssortCreator.ts"],"names":[],"mappings":"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"}
|
||||
@@ -0,0 +1,175 @@
|
||||
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
|
||||
import { IBarterScheme, ITrader } from "@spt-aki/models/eft/common/tables/ITrader";
|
||||
import { Money } from "@spt-aki/models/enums/Money";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
||||
|
||||
export class FluentAssortConstructor
|
||||
{
|
||||
protected itemsToSell: Item[] = [];
|
||||
protected barterScheme: Record<string, IBarterScheme[][]> = {};
|
||||
protected loyaltyLevel: Record<string, number> = {};
|
||||
protected hashUtil: HashUtil;
|
||||
protected logger: ILogger;
|
||||
|
||||
constructor(hashutil: HashUtil, logger: ILogger)
|
||||
{
|
||||
this.hashUtil = hashutil
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start selling item with tpl
|
||||
* @param itemTpl Tpl id of the item you want trader to sell
|
||||
* @param itemId Optional - set your own Id, otherwise unique id will be generated
|
||||
*/
|
||||
public createSingleAssortItem(itemTpl: string, itemId = undefined): FluentAssortConstructor
|
||||
{
|
||||
// Create item ready for insertion into assort table
|
||||
const newItemToAdd: Item = {
|
||||
_id: !itemId ? this.hashUtil.generate(): itemId,
|
||||
_tpl: itemTpl,
|
||||
parentId: "hideout", // Should always be "hideout"
|
||||
slotId: "hideout", // Should always be "hideout"
|
||||
upd: {
|
||||
UnlimitedCount: false,
|
||||
StackObjectsCount: 100
|
||||
}
|
||||
};
|
||||
|
||||
this.itemsToSell.push(newItemToAdd);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public createComplexAssortItem(items: Item[]): FluentAssortConstructor
|
||||
{
|
||||
items[0].parentId = "hideout";
|
||||
items[0].slotId = "hideout";
|
||||
|
||||
if (!items[0].upd)
|
||||
{
|
||||
items[0].upd = {}
|
||||
}
|
||||
|
||||
items[0].upd.UnlimitedCount = false;
|
||||
items[0].upd.StackObjectsCount = 100;
|
||||
|
||||
this.itemsToSell.push(...items);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addStackCount(stackCount: number): FluentAssortConstructor
|
||||
{
|
||||
this.itemsToSell[0].upd.StackObjectsCount = stackCount;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addUnlimitedStackCount(): FluentAssortConstructor
|
||||
{
|
||||
this.itemsToSell[0].upd.StackObjectsCount = 999999;
|
||||
this.itemsToSell[0].upd.UnlimitedCount = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public makeStackCountUnlimited(): FluentAssortConstructor
|
||||
{
|
||||
this.itemsToSell[0].upd.StackObjectsCount = 999999;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addBuyRestriction(maxBuyLimit: number): FluentAssortConstructor
|
||||
{
|
||||
this.itemsToSell[0].upd.BuyRestrictionMax = maxBuyLimit;
|
||||
this.itemsToSell[0].upd.BuyRestrictionCurrent = 0;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addLoyaltyLevel(level: number)
|
||||
{
|
||||
this.loyaltyLevel[this.itemsToSell[0]._id] = level;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addMoneyCost(currencyType: Money, amount: number): FluentAssortConstructor
|
||||
{
|
||||
this.barterScheme[this.itemsToSell[0]._id] = [
|
||||
[
|
||||
{
|
||||
count: amount,
|
||||
_tpl: currencyType
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addBarterCost(itemTpl: string, count: number): FluentAssortConstructor
|
||||
{
|
||||
const sellableItemId = this.itemsToSell[0]._id;
|
||||
|
||||
// No data at all, create
|
||||
if (Object.keys(this.barterScheme).length === 0)
|
||||
{
|
||||
this.barterScheme[sellableItemId] = [[
|
||||
{
|
||||
count: count,
|
||||
_tpl: itemTpl
|
||||
}
|
||||
]];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Item already exists, add to
|
||||
const existingData = this.barterScheme[sellableItemId][0].find(x => x._tpl === itemTpl);
|
||||
if (existingData)
|
||||
{
|
||||
// itemtpl already a barter for item, add to count
|
||||
existingData.count+= count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No barter for item, add it fresh
|
||||
this.barterScheme[sellableItemId][0].push({
|
||||
count: count,
|
||||
_tpl: itemTpl
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset objet ready for reuse
|
||||
* @returns
|
||||
*/
|
||||
public export(data: ITrader): FluentAssortConstructor
|
||||
{
|
||||
const itemBeingSoldId = this.itemsToSell[0]._id;
|
||||
if (data.assort.items.find(x => x._id === itemBeingSoldId))
|
||||
{
|
||||
this.logger.error(`Unable to add complex item with item key ${this.itemsToSell[0]._id}, key already used`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data.assort.items.push(...this.itemsToSell);
|
||||
data.assort.barter_scheme[itemBeingSoldId] = this.barterScheme[itemBeingSoldId];
|
||||
data.assort.loyal_level_items[itemBeingSoldId] = this.loyaltyLevel[itemBeingSoldId];
|
||||
|
||||
this.itemsToSell = [];
|
||||
this.barterScheme = {};
|
||||
this.loyaltyLevel = {};
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
"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 (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const ConfigTypes_1 = require("/snapshot/project/obj/models/enums/ConfigTypes");
|
||||
const fs = __importStar(require("node:fs"));
|
||||
const path = __importStar(require("node:path"));
|
||||
// New trader settings
|
||||
const baseJson = __importStar(require("../db/base.json"));
|
||||
const traderHelpers_1 = require("./traderHelpers");
|
||||
const fluentTraderAssortCreator_1 = require("./fluentTraderAssortCreator");
|
||||
const Money_1 = require("/snapshot/project/obj/models/enums/Money");
|
||||
const Traders_1 = require("/snapshot/project/obj/models/enums/Traders");
|
||||
class HideoutHarry {
|
||||
mod;
|
||||
logger;
|
||||
traderHelper;
|
||||
fluentAssortCreator;
|
||||
static config;
|
||||
static itemsPath = path.resolve(__dirname, "../config/items.json");
|
||||
static configPath = path.resolve(__dirname, "../config/config.json");
|
||||
constructor() {
|
||||
this.mod = "acidphantasm-harryhideout"; // Set name of mod so we can log it to console later
|
||||
}
|
||||
/**
|
||||
* Some work needs to be done prior to SPT code being loaded, registering the profile image + setting trader update time inside the trader config json
|
||||
* @param container Dependency container
|
||||
*/
|
||||
preAkiLoad(container) {
|
||||
// Get a logger
|
||||
this.logger = container.resolve("WinstonLogger");
|
||||
// Get SPT code/data we need later
|
||||
const preAkiModLoader = container.resolve("PreAkiModLoader");
|
||||
const imageRouter = container.resolve("ImageRouter");
|
||||
const hashUtil = container.resolve("HashUtil");
|
||||
const configServer = container.resolve("ConfigServer");
|
||||
const traderConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.TRADER);
|
||||
const ragfairConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.RAGFAIR);
|
||||
// Create helper class and use it to register our traders image/icon + set its stock refresh time
|
||||
this.traderHelper = new traderHelpers_1.TraderHelper();
|
||||
this.fluentAssortCreator = new fluentTraderAssortCreator_1.FluentAssortConstructor(hashUtil, this.logger);
|
||||
this.traderHelper.registerProfileImage(baseJson, this.mod, preAkiModLoader, imageRouter, "harry.jpg");
|
||||
this.traderHelper.setTraderUpdateTime(traderConfig, baseJson, 3600, 4000);
|
||||
// Add trader to trader enum
|
||||
Traders_1.Traders[baseJson._id] = baseJson._id;
|
||||
// Add trader to flea market
|
||||
ragfairConfig.traders[baseJson._id] = true;
|
||||
}
|
||||
/**
|
||||
* Majority of trader-related work occurs after the aki database has been loaded but prior to SPT code being run
|
||||
* @param container Dependency container
|
||||
*/
|
||||
postDBLoad(container) {
|
||||
HideoutHarry.config = JSON.parse(fs.readFileSync(HideoutHarry.configPath, "utf-8"));
|
||||
// Resolve SPT classes we'll use
|
||||
const logger = container.resolve("WinstonLogger");
|
||||
const databaseServer = container.resolve("DatabaseServer");
|
||||
const configServer = container.resolve("ConfigServer");
|
||||
const jsonUtil = container.resolve("JsonUtil");
|
||||
const priceTable = databaseServer.getTables().templates.prices;
|
||||
const handbookTable = databaseServer.getTables().templates.handbook;
|
||||
// Get a reference to the database tables
|
||||
const tables = databaseServer.getTables();
|
||||
// Add new trader to the trader dictionary in DatabaseServer - has no assorts (items) yet
|
||||
this.traderHelper.addTraderToDb(baseJson, tables, jsonUtil);
|
||||
const start = performance.now();
|
||||
const itemList = JSON.parse(fs.readFileSync(HideoutHarry.itemsPath, "utf-8"));
|
||||
const nonBarterItems = itemList.nonBarterItems;
|
||||
const barterItems = itemList.barterItems;
|
||||
const lowFleaRange = 0.85;
|
||||
// Non-Barter Items Iteration
|
||||
for (const item in nonBarterItems) {
|
||||
{
|
||||
const itemID = nonBarterItems[item].itemID;
|
||||
if (HideoutHarry.config.useFleaPrices) {
|
||||
let price = (priceTable[itemID] * HideoutHarry.config.itemPriceMultiplier);
|
||||
if (!price) {
|
||||
price = (handbookTable.Items.find(x => x.Id === itemID)?.Price ?? 1) * HideoutHarry.config.itemPriceMultiplier;
|
||||
}
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addMoneyCost(Money_1.Money.ROUBLES, Math.round(price * lowFleaRange))
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id]);
|
||||
if (HideoutHarry.config.enableConsoleDebug) {
|
||||
logger.log("ItemID: " + itemID + " for price: " + Math.round(price), "cyan");
|
||||
}
|
||||
}
|
||||
else {
|
||||
const price = nonBarterItems[item].price;
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addMoneyCost(Money_1.Money.ROUBLES, Math.round(price * lowFleaRange))
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id]);
|
||||
if (HideoutHarry.config.enableConsoleDebug) {
|
||||
logger.log("ItemID: " + itemID + " for price: " + Math.round(price), "cyan");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Barter Items Iteration
|
||||
for (const item in barterItems) {
|
||||
{
|
||||
const itemID = barterItems[item].itemID;
|
||||
const barterItem = barterItems[item].barterItemID;
|
||||
const barterAmount = barterItems[item].barterAmount;
|
||||
if (HideoutHarry.config.useBarters) {
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addBarterCost(barterItem, barterAmount)
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id]);
|
||||
if (HideoutHarry.config.enableConsoleDebug) {
|
||||
logger.log("ItemID: " + itemID + " for barter: " + barterAmount + " " + barterItem, "cyan");
|
||||
}
|
||||
}
|
||||
else {
|
||||
const price = barterItems[item].price;
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addMoneyCost(Money_1.Money.ROUBLES, Math.round(price))
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id]);
|
||||
if (HideoutHarry.config.enableConsoleDebug) {
|
||||
logger.log("ItemID: " + itemID + " for price: " + Math.round(price), "cyan");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add trader to locale file, ensures trader text shows properly on screen
|
||||
// WARNING: adds the same text to ALL locales (e.g. chinese/french/english)
|
||||
this.traderHelper.addTraderToLocales(baseJson, tables, baseJson.name, "Hideout Harry", baseJson.nickname, baseJson.location, "I'm sellin', what are you buyin'?");
|
||||
this.logger.debug(`[${this.mod}] loaded... `);
|
||||
const timeTaken = performance.now() - start;
|
||||
logger.log(`[${this.mod}] Assort generation took ${timeTaken.toFixed(3)}ms.`, "green");
|
||||
}
|
||||
}
|
||||
module.exports = { mod: new HideoutHarry() };
|
||||
//# sourceMappingURL=mod.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,184 @@
|
||||
import { DependencyContainer } from "tsyringe";
|
||||
|
||||
// SPT types
|
||||
import { IPreAkiLoadMod } from "@spt-aki/models/external/IPreAkiLoadMod";
|
||||
import { IPostDBLoadMod } from "@spt-aki/models/external/IPostDBLoadMod";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
|
||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
import { ImageRouter } from "@spt-aki/routers/ImageRouter";
|
||||
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { ITraderConfig } from "@spt-aki/models/spt/config/ITraderConfig";
|
||||
import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig";
|
||||
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
// New trader settings
|
||||
import * as baseJson from "../db/base.json";
|
||||
import { TraderHelper } from "./traderHelpers";
|
||||
import { FluentAssortConstructor as FluentAssortCreator } from "./fluentTraderAssortCreator";
|
||||
import { Money } from "@spt-aki/models/enums/Money";
|
||||
import { Traders } from "@spt-aki/models/enums/Traders";
|
||||
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
||||
|
||||
class HideoutHarry implements IPreAkiLoadMod, IPostDBLoadMod
|
||||
{
|
||||
private mod: string
|
||||
private logger: ILogger
|
||||
private traderHelper: TraderHelper
|
||||
private fluentAssortCreator: FluentAssortCreator
|
||||
private static config: Config;
|
||||
private static itemsPath = path.resolve(__dirname, "../config/items.json");
|
||||
private static configPath = path.resolve(__dirname, "../config/config.json");
|
||||
|
||||
constructor() {
|
||||
this.mod = "acidphantasm-harryhideout"; // Set name of mod so we can log it to console later
|
||||
}
|
||||
/**
|
||||
* Some work needs to be done prior to SPT code being loaded, registering the profile image + setting trader update time inside the trader config json
|
||||
* @param container Dependency container
|
||||
*/
|
||||
public preAkiLoad(container: DependencyContainer): void
|
||||
{
|
||||
// Get a logger
|
||||
this.logger = container.resolve<ILogger>("WinstonLogger");
|
||||
|
||||
// Get SPT code/data we need later
|
||||
const preAkiModLoader: PreAkiModLoader = container.resolve<PreAkiModLoader>("PreAkiModLoader");
|
||||
const imageRouter: ImageRouter = container.resolve<ImageRouter>("ImageRouter");
|
||||
const hashUtil: HashUtil = container.resolve<HashUtil>("HashUtil");
|
||||
const configServer = container.resolve<ConfigServer>("ConfigServer");
|
||||
const traderConfig: ITraderConfig = configServer.getConfig<ITraderConfig>(ConfigTypes.TRADER);
|
||||
const ragfairConfig = configServer.getConfig<IRagfairConfig>(ConfigTypes.RAGFAIR);
|
||||
|
||||
// Create helper class and use it to register our traders image/icon + set its stock refresh time
|
||||
this.traderHelper = new TraderHelper();
|
||||
this.fluentAssortCreator = new FluentAssortCreator(hashUtil, this.logger);
|
||||
this.traderHelper.registerProfileImage(baseJson, this.mod, preAkiModLoader, imageRouter, "harry.jpg");
|
||||
this.traderHelper.setTraderUpdateTime(traderConfig, baseJson, 3600, 4000);
|
||||
|
||||
// Add trader to trader enum
|
||||
Traders[baseJson._id] = baseJson._id;
|
||||
|
||||
// Add trader to flea market
|
||||
ragfairConfig.traders[baseJson._id] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Majority of trader-related work occurs after the aki database has been loaded but prior to SPT code being run
|
||||
* @param container Dependency container
|
||||
*/
|
||||
public postDBLoad(container: DependencyContainer): void
|
||||
{
|
||||
|
||||
HideoutHarry.config = JSON.parse(fs.readFileSync(HideoutHarry.configPath, "utf-8"));
|
||||
|
||||
// Resolve SPT classes we'll use
|
||||
const logger = container.resolve<ILogger>("WinstonLogger");
|
||||
const databaseServer: DatabaseServer = container.resolve<DatabaseServer>("DatabaseServer");
|
||||
const configServer: ConfigServer = container.resolve<ConfigServer>("ConfigServer");
|
||||
const jsonUtil: JsonUtil = container.resolve<JsonUtil>("JsonUtil");
|
||||
const priceTable = databaseServer.getTables().templates.prices;
|
||||
const handbookTable = databaseServer.getTables().templates.handbook;
|
||||
|
||||
// Get a reference to the database tables
|
||||
const tables = databaseServer.getTables();
|
||||
|
||||
// Add new trader to the trader dictionary in DatabaseServer - has no assorts (items) yet
|
||||
this.traderHelper.addTraderToDb(baseJson, tables, jsonUtil);
|
||||
|
||||
const start = performance.now();
|
||||
|
||||
const itemList = JSON.parse(fs.readFileSync(HideoutHarry.itemsPath, "utf-8"));
|
||||
const nonBarterItems = itemList.nonBarterItems;
|
||||
const barterItems = itemList.barterItems;
|
||||
const lowFleaRange = 0.85;
|
||||
|
||||
// Non-Barter Items Iteration
|
||||
for (const item in nonBarterItems){
|
||||
{
|
||||
const itemID = nonBarterItems[item].itemID;
|
||||
if (HideoutHarry.config.useFleaPrices)
|
||||
{
|
||||
let price = (priceTable[itemID] * HideoutHarry.config.itemPriceMultiplier);
|
||||
if (!price)
|
||||
{
|
||||
price = (handbookTable.Items.find(x => x.Id === itemID)?.Price ?? 1) * HideoutHarry.config.itemPriceMultiplier;
|
||||
}
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addMoneyCost(Money.ROUBLES, Math.round(price * lowFleaRange))
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id])
|
||||
if (HideoutHarry.config.enableConsoleDebug){
|
||||
logger.log("ItemID: " + itemID + " for price: " + Math.round(price), "cyan");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const price = nonBarterItems[item].price
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addMoneyCost(Money.ROUBLES, Math.round(price * lowFleaRange))
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id]);
|
||||
if (HideoutHarry.config.enableConsoleDebug){
|
||||
logger.log("ItemID: " + itemID + " for price: " + Math.round(price), "cyan");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Barter Items Iteration
|
||||
for (const item in barterItems){
|
||||
{
|
||||
const itemID = barterItems[item].itemID;
|
||||
const barterItem = barterItems[item].barterItemID;
|
||||
const barterAmount = barterItems[item].barterAmount;
|
||||
if (HideoutHarry.config.useBarters)
|
||||
{
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addBarterCost(barterItem, barterAmount)
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id])
|
||||
if (HideoutHarry.config.enableConsoleDebug){
|
||||
logger.log("ItemID: " + itemID + " for barter: " + barterAmount + " "+ barterItem, "cyan");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const price = barterItems[item].price
|
||||
this.fluentAssortCreator.createSingleAssortItem(itemID)
|
||||
.addUnlimitedStackCount()
|
||||
.addMoneyCost(Money.ROUBLES, Math.round(price))
|
||||
.addLoyaltyLevel(1)
|
||||
.export(tables.traders[baseJson._id]);
|
||||
if (HideoutHarry.config.enableConsoleDebug){
|
||||
logger.log("ItemID: " + itemID + " for price: " + Math.round(price), "cyan");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add trader to locale file, ensures trader text shows properly on screen
|
||||
// WARNING: adds the same text to ALL locales (e.g. chinese/french/english)
|
||||
this.traderHelper.addTraderToLocales(baseJson, tables, baseJson.name, "Hideout Harry", baseJson.nickname, baseJson.location, "I'm sellin', what are you buyin'?");
|
||||
|
||||
this.logger.debug(`[${this.mod}] loaded... `);
|
||||
|
||||
const timeTaken = performance.now() - start;
|
||||
logger.log(`[${this.mod}] Assort generation took ${timeTaken.toFixed(3)}ms.`, "green");
|
||||
}
|
||||
}
|
||||
|
||||
interface Config
|
||||
{
|
||||
useBarters: boolean,
|
||||
itemPriceMultiplier: number,
|
||||
useFleaPrices: boolean,
|
||||
enableConsoleDebug: boolean,
|
||||
}
|
||||
|
||||
module.exports = { mod: new HideoutHarry() }
|
||||
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TraderHelper = void 0;
|
||||
class TraderHelper {
|
||||
/**
|
||||
* Add profile picture to our trader
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param preAkiModLoader mod loader class - used to get the mods file path
|
||||
* @param imageRouter image router class - used to register the trader image path so we see their image on trader page
|
||||
* @param traderImageName Filename of the trader icon to use
|
||||
*/
|
||||
registerProfileImage(baseJson, modName, preAkiModLoader, imageRouter, traderImageName) {
|
||||
// Reference the mod "res" folder
|
||||
const imageFilepath = `./${preAkiModLoader.getModPath(modName)}res`;
|
||||
// Register a route to point to the profile picture - remember to remove the .jpg from it
|
||||
imageRouter.addRoute(baseJson.avatar.replace(".jpg", ""), `${imageFilepath}/${traderImageName}`);
|
||||
}
|
||||
/**
|
||||
* Add record to trader config to set the refresh time of trader in seconds (default is 60 minutes)
|
||||
* @param traderConfig trader config to add our trader to
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param refreshTimeSecondsMin How many seconds between trader stock refresh min time
|
||||
* @param refreshTimeSecondsMax How many seconds between trader stock refresh max time
|
||||
*/
|
||||
setTraderUpdateTime(traderConfig, baseJson, refreshTimeSecondsMin, refreshTimeSecondsMax) {
|
||||
// Add refresh time in seconds to config
|
||||
const traderRefreshRecord = {
|
||||
traderId: baseJson._id,
|
||||
seconds: {
|
||||
min: refreshTimeSecondsMin,
|
||||
max: refreshTimeSecondsMax
|
||||
}
|
||||
};
|
||||
traderConfig.updateTime.push(traderRefreshRecord);
|
||||
}
|
||||
/**
|
||||
* Add our new trader to the database
|
||||
* @param traderDetailsToAdd trader details
|
||||
* @param tables database
|
||||
* @param jsonUtil json utility class
|
||||
*/
|
||||
// rome-ignore lint/suspicious/noExplicitAny: traderDetailsToAdd comes from base.json, so no type
|
||||
addTraderToDb(traderDetailsToAdd, tables, jsonUtil) {
|
||||
// Add trader to trader table, key is the traders id
|
||||
tables.traders[traderDetailsToAdd._id] = {
|
||||
assort: this.createAssortTable(), // assorts are the 'offers' trader sells, can be a single item (e.g. carton of milk) or multiple items as a collection (e.g. a gun)
|
||||
base: jsonUtil.deserialize(jsonUtil.serialize(traderDetailsToAdd)), // Deserialise/serialise creates a copy of the json and allows us to cast it as an ITraderBase
|
||||
questassort: {
|
||||
started: {},
|
||||
success: {},
|
||||
fail: {}
|
||||
} // questassort is empty as trader has no assorts unlocked by quests
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create basic data for trader + add empty assorts table for trader
|
||||
* @param tables SPT db
|
||||
* @param jsonUtil SPT JSON utility class
|
||||
* @returns ITraderAssort
|
||||
*/
|
||||
createAssortTable() {
|
||||
// Create a blank assort object, ready to have items added
|
||||
const assortTable = {
|
||||
nextResupply: 0,
|
||||
items: [],
|
||||
barter_scheme: {},
|
||||
loyal_level_items: {}
|
||||
};
|
||||
return assortTable;
|
||||
}
|
||||
/**
|
||||
* Add traders name/location/description to the locale table
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param tables database tables
|
||||
* @param fullName Complete name of trader
|
||||
* @param firstName First name of trader
|
||||
* @param nickName Nickname of trader
|
||||
* @param location Location of trader (e.g. "Here in the cat shop")
|
||||
* @param description Description of trader
|
||||
*/
|
||||
addTraderToLocales(baseJson, tables, fullName, firstName, nickName, location, description) {
|
||||
// For each language, add locale for the new trader
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.TraderHelper = TraderHelper;
|
||||
//# sourceMappingURL=traderHelpers.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"traderHelpers.js","sourceRoot":"","sources":["traderHelpers.ts"],"names":[],"mappings":";;;AAOA,MAAa,YAAY;IAErB;;;;;;OAMG;IACI,oBAAoB,CAAC,QAAa,EAAE,OAAe,EAAE,eAAgC,EAAE,WAAwB,EAAE,eAAuB;QAE3I,iCAAiC;QACjC,MAAM,aAAa,GAAG,KAAK,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;QAEpE,yFAAyF;QACzF,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,aAAa,IAAI,eAAe,EAAE,CAAC,CAAC;IACrG,CAAC;IAED;;;;;;OAMG;IACI,mBAAmB,CAAC,YAA2B,EAAE,QAAa,EAAE,qBAA6B,EAAE,qBAA6B;QAE/H,wCAAwC;QACxC,MAAM,mBAAmB,GAAe;YACpC,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,OAAO,EAAE;gBACL,GAAG,EAAE,qBAAqB;gBAC1B,GAAG,EAAE,qBAAqB;aAC7B;SAAE,CAAC;QAER,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,iGAAiG;IAC1F,aAAa,CAAC,kBAAuB,EAAE,MAAuB,EAAE,QAAkB;QAErF,oDAAoD;QACpD,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG;YACrC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,EAAE,mIAAmI;YACrK,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAgB,EAAE,8FAA8F;YACjL,WAAW,EAAE;gBACT,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,EAAE;gBACX,IAAI,EAAE,EAAE;aACX,CAAC,mEAAmE;SACxE,CAAC;IACN,CAAC;IAED;;;;;OAKG;IACK,iBAAiB;QAErB,0DAA0D;QAC1D,MAAM,WAAW,GAAkB;YAC/B,YAAY,EAAE,CAAC;YACf,KAAK,EAAE,EAAE;YACT,aAAa,EAAE,EAAE;YACjB,iBAAiB,EAAE,EAAE;SACxB,CAAA;QAED,OAAO,WAAW,CAAC;IACvB,CAAC;IAED;;;;;;;;;OASG;IACI,kBAAkB,CAAC,QAAa,EAAE,MAAuB,EAAE,QAAgB,EAAE,SAAiB,EAAE,QAAgB,EAAE,QAAgB,EAAE,WAAmB;QAE1J,mDAAmD;QACnD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAA6B,CAAC;QACjF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC;YAC9C,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC,GAAG,SAAS,CAAC;YAChD,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC;YAC9C,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC;YAC9C,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,cAAc,CAAC,GAAG,WAAW,CAAC;QACxD,CAAC;IACL,CAAC;CACJ;AApGD,oCAoGC"}
|
||||
@@ -0,0 +1,108 @@
|
||||
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
|
||||
import { ITraderBase, ITraderAssort } from "@spt-aki/models/eft/common/tables/ITrader";
|
||||
import { ITraderConfig, UpdateTime } from "@spt-aki/models/spt/config/ITraderConfig";
|
||||
import { IDatabaseTables } from "@spt-aki/models/spt/server/IDatabaseTables";
|
||||
import { ImageRouter } from "@spt-aki/routers/ImageRouter";
|
||||
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
||||
|
||||
export class TraderHelper
|
||||
{
|
||||
/**
|
||||
* Add profile picture to our trader
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param preAkiModLoader mod loader class - used to get the mods file path
|
||||
* @param imageRouter image router class - used to register the trader image path so we see their image on trader page
|
||||
* @param traderImageName Filename of the trader icon to use
|
||||
*/
|
||||
public registerProfileImage(baseJson: any, modName: string, preAkiModLoader: PreAkiModLoader, imageRouter: ImageRouter, traderImageName: string): void
|
||||
{
|
||||
// Reference the mod "res" folder
|
||||
const imageFilepath = `./${preAkiModLoader.getModPath(modName)}res`;
|
||||
|
||||
// Register a route to point to the profile picture - remember to remove the .jpg from it
|
||||
imageRouter.addRoute(baseJson.avatar.replace(".jpg", ""), `${imageFilepath}/${traderImageName}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add record to trader config to set the refresh time of trader in seconds (default is 60 minutes)
|
||||
* @param traderConfig trader config to add our trader to
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param refreshTimeSecondsMin How many seconds between trader stock refresh min time
|
||||
* @param refreshTimeSecondsMax How many seconds between trader stock refresh max time
|
||||
*/
|
||||
public setTraderUpdateTime(traderConfig: ITraderConfig, baseJson: any, refreshTimeSecondsMin: number, refreshTimeSecondsMax: number): void
|
||||
{
|
||||
// Add refresh time in seconds to config
|
||||
const traderRefreshRecord: UpdateTime = {
|
||||
traderId: baseJson._id,
|
||||
seconds: {
|
||||
min: refreshTimeSecondsMin,
|
||||
max: refreshTimeSecondsMax
|
||||
} };
|
||||
|
||||
traderConfig.updateTime.push(traderRefreshRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our new trader to the database
|
||||
* @param traderDetailsToAdd trader details
|
||||
* @param tables database
|
||||
* @param jsonUtil json utility class
|
||||
*/
|
||||
// rome-ignore lint/suspicious/noExplicitAny: traderDetailsToAdd comes from base.json, so no type
|
||||
public addTraderToDb(traderDetailsToAdd: any, tables: IDatabaseTables, jsonUtil: JsonUtil): void
|
||||
{
|
||||
// Add trader to trader table, key is the traders id
|
||||
tables.traders[traderDetailsToAdd._id] = {
|
||||
assort: this.createAssortTable(), // assorts are the 'offers' trader sells, can be a single item (e.g. carton of milk) or multiple items as a collection (e.g. a gun)
|
||||
base: jsonUtil.deserialize(jsonUtil.serialize(traderDetailsToAdd)) as ITraderBase, // Deserialise/serialise creates a copy of the json and allows us to cast it as an ITraderBase
|
||||
questassort: {
|
||||
started: {},
|
||||
success: {},
|
||||
fail: {}
|
||||
} // questassort is empty as trader has no assorts unlocked by quests
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create basic data for trader + add empty assorts table for trader
|
||||
* @param tables SPT db
|
||||
* @param jsonUtil SPT JSON utility class
|
||||
* @returns ITraderAssort
|
||||
*/
|
||||
private createAssortTable(): ITraderAssort
|
||||
{
|
||||
// Create a blank assort object, ready to have items added
|
||||
const assortTable: ITraderAssort = {
|
||||
nextResupply: 0,
|
||||
items: [],
|
||||
barter_scheme: {},
|
||||
loyal_level_items: {}
|
||||
}
|
||||
|
||||
return assortTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add traders name/location/description to the locale table
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param tables database tables
|
||||
* @param fullName Complete name of trader
|
||||
* @param firstName First name of trader
|
||||
* @param nickName Nickname of trader
|
||||
* @param location Location of trader (e.g. "Here in the cat shop")
|
||||
* @param description Description of trader
|
||||
*/
|
||||
public addTraderToLocales(baseJson: any, tables: IDatabaseTables, fullName: string, firstName: string, nickName: string, location: string, description: string)
|
||||
{
|
||||
// For each language, add locale for the new trader
|
||||
const locales = Object.values(tables.locales.global) as Record<string, string>[];
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user