Pyroteknics Posted June 17, 2024 Share Posted June 17, 2024 Got a small script that adds some armour to the clothing shop Fallons Basement and worked first try (which is a bonus) and can see the new items in the store. But, seems that some items spawn with random prefixes or mods without me doing anything other than specifying the base item ID. For example, if I scripted it to add 10 items of the same form ID to a shop, 6 of those might be unmodified but another 2 might have a different preifx (shadowed, muffled etc), 1 might have a legendary and another with a mod and a legendary. Example screenshot below: Is it possible to make it so it only adds unmodified items so they stack nicely? While not the end of the world it does massively fill out the shop window especially when there are multiple base armours to add which all could potentially have different armour mods. The method I used is following Seddon4494's YouTube video guide that runs a 'run-once' quest that adds the items via a simple script: Scriptname CWM_Armor_Inject_Script extends Quest Armor Property ccBGSFO4117_ClothesMercTroublemakerMale auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercVeteranMale_Helm auto Const Armor Property ccBGSFO4117_ClothesMercVeteranMale auto Const Armor Property ccBGSFO4117_ClothesMercVeteranMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerFemale auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerFemaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercThreeDog auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerMale_Helm auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerMale auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercCharmerFemale auto Const Armor Property ccBGSFO4117_ClothesMercCharmerFemaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercCharmerFemaleHelm auto Const Armor Property ccBGSFO4117_ClothesMercCharmerMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercCharmerMale auto Const Armor Property ccBGSFO4117_ClothesMercCharmerMaleHelm auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerFemaleHelm auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerFemale auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerFemaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercVeteranFemale_Helm auto Const Armor Property ccBGSFO4117_ClothesMercVeteranFemale auto Const Armor Property ccBGSFO4117_ClothesMercVeteranFemaleVariant01 auto Const Armor Property ccBGSFO4117_TalonCompanyArmor auto Const Armor Property ccBGSFO4117_TalonCompanyHelmet auto Const LeveledItem Property VL_Vendor_Clothing auto Const Event OnQuestInit() VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranMale_Helm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercThreeDog, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerMale_Helm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerFemaleHelm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerMaleHelm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerFemaleHelm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranFemale_Helm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_TalonCompanyArmor, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_TalonCompanyHelmet, 1, 10) EndEvent Does it need to be added to a leveled list (using 'VL_Vendor_Clothing' which only Fallons uses) or can the script directly add them to a container? Fallons Basement container ("VendorsDCFallons") in CK links to leveled lists as normal but also has an single hazmat suit so assuming it might be possible to do it this way? Thanks in advance. Link to comment Share on other sites More sharing options...
adb3nj Posted June 18, 2024 Share Posted June 18, 2024 Create duplicate forms (e.g. NoMods_ClothesMercTroublemakerMale) with all the object template combinations removed apart from the ones labelled 'default', and use your script to add those duplicates. Or you can remove the template combinations from the original forms if you don't care about them always spawning without mods / legendary effects attached. Link to comment Share on other sites More sharing options...
Pyroteknics Posted June 20, 2024 Author Share Posted June 20, 2024 Thanks for that, will have to consider that option. For the script, is there a way of adding stuff directly into the container rather than a leveled list? Seems using the example above ( VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerMale, 1, 10) ) works fine when it refers to a leveled list but doesn't like it if I switch it to the container name (and changing the variable above to from 'LeveldItem' to 'Container' which it is also happy with) saying 'AddForm is not a function'. Also tried just a simple 'AddItem' comes up with it saying the same thing about it not being a function. Example code it doesn't like if trying to add an item directly to a container (shortened showing 2 lines I've tried): Scriptname CWM_Armor_Inject_Script extends Quest Armor Property ccBGSFO4117_ClothesMercTroublemakerMale auto Const Container Property VendorDCFallons auto Const Event OnQuestInit() VendorDCFallons.AddForm(ccBGSFO4117_ClothesMercTroublemakerMale, 1, 10) ...or... VendorDCFallons.AddItem(ccBGSFO4117_ClothesMercTroublemakerMale, 10) EndEvent Link to comment Share on other sites More sharing options...
adb3nj Posted June 20, 2024 Share Posted June 20, 2024 AddItem should work, but you need to add it to a container's object reference rather than the base form. So when you declare your properties, ObjectReference Property VendorDCFallons auto Const rather than Container Property. (I assume you'll also want to change the name of the property to get it to autofill in Creation Kit.) This won't solve your problem though – the mod templates are part of the base forms rather than the levelled lists. If you want a purely script-based solution, you'll need to do something like the following: ObjectReference myArmor = VendorDCFallons.PlaceAtMe(ccBGSFO4117_ClothesMercTroublemakerMale) myArmor.RemoveAllMods() VendorDCFallons.additem(myArmor) For some items, you'll then need to add some mods back, e.g. combat armor has 'light armor' size, 'standard' material and 'no misc' lining mods attached as default. So on balance, I think creating new forms is the easiest way of doing it. Link to comment Share on other sites More sharing options...
Pyroteknics Posted June 21, 2024 Author Share Posted June 21, 2024 I tried your suggestion using the object reference to put the armour directly into the container with the following condensed sample: Scriptname CWM_Armor_Inject_Script extends Quest Armor Property ccBGSFO4117_ClothesMercTroublemakerMale auto Const 00072013 Property VendorDCFallons auto Const Event OnQuestInit() VendorDCFallons.AddItem (ccBGSFO4117_ClothesMercTroublemakerMale, 10) EndEvent But now the compiler comes up with a failure showing C:\Users\Pyroteknics\AppData\Local\Temp\PapyrusTemp\CWM_Armor_Inject_Script.psc(4,0): missing EndOfFile at '00072013' - I have no idea what it's looking for? Even tried adding stuff like a semi-colon on the end. Apologies, the script side of FO4 is still pretty new for me. I'm also assuming the 'object reference' is the same thing as 'Form ID'? If so the container 'VendorDCFallons' one is 00072013. Link to comment Share on other sites More sharing options...
adb3nj Posted June 21, 2024 Share Posted June 21, 2024 (edited) The object reference is the thing that points to your container in the game world, whereas the base form is the underlying shape of the container. VendorDCFallons is only used once in the game so it's a bad example for clarifying, but consider the generic footlocker. There are loads of them in the game, and they all have the same base form: FootLocker01. Each specific footlocker has its own object reference though, and that's what lets you identify it. Theoretically, if you were to add an item to FootLocker01, you'd be adding the same item to every footlocker in the game, which you're unlikely to want to do (and I don't think you can with a script anyway). That's essentially what you're doing by trying to add an item to VendorDCFallons – the issue is just confused slightly by the fact VendorDCFallons only appears once in the game. I don't believe form IDs are useful for scripting – you need an editor ID. And annoyingly, not all object references have one. You can add one though. Or locate the object reference manually, but that can be a pain in CreationKit. I would download FO4Edit and add an editor ID to the VendorDCFallons object reference, and then return to CreationKit and use the new editor ID in your script. To stay within CreationKit though, this is what you need to do: Go to the object window, expand the 'WorldObjects' tree and select 'Container'. Search for and right-click 'VendorDCFallons'. Select 'use info' right at the bottom, and a new window will open. In the bottom half of that window, it will say 'Used in these Cells', followed by a cell reference. Double click the cell reference and a couple of chests will load into the render window. The chest on the left is the copy of VendorDCFallons that is placed into the game world. Double click it and you'll get a reference window, which in its second row should say 'Base Object: VendorDCFallons'. If it doesn't say that, you've got the wrong chest. Anyway, once you've got the right chest, type 'VendorDCFallonsREF' into the Reference Editor ID box, click 'okay' and save your mod. You can now go back to your script. Declare your ObjectReference like this: ObjectReference Property VendorDCFallonsREF auto const Add your item to it like this: VendorDCFallonsREF.AddItem (ccBGSFO4117_ClothesMercTroublemakerMale, 10) As long as the references in those two script snippets match, your script will compile, but you want them to also match the Editor ID you added in the render window so CreationKit autofills it when you close the script window, right-click the script name and select 'edit properties' (or, if you're using a fragment, just hit 'properties'). 'Okay' out of any open windows, save your mod, and you should be good to go. Edited June 21, 2024 by adb3nj Link to comment Share on other sites More sharing options...
Pyroteknics Posted June 22, 2024 Author Share Posted June 22, 2024 That makes perfect sense with difference between object reference vs base form ID. Adding an object reference like you suggested did work in having to add a new one as the field was blank in CK and the script does compile now but strangely the items now don't show up in the vendor? Very odd. While the code for adding to a leveled list worked above, that has issues with vendors that don't have a leveled list without the random element of items not appearing (the 'Chance None' field on any leveled item), again Fallons Basement has its own dedicated LL (VL_Vendor_Clothing) so is a bad example. Maybe it's just the way scripting is without having to directly use CK to add the items to a container (and possibly affecting anyone else using/changing these). Probably safer to stick with the LL and the possible different variations of clothing than overcomplicate things with duplicates! Link to comment Share on other sites More sharing options...
LarannKiar Posted June 22, 2024 Share Posted June 22, 2024 On 6/17/2024 at 3:51 PM, Pyroteknics said: Got a small script that adds some armour to the clothing shop Fallons Basement and worked first try (which is a bonus) and can see the new items in the store. But, seems that some items spawn with random prefixes or mods without me doing anything other than specifying the base item ID. For example, if I scripted it to add 10 items of the same form ID to a shop, 6 of those might be unmodified but another 2 might have a different preifx (shadowed, muffled etc), 1 might have a legendary and another with a mod and a legendary. Example screenshot below: Is it possible to make it so it only adds unmodified items so they stack nicely? While not the end of the world it does massively fill out the shop window especially when there are multiple base armours to add which all could potentially have different armour mods. The method I used is following Seddon4494's YouTube video guide that runs a 'run-once' quest that adds the items via a simple script: Scriptname CWM_Armor_Inject_Script extends Quest Armor Property ccBGSFO4117_ClothesMercTroublemakerMale auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercVeteranMale_Helm auto Const Armor Property ccBGSFO4117_ClothesMercVeteranMale auto Const Armor Property ccBGSFO4117_ClothesMercVeteranMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerFemale auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerFemaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercThreeDog auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerMale_Helm auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerMale auto Const Armor Property ccBGSFO4117_ClothesMercAdventurerMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercCharmerFemale auto Const Armor Property ccBGSFO4117_ClothesMercCharmerFemaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercCharmerFemaleHelm auto Const Armor Property ccBGSFO4117_ClothesMercCharmerMaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercCharmerMale auto Const Armor Property ccBGSFO4117_ClothesMercCharmerMaleHelm auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerFemaleHelm auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerFemale auto Const Armor Property ccBGSFO4117_ClothesMercTroublemakerFemaleVariant01 auto Const Armor Property ccBGSFO4117_ClothesMercVeteranFemale_Helm auto Const Armor Property ccBGSFO4117_ClothesMercVeteranFemale auto Const Armor Property ccBGSFO4117_ClothesMercVeteranFemaleVariant01 auto Const Armor Property ccBGSFO4117_TalonCompanyArmor auto Const Armor Property ccBGSFO4117_TalonCompanyHelmet auto Const LeveledItem Property VL_Vendor_Clothing auto Const Event OnQuestInit() VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranMale_Helm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercThreeDog, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerMale_Helm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercAdventurerMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerFemaleHelm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerMaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerMale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercCharmerMaleHelm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerFemaleHelm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercTroublemakerFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranFemale_Helm, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranFemale, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_ClothesMercVeteranFemaleVariant01, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_TalonCompanyArmor, 1, 10) VL_Vendor_Clothing.AddForm(ccBGSFO4117_TalonCompanyHelmet, 1, 10) EndEvent Does it need to be added to a leveled list (using 'VL_Vendor_Clothing' which only Fallons uses) or can the script directly add them to a container? Fallons Basement container ("VendorsDCFallons") in CK links to leveled lists as normal but also has an single hazmat suit so assuming it might be possible to do it this way? Thanks in advance. Take a look at the LeveledItem (LLI) data flags if you're not sure what they do. Here's a link to the Fallout 4 CK site but it doesn't really contain anything about LLIs. You can't add Forms directly to a Container base form in vanilla Papyrus, only to the inventory of a Container object reference with AddItem(). You can call LeveledItem.AddForm() on a LeveledItem form instead. Drag and drop your Armor and Weapon forms to an LLI (don't drag and drop their object references), check the Use All flag if you'd like all of them to be added to the Container form then add this LLI to the Item List of the Container. Removing the Object Templates from base forms that are eligible to be an inventory item with instance data (Armors and Weapons) makes the engine create object references of these base forms without random ObjectMods. NPC Vendor data is reevaluated by the native code periodically (per NPC) but there's a timer that resets the actual "vendor chest" of vendor factions in every two game days. Timer starts after closing the BarterMenu if I'm remembering right. NPC Vendor data has a few engine bugs. For mod testing purposes, you can trigger the 3D load event of the vendor NPC (e.g. call Disable() - Enable() on them, or leave and reenter their location yourself) before attempting to open their BarterMenu. (Sorry I didn't read everything mentioned above but it seems you're overcomplicating this a bit). Link to comment Share on other sites More sharing options...
Pyroteknics Posted June 22, 2024 Author Share Posted June 22, 2024 2 hours ago, LarannKiar said: You can't add Forms directly to a Container base form in vanilla Papyrus, only to the inventory of a Container object reference with AddItem(). Yeah found that out the hard way as adb3nj mentioned above with my example of trying to use the container 'VendorDCFallons' to put the armour in as in this example, because its only used once, seems like it doesn't have an object reference. Even adding a new object reference to it in CK and pointing at it with code, while it compiles, doesn't seem to actually add the item to it viewing in game. My topic has slightly side-tracked a little bit going from various mod options on clothing filling up the vendor window etc appearing in shops to actually getting them into the shop preferably without injecting into a leveled list but ultimately related - again just very convenient that the VendorDCFallons container from initial post actually has a unique leveled list VL_Vendor_Clothing in it that always lists everything in it but a lot of other vendors don't and are chance based and pulls randomly from LL assigned to it such as food or chem vendors etc. Link to comment Share on other sites More sharing options...
Recommended Posts