Jump to content

My Script doesnt works


Recommended Posts

Scriptname LimitedSpellLearningScript extends ReferenceAlias

GlobalVariable Property MaximumLearning Auto
GlobalVariable Property CurrentLearning Auto

Actor Property PlayerRef Auto

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
	Book b = (akBaseObject as Book)
	if b
		Spell s = b.GetSpell()
			if s
				if !PlayerRef.HasSpell(s) && CurrentLearning.GetValue() < MaximumLearning.GetValue()
					Int Temp = CurrentLearning.GetValue() as Int
					CurrentLearning.SetValue(Temp + 1)
				elseif !PlayerRef.HasSpell(s) && CurrentLearning.GetValue() >= MaximumLearning.GetValue()
					PlayerRef.RemoveSpell(s)
					Debug.Notification("This Spell Cant be learned")
				else
					return
				endif
			endif
	endif
EndEvent


Global Variables like MaximumLearning and CurrentLearning arent changed When I read a spell book

What did I miss?

Link to comment
Share on other sites

What exactly does this script attach to?    My assumption it is to Player Alias in the owning quest.    Is the quest running?    Are the properties loaded in the 'Properties'  page with their corresponding forms?

I would enable Papyrus logging, and add a Debug.Trace statement at the beginning of your function to make sure that is is indeed being called.    I also assume that your CurrentLearning and MaximumLearning GVs are initialized somewhere to proper values.

Now, to the actual logic of your code:  when a player reads a book that teaches a spell, the book is consumed and the spell is added to the player.    This is done in-engine, which is much faster than papyrus, which means that by the time this event handler gets called, the spell potentially was already added to the player.   Meaning that  '!PlayerRef.HasSpell(s)' clause is going to fail since by that time, player already has the spell.    I suggest you add a clause that verifies it and do a Debug.Trace

If PlayerRef.HasSpell(s)
    Debug.Trace(Self + "Player already has spell " + s)
EndIf

What can you do:   Normal books in the world, when activated, open up for you to read, and from there you can choose to take the book.   But spell books are added to your inventory, and you need to use a book from inventory to learn the spell.   In other words, before a spell book can be read, it has to be added to your inventory.    Thus, what you can do:

First, in your mod, you create an empty FormList.     Then, your script:

Scriptname LimitedSpellLearningScript extends ReferenceAlias

GlobalVariable Property MaximumLearning Auto
GlobalVariable Property CurrentLearning Auto
FormList Property PendingSpells Auto 

Actor Property PlayerRef Auto
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    Book b = (akBaseItem as Book)
    If b
        Spell s = b.GetSpell()
        If s
            If !PlayerRef.HasSpell(s) && !PendingSpells.HasForm(s)
                PendingSpells.AddForm(s)
            EndIf
        EndIf
    EndIf
EndEvent

Event OnMenuOpen("InventoryMenu")
    Int n = PendingSpells.GetSize()
    While n > 0
        n = n - 1
        Spell s = (PendingSpells.GetAt(n) as Spell)
        If PlayerRef.HasSpell(s)
            PendingSpells.RemoveAddedForm(s)
        EndIf
    EndWhile
EndEvent

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
    Book b = (akBaseObject as Book)
    If b
        Spell s = b.GetSpell()
        If s
            If PendingSpells.HasForm(s)
                Int Temp = CurrentLearning.GetValueInt()
                If Temp < MaximumLearning.GetValueInt()
                    CurrentLearning.SetValueInt(Temp + 1)
                    PendingSpells.RemoveAddedForm(s)
                Else
                    Debug.Notification("This Spell Cant be learned")
                    PlayerRef.RemoveSpell(s)
                    PlayerRef.AddItem(b, 1, true) ; the book has been consumed, so need to re-add            
                EndIf
            EndIf
        EndIf
    EndIf
EndEvent

The logic here is that if player ever gains a spellbook with a spell he does not know yet, that spell goes into PendingSpells formlist.
Anytime player accesses inventory, the PendingSpells list is checked to see if player potentially learned any spells on that list via alternate means.
Then if player attempts to read a book and spell is on pending list, a successful learn removes the spell from list, and failed one removes spell and restores book in inventory.

  • Thanks 1
Link to comment
Share on other sites

13 hours ago, scorrp10 said:

What exactly does this script attach to?    My assumption it is to Player Alias in the owning quest.    Is the quest running?    Are the properties loaded in the 'Properties'  page with their corresponding forms?

I would enable Papyrus logging, and add a Debug.Trace statement at the beginning of your function to make sure that is is indeed being called.    I also assume that your CurrentLearning and MaximumLearning GVs are initialized somewhere to proper values.

Now, to the actual logic of your code:  when a player reads a book that teaches a spell, the book is consumed and the spell is added to the player.    This is done in-engine, which is much faster than papyrus, which means that by the time this event handler gets called, the spell potentially was already added to the player.   Meaning that  '!PlayerRef.HasSpell(s)' clause is going to fail since by that time, player already has the spell.    I suggest you add a clause that verifies it and do a Debug.Trace

If PlayerRef.HasSpell(s)
    Debug.Trace(Self + "Player already has spell " + s)
EndIf

What can you do:   Normal books in the world, when activated, open up for you to read, and from there you can choose to take the book.   But spell books are added to your inventory, and you need to use a book from inventory to learn the spell.   In other words, before a spell book can be read, it has to be added to your inventory.    Thus, what you can do:

First, in your mod, you create an empty FormList.     Then, your script:

Scriptname LimitedSpellLearningScript extends ReferenceAlias

GlobalVariable Property MaximumLearning Auto
GlobalVariable Property CurrentLearning Auto
FormList Property PendingSpells Auto 

Actor Property PlayerRef Auto
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
    Book b = (akBaseItem as Book)
    If b
        Spell s = b.GetSpell()
        If s
            If !PlayerRef.HasSpell(s) && !PendingSpells.HasForm(s)
                PendingSpells.AddForm(s)
            EndIf
        EndIf
    EndIf
EndEvent

Event OnMenuOpen("InventoryMenu")
    Int n = PendingSpells.GetSize()
    While n > 0
        n = n - 1
        Spell s = (PendingSpells.GetAt(n) as Spell)
        If PlayerRef.HasSpell(s)
            PendingSpells.RemoveAddedForm(s)
        EndIf
    EndWhile
EndEvent

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
    Book b = (akBaseObject as Book)
    If b
        Spell s = b.GetSpell()
        If s
            If PendingSpells.HasForm(s)
                Int Temp = CurrentLearning.GetValueInt()
                If Temp < MaximumLearning.GetValueInt()
                    CurrentLearning.SetValueInt(Temp + 1)
                    PendingSpells.RemoveAddedForm(s)
                Else
                    Debug.Notification("This Spell Cant be learned")
                    PlayerRef.RemoveSpell(s)
                    PlayerRef.AddItem(b, 1, true) ; the book has been consumed, so need to re-add            
                EndIf
            EndIf
        EndIf
    EndIf
EndEvent

The logic here is that if player ever gains a spellbook with a spell he does not know yet, that spell goes into PendingSpells formlist.
Anytime player accesses inventory, the PendingSpells list is checked to see if player potentially learned any spells on that list via alternate means.
Then if player attempts to read a book and spell is on pending list, a successful learn removes the spell from list, and failed one removes spell and restores book in inventory.


It works now!! Thank you for answer!!

Link to comment
Share on other sites

  • Recently Browsing   0 members

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