Jump to content

Papyrus Help: Setting a Global Variable from a Count


Recommended Posts

If I ever get the hang of this, my mod(s) will be a testament to all of your patience and wisdom. And now I'm asking for that wisdom again, because my code looks right to me, but won't compile, which means it most assuredly is not.

I'm creating a series of quests where the player has to find specific gems. The gems are all the same item, but each of the quests has a list of specific gems (in a corresponding FormList) that have to be acquired for the quest to progress. The

 

The script is supposed to:

  • Check the items in the quest's FormList one at a time to see if they're in the player's inventory.
  • For each match, add one to a variable.
  • Save the total to a global variable, which is referenced in the quest's objectives (a la "No Stone Unturned" or "A Return to Your Roots".)

I get two errors when I try to compile it:

_BL_SCR_GemCount.psc(9,16): no viable alternative at input 'Property'
_BL_SCR_GemCount.psc(21,1): missing EOF at 'While'

The lines referenced are declaring the global variable and the beginning of the "While" loop. I've looked up examples of both, and my code matches them as best I can tell, but the errors persist.

My code is attached as a text doc. Any help would be appreciated, as always. And if the code is VERY wrong for what I'm trying to do, feel free to point that out as well - this is my first time writing code for Global Variables and FormLists.

Link to comment
Share on other sites

That's odd. I did upload it. Here it is in a post.

 

 

Scriptname _BL_SCR_GemCount extends Quest

Function GemCount()

;-----------------------------------------
; Properties to make the thing run.
;-----------------------------------------

GlobalVariable Property gloGems Auto ;; The global variable to update.

FormList Property lstGems Auto ;; The formlist of all gems relevant to the quest.

int Property stgGems Auto ;; The stage of the quest that references the variable.
int intGems = 0 ;; The count of gems in the player's inventory.
int lenGems = 0 ;; The length of the Formlist handling the gems for this quest.

;---------------------------------------------
; Count the Gems in Player Inventory.
;---------------------------------------------

While (lenGems < lstGems.GetSize())
Form Entry = lstGems.GetAt(lenGems)
If (Entry as ObjectReference)
If (Game.GetPlayer().getItemCount(Entry) > 0)
intGems += 1
EndIf
EndIf
lenGems += 1
EndWhile

;-----------------------------------------------------------------------------
; Update quest based on how many of the gems the player has.
;-----------------------------------------------------------------------------

if (intGems >= lstGems.GetSize())
if (GetStage() >= stgGems)
gloGems.SetValue(intGems)
SetObjectiveDisplayed(stgGems,1)
SetObjectiveCompleted(stgGems,1)
endIf
else
if (GetStage() >= stgGems)
gloGems.SetValue(intGems)
SetObjectiveDisplayed(stgGems,1)
endIf
endIf

endFunction

 

Link to comment
Share on other sites

I took a quick peek before leaving for work, and you have the properties inside the function.


GlobalVariable Property gloGems Auto
FormList Property lstGems Auto
int Property stgGems Auto
int intGems = 0
int lenGems = 0


FUNCTION GemCount()
While (lenGems < lstGems.GetSize())
Form Entry = lstGems.GetAt(lenGems)
If (Entry as ObjectReference)
If (Game.GetPlayer().getItemCount(Entry) > 0)
intGems += 1
EndIf
EndIf
lenGems += 1
EndWhile
if (intGems >= lstGems.GetSize())
if (GetStage() >= stgGems)
gloGems.SetValue(intGems)
SetObjectiveDisplayed(stgGems,1)
SetObjectiveCompleted(stgGems,1)
endIf
else
if (GetStage() >= stgGems)
gloGems.SetValue(intGems)
SetObjectiveDisplayed(stgGems,1)
endIf
endIf
ENDFUNCTION


Edited by maxarturo
Link to comment
Share on other sites

You're kidding me - I stared at that for HOURS. Only thing I can think is that I've been coding functions for Gsheets for days, and everything there is contained - guess I just defaulted to that.

 

Thank you so much - that did it.

 

*** EDIT TO ADD ***
Well, not quite. New post below.

Link to comment
Share on other sites

Okay, I spent a chunk of today writing the trigger, and the good news is, the trigger script works perfectly - it runs this script whenever a gem is added to, or removed from, the player's inventory.

The bad news is that this script, while it compiles, doesn't quite do what I intended it to.

The intGems variable (which should go up every time a gem from the list is found in the player's inventory) doesn't go above 1, even though we are cycling through the entire Formlist. I added a notification to the script to confirm the lenGems and intGems variables after the while loop runs, and while lenGems goes to 24 (indicating the loop ran 24 times), intGems sits at 1 no matter how many gems the player has.

Here's the code from the loop (it's already above this, but just to see it in isolation):

 

 

 

While (lenGems < lstGems.GetSize())
Form Entry = lstGems.GetAt(lenGems)
If (Entry as ObjectReference)
If (Game.GetPlayer().getItemCount(Entry) > 0)
intGems += 1
EndIf
EndIf
lenGems += 1
EndWhile

Debug.Notification("Length is " + lenGems + ". Currently carrying " + intGems + ".")


 

The formlist contains all the individual Stones of Barenziah (yes, I'm trying to rewrite that most infamous of quests), so as far as I can tell, it should add 1 to the variable for each one I have:

 

Screenshot-2023-03-15-183415.png

The scriptt properties are all filled in, but the Debug Notification returned is "Length is 24. Currently carrying 1."
It doesn't matter whether I'm carrying 1 or 5. Still returning 1.

Any thoughts?

Link to comment
Share on other sites

Rather than referring to the references placed by the activators managed by the quest handler script, just use the base object that the 24 references are derived from. That is what the original dialog uses as a condition for both Vex and Maul to say their bits about it.

 

[00] Skyrim.esm (AF75991D) \ Misc. Item \ 0009DFBB <TGCrownGemInventory>

 

Example:

Actor PlayerRef = Game.GetPlayer()
Int num = PlayerRef.GetItemCount(TGCrownGemInventory)
Debug.Notification("Currently carrying "+num+" gems")

I cannot speculate as to why what you have won't work. It may be due to some 'funky-ness' that takes place between inventories and object references. But I cannot say for certain.

Link to comment
Share on other sites

That will work for the main quest where you have to collect all 24, but my plan is to break the gems into multiple quests, categorized by type of location, making it less of a random slog and more like a treasure hunt.

 

My goal with this script was to have a single script I could use with all of my quests to track a grouping of gems.

 

I'll play with it again tomorrow, and if I can't figure out, I'll work on an alternate method.

 

Thanks again for all the help.

Link to comment
Share on other sites

All the quests could share one script. You just need to write it in a way that it resolves itself before processing gem aliases and such. This said, personally I would likely just use one quest, and one alias script to rule them all, but going with your route, the easiest way to resolve which quest you are working with is, is the SKSE call of GetID()

 

String Label = GetID()

If Label == "GemsQuestABC01"

; whatever

ElseIf Label == "GemsQuestABC02"

; Etc

EndIf

 

You actually dont need properties at all to do any of this, but it may be more convenient to use them. Your preference there. The quest has a function called GetAlias(Digit). It can read those to evaluate the ref situation. Like if its been acquired or whatever

Link to comment
Share on other sites

There is some very funky stuff with those gems.

Namely, as you pick up those gems BEFORE you talk to Vex about them, they appear to accumulate in your inventory as a single-entry item. Meaning they are not added as individual references, but rather as increased counter of same reference. It has something to with the fact that at this stage, they are called 'Unusual Gem'. But once you talk to Vex, they turn into 'Stone of Barenziah', and any further ones you find, are added to your inventory as individual references.

 

As you can see here, console still calls them 'unusual gems'. 7 found before chat with Vex, 6 after.

 

FvfCwMt.jpg

 

 

You might amend your counting function a bit to see what's going on:

While (lenGems < lstGems.GetSize())
	Form Entry = lstGems.GetAt(lenGems)	
	If (Entry as ObjectReference)
		Int _cnt = Game.GetPlayer().getItemCount(Entry)
		Debug.Trace(Self + " Checking Gem Ref " + lenGems + " (" + Entry + ") : " + _cnt) 
		If (_cnt > 0)
			intGems += 1
		EndIf
	EndIf
	lenGems += 1
EndWhile
Link to comment
Share on other sites

  • Recently Browsing   0 members

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