Good0Provider Posted June 4 Posted June 4 I need the function GetNinaDebt_Paid to be global. How do I declare Paid so it is with in the scope of GetNinaDebt_Paid? error `variable NinaDebt_Paid is undefined` Bool NinaDebt_Paid String Function GetNinaDebt_Paid(Actor akActor) global Debug.Trace("[NinaDebtProblem_Main] GetNinaDebt_Amount called") if NinaDebt_Paid Debug.Trace("[NinaDebtProblem_Main] Debt has been paid") return "true" else Debug.Trace("[NinaDebtProblem_Main] Debt has not been paid") return "false" endif endFunction
PeterMartyr Posted June 4 Posted June 4 I got no idea what you trying to do but... [Private Variable]Can't be done. use a getter and setter Even better use an auto property for more control use FULL property Bool NinaDebt_Paid, is declared, but is it initialised? On 6/4/2025 at 7:36 AM, Good0Provider said: error `variable NinaDebt_Paid is undefined` Expand FYI if not initialised, it is undefined, I 100% agree with the compiler on that but by default in papyrus, variables are initialised to their default status Bool is false int is 0 float is 0.0 which bring us to the next question, does the header have the Hidden Keyword (I do not think so, but I had to ask) perhaps you could tell us what you trying to achieve? But look at this in the meantime: ScriptName firstScript Extends Quest Bool Property NinaDebt_Paid Auto ScriptName secondScript Extends Quest firstScript Property ScriptA Auto Bool Function GetNinaDebt_Paid(Actor akActor) Debug.Trace("[NinaDebtProblem_Main] GetNinaDebt_Amount called") if ScriptA.NinaDebt_Paid == true Debug.Trace("[NinaDebtProblem_Main] Debt has been paid") return true else Debug.Trace("[NinaDebtProblem_Main] Debt has not been paid") return False endif endFunction notice I removed the Global Keyword to, do not misuse keyword, I had a massive rant on that not long ago, I think that was your whole problem, plus variable are private, it needed it to be public, by default above is false OK? Until you the set the value to be true on first script property Bool Property NinaDebt_Paid Auto which be can done from any script ScriptName ThirdScript Extends Quest firstScript Property ScriptA Auto Function someFunction() ScriptA.NinaDebt_Paid = true EndFunction three scripts, it is not Global, but it is Public, and accessible to be mutated through properties by every mod in the game
PeterMartyr Posted June 4 Posted June 4 EDIT if you want the debt value for some dialogue topic 'You owe me money Nina' 'Thanks for paying Nina' that a whole other story, and I have seen intermediate to advance self taught coder struggle with that. Work on getting better for that one) but what I forgot to say is , as easy as access that property in script one, I can access any function in script one tooo
Qvorvm Posted June 4 Posted June 4 It's the basic limitation of "global" functions in papyrus. They cannot have any memory (variables, properties, etc). They can however use constants and other global functions. So you could do bool property NinaDebt_Paid Auto function something() global If (Game.getFormFromFile( 0xnnnnnn, "myesp.esp") as MyScriptFilename).NinaDebt_Paid ... endfunction In general, it's not worth the trouble. Use a non-global function instead.
scorrp10 Posted June 4 Posted June 4 Memory space to hold a script's global variables and properties is allocated when an instance of the script is created. In this context, 'global variable' means a variable scoped to entire instance. A global function in a script is not associated with any instance of the script, and thus has no access to any variables or properties that would be specific to an instance. A global function is more or les an equivalent of a static function in a C++ class. However, C++ also has a concept of static class member variables, which get a specific memory location and can be accessed by static class functions. No such thing in Papyrus. Any parameters passed to a global function, and any local variables declared during its execution, are allocated on the call stack, and exist only while this function code is executing. So, what you can do: Option 1 - create a Global form for this variable. Then, in any script that needs to access it, you declare a 'GlobalVariable Property NinaDebt_Paid Auto', fill this property with the Global form you created, and you can check it or change it using NinaDebt_Paid.GetValueInt() or NinaDebt_Paid.SetValueInt(_value_). You can also use this Global in any conditions (dialogue, package, scene, perk, effect, you name it) Option 2 - designate a script instance that will be attached to some object persisting throughout your mod. Most likely, it will be a quest object that is either start game enabled or triggered by some event. Attach a script to it, declare the property in there. A good idea to make this script conditional, and this property as well, so that you can access this property in conditions.
PeterMartyr Posted June 4 Posted June 4 @Qvorvm I decided to answer the question, but I would really prefer to know what they are doing. To answer it correctly. Here is to blindly answering it, Cheeeeeeeeeeeers. @Good0Provider Still do not know what you want 100%, but..... this is my best guess, but read my post about the property to other scripts please Quote var declaration in global scope Expand On 6/4/2025 at 7:36 AM, Good0Provider said: I need the function GetNinaDebt_Paid to be global. How do I declare Paid so it is with in the scope of GetNinaDebt_Paid? Expand ScriptName NinaDebtScript Extends Quest {Using a Private Variable} Bool NinaDebt_Paid Function PayNinaDebt(bool payment) Debug.Trace("[NinaDebtProblem_Main] GetNinaDebt_Amount called") if !NinaDebt_Paid && payment Debug.Trace("[NinaDebtProblem_Main] Debt has been paid") NinaDebt_Paid = payment ElseIf !payment && !NinaDebt_Paid Debug.Trace("[NinaDebtProblem_Main] Debt has not been paid and is still outstanding!!!!") Else Debug.Trace("[NinaDebtProblem_Main] Debt was already Paid in FULL!!!!") endif endFunction just use the call below where is appropriate, example here is a topic info! first make a semi-colon comment ; In the right or end frag box and compile then add the property to the script and compile then add the frag >>> NinaDebt.PayNinaDebt(true) in the right or end frag ScriptName PayThatDebt Extends TopicInfo Function Fragment_0(ObjectReference akSpeakerRef) Actor akSpeaker = akSpeakerRef as Actor ;BEGIN CODE NinaDebt.PayNinaDebt(true) ;END CODE EndFunction NinaDebtScript Property NinaDebt Auto the Property to the script, is what you were missing, which is why I explain it in great detail, If you require a getter for NinaDebt_Paid? ¯\_(ツ)_/¯ it looks like this Bool NinaDebt_Paid bool Function getNinaDebt_Paid() return NinaDebt_Paid EndFunction is the correct way to do it)) just call it. NOTE you do not need a setter, that will Protect the private variable) which the whole point of making it private. To Protect it!!!!! and stop other mods messing with it. @Qvorvm You can have memory access in a Global Function too! You made an oopsie, I know you know better On 6/4/2025 at 10:22 AM, Qvorvm said: It's the basic limitation of "global" functions in papyrus. They cannot have any memory (variables, properties, etc). Expand Reveal hidden contents String Function PapyrusUtilVersionToString() Global Int nResult = PapyrusUtil.GetVersion() Int nLength = StringUtil.GetLength(nResult As String) Return StringUtil.Substring(nResult / 10 As Float, 0, nLength + 1) EndFunction but it need to be self contained and 100% local in the Global Function, or passed by a Parameter Int Function ClampInt(Int nValue, Int nMin, Int nMax) Global If nValue > nMax Return nMax ElseIf nValue < nMin Return nMin EndIf Return nValue EndFunction I know what you mean, but geez you explain it poorly, folks it is Weirdly Global Functions cannot access Global Variables or Global Properties, is more to the point.
PeterMartyr Posted June 4 Posted June 4 @Qvorvm and @scorrp10 guys no global can set a private variable, weirdly you both admit that, the author just a newbie that incorrectly use the keyword Global instead of Public.... the Private Variable is fine and a normal Function is fine, they just do not know what are doing... go back to your roots Const Private Protected Public Beside Papyrus a is half ass f*#@ed up Object Orientated Programing language, that not even a true OOP, else prove me wrong by explaining how a papyrus script can extend two parents, basically this language is not worth our time!! Edit BTW if it dialogue which is unknown at this point, they can also use GetOwningQuest, if the dialogue and Quest Script is the same Quest. We need more info, but I stand by the Private variable and a Void Function, is all we need, not Static or one with a Return
Recommended Posts