MusicManiac added a new version:
QuoteMore debug shenanigans, no functional changes
Dependencies are included
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteMore debug shenanigans, no functional changes
Dependencies are included
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteDisplay MoreRemoved OG meldonin and OG Obdolbos, now they can be found in Stims Galore
Skill limits array now has all skills in it.
Added innate support for Stims Galore
Download zMusicManiac-NegativeEffectsChance.rar and extract it into /user/mods.
Delete old version of the mod if you had it.
MusicManiac added a new file:
QuoteDisplay MoreRegarding SPT 3.9.X or higher
If you're a user:
I do not plan on actively playing SPT 3.9.X or higher, therefore I do not plan on updating my less-used mods. If most recent version of the mod is 3.9.X simply updating package to 3.10.X might workIf you're a modder:
Do not reupload my old mods, thank you. If you want to fix compatibility, please ping @MusicManiac on SPT discord and I can add you to authors so you can update the mod if it requires an update.This has content. This can be used as dependency.
Welcome to Consumables Galore. Easy way to add stims and foods into your games. Even you can create a stim/food/drink now! And Stims Galore has following functions:
- Newly created items are properly added to flea
- (Optional) Added to trader of your choosing
- (Optional) Added to all quests that require similar stims to be found/turned in
- (Optional) You can even make crafts for them.
- (Optional) Added to spawnpoints so they can spawn on maps
- All items are on on-need basis. Don't want items to be in the game? Just delete it's file.
Comes prepacked with
- Old Meldonin (called "Meldonin v13.5 Injector")
- Old Odbolbos (called "Obdolbos v13 Injector")
- Elephant, a stim that combines Mule + SR3D-E.H.E.T.S. (which allows you to have your carry weight be boosted to big boy values, since you can't stack carry weight multipliers in base game so you gotta combine 2 stims into one to benefit from carry weight modifiers from both)
- Couple of stims from More Stim Injectors
- Adrenaline+ injector
- Another like 4 stims and 4 pills
- Couple of drinks and foods.
Installation is very simple, just drop the folder into your user/mods category.
Config is done on per-item basis. Each item is a json file located in items folder. In there you can edit a whole lot of things. If you need help figuring the config, just check next tab.
If you don't like the item, just delete the item file from items folder. Make sure that you don't have them in your inventory/stashMod loads all items that it finds in items folder. 1 item per file.
USE PROVIDED ITEMS AS REFERENCE POINTS FOR YOUR OWN ITEMS
If you come up with cool items, comment with your item file and I maybe can add it.
Now towards json itself, lets have a look at prepackaged Elephant stim:Code: Elephant.jsonDisplay More{ "cloneOrigin": "5ed51652f6c34d2cc26336a1", "id": "elephant_stim", "fleaPrice": 190000, "handBookPrice": 200000, "includeInSameQuestsAsOrigin": true, "addSpawnsInSamePlacesAsOrigin": true, "spawnWeightComparedToOrigin": 0.5, "Buffs": [ ... }
"cloneOrigin" - the base game item that we gonna use as baseline for our stim. This means we'll use it's model, animation, sound, properties, etc. To find id you wanna use, use https://db.sp-tarkov.com/search/ . You're interested in "_id" which can be found at very top.
"id" - id of our new items. Gotta be unique.
"fleaPrice" - flea price of our item. Accepted values: "asOriginal", value between 0-10, value above 10. "asOriginal" uses same flea price as stim we copying from. Useful for variations of existing drugs (check Meldonin v13.5 or Obdolbos v.13 files), value between 0 and 10 is treated as multiplier. So if you set it to 1.6 price will be 1.6 times of original price. Anything above 10 is treated as flat value in roubles.
"handBookPrice" - absolutely same system.
"includeInSameQuestsAsOrigin" - if set to true, this adds new item to all quests where you need to find/hand in as our original is. For example, if you make new item that's based on vanilla one but with better/worse/slightly different effects you can set it so quests that require original also accept this stim."addSpawnsInSamePlacesAsOrigin" - adds stim into same spawn locations as origin item.
spawnWeightComparedToOrigin - weight multiplier relative to original item spawn weight. <1 means your item is more rare. >1 means your item is more common.
Code: Elephant.json - continuationDisplay More"Buffs": [ { "BuffType": "StaminaRate", "Chance": 1, "Delay": 1, "Duration": 1800, "Value": 0.5, "AbsoluteValue": true, "SkillName": "" }, { "BuffType": "SkillRate", "Chance": 1, "Delay": 1, "Duration": 1800, "Value": 10, "AbsoluteValue": true, "SkillName": "Endurance" }, ... ],
"Buffs": - very simple, it's an array of buffs/debuffs that your item gives. To find a reference, go to Aki_Data/Server/database/globals.json and ctrl+f for "Buffs": { it will get you to the very top of list of buffs used by game, including stims. Just browse that. Buffs in item json must be in same format as Buffs in globals. Use provided items as reference point.
Code: Elephant.json - continuationDisplay More"locales": { "en": { "name": "Elephant Injector", "shortName": "Elephant", "description": "A crazy mix of M.U.L.E. stimulant injector and SR3D-E.H.E.T.S. Injector, which effectively combines effects of 2 stims together." } }, "trader": { "traderId": "54cb57776803fa99248b456e", "loyaltyReq": 4, "price": 195000, "amountForSale": 10 },
"locales" - understandable.
"trader" - (OPTIONAL) here you can add 1 trader that will sell your stim. In all provided files traderId is therapist. If you wanna use someone else - gotta provide their id. Rest of fields are self-explaining.
Code: Elephant.json - continuationDisplay More"craft": { "_id": "elephant_stim_craft", "areaType": 7, "requirements": [ { "areaType": 7, "requiredLevel": 3, "type": "Area" }, { "templateId": "5ed51652f6c34d2cc26336a1", "count": 1, "isFunctional": false, "isEncoded": false, "type": "Item" }, { "templateId": "ehets_stim", "count": 1, "isFunctional": false, "isEncoded": false, "type": "Item" }, { "templateId": "5d1b3a5d86f774252167ba22", "count": 2, "isFunctional": false, "isEncoded": false, "type": "Item" } ], "productionTime": 10400, "needFuelForAllProductionTime": false, "locked": false, "endProduct": "elephant_stim", "continuous": false, "count": 1, "productionLimitCount": 0, "isEncoded": false }
"craft": - (OPTIONAL) this is where you can add 1 craft recipe for your new item. Take a note that id must be unique, area type 7 is medstation. In requirement you can put what is required for craft. Area level, items, tools. "templateId" is items consumed. "endProduct" must be your item id. Rest is self-explanatory. You can browse base game crafts in Aki_Data/Server/database/hideout/production.json.
Use https://db.sp-tarkov.com/search/ for ID finding.
Adrenaline Plus has some extra stuff to look at.Code: AdrenalinePlus.jsonDisplay More"MaxResource": 2, "BackgroundColor": "red", "effects_health": { "Energy": { "value": -10 } }, "effects_damage": { "Contusion": { "delay": 0, "duration": 110, "fadeOut": 20 }, "Pain": { "delay": 0, "duration": 30, "fadeOut": 20 } },
The effects_health and effects_damage are there for ppl also to use, check https://db.sp-tarkov.com/search/ for different stims to see what they do.
Wanna add stims/food/drinks to your mod but don't wanna bother with figuring it out or just want to save coding time? Use this as dependency. When shipping your mod, just include in it empty folder MusicManiac-ConsumablesGalore/items/ with your items inside and link to this as dependency.
Big thanks to RainbowPC and his Lots of Loot as I directly took their function that digs inside loot tables. Made my life much easier by saving me a good hour of figuring out how to dig through them.
Another thanks to papershredder432 and his More Stim Injectors as I took some stims from there.Also thanks to Riisn for providing a good amount of 15 items for the mod
If you wanna be true homie or say thanks for time I've spent modding the game, feel free to send me a coffee on kofi
MusicManiac added a new version:
QuoteAdditional debug option,
More errors handling (now warns if array that's not supposed to be empty is empty)
Dependencies are included
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteJust dependencies update, no changes whatsoever.
Dependencies are included
Installation: delete old loader (MusicManiac-MusicManiacsCustomQuestLoader), then put folders into your user/mods folder.
MusicManiac added a new version:
QuoteCode refracture, no functional changes
Also mod name change due to request.
Dependencies are included
Installation: put folders into your user/mods folder. Delete old version of the loader
MusicManiac added a new version:
QuoteCode refracture, no functional changes
Also mod name change due to request.
Dependencies are included
Installation: put folders into your user/mods folder. Delete old version of the loader
MusicManiac added a new version:
QuoteDisplay MoreRemoved NGV task requirement to get kills on labs
Extended NVG time requirement to from 22:00-06:00 to 21:00-06:00
Fixed stim prices.
Dependencies update
Probably fixed something else along the way.
Dependencies are included
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteRemoved debug console spam.
No changes in functional part of the loader.
Dependencies are included
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteRemoved debug console spam.
No changes in functional part of the loader.
Dependencies are included
Installation: put folders into your user/mods folder.
MusicManiac added a new file:
QuoteDisplay MoreRegarding SPT 3.9.X or higher
If you're a user:
I do not plan on actively playing SPT 3.9.X or higher, therefore I do not plan on updating my less-used mods.If you're a modder:
Do not reupload my old mods, thank you. If you want to fix compatibility, please ping @MusicManiac on SPT discord and I can add you to authors so you can update the mod if it requires an update.50round mag for 9x39mm
If someone wanna make custom bundle for it hit me up, currently it's cloned from existing item.
Can be bought of flea or mechanic LL2.
Recommended to be ran with Two Slot Extended Mags
Drum mag can be found here: Tron's The Little Drummer Boy (Fixed)
To use good pistol grips for VAL:andre1337's Expansion Pack
If you wanna be true homie or say thanks for time I've spent modding the game, feel free to send me a coffee on kofi
MusicManiac added a new version:
QuoteAdded goons and zryachi to list of bosses that can count of kill bosses quests
Added quest for stims
All dependencies are included
Installation: put folders into your user/mods folder. Preferably delete old version of MusicManiac-Erika folder.
MusicManiac added a new version:
QuoteRefractured code, now has a dependency.
Added quest fog high capacity mags.
Don't forget to install dependency: MusicManiac's Custom Quest Loader (MMCQL)
Installation: put folders into your user/mods folder.
MusicManiac added a new file:
QuoteDisplay MoreRegarding SPT 3.9.X or higher
If you're a user:
I do not plan on actively playing SPT 3.9.X or higher, therefore I do not plan on updating my less-used mods.If you're a modder:
Do not reupload my old mods, thank you. If you want to fix compatibility, please ping @MusicManiac on SPT discord and I can add you to authors so you can update the mod if it requires an update.
THIS DOES NOT HAVE ANY CONTENT, IT'S A DEPENDENCY FOR MODDERS TO USE
This tool is similar to Virtual's Custom Quest Loader in regards of functionality, but it has a couple of QOL features in it:
- Automatic ID generation
- Automatic arrays formating
- Equipment and weapons categories to use in quests
- Which in turn makes your quests automatically support modded items
- Quests configuration on user-side via config file (so they don't have to go dig inside quests jsons to change values).
Mods developed for Virtual's Custom Quest Loader will work with this loader, this is why folders structure is preserved. My guenia pig for testing this was Guiding Light (85%), which has well over 50 quests with different conditions, counter, etc.
However, it's one-way compatibility. If you use QOL features in this loader, your quests will NOT load correctly in Virtual's Custom Quest Loader. They will most likely load, you'll get no errors, but they will most definitely be broken in-game.
QnA:
Q: Can I run this alongside Virtual's Custom Quest Loader?
A: Yes.
Q: Do I need to move my custom traders that I installed from Virtual's Custom Quest Loader to this mod?
A: No, unless they get updated and their dependency changes from Virtual's Custom Quest Loader to this.
Q: Can I delete Virtual's Custom Quest Loader and use this instead?
A: Yes but you don't need to + you'll need to dig in mod files. Just use VCQL. All the QOL in this mod is for MODDERS (with exception of ability to painlessly configure quests by users). You only EVER need this if you run a mod that has a dependency on this.Installation is simple, download this mod, put the mod inside SPT/user/mods folder.
This mod has a dependency on it's own, Weapon Categories Fixer because to use some features of this loader, we first gotta fix BSG inconsistent database.
It's included in the download.
Resources for developing quests:
- Resources: Quest Values Reference Tool
- https://db.sp-tarkov.com/search
- Any trader that adds quests
- Vanilla quests that can be found in Aki_Data/server/database/templates/quests.json
Following things are needed to add your quests into the game:
Traders (Optional)
If you want to have trader + quests, this mod can handle quests side of trader. Loading the trader himself you'll have to do on your own. As a good example to look at how you can load a trader (with pretty much changing a couple of values here and there), check out Guiding Light (85%) or Erika. I'm sure there are more mods that do same thing but these are the only 2 that I use, therefore I looked at their code (or in case of Erika, wrote one) and know that it can be easily adjusted to make your own trader. Or use templates from https://dev.sp-tarkov.com/chomp/ModExamples.
Configs (Optional)
You can add config files for your quests so users can adjust quests as they like. Read more on it in next tab.
Quests (Mandatory)
Quest files can have any name but must follow the format in Aki_Data/server/database/templates/quests.json. For more examples of how quests can look you can check Guiding Light (85%) or Erika, for example.
Side specific quests are supported. The "side" value of a quest can either be "Pmc" (for both sides), "Bear" or "Usec".
Locales (Mandatory)
Language files must also follow a particular format. You can check how exisiting locales file look in Aki_Data/server/database/locales/global/en.
Locales files can also have any name.
Every unique locale, located in any of the language files, will be added to every other place where the same key is not present.
Images (Optional)
All images need to be 314 x 177 and MUST be either a .png or .jpg.
To use custom images, place the image into the 'res/quests' directory and reference the name of the image in your quest file. For example, if you place testImg.png in the folder you can reference it in your quests like "image": "/files/quest/icon/testImg.png",
All Tarkov quest images can be found in Aki_Data/server/images/quests, feel free to use them or load your own.
Now this is where we shine.
This section assumes you're capable browsing AKI_DATA/server/database/templates/quests.json to see how vanilla quests look like or you have used VCQL before.
1. Automatic ID generation
CodeDisplay More"QM_45_AP": { "_id": "QM_45_AP", ... "conditions": { "AvailableForFinish": [ { "_parent": "CounterCreator", "_props": { "counter": { "conditions": [ { "_parent": "Kills", "_props": { ... "id": "thisIsRandomizedInCode", ... } }, { "_parent": "Location", "_props": { "id": "thisIsRandomizedInCode", "target": [ "bigmap" ] } } ], "id": "thisIsSetInCode" }, ... "id": "QM_45_AP Kills_0", "type": "Elimination", ... }, "dynamicLocale": false } ], "AvailableForStart": [ { "_parent": "Level", "_props": { ... "id": "thisIsRandomizedInCode", ... }, "dynamicLocale": false }, { "_parent": "Quest", "_props": { ... "id": "thisIsRandomizedInCode", ... }, "dynamicLocale": false } ], ... }, ... }
What can we see in this snippet:
- Counter conditions ID's no longer need to be set. You don't have to generate new ID for any of your Kill Counter conditions. If you want to generate them, you still can, loader will randomize only ones that are set to "thisIsRandomizedInCode". Attention: this randomizes IDs of conditions use ONLY in "type": "Elimination," counters ("_parent": "CounterCreator",). Why? Because those ID's are unimportant from modding perspective.
- "AvailableForStart" level and quest conditions ("_parent": "Level" and "_parent": "Quest") also can be randomized, they are unimportant to modder.
- Counter itself has an ID, and this one is important. To save progress on quest, information is written in save file, and counterID needs to be same between player sessions. That's why you can see it's not "thisIsRandomizedInCode" but it's "id": "thisIsSetInCode". It set's counter id to quest _id + " counterId". As usual, this only works if you don't set counter id yourself. If it's anything else than "id": "thisIsSetInCode", loader will not touch it.
For example, in snippet above, counter id would be set to "QM_45_AP Kills_0 counterId". And it would be set to it every time loader runs, as long as you keep the same "id": "QM_45_AP Kills_0", which you shouldn't be changing anyway.Example How Above snippet looks without skipping lines:
CodeDisplay More"QM_45_AP": { "QuestName": "Getting that .45 ACP AP", "_id": "QM_45_AP", "acceptPlayerMessage": "QM_45_AP description", "canShowNotificationsInGame": true, "changeQuestMessageText": "QM_45_AP changeQuestMessageText", "completePlayerMessage": "QM_45_AP successMessageText", "conditions": { "AvailableForFinish": [ { "_parent": "CounterCreator", "_props": { "counter": { "conditions": [ { "_parent": "Kills", "_props": { "compareMethod": ">=", "id": "thisIsRandomizedInCode", "target": "Any", "value": "1" } }, { "_parent": "Location", "_props": { "id": "thisIsRandomizedInCode", "target": [ "bigmap" ] } } ], "id": "thisIsSetInCode" }, "doNotResetIfCounterCompleted": false, "dynamicLocale": false, "id": "QM_45_AP Kills_0", "index": 0, "oneSessionOnly": false, "parentId": "", "type": "Elimination", "value": "20", "visibilityConditions": [] }, "dynamicLocale": false } ], "AvailableForStart": [ { "_parent": "Level", "_props": { "compareMethod": ">=", "dynamicLocale": false, "id": "thisIsRandomizedInCode", "index": 0, "parentId": "", "value": 40, "visibilityConditions": [] }, "dynamicLocale": false }, { "_parent": "Quest", "_props": { "availableAfter": 0, "dispersion": 0, "dynamicLocale": false, "id": "thisIsRandomizedInCode", "index": 0, "parentId": "", "status": [ 4 ], "target": "GL_4M", "visibilityConditions": [] }, "dynamicLocale": false } ], "Fail": [] }, "description": "QM_45_AP description", "failMessageText": "QM_45_AP failMessageText", "image": "/files/quest/icon/596b453b86f77457c827bf44.jpg", "instantComplete": false, "isKey": false, "location": "any", "name": "QM_45_AP name", "note": "QM_45_AP note", "questStatus": {}, "restartable": false, "rewards": { "Fail": [], "Started": [], "Success": [] } }, "secretQuest": false, "side": "Pmc", "startedMessageText": "QM_45_AP description", "successMessageText": "QM_45_AP successMessageText", "templateId": "QM_45_AP", "traderId": "Erika_Temporal_Id", "type": "Skill" }
If you ever made a quest that excludes or includes weapon parts or equipment you hate yourself, BSG, earth, sky, heaven and life.
If you make a killcounter that has "equipmentInclusive":, "equipmentExclusive", "weaponModsExclusive' or "weaponModsInclusive" you know that each equipment id has to be in a separate array. Loader implements QOL feature that puts the ids into correct format.
Example:
CodeDisplay More"QM_30mm_scopes": { "QuestName": "Getting those 30mm riflescopes", "_id": "QM_30mm_scopes", ... "conditions": { "AvailableForFinish": [ { "_parent": "CounterCreator", "_props": { "counter": { "conditions": [ { "_parent": "Kills", "_props": { ... "weaponModsInclusive": ["asdb234nj24j32324", "324jnbkj213jbkjb", "21kj31kj32jbfkj"], "weaponModsEclusive": ["324jn324j23n4rfe", "fjn3i4023409fj203jj"], "equipmentInclusive": ["5c0558060db834001b735271"], "equipmentExclusive": ["348945978ghn934htg374htr", "3278hf7fh37fh78f4g72fg"], "value": "1" } } ], "id": "thisIsSetInCode" }, ... }, "dynamicLocale": false }
As you can see, "weaponModsInclusive": ["asdb234nj24j32324", "324jnbkj213jbkjb", "21kj31kj32jbfkj"], is an array with depth of 1, not an array of arrays (as BSG does it for some reason). To clarify, usually any of weaponModsInclusive, weaponModsEclusive, equipmentInclusive, equipmentExclusive has to follow format of [["id1"], ["id2"], ["id3"], ...].
This is optional to use, if you put your ids into array of arrays (as BSG quests do), loader will not touch them. So:
- "weaponModsInclusive": ["asdb234nj24j32324", "324jnbkj213jbkjb", "21kj31kj32jbfkj"], - this will work
- "weaponModsInclusive": [["asdb234nj24j32324"], ["324jnbkj213jbkjb"], ["21kj31kj32jbfkj"]], - this will work
- However, do not combine them inside one property. Loader checks if property (such as "weaponModsInclusive" is an array of arrays, and if it's not, it wraps each element into array)
"weaponModsInclusive": [["asdb234nj24j32324"], "324jnbkj213jbkjb", "21kj31kj32jbfkj"], - this will not workFor next QOL feature to work, these properties must be in 1-depth array. It's made this way to provide compatibility with OLD quests written for Virtual's Custom Quest Loader.
Example How Above snippet looks without skipping lines and applying 2 features previously described:
CodeDisplay More"QM_45_AP": { "QuestName": "Getting that .45 ACP AP", "_id": "QM_45_AP", "acceptPlayerMessage": "QM_45_AP description", "canShowNotificationsInGame": true, "changeQuestMessageText": "QM_45_AP changeQuestMessageText", "completePlayerMessage": "QM_45_AP successMessageText", "conditions": { "AvailableForFinish": [ { "_parent": "CounterCreator", "_props": { "counter": { "conditions": [ { "_parent": "Kills", "_props": { "compareMethod": ">=", "id": "thisIsRandomizedInCode", "target": "Any", "weaponModsInclusive": ["asdb234nj24j32324", "324jnbkj213jbkjb", "21kj31kj32jbfkj"], "weaponModsEclusive": ["324jn324j23n4rfe", "fjn3i4023409fj203jj"], "equipmentInclusive": ["5c0558060db834001b735271"], "equipmentExclusive": ["348945978ghn934htg374htr", "3278hf7fh37fh78f4g72fg"], "value": "1" } }, { "_parent": "Location", "_props": { "id": "thisIsRandomizedInCode", "target": [ "bigmap" ] } } ], "id": "thisIsSetInCode" }, "doNotResetIfCounterCompleted": false, "dynamicLocale": false, "id": "QM_45_AP Kills_0", "index": 0, "oneSessionOnly": false, "parentId": "", "type": "Elimination", "value": "20", "visibilityConditions": [] }, "dynamicLocale": false } ], "AvailableForStart": [ { "_parent": "Level", "_props": { "compareMethod": ">=", "dynamicLocale": false, "id": "thisIsRandomizedInCode", "index": 0, "parentId": "", "value": 40, "visibilityConditions": [] }, "dynamicLocale": false }, { "_parent": "Quest", "_props": { "availableAfter": 0, "dispersion": 0, "dynamicLocale": false, "id": "thisIsRandomizedInCode", "index": 0, "parentId": "", "status": [ 4 ], "target": "GL_4M", "visibilityConditions": [] }, "dynamicLocale": false } ], "Fail": [] }, "description": "QM_45_AP description", "failMessageText": "QM_45_AP failMessageText", "image": "/files/quest/icon/596b453b86f77457c827bf44.jpg", "instantComplete": false, "isKey": false, "location": "any", "name": "QM_45_AP name", "note": "QM_45_AP note", "questStatus": {}, "restartable": false, "rewards": { "Fail": [], "Started": [], "Success": [] } }, "secretQuest": false, "side": "Pmc", "startedMessageText": "QM_45_AP description", "successMessageText": "QM_45_AP successMessageText", "templateId": "QM_45_AP", "traderId": "Erika_Temporal_Id", "type": "Skill" }
Ever wanted to make the quest that requires kills with pistols only and realized you have to put every goddamn pistol id in the quest? This loader features loading categories of weapons/equipment/attachments/barter items/etc. Currently implemented categories can be viewed in mod.ts in public configureCategories(itemDB) function. It parses the database before adding quests. This means that these categories support modded items. For example, if you have a mod that adds brand new sniper rifle that shoots 7,62x51mm rounds, it will automatically count for all the quests that have either "sniperRifles762x51" or "sniperRifles" listed in their weapons.
So you could do something like
CodeDisplay More"QM_45_AP": { "_id": "QM_45_AP", ... "conditions": { "AvailableForFinish": [ { "_parent": "HandoverItem", "_props": { ... "target": ["scopes30mm", "23h123ubuidh1u23ghiu1", "sniperRifles"], "value": "5", "visibilityConditions": [] }, "dynamicLocale": false }, { "_parent": "CounterCreator", "_props": { "counter": { "conditions": [ { "_parent": "Kills", "_props": { ... "weapon": ["SMGs45", "pistols45", "23h3jkhb2hj3bhb12h3gb12h"], "weaponModsInclusive": ["scopes30mm", "324jnbkj213jbkjb", "21kj31kj32jbfkj"], "weaponModsEclusive": ["flashlights", "tacticalComboDevices"], "equipmentInclusive": ["5c0558060db834001b735271", "backpacks (not implemented category, just an example)"], "equipmentExclusive": ["348945978ghn934htg374htr", "helmets (not implemented category, just an example)"], ... } } ], "id": "thisIsSetInCode" }, ... "type": "Elimination", ... }, "dynamicLocale": false } ... }
As you can see, instead of listing every damn id inside "weapon" property we can just list some categories. You can mix in normal ids there too. Note that list of categories available to be used is limited and needs to be expanded manually. If you want to have a category created, you will have to ask for it and wait for it. Providing a code snippet that can be added to public parseItemsDatabase(itemDB) function will accelerate the process.
Categories work in:
- In "_parent": "CounterCreator", of "type": "Elimination", inside "_parent": "Kills", conditions properties: "weapon": ,"equipmentInclusive":, "equipmentExclusive", "weaponModsExclusive' or "weaponModsInclusive"
- In "_parent": "HandoverItem", properties "_props": inside "target": property
For this QOL feature to work, these properties must be in 1-depth array. It's made this way to provide compatibility with OLD quests written for Virtual's Custom Quest Loader, as I don't expect people to convert old quests into better format since they will load anyway.
- These will work:
- "weapon": ["SMGs45", "pistols45", "23h3jkhb2hj3bhb12h3gb12h"],
- "weaponModsInclusive": ["scopes30mm", "324jnbkj213jbkjb", "21kj31kj32jbfkj"],
- "weaponModsEclusive": ["flashlights", "tacticalComboDevices"],
- "equipmentInclusive": ["5c0558060db834001b735271", "backpacks"],
- "equipmentExclusive": ["348945978ghn934htg374htr", "helmets"],
- These will NOT work:
- "weaponModsInclusive": [["scopes30mm"], ["324jnbkj213jbkjb"], ["21kj31kj32jbfkj"]],
- "weaponModsEclusive": ["flashlights", "tacticalComboDevices", ["djk234jkb32423h4gk34h"]],
- "equipmentInclusive": [["5c0558060db834001b735271"], ["backpacks"]],
- "equipmentExclusive": ["348945978ghn934htg374htr", ["helmets"]],
Example How Above snippet looks without skipping lines and applying 3 features previously described:
CodeDisplay More"QM_45_AP": { "QuestName": "Getting that .45 ACP AP", "_id": "QM_45_AP", "acceptPlayerMessage": "QM_45_AP description", "canShowNotificationsInGame": true, "changeQuestMessageText": "QM_45_AP changeQuestMessageText", "completePlayerMessage": "QM_45_AP successMessageText", "conditions": { "AvailableForFinish": [ { "_parent": "HandoverItem", "_props": { "countInRaid": false, "dogtagLevel": 0, "dynamicLocale": false, "id": "QM_45_AP HandoverItem_0", "index": 0, "isEncoded": false, "maxDurability": 100, "minDurability": 0, "onlyFoundInRaid": false, "parentId": "", "target": [ "5efb0cabfb3e451d70735af5", "scopes30mm" ], "value": "600", "visibilityConditions": [] }, "dynamicLocale": false }, { "_parent": "CounterCreator", "_props": { "counter": { "conditions": [ { "_parent": "Kills", "_props": { "compareMethod": ">=", "id": "thisIsRandomizedInCode", "target": "Any", "weapon": ["SMGs45", "pistols45"], "weaponModsInclusive": ["scopes30mm", "324jnbkj213jbkjb", "21kj31kj32jbfkj"], "weaponModsEclusive": ["flashlights", "tacticalComboDevices"], "equipmentInclusive": ["5c0558060db834001b735271"], "equipmentExclusive": ["348945978ghn934htg374htr"], "value": "1" } }, { "_parent": "Location", "_props": { "id": "thisIsRandomizedInCode", "target": [ "bigmap" ] } } ], "id": "thisIsSetInCode" }, "doNotResetIfCounterCompleted": false, "dynamicLocale": false, "id": "QM_45_AP Kills_0", "index": 0, "oneSessionOnly": false, "parentId": "", "type": "Elimination", "value": "20", "visibilityConditions": [] }, "dynamicLocale": false } ] "AvailableForStart": [ { "_parent": "Level", "_props": { "compareMethod": ">=", "dynamicLocale": false, "id": "thisIsRandomizedInCode", "index": 0, "parentId": "", "value": 40, "visibilityConditions": [] }, "dynamicLocale": false } ], "Fail": [] }, "description": "QM_45_AP description", "failMessageText": "QM_45_AP failMessageText", "image": "/files/quest/icon/596b453b86f77457c827bf44.jpg", "instantComplete": false, "isKey": false, "location": "any", "name": "QM_45_AP name", "note": "QM_45_AP note", "questStatus": {}, "restartable": false, "rewards": { "Fail": [], "Started": [], "Success": [ { "target": "Erika_Temporal_Id QM_45_AP Trade", "id": "QM_45_AP Erika_Temporal_Id QM_45_AP Trade", "type": "AssortmentUnlock", "index": 3, "loyaltyLevel": 1, "traderId": "Erika_Temporal_Id", "items": [ { "_id": "Erika_Temporal_Id QM_45_AP Trade", "_tpl": "5efb0cabfb3e451d70735af5", "parentId": "hideout", "slotId": "hideout" } ] } ] }, "secretQuest": false, "side": "Pmc", "startedMessageText": "QM_45_AP description", "successMessageText": "QM_45_AP successMessageText", "templateId": "QM_45_AP", "traderId": "Erika_Temporal_Id", "type": "Skill" }
Balancing quests is annoying cuz people always complain about balance anyway? This loader allows configs for your quests. Users no longer have to go browse jsons of quests to find what they want. Simply add config file in configs folder with following structure:
CodeDisplay More{ "questsItemCounterMultipliers" : { "QM_46x30_AP" : 1, }, "questsKillsCounterMultipliers" : { "QM_46x30_AP" : 1, "QM_9x19_AP" : 1, "QM_9x19_PBP" : 2 }, "questsCultistsKillsCounterMultipliers" : { "QM_46x30_AP" : 1 "QM_GPNVG_18_NVGs" : 1 }, "questsLevelRequirements" : { "QM_46x30_AP" : 35 } }
Idea is very simple, you provide quest ID and number. Make sure your quest IDs are readable by user or else this will not help much and will not make it in any way easier for user to configure quests, which is endgoal.
- questsItemCounterMultipliers - multiplier for your HandoverItem subconditions. So user can make quest require to turn in only 50% of items for quest to complete if they set it to 0.5, for example
- questsKillsCounterMultipliers - multiplier for your kill counters.
- questsCultistsKillsCounterMultipliers - multiplier for your kill counters that have sectantWarrior in list of targets. This take precedence over questsKillsCounterMultipliers. Aka if condition has cultists in it, questsCultistsKillsCounterMultipliers will be applied, NOT questsKillsCounterMultipliers.
- questsLevelRequirements - if quest has level requirement, users can change it here.
You don't have to have this config file, it can be half-empty, it can have only half of your quest Ids, it can have only questsLevelRequirements if you wish. It's however important that IF you have config category that it's named either questsItemCounterMultipliers or questsKillsCounterMultipliers or questsLevelRequirements questsCultistsKillsCounterMultipliers
- I used these QOL to develop Erika and it made my life 10 times simpler. 10/10 recommend. If you need help, take a glance at her files.
- DO NOT include this into your mod, use this as dependency. You can structure your mod so it extracts into appropriate places.
- Please use naming convention I used in Erika files so its easier later (assuming people will be interested in using this loader)
- Ping me on discord in mod-dev channel if you have a question and need semi-fast reply
test
MusicManiac added a new file:
QuoteDisplay MoreGym for real gigachads
Features:
- More gym reps (get swole bro)
- Make all skillchecks (circles) same as first one
- Disable fracture on fail (not tested but should work)
- Normalized exp (now if your Str is lvl 30 you won't be getting shitty exp, it's same regardless of level)
- Extra exp multiplier
- Change duration of muscle pain
Everything is configurable in config.
If you wanna be true homie or say thanks for time I've spent modding the game, feel free to send me a coffee on kofi
I effectively stopped playing SPT in favor of PvE since I can play with friends there (and no I don't care about coop SPT mods).
I will be keeping this mod up-to-date as best as I could, however I do not follow SPT dev cycle anymore so might take some time for updates since I literally miss new SPT releases. My 3.9.X and 3.10.X updates were put up literally because someone tipped me on ko-fi and it send email to me so I was like "oh, new SPT version is up"
Do not repost updates of my mods without reaching me first on SPT discord.
MusicManiac added a new version:
QuoteFixed .45 ACP quest a bit
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteDisplay MoreAdded kill cultist part in all quests
Added cultist boss to list of bosses
Added config option to set multiplier for cultists kills on per quest basis (if someone is terrified of cultists)
Or just use Normalized Bots to make them make footsteps
Installation: put folders into your user/mods folder.
MusicManiac added a new version:
QuoteAdded quest for NVGs,
New picture
I think I also fixed something somewhere? Not sure.
Installation: put folders into your user/mods folder.