AceSevenFive Posted March 15, 2016 Share Posted March 15, 2016 So, my script for liquid barrels could use some more vessels for storing liquid, but my activator is out of script properties. How would I use arrays/property groups as script properties (since I can add new members of an array/property group)? Link to comment Share on other sites More sharing options...
Reneer Posted March 15, 2016 Share Posted March 15, 2016 (edited) For more help, you might want to post your script. But, basically, don't worry about the properties / VMAD stuff in FO4Edit. It's a pain in the ass and you don't need to worry about it. The easiest way to set this up would be like this: scriptname BlahBlah extends Activator ObjectReference[] vessels Function InitializeVariables() if (vessels == none) vessels = new ObjectReference[128] endif vessels[0] = Game.GetFormFromFile(0xFormIDHere, "Fallout4.esm") As ObjectReference ; or Container, but you would want to change the ObjectReference to Container above vessels[1] = Game.GetFormFromFile(0xFormIDHere, "Fallout4.esm") As ObjectReference vessels[2] = Game.GetFormFromFile(0xFormIDHere, "Fallout4.esm") As ObjectReference ; ... vessels[127] = Game.GetFormFromFile(0xFormIDHere, "Fallout4.esm") As ObjectReference EndFunction Event OnLoad() InitializeVariables() EndEvent And there you have all the containers you will hopefully ever need. Edited March 15, 2016 by Reneer Link to comment Share on other sites More sharing options...
AceSevenFive Posted March 15, 2016 Author Share Posted March 15, 2016 (edited) Here's the script as it currently stands: ScriptName BarrelScript extends ObjectReference ActorValue Property BarrelCapacity Auto ActorValue Property FillLevel Auto Actor Property PlayerDude Auto Form Property BeerBottleEmpty Auto Form Property SyringeEmpty Auto Form Property PufferEmpty Auto Form Property BottleEmpty Auto Form Property BottleFilled Auto Form Property SyringeFilled Auto Form Property PufferFilled Auto Form Property BeerBottleFilled Auto Message Property BarrelMenu Auto Message Property BarrelFillSubMenu Auto Message Property BarrelInsertSubMenu Auto int Property CapacityOfWaterBottle Auto int Property CapacityOfSyringe Auto int Property CapacityOfPuffer Auto int Property CapacityOfBeerBottle Auto int Property MenuOption Auto int Property FillSubMenuOption Auto int Property InsertSubMenuOption Auto int Property BarrelCapacityExpected Auto Function OnActivate(ObjectReference akActionRef) if(Self.GetValue(BarrelCapacity) == 0) Self.SetValue(BarrelCapacity, BarrelCapacityExpected) endif MenuOption = BarrelMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(MenuOption == 0) FillSubMenuOption = BarrelFillSubMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(FillSubMenuOption == 0) if(PlayerDude.GetItemCount(BeerBottleEmpty) >= 1) PlayerDude.RemoveItem(BeerBottleEmpty, 1, false, none) Self.ModValue(FillLevel, CapacityOfBeerBottle * -1) PlayerDude.AddItem(BeerBottleFilled, 1, false) endif elseif(FillSubMenuOption == 1) if(PlayerDude.GetItemCount(SyringeEmpty) >= 1) PlayerDude.RemoveItem(SyringeEmpty, 1, false, none) Self.ModValue(FillLevel, CapacityOfSyringe * -1) PlayerDude.AddItem(SyringeFilled, 1, false) endif elseif(FillSubMenuOption == 2) if(PlayerDude.GetItemCount(PufferEmpty) >= 1) PlayerDude.RemoveItem(PufferEmpty, 1, false, none) Self.ModValue(FillLevel, CapacityOfPuffer * -1) PlayerDude.AddItem(PufferFilled, 1, false) endif elseif(FillSubMenuOption == 3) if(PlayerDude.GetItemCount(BottleEmpty) >= 1) PlayerDude.RemoveItem(BottleEmpty, 1, false, none) Self.ModValue(FillLevel, CapacityOfWaterBottle * -1) PlayerDude.AddItem(BottleFilled, 1, false) endif endif elseif(MenuOption == 1) InsertSubMenuOption = BarrelInsertSubMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(InsertSubMenuOption == 0) if(PlayerDude.GetItemCount(BeerBottleFilled) >= 1) PlayerDude.RemoveItem(BeerBottleFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfBeerBottle) PlayerDude.AddItem(BeerBottleEmpty, 1, false) endif elseif(InsertSubMenuOption == 1) if(PlayerDude.GetItemCount(SyringeFilled) >= 1) PlayerDude.RemoveItem(SyringeFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfSyringe) PlayerDude.AddItem(SyringeEmpty, 1, false) endif elseif(InsertSubMenuOption == 2) if(PlayerDude.GetItemCount(PufferFilled) >= 1) PlayerDude.RemoveItem(PufferFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfPuffer) PlayerDude.AddItem(PufferEmpty, 1, false) endif elseif(InsertSubMenuOption == 3) if(PlayerDude.GetItemCount(BottleFilled) >= 1) PlayerDude.RemoveItem(BottleFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfWaterBottle) PlayerDude.AddItem(BottleEmpty, 1, false) endif endif endif EndFunction Furthermore, are arrays of ObjectReference considered arrays of object in FO4Edit? I would prefer to be able to reuse the script with a few minor tweaks for each barrel. EDIT: So, I edited the script, added the array and an initialization routine, and replaced the empty vessel properties with the array. The problem is, when I put water into a Purified Water barrel, I don't receive anything back. The intended behavior is that you receive the vessel back [ie if you put a syringe into the barrel, you get an empty syringe back.] Edited March 15, 2016 by AceCarteria Link to comment Share on other sites More sharing options...
Reneer Posted March 16, 2016 Share Posted March 16, 2016 I'd need to see the new script, but likely you will need two arrays of ObjectReferences - filled and empty, and if you number them both the same, you shouldn't have too much trouble "swapping" between the two. Link to comment Share on other sites More sharing options...
Neanka Posted March 17, 2016 Share Posted March 17, 2016 ActorValue Strength = Game.GetFormFromFile(0x2c2, "Fallout4.esm") as ActorValueright? Link to comment Share on other sites More sharing options...
AceSevenFive Posted March 17, 2016 Author Share Posted March 17, 2016 Here's the script with arrays instead of properties: ScriptName BarrelScript extends ObjectReference ActorValue Property BarrelCapacity Auto ActorValue Property FillLevel Auto Actor Property PlayerDude Auto Form[] Vessels Form Property BottleFilled Auto Form Property SyringeFilled Auto Form Property PufferFilled Auto Form Property BeerBottleFilled Auto Message Property BarrelMenu Auto Message Property BarrelFillSubMenu Auto Message Property BarrelInsertSubMenu Auto int Property CapacityOfWaterBottle Auto int Property CapacityOfSyringe Auto int Property CapacityOfPuffer Auto int Property CapacityOfBeerBottle Auto int Property MenuOption Auto int Property FillSubMenuOption Auto int Property InsertSubMenuOption Auto int Property BarrelCapacityExpected Auto Function OnActivate(ObjectReference akActionRef) if(Self.GetValue(BarrelCapacity) == 0) Self.SetValue(BarrelCapacity, BarrelCapacityExpected) endif Vessels[0] = Game.GetFormFromFile(0x000211dd, "Fallout4.esm") Vessels[1] = Game.GetFormFromFile(0x00000cc6, "Project Ascendance.esm") Vessels[2] = Game.GetFormFromFile(0x00000cc7, "Project Ascendance.esm") Vessels[3] = Game.GetFormFromFile(0x0004853a, "Fallout4.esm") MenuOption = BarrelMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(MenuOption == 0) FillSubMenuOption = BarrelFillSubMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(FillSubMenuOption == 0) if(PlayerDude.GetItemCount(Vessels[0]) >= 1) PlayerDude.RemoveItem(Vessels[0], 1, false, none) Self.ModValue(FillLevel, CapacityOfBeerBottle * -1) PlayerDude.AddItem(BeerBottleFilled, 1, false) endif elseif(FillSubMenuOption == 1) if(PlayerDude.GetItemCount(Vessels[1]) >= 1) PlayerDude.RemoveItem(Vessels[1], 1, false, none) Self.ModValue(FillLevel, CapacityOfSyringe * -1) PlayerDude.AddItem(SyringeFilled, 1, false) endif elseif(FillSubMenuOption == 2) if(PlayerDude.GetItemCount(Vessels[2]) >= 1) PlayerDude.RemoveItem(Vessels[2], 1, false, none) Self.ModValue(FillLevel, CapacityOfPuffer * -1) PlayerDude.AddItem(PufferFilled, 1, false) endif elseif(FillSubMenuOption == 3) if(PlayerDude.GetItemCount(Vessels[3]) >= 1) PlayerDude.RemoveItem(Vessels[3], 1, false, none) Self.ModValue(FillLevel, CapacityOfWaterBottle * -1) PlayerDude.AddItem(BottleFilled, 1, false) endif endif elseif(MenuOption == 1) InsertSubMenuOption = BarrelInsertSubMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(InsertSubMenuOption == 0) if(PlayerDude.GetItemCount(BeerBottleFilled) >= 1) PlayerDude.RemoveItem(BeerBottleFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfBeerBottle) PlayerDude.AddItem(Vessels[0], 1, false) endif elseif(InsertSubMenuOption == 1) if(PlayerDude.GetItemCount(SyringeFilled) >= 1) PlayerDude.RemoveItem(SyringeFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfSyringe) PlayerDude.AddItem(Vessels[1], 1, false) endif elseif(InsertSubMenuOption == 2) if(PlayerDude.GetItemCount(PufferFilled) >= 1) PlayerDude.RemoveItem(PufferFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfPuffer) PlayerDude.AddItem(Vessels[2], 1, false) endif elseif(InsertSubMenuOption == 3) if(PlayerDude.GetItemCount(BottleFilled) >= 1) PlayerDude.RemoveItem(BottleFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfWaterBottle) PlayerDude.AddItem(Vessels[3], 1, false) endif endif endif EndFunction Link to comment Share on other sites More sharing options...
Reneer Posted March 17, 2016 Share Posted March 17, 2016 (edited) ActorValue Strength = Game.GetFormFromFile(0x2c2, "Fallout4.esm") as ActorValueright? Looks good to me, assuming that FormID is right (I tend to put the full FormID, just 'cause I'm paranoid like that). Here's the script with arrays instead of properties:ScriptName BarrelScript extends ObjectReference ActorValue Property BarrelCapacity Auto ActorValue Property FillLevel Auto Actor Property PlayerDude Auto Form[] Vessels Form Property BottleFilled Auto Form Property SyringeFilled Auto Form Property PufferFilled Auto Form Property BeerBottleFilled Auto Message Property BarrelMenu Auto Message Property BarrelFillSubMenu Auto Message Property BarrelInsertSubMenu Auto int Property CapacityOfWaterBottle Auto int Property CapacityOfSyringe Auto int Property CapacityOfPuffer Auto int Property CapacityOfBeerBottle Auto int Property MenuOption Auto int Property FillSubMenuOption Auto int Property InsertSubMenuOption Auto int Property BarrelCapacityExpected Auto Function OnActivate(ObjectReference akActionRef) if(Self.GetValue(BarrelCapacity) == 0) Self.SetValue(BarrelCapacity, BarrelCapacityExpected) endif Vessels[0] = Game.GetFormFromFile(0x000211dd, "Fallout4.esm") Vessels[1] = Game.GetFormFromFile(0x00000cc6, "Project Ascendance.esm") Vessels[2] = Game.GetFormFromFile(0x00000cc7, "Project Ascendance.esm") Vessels[3] = Game.GetFormFromFile(0x0004853a, "Fallout4.esm") MenuOption = BarrelMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(MenuOption == 0) FillSubMenuOption = BarrelFillSubMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(FillSubMenuOption == 0) if(PlayerDude.GetItemCount(Vessels[0]) >= 1) PlayerDude.RemoveItem(Vessels[0], 1, false, none) Self.ModValue(FillLevel, CapacityOfBeerBottle * -1) PlayerDude.AddItem(BeerBottleFilled, 1, false) endif elseif(FillSubMenuOption == 1) if(PlayerDude.GetItemCount(Vessels[1]) >= 1) PlayerDude.RemoveItem(Vessels[1], 1, false, none) Self.ModValue(FillLevel, CapacityOfSyringe * -1) PlayerDude.AddItem(SyringeFilled, 1, false) endif elseif(FillSubMenuOption == 2) if(PlayerDude.GetItemCount(Vessels[2]) >= 1) PlayerDude.RemoveItem(Vessels[2], 1, false, none) Self.ModValue(FillLevel, CapacityOfPuffer * -1) PlayerDude.AddItem(PufferFilled, 1, false) endif elseif(FillSubMenuOption == 3) if(PlayerDude.GetItemCount(Vessels[3]) >= 1) PlayerDude.RemoveItem(Vessels[3], 1, false, none) Self.ModValue(FillLevel, CapacityOfWaterBottle * -1) PlayerDude.AddItem(BottleFilled, 1, false) endif endif elseif(MenuOption == 1) InsertSubMenuOption = BarrelInsertSubMenu.Show(Self.GetValue(FillLevel), Self.GetValue(BarrelCapacity), 0, 0, 0, 0, 0, 0, 0) if(InsertSubMenuOption == 0) if(PlayerDude.GetItemCount(BeerBottleFilled) >= 1) PlayerDude.RemoveItem(BeerBottleFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfBeerBottle) PlayerDude.AddItem(Vessels[0], 1, false) endif elseif(InsertSubMenuOption == 1) if(PlayerDude.GetItemCount(SyringeFilled) >= 1) PlayerDude.RemoveItem(SyringeFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfSyringe) PlayerDude.AddItem(Vessels[1], 1, false) endif elseif(InsertSubMenuOption == 2) if(PlayerDude.GetItemCount(PufferFilled) >= 1) PlayerDude.RemoveItem(PufferFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfPuffer) PlayerDude.AddItem(Vessels[2], 1, false) endif elseif(InsertSubMenuOption == 3) if(PlayerDude.GetItemCount(BottleFilled) >= 1) PlayerDude.RemoveItem(BottleFilled, 1, false, none) Self.ModValue(FillLevel, CapacityOfWaterBottle) PlayerDude.AddItem(Vessels[3], 1, false) endif endif endif EndFunction The likely issue is that you aren't creating Vessels in the script. You need to do something like this:Function OnActivate(ObjectReference akActionRef) if (Vessels == none) Vessels = new Form[128] endif ...The issue is that the Papyrus compiler doesn't know how many elements you want in the Form array, so you need to tell it how much before you start addressing each element. Edited March 17, 2016 by Reneer Link to comment Share on other sites More sharing options...
registrator2000 Posted March 18, 2016 Share Posted March 18, 2016 (edited) Hi, for related values, using an array property is certainly cleaner! As you've mentioned, you can easily add array elements via FO4Edit, while you can't do the same for single properties. These array properties are a great way to store related properties. Usage is quite straightforward. Just query MyArray[indexNumber] in your script to access that array element. The array is automatically initialized by Papyrus if you've declared it as a property in the ESP - no need to initialize it yourself or populate it with Game.GetFormFromFile. You can also query array length with MyArray.length. I have an array set up in my Car Launcher mod holding the various spells for the different car types to shoot a random car every time you pull the trigger. Sources are attached so you could take a look there as a working sample. I also use arrays in Companions Go Home to store the references of the various companions (source also on mod page). Both are relatively simple mods - they might be useful as a working reference. EDIT: Attached screens in FO4Edit http://i.imgur.com/mVdNLF2.png Relevant code snippet: Function Fire() int randomIndex = Utility.RandomInt(0, numCarsType - 1) carToLaunch = CarLaunchSpells[randomIndex] ... EndFunction Edited March 18, 2016 by registrator2000 Link to comment Share on other sites More sharing options...
Reneer Posted March 18, 2016 Share Posted March 18, 2016 Hi, for related values, using an array property is certainly cleaner! As you've mentioned, you can easily add array elements via FO4Edit, while you can't do the same for single properties. These array properties are a great way to store related properties. Usage is quite straightforward. Just query MyArray[indexNumber] in your script to access that array element. The array is automatically initialized by Papyrus if you've declared it as a property in the ESP - no need to initialize it yourself or populate it with Game.GetFormFromFile. You can also query array length with MyArray.length. I have an array set up in my Car Launcher mod holding the various spells for the different car types to shoot a random car every time you pull the trigger. Sources are attached so you could take a look there as a working sample. I also use arrays in Companions Go Home to store the references of the various companions (source also on mod page). Both are relatively simple mods - they might be useful as a working reference. EDIT: Attached screens in FO4Edit http://i.imgur.com/mVdNLF2.png Relevant code snippet: Function Fire() int randomIndex = Utility.RandomInt(0, numCarsType - 1) carToLaunch = CarLaunchSpells[randomIndex] ... EndFunction Ah, very nice! I was going the other route and manually declaring my arrays and such in my Papyrus scripts instead of using properties. I guess I just prefer being able to see what I put in my arrays in the script (that and working with Properties in FO4Edit is... annoying right now). Link to comment Share on other sites More sharing options...
Recommended Posts