Jump to content

How do I use arrays/property group as script properties?


Recommended Posts

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

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 by Reneer
Link to comment
Share on other sites

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 by AceCarteria
Link to comment
Share on other sites

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

 

ActorValue Strength =  Game.GetFormFromFile(0x2c2, "Fallout4.esm") as ActorValue
right?

 

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 by Reneer
Link to comment
Share on other sites

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 by registrator2000
Link to comment
Share on other sites

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...