Jump to content

[LE] filling a formlist with spells a player knows


irswat

Recommended Posts

My apologies because I have posted this before to no satisfactory resolution. This function fills a formlist with all spells a player knows:

function InitializeFormlists()
;************************************************************
;*******Fills formlist with all spells a player has learned**
;************************************************************
	int nSpellsLearned=PlayerRef.GetSpellCount()
	int LoopCounter=0
	debug.trace("Spells player knows: " + nSpellsLearned)
	form curSpell
	
	while (LoopCounter<nSpellsLearned)
		curSpell=PlayerRef.GetNthSpell(LoopCounter)
		if PlayerRef.HasSpell(curSpell)
			SpellFormList.AddForm(curSpell)
			;debug.notification("Spell " + LoopCounter + " added: " + curSpell.GetName())
		endif
		LoopCounter+=1
	endwhile
	
	;debug.notification ("Spells form list initialized!")

It works...pretty good, however, it doesn't work good enough. For example, on a clean save, at the beginning of the game, this function is not returning Flames, but it does return Sparks, it returns the warrior stone, full shrouded armor set, nightgale armor set, crossbow bonus, Oakflesh, and Ahziels Genius. Obviously I don't have shrouded armor, i dont have the nightingale set, I don't have ahziels genius, and I don't have a cross bow. Is there something I am doing incorrectly?

I have come across these new functions released by Quad2Core, and was wondering if anyone has played with them?

What is the difference between an actors spells, and an actor bases spells?

Link to comment
Share on other sites

An actorbase's spells are those defined in the CK on the actor record being used as the base for the actor reference.

An actor's spells are those that have been learned through the course of the game as well as any inherited from the actorbase.

 

At least that is my understanding, but lets leave room for error. :P

Link to comment
Share on other sites

I tried playing with Quad2Core's inventory functions:

        SpellsFormListII=_Q2C_Functions.ActorGetSpells(PlayerRef)
	int SpellsListIILength=SpellsFormListII.Length
	int counter=0
	while (counter<=SpellsListIILength)
		debug.trace("Test. Spells Form List II #" + counter + " " + SpellsFormListII[counter])
	endwhile

the results broke my notepad++
edit: i forgot to increment counter.

 

stack:

[sVE (05000D62)].SVE_ParserEngine.InitializeFormlists() - "SVE_ParserEngine.psc" Line 1977
[sVE (05000D62)].SVE_ParserEngine.OnInit() - "SVE_ParserEngine.psc" Line 61
[01/10/2017 - 07:03:46PM] Test. Spells Form List II #0 [sPELL < (0403B563)>]
[01/10/2017 - 07:03:46PM] error: Cannot access an element of a None array

ad on infinitum

Edited by irswat
Link to comment
Share on other sites

It works...pretty good, however, it doesn't work good enough. For example, on a clean save, at the beginning of the game, this function is not returning Flames, but it does return Sparks, it returns the warrior stone, full shrouded armor set, nightgale armor set, crossbow bonus, Oakflesh, and Ahziels Genius. Obviously I don't have shrouded armor, i dont have the nightingale set, I don't have ahziels genius, and I don't have a cross bow. Is there something I am doing incorrectly?

 

Flames and Healing are defined in the CK on the ActorBase form called player (with formID 00000007) and those other spells and effects are on the player reference (with formID 00000014).

 

The extra "spells" like the warrior stone, shrouded armor, etc. are abilities added by various quests at the beginning of the game but hidden from the player in the user interface. Those are used with conditions to implement some of the special features of the matching items.

 

In theory you can determine which of the "spells" are really special abilities normally hidden from the player by scanning their magic effects and checking to see if the HideInUI is set in each of the effects by using SKSE functions.

Link to comment
Share on other sites

super good info cdcooley. thank you!

I found the IsEffectFlagSet() function. Here is my updated code:

 

;************************************************************
;*******Fills formlist with all spells a player has learned**
;************************************************************
	int nSpellsLearned=PlayerRef.GetSpellCount()
	int LoopCounter=0
	int iSpell
	debug.trace("Spells player ref knows: " + nSpellsLearned)
	form curSpell
	;gets spells on playerref 0x00000014
	while (LoopCounter<nSpellsLearned)
		curSpell=PlayerRef.GetNthSpell(LoopCounter)
		if IsEffectFlagSet((curSpell as MagicEffect), 0x00008000)==false
			if PlayerRef.HasSpell(curSpell)
				iSpell=SpellFormList.Find(curSpell)
				if iSpell==-1
					SpellFormList.AddForm(curSpell)
					debug.trace("Spell " + LoopCounter + " added: " + curSpell.GetName())
				endif
			endif
		endif	
		LoopCounter+=1
	endwhile
	
	LoopCounter=0
	nSpellsLearned=Game.GetPlayer().GetSpellCount()
	debug.trace("Spells player base knows: " + nSpellsLearned)
	;gets spells on player base 0x00000007
	while (LoopCounter<nSpellsLearned)
		curSpell=Game.GetPlayer().GetNthSpell(LoopCounter)
		if IsEffectFlagSet((curSpell as MagicEffect), 0x00008000)==false
			if Game.GetPlayer().HasSpell(curSpell)
				iSpell=SpellFormList.Find(curSpell)
				if iSpell==-1
					SpellFormList.AddForm(curSpell)
					debug.trace("Spell " + LoopCounter + " added: " + curSpell.GetName())
				endif
			endif
		endif
		LoopCounter+=1
	endwhile
	
	debug.notification ("Spells form list initialized!")

 



Aside from questions about the proper usage of actorbases and spell scripts, which I can probably figure out myself, when I try to use the IsEffectFlagSet as above I get the following error:

 

C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(1957,5): IsEffectFlagSet is not a function or does not exist

C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(1957,59): cannot compare a none to a bool (cast missing or types unrelated)
C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(1975,5): IsEffectFlagSet is not a function or does not exist
C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(1975,59): cannot compare a none to a bool (cast missing or types unrelated

I'm assuming I can't cast a spell as a magic effect? the only example of this particular function in usage seems to suggest the syntax is:

akMagicEffect.IsEffectFlagSet(int flag)

is that correct?

EDIT: (curSpell as MagicEffect).IsEffectFlagSet(0x00008000) <~~~~THIS COMPILED! Thanks for your help cdcooley. You rock!

Edited by irswat
Link to comment
Share on other sites

 

[01/11/2017 - 12:32:49PM] Spells player ref knows: 8

[01/11/2017 - 12:32:50PM] Spells player base knows: 3
[01/11/2017 - 12:32:50PM] TEST: Printing Spell FormList
[01/11/2017 - 12:32:50PM] Formlist Spell #0:Shrouded Armor Full Set
[01/11/2017 - 12:32:50PM] Formlist Spell #1:Nightingale Armor Full Set
[01/11/2017 - 12:32:50PM] Formlist Spell #2:The Warrior Stone
[01/11/2017 - 12:32:50PM] Formlist Spell #3:Oakflesh
[01/11/2017 - 12:32:50PM] Formlist Spell #4:Sparks
[01/11/2017 - 12:32:50PM] Formlist Spell #5:Ahzidal's Genius
[01/11/2017 - 12:32:51PM] Formlist Spell #6:Deathbrand Instinct
[01/11/2017 - 12:32:51PM] Formlist Spell #7:Flames
[01/11/2017 - 12:32:51PM] Formlist Spell #8:Healing
[01/11/2017 - 12:32:51PM] Formlist Spell #9:Combat Heal Rate
[01/11/2017 - 12:32:51PM] Formlist Spell #10:Crossbow bonus

well that is encouraging. However I used grimybunyip's SKSE plugin GetSpellType function to check whether the current spell was of type 0 (spell) as a conditional for the forms being added to the formlist. I was hoping to omit the weird abilities inherent to the player and player ref. I guess even abilities are spells?

 

 

	while (LoopCounter<nSpellsLearned)
		curSpell=PlayerRef.GetNthSpell(LoopCounter)
		IsASpell==GetSpellType(curSpell)
		;if (curSpell as Spell).IsEffectFlagSet(0x00008000)==false
		if IsASpell==0
			if PlayerRef.HasSpell(curSpell)
				iSpell=SpellFormList.Find(curSpell)
				if iSpell==-1
					SpellFormList.AddForm(curSpell)
					debug.trace("Spell " + LoopCounter + " added: " + curSpell.GetName())
				endif
			endif
		endif
		;endif	
		LoopCounter+=1
	endwhile
	
	ActorBase Player=PlayerRef.GetActorBase()
	LoopCounter=0
	nSpellsLearned=Player.GetSpellCount()
	debug.trace("Spells player base knows: " + nSpellsLearned)
	;gets spells on player base 0x00000007
	while (LoopCounter<nSpellsLearned)
		curSpell=Player.GetNthSpell(LoopCounter)
		IsASpell==GetSpellType(curSpell)
		;if (curSpell as Spell).IsEffectFlagSet(0x00008000)==false
		if IsASpell==0
			if PlayerRef.HasSpell(curSpell)
				iSpell=SpellFormList.Find(curSpell)
				if iSpell==-1
					SpellFormList.AddForm(curSpell)
					debug.trace("Spell " + LoopCounter + " added: " + curSpell.GetName())
				endif
			endif
		endif
		;endif
		LoopCounter+=1
	endwhile
	
	int spellFormListSize=SpellFormList.GetSize()
	
	LoopCounter=0
	debug.trace("TEST: Printing Spell FormList")
	while (LoopCounter<spellFormListSize)
			debug.trace("Formlist Spell #" + LoopCounter + ":" + SpellFormList.GetAt(LoopCounter).GetName())
			LoopCounter+=1
	endWhile
	debug.notification ("Spells form list initialized!")

On the bright side, once I get this perfected it could make for a good function that returns a formlist of all spells a player knows.

Edited by irswat
Link to comment
Share on other sites

The line between ability and spell is blurry. And some of those might actually be classified as spells. You probably will need to cycle through their magic effects. (Each spell can have more than one effect and some of the standard spells have the HideInUI flag for some of their effects but not all of them.) Working with spells from scripts is messy as you've discovered.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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