Jump to content

Script questions


Genamine

Recommended Posts

Lets say I have some FormLists

 

FormList A with a list of 3 perks

FormList B with sub-FormLists C, D and E

FormList C, D and E with a list of actors

 

Now, what Im trying to do is run a loop that adds the perk at a certain index on FormList A to all sub-FormLists on FormList B with the same index as the belonging perk

So.. perk 1 will go with FormList C, perk 2 will go with FormList D and perk 3 will go with FormList E

 

This requires some variables, ofcourse, lets presume:

Perk Property RegisteredPotentialPerk Auto

RegisteredPotentialPerk = PotentialPerkList.GetAt(iFormsToRun) as Perk

Question 1: Would this be a working set of variables?

 

 

Now, to continue, we want to add these perks to an actor from the other FormLists, lets presume:

Int iIndex = RegisteredActorList.GetSize()
While iIndex > -1
	Actor akActor = RegisteredActorList.GetAt(iIndex) as Actor
	If akActor.HasPerk(RegisteredPotentialPerk) == 0
		akActor.AddPerk(RegisteredPotentialPerk)
	EndIf
	iIndex -= 1
EndWhile

Question 2: Is this a functioning fragment of code?

 

 

Now, to end with, I obviously wouldnt be asking this if it was actually working

See, the thing is, after some debugging I found that everything works as intended, it compiled, all statements conditions and functions pass just fine, but the perks are not being applied as expected

Which makes me wonder if calling [RegisteredPotentialPerk = PotentialPerkList.GetAt(0) as Perk] actually works or not, does this not set the property as a perk?, does this still remain a Form?

 

Its a bit of a problem for me right now, because I find a script preferable over adding perks to just under 1200 actors by hand

 

 

For those interested, here is the full script, its only a little more complex than shown fragments:

 

 

Scriptname AddPerksOnLaunch extends Quest

FormList Property PotentialPerkList Auto Const
FormList Property ActorList Auto Const
Bool Property HardMode Auto Const
FormList Property RegisteredActorList Auto
Perk Property RegisteredPotentialPerk Auto

Function RunForFormList()
	Int iIndex = RegisteredActorList.GetSize()
	While iIndex > -1
		Actor akActor = RegisteredActorList.GetAt(iIndex) as Actor
		If akActor.HasPerk(RegisteredPotentialPerk) == 0
			akActor.AddPerk(RegisteredPotentialPerk)
		EndIf
		iIndex -= 1
	EndWhile
EndFunction

Event OnInit()
	Utility.Wait(10)
	Int iFormsToRun = PotentialPerkList.GetSize()
	While iFormsToRun > -1
		RegisteredActorList = ActorList.GetAt(iFormsToRun) as FormList
		If PotentialPerkList.GetAt(iFormsToRun) as FormList
			Actor akPlayerActor = RegisteredActorList.GetAt(0) as Actor
			Perk kPerk01 = PotentialPerkList.GetAt(0) as Perk
			Perk kPerk02 = PotentialPerkList.GetAt(1) as Perk
			Perk kPerk03 = PotentialPerkList.GetAt(2) as Perk
			If HardMode == True
				Perk kPerk04 = PotentialPerkList.GetAt(3) as Perk
				If akPlayerActor.HasPerk(kPerk04) == 0
					akPlayerActor.AddPerk(kPerk04)
				EndIf
			EndIf
			If akPlayerActor.HasPerk(kPerk01) == 0
				akPlayerActor.AddPerk(kPerk01)
			EndIf
			If akPlayerActor.HasPerk(kPerk02) == 0
				akPlayerActor.AddPerk(kPerk02)
			EndIf
			If akPlayerActor.HasPerk(kPerk03) == 0
				akPlayerActor.AddPerk(kPerk03)
			EndIf
		ElseIf PotentialPerkList.GetAt(iFormsToRun) as Perk
			RegisteredPotentialPerk = PotentialPerkList.GetAt(iFormsToRun) as Perk
			RunForFormList()
		EndIf
		iFormsToRun -= 1
	EndWhile
EndEvent

 

 

Link to comment
Share on other sites

It`s a bit complicated with so many formlists :D. You can try to look at debug log . Use usual text search to find anything that has something to do with your script name.

If there are any errors that abort some of the functions it will show them. You need to enable debug log for this.

 

What I can see from looking at it is that you use getsize() and then you use this size as an index for getat()

If I understand the work of these things correct then , for example, a formlist that has size = 5 does not have position number 5. So you can`t use getat(5) . It has positions 0, 1, 2, 3, 4

So you probably need to type GetAt(Index -1) , or type in the beginning Int iIndex = RegisteredActorList.GetSize() - 1 , or move the line iIndex -= 1 upper so it runs before the getat()

 

This is a simple good example from wiki of using while with formlist. iTndex -= 1 runs before the GetAt() so it never gets at the position equal to the size. It starts from the position = size -1

Int iIndex = akList.GetSize() ; Will always return a finite value
While iIndex > 0
iIndex -= 1
If akList.GetAt(iIndex) == akMember
Return iIndex
EndIf
EndWhile
Link to comment
Share on other sites

 

It`s a bit complicated with so many formlists :D. You can try to look at debug log . Use usual text search to find anything that has something to do with your script name.

If there are any errors that abort some of the functions it will show them. You need to enable debug log for this.

 

What I can see from looking at it is that you use getsize() and then you use this size as an index for getat()

If I understand the work of these things correct then , for example, a formlist that has size = 5 does not have position number 5. So you can`t use getat(5) . It has positions 0, 1, 2, 3, 4

So you probably need to type GetAt(Index -1) , or type in the beginning Int iIndex = RegisteredActorList.GetSize() - 1 , or move the line iIndex -= 1 upper so it runs before the getat()

 

This is a simple good example from wiki of using while with formlist. iTndex -= 1 runs before the GetAt() so it never gets at the position equal to the size. It starts from the position = size -1

Int iIndex = akList.GetSize() ; Will always return a finite value
While iIndex > 0
iIndex -= 1
If akList.GetAt(iIndex) == akMember
Return iIndex
EndIf
EndWhile

 

 

Thats the original syntax I used, but it had the same problem as the current one, everything runs as it should, trial and error shows that it gets to the akActor.AddPerk() line just fine, but it doesnt actually apply the perk

 

EDIT: small update from looking at the papyrus log, it says cannot call HasPerk() and AddPerk() on a none object, as well as warning: Assigning None to a non-object variable named "::temp27"

So it must be going wrong at Actor akActor = RegisteredActorList.GetAt(iIndex) as Actor

 

Debugging the properties results in the following, Debug.Trace(akActor) returns "None", Debug.Trace(RegisteredPotentialPerk) returns "[Perk < (0D340A85)>]", which is correct

Debug.Trace(RegisteredActorList.GetAt(iIndex)) returns the correct form of the actor(s) the perk is to be applied to, it appears that calling "as Actor" sets the value to "None"

Link to comment
Share on other sites

Little addition to previous post:

 

Heres the script with added debug lines:

 

 

Scriptname AddPerksOnLaunch extends Quest

FormList Property PotentialPerkList Auto Const
FormList Property ActorList Auto Const
Bool Property HardMode Auto Const
FormList Property RegisteredActorList Auto
Perk Property RegisteredPotentialPerk Auto
Bool Property CurrentlyRunning Auto

Function RunForFormList()
	CurrentlyRunning = True
	Int iIndex = RegisteredActorList.GetSize()
	Debug.Trace(iIndex)
	While iIndex > -1
		iIndex -= 1
		Debug.Trace(iIndex)
		Form kActorForm = RegisteredActorList.GetAt(iIndex)
		Actor akRegisteredActor = kActorForm as Actor
		Debug.Trace(kActorForm)
		If kActorForm as Actor
			Debug.Trace("Form is type Actor.")
		Else
			Debug.Trace("Form is not type Actor.")
		EndIf
		Debug.Trace(akRegisteredActor)
		If akRegisteredActor != None
			If akRegisteredActor.HasPerk(RegisteredPotentialPerk) == 0
				Debug.Trace("Actor returned, did not have perk, applying perk now.")
				akRegisteredActor.AddPerk(RegisteredPotentialPerk)
			Else
				Debug.Trace("Actor returned, already had perk, will not proceed.")
			EndIf
		Else
			Debug.Trace("Actor returned none, will not proceed.")
		EndIf
	EndWhile
	CurrentlyRunning = False
EndFunction

Event OnInit()
	Utility.Wait(10)
	Int iFormsToRun = PotentialPerkList.GetSize()
	While iFormsToRun > -1
		Utility.Wait(1)
		If CurrentlyRunning == False
			iFormsToRun -= 1
			RegisteredActorList = ActorList.GetAt(iFormsToRun) as FormList
			If PotentialPerkList.GetAt(iFormsToRun) as FormList
				Actor akPlayerActor = Game.GetPlayer()
				Perk kPerk01 = PotentialPerkList.GetAt(0) as Perk
				Perk kPerk02 = PotentialPerkList.GetAt(1) as Perk
				Perk kPerk03 = PotentialPerkList.GetAt(2) as Perk
				If HardMode == True
					Perk kPerk04 = PotentialPerkList.GetAt(3) as Perk
					If akPlayerActor.HasPerk(kPerk04) == 0
						akPlayerActor.AddPerk(kPerk04)
					EndIf
				EndIf
				If akPlayerActor.HasPerk(kPerk01) == 0
					akPlayerActor.AddPerk(kPerk01)
				EndIf
				If akPlayerActor.HasPerk(kPerk02) == 0
					akPlayerActor.AddPerk(kPerk02)
				EndIf
				If akPlayerActor.HasPerk(kPerk03) == 0
					akPlayerActor.AddPerk(kPerk03)
				EndIf
			ElseIf PotentialPerkList.GetAt(iFormsToRun) as Perk
				RegisteredPotentialPerk = PotentialPerkList.GetAt(iFormsToRun) as Perk
				Debug.Trace(RegisteredActorList)
				Debug.Trace(RegisteredPotentialPerk)
				RunForFormList()
			EndIf
		EndIf
	EndWhile
EndEvent

 

 

 

And heres the result in the papyrus log:

 

 

[02/28/2017 - 03:01:22PM] [FormList < (0D340A86)>]

[02/28/2017 - 03:01:22PM] [Perk < (0D340A85)>]
[02/28/2017 - 03:01:22PM] 265
[02/28/2017 - 03:01:22PM] 264
[02/28/2017 - 03:01:22PM] [Form < (001167A8)>]
[02/28/2017 - 03:01:22PM] Form is not type Actor.
[02/28/2017 - 03:01:22PM] None
[02/28/2017 - 03:01:22PM] Actor returned none, will not proceed.

 

In order, these lines are from:

Debug.Trace(RegisteredActorList)

Debug.Trace(RegisteredPotentialPerk)

Debug.Trace(iIndex) - before loop

Debug.Trace(iIndex) - after iIndex -= 1, 264 is indeed the last actor in the FormList, this is where the loop should begin adding perks

Debug.Trace(kActorForm)

Debug.Trace("Form is not type Actor.")

Debug.Trace(akRegisteredActor)

Debug.Trace("Actor returned none, will not proceed.")

 

This repeats for the entire FormList, the other debug lines never run

 

 

 

It looks like its probably because form Actor is a reference form, while the forms on the FormList are ActorBase, which is a base form, you cant run "as Actor" on those and you cant run HasPerk() or AddPerk() on those

 

In other words, what Im trying to do is probably not even possible

Link to comment
Share on other sites

 

This repeats for the entire FormList, the other debug lines never run

 

 

 

It looks like its probably because form Actor is a reference form, while the forms on the FormList are ActorBase, which is a base form, you cant run "as Actor" on those and you cant run HasPerk() or AddPerk() on those

 

In other words, what Im trying to do is probably not even possible

 

oh sorry, maybe I missed something in your script. It`s just the way I saw it was done. But glad that debug helped. Just curious why do you want to add perks to base actors by script(is this even correct? Do you have a list of actors form ID-s) ? You can add perks to base actors in the CK. What exactly do you want to accomplish?

 

Oh, wait I see now , I`m very absent-minded today. 1200 actors...do you want to add perks to all base actors? I never thought that there are so many base actors there. lol

I don`t think there is a way to change baseobjects in any way by script. Though you can get some values from them. If you have form ID-s in your list then it`s actorbase objects. Not actors so it won`t work.

Edited by kitcat81
Link to comment
Share on other sites

 

 

This repeats for the entire FormList, the other debug lines never run

 

 

 

It looks like its probably because form Actor is a reference form, while the forms on the FormList are ActorBase, which is a base form, you cant run "as Actor" on those and you cant run HasPerk() or AddPerk() on those

 

In other words, what Im trying to do is probably not even possible

 

oh sorry, maybe I missed something in your script. It`s just the way I saw it was done. But glad that debug helped. Just curious why do you want to add perks to base actors by script(is this even correct? Do you have a list of actors form ID-s) ? You can add perks to base actors in the CK. What exactly do you want to accomplish?

 

Oh, wait I see now , I`m very absent-minded today. 1200 actors...do you want to add perks to all base actors? I never thought that there are so many base actors there. lol

I don`t think there is a way to change baseobjects in any way by script. Though you can get some values from them. If you have form ID-s in your list then it`s actorbase objects. Not actors so it won`t work.

 

 

I want to add perks to almost 1200 NPCs, multiple perks for many

I was hoping to be able to do so by script so that A - the process is reversible on demand and B - it doesnt conflict with other mods that edit the NPCs in question

 

Sadly it doesnt appear to be a plausible option, I dont believe there is really anything significant you can do to base actors by script

I know my way around programming, but papyrus is still new to me

Link to comment
Share on other sites

I fully admit I'm only half reading this. =/

...an alternative to perks themselves might be spells that apply the perks. Spells seem to be much easier to apply to base actors (if applying perks is at all possible even, actually), (big) iirc.

If you could do it by race, that might even be an alternative to make this process a little more compact.

I don't know if I missed it...but what are you trying to apply? A random height change?

Anywho...=)

Link to comment
Share on other sites

I fully admit I'm only half reading this. =/

 

...an alternative to perks themselves might be spells that apply the perks. Spells seem to be much easier to apply to base actors (if applying perks is at all possible even, actually), (big) iirc.

 

If you could do it by race, that might even be an alternative to make this process a little more compact.

 

I don't know if I missed it...but what are you trying to apply? A random height change?

 

Anywho...=)

 

Well, as far as Im aware you cant apply spells to base actors by script either

Race isnt much of an option for me either, I dont want all actors of a certain race to have the same perk

 

What I want to do is apply different perks with different damage modifiers (both conditional and unconditional) to different actors, Id like the process to reversible on-demand ingame (via cqf in console)

The first step toward that was to find a way to apply the perks in the first place, and then write a function to remove the perks (and a function to re-add them, should you regret your decision)

Sadly though, it doesnt appear to be plausible

 

As far as being able to disable and enable the perks on-demand ingame, Im aware of other (easier) ways to do this

But applying the perks by script isnt an option, I will instead batch add them to the NPCs with FO4Edit

Link to comment
Share on other sites

  • Recently Browsing   0 members

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