Jump to content

CK - Can't get a global variable to change value


Recommended Posts

Posted

This is driving me mad...I'm just a beginner at FO4 scripting, but I thought this would be an easier task.

The code I'm trying to implement is this:

 

;Current Appearance calculation
    _T_CurrentAppearance = (_T_Appearance.GetValue() - _T_BeatenCounter.GetValue())
       If Game.GetPlayer().GetValue(Charisma) >= 7
           _T_CurrentAppearance.Mod(2)
       Elseif Game.GetPlayer().GetValue(Charisma) >= 3
           _T_CurrentAppearance.Mod(1)
       Endif

       If (_T_CurrentAppearance.GetValue()) >= 11
          _T_CurrentAppearance.SetValue(10)
       Elseif (_T_CurrentAppearance.GetValue()) < 0
          _T_CurrentAppearance.SetValue(0)
       Endif

 

The idea is to introduce a dynamic appearance value to the Beggar Whore mod to be used in more dialogue choices. But the global never changes.

All the variables are globals, this code is inside an OnTimer block that updates other globals from the mod, the new global "_T_CurrentAppearance" is set in properties and is not a constant, and I can change the "_T_Appearance" value just fine through the mod's own menu (which I modified a bit to have extra choices), even thought that one is set as constant. I also tried turning the globals into local float variables, but then it fails to compile when changing the global to the local variable value.

What am I doing wrong?

Posted (edited)
6 hours ago, JohnyBurner said:

This is driving me mad...I'm just a beginner at FO4 scripting, but I thought this would be an easier task.

The code I'm trying to implement is this:

 

;Current Appearance calculation
    _T_CurrentAppearance = (_T_Appearance.GetValue() - _T_BeatenCounter.GetValue())
       If Game.GetPlayer().GetValue(Charisma) >= 7
           _T_CurrentAppearance.Mod(2)
       Elseif Game.GetPlayer().GetValue(Charisma) >= 3
           _T_CurrentAppearance.Mod(1)
       Endif

       If (_T_CurrentAppearance.GetValue()) >= 11
          _T_CurrentAppearance.SetValue(10)
       Elseif (_T_CurrentAppearance.GetValue()) < 0
          _T_CurrentAppearance.SetValue(0)
       Endif

 

The idea is to introduce a dynamic appearance value to the Beggar Whore mod to be used in more dialogue choices. But the global never changes.

All the variables are globals, this code is inside an OnTimer block that updates other globals from the mod, the new global "_T_CurrentAppearance" is set in properties and is not a constant, and I can change the "_T_Appearance" value just fine through the mod's own menu (which I modified a bit to have extra choices), even thought that one is set as constant. I also tried turning the globals into local float variables, but then it fails to compile when changing the global to the local variable value.

What am I doing wrong?

 

I think, you need to change the check for Charisma: Game.GetPlayer().GetValue(Game.GetCharismaAV())

Edited by Heinzelman
Posted (edited)

Edit: I was SO  wrong; the property wrapper apparently does allow direct assignments with the equal sign, without having to use GlobalVar.SetValue(newvalue)

Live and learn.

If your GlobalVariable is not a property but just a  regular GlobalVariable type asset,  SetValue() is still mandatory there to store a numerical value in it. 

 

 

if _T_CurrentAppearance is a GlobalVariable type asset, ( and not a regular run of the mill  float)  then I think  you cannot assign a numerical value like this

_T_CurrentAppearance = (_T_Appearance.GetValue() - _T_BeatenCounter.GetValue())

needs to be explicit instead

_T_CurrentAppearance.SetValue(_T_Appearance.GetValue() - _T_BeatenCounter.GetValue())

Direct attribution is only for if you make the GlobalVariable point to another GlobalVariable (essentially telling it to be that other global from that moment on), not a numerical value. 

 

 

 



Also, to try and pre-empt further confusion about Const the declaration in the script like


GlobalVariable Property MyGlobalName Auto Const

 

The const there is not for the value contents stored within the gobalvarialbe, but for the property itself; it dictates if it can be re-assigned to point to another global variable content or not.

To make things confusing:  the Const Flag in the CK GlobalVariable window, that one IS for the hosted numerical content. So that Const flag in the CK small GlobalVariable window is not the same as the Const used in the property declarations within the script; they are two different things. 
One of them ( the one in the CK Global Variable window) means the contained numeric value is a constant 
The other Const (the one in the script) is "This globalvariable property cannot ever be made to point to another globalvariable other than the one it was initialized with. "

At least that's what I think,  figured in my year and a half of Papyrus modding :)
 

Edited by MSM_Alice
Posted (edited)
1 hour ago, Heinzelman said:

 

I think, you need to change the check for Charisma: Game.GetPlayer().GetValue(Game.GetCharismaAV())

That one could work as described there in the original post, if they previously declared an ActorValue type variable (or property) called Charisma, in that script,  and then have initialized that variable (or property) with the actual Charisma ActorValue   (via script properties in CK, or otherwise, with LoadFormFrom...blah blah blah)

I agree, though, that using  Game.GetCharismaAV() is a smart and elegant way of offsetting all this preparation work. 

Edited by MSM_Alice
Posted (edited)
8 hours ago, JohnyBurner said:

This is driving me mad...I'm just a beginner at FO4 scripting, but I thought this would be an easier task.

The code I'm trying to implement is this:

 

;Current Appearance calculation
    _T_CurrentAppearance = (_T_Appearance.GetValue() - _T_BeatenCounter.GetValue())
       If Game.GetPlayer().GetValue(Charisma) >= 7
           _T_CurrentAppearance.Mod(2)
       Elseif Game.GetPlayer().GetValue(Charisma) >= 3
           _T_CurrentAppearance.Mod(1)
       Endif

       If (_T_CurrentAppearance.GetValue()) >= 11
          _T_CurrentAppearance.SetValue(10)
       Elseif (_T_CurrentAppearance.GetValue()) < 0
          _T_CurrentAppearance.SetValue(0)
       Endif

 

The idea is to introduce a dynamic appearance value to the Beggar Whore mod to be used in more dialogue choices. But the global never changes.

All the variables are globals, this code is inside an OnTimer block that updates other globals from the mod, the new global "_T_CurrentAppearance" is set in properties and is not a constant, and I can change the "_T_Appearance" value just fine through the mod's own menu (which I modified a bit to have extra choices), even thought that one is set as constant. I also tried turning the globals into local float variables, but then it fails to compile when changing the global to the local variable value.

What am I doing wrong?

Oh, one other thing I  bumped my head into with Papyrus is that when doing comparisons on floats and ints,  to be extra safe, to do explicit typecasting, I expressed the constant with a decimal digit too.

If your GlobalVar stores a float 


if  GlobalVar.GetValueInt()==1 
will work  as expected (both are int)

if  GlobalVar.GetValue()==1.0
will work  as expected (both are float)
 

if  GlobalVar.GetValue()==(1) as float
will work  as expected  (both are float)

 if  GlobalVar.GetValue()==1 
One is float, one is int; might produce some awkwardness.
 it compiles, but 1.0  is not the same  1 as far as Papyrus is concerned, in some cases.


 

The only other thing I can think of is to make sure the property is indeed correctly set/linked in the CK in the properties of the script too, and the ESP is saved.

In my case, the reason for " why isn't that damned property changing its value"  was, in 99 out of 100 cases, that I had forgotten to save the script, recompile the script, link the property in CK, and save the ESP.

Edited by MSM_Alice
Posted
3 hours ago, MSM_Alice said:

Oh, one other thing I  bumped my head into with Papyrus is that when doing comparisons on floats and ints,  to be extra safe, to do explicit typecasting, I expressed the constant with a decimal digit too.

If your GlobalVar stores a float 


if  GlobalVar.GetValueInt()==1 
will work  as expected (both are int)

if  GlobalVar.GetValue()==1.0
will work  as expected (both are float)
 

if  GlobalVar.GetValue()==(1) as float
will work  as expected  (both are float)

 if  GlobalVar.GetValue()==1 
One is float, one is int; might produce some awkwardness.
 it compiles, but 1.0  is not the same  1 as far as Papyrus is concerned, in some cases.


 

The only other thing I can think of is to make sure the property is indeed correctly set/linked in the CK in the properties of the script too, and the ESP is saved.

In my case, the reason for " why isn't that damned property changing its value"  was, in 99 out of 100 cases, that I had forgotten to save the script, recompile the script, link the property in CK, and save the ESP.

 

Wait, you save the script and then compile? If I do it the other way around does that cause issues?

 

And if I understood correctly, I can either fetch the global values as int, or use "1.0" in the places where currently there is "1". But I shouldn't do both.

 

But it still doesn't explain why using two globals doesn't change the one I added. I can't even set CurrentAppearance to the value stored in Appearance.

Posted
4 hours ago, MSM_Alice said:

That one could work as described there in the original post, if they previously declared an ActorValue type variable (or property) called Charisma, in that script,  and then have initialized that variable (or property) with the actual Charisma ActorValue   (via script properties in CK, or otherwise, with LoadFormFrom...blah blah blah)

I agree, though, that using  Game.GetCharismaAV() is a smart and elegant way of offsetting all this preparation work. 

 

And I'll check this one. I've set up a property called charisma and added "charisma" to it in the script properties. You are saying there's an actual charisma actor value that I should have put there instead?

Posted
35 minutes ago, JohnyBurner said:

 

And I'll check this one. I've set up a property called charisma and added "charisma" to it in the script properties. You are saying there's an actual charisma actor value that I should have put there instead?

I was on the wrong track. Your Charisma check should work if you declared it with "ActorValue Property Charisma Auto"

Posted
29 minutes ago, Heinzelman said:

I was on the wrong track. Your Charisma check should work if you declared it with "ActorValue Property Charisma Auto"

 

Yeah, I'm sure the check is working, but changing the global isn't.

To make things more complicated, the actual variable being modified here is _T_Appearance, that changes by the value of _T_BeatenCounter, when I wanted _T_CurrentAppearance to change. Did I mess up the code there? I did removed the "const" from the Appearance properties thinking it was blocking the use of the variable but it was instead blocking it from being changed? But the code shouldn't be changing it in the first place.

So every variable changes except the one I want. Do I need to initialize it? Set it up to be modified? I wonder if I missed a step.

Posted (edited)
34 minutes ago, JohnyBurner said:

 

Yeah, I'm sure the check is working, but changing the global isn't.

To make things more complicated, the actual variable being modified here is _T_Appearance, that changes by the value of _T_BeatenCounter, when I wanted _T_CurrentAppearance to change. Did I mess up the code there? I did removed the "const" from the Appearance properties thinking it was blocking the use of the variable but it was instead blocking it from being changed? But the code shouldn't be changing it in the first place.

So every variable changes except the one I want. Do I need to initialize it? Set it up to be modified? I wonder if I missed a step.

 

I think, the first line may cause the issue. To avoid a misunderstanding:

 

The _T_CurrentAppearance is your own global value, which you want to use in dialogue, and you want to calculate it with _T_Appearance minus _T_BeatenCounter plus 1 or 2 depending on charisma?

 

So in the end you need _T_CurrentAppearance as a value which can be dynamically changed when you call your calculation, correct? While _T_Appearance remains a fixed value (or only managed by Beggar/Whore).

Edited by Heinzelman
Posted
8 minutes ago, Heinzelman said:

 

So the _T_CurrentAppearance is your own global value, which you want to use in dialogue right? And you want to calculate it with _T_Appearance minus _T_BeatenCounter plus 1 or 2 depending on charisma. So in the end you need _T_CurrentAppearance as a value which can be dynamically changed when you call your calculation, correct? While _T_Appearance is a fixed value (or only managed by Beggar/Whore).

 

Yeah, _T_Appearance is chosen in the mod as it initializes (or through the debug menu), but it stays constant.
 

_T_CurrentAppearance is the dynamic one, changing based on the BeatenCounter and Charisma (so far, I plan to add a couple more variables).
 

I tried to set it to 0 before making the calculations, but it only send both Appearances to 0. _T_Appearance is modified by _T_BeatenCounter, and _T_CurrentAppearance is not modified by the charisma check.

Current code:

;Current Appearance calculation
       _T_CurrentAppearance.SetValue(0.0)
       _T_CurrentAppearance.Mod(_T_Appearance.GetValue())
       _T_CurrentAppearance.Mod(- _T_BeatenCounter.GetValue())
       If Game.GetPlayer().GetValue(Charisma) >= 7
           _T_CurrentAppearance.Mod(2.0)
       Elseif Game.GetPlayer().GetValue(Charisma) >= 3
           _T_CurrentAppearance.Mod(1.0)
       Endif

       If (_T_CurrentAppearance.GetValue()) as int >= 11
          _T_CurrentAppearance.SetValue(10.0)
       Elseif (_T_CurrentAppearance.GetValue()) as int < 0
          _T_CurrentAppearance.SetValue(0.0)
       Endif

 

This one eventually sets _T_Appearance to 0. The OnTimer block runs on a 3 second timer, so I can see that _T_Appearance can be set in the debug menu before being set to 0. Should I set it to "const" in the script? I already tried that with a slightly different code, but _T_CurrentAppearance still didn't get modified...

Posted

Maybe I should just calculate CurrentAppearance as a local variable and then pass it to a global? But I had issues with that before, with the compiler complaining about the variable types...

Posted (edited)
1 hour ago, JohnyBurner said:

 

Yeah, _T_Appearance is chosen in the mod as it initializes (or through the debug menu), but it stays constant.
 

_T_CurrentAppearance is the dynamic one, changing based on the BeatenCounter and Charisma (so far, I plan to add a couple more variables).
 

I tried to set it to 0 before making the calculations, but it only send both Appearances to 0. _T_Appearance is modified by _T_BeatenCounter, and _T_CurrentAppearance is not modified by the charisma check.

Current code:

;Current Appearance calculation
       _T_CurrentAppearance.SetValue(0.0)
       _T_CurrentAppearance.Mod(_T_Appearance.GetValue())
       _T_CurrentAppearance.Mod(- _T_BeatenCounter.GetValue())
       If Game.GetPlayer().GetValue(Charisma) >= 7
           _T_CurrentAppearance.Mod(2.0)
       Elseif Game.GetPlayer().GetValue(Charisma) >= 3
           _T_CurrentAppearance.Mod(1.0)
       Endif

       If (_T_CurrentAppearance.GetValue()) as int >= 11
          _T_CurrentAppearance.SetValue(10.0)
       Elseif (_T_CurrentAppearance.GetValue()) as int < 0
          _T_CurrentAppearance.SetValue(0.0)
       Endif

 

This one eventually sets _T_Appearance to 0. The OnTimer block runs on a 3 second timer, so I can see that _T_Appearance can be set in the debug menu before being set to 0. Should I set it to "const" in the script? I already tried that with a slightly different code, but _T_CurrentAppearance still didn't get modified...

 

I dont see a reason for using const in your script, so I would go without. As long as you dont need decimal places, I would use integers instead of floats, like ...Mod(1). You could combine the first 3 lines:

 

_T_CurrentAppearance.SetValue() = _T_Appearance.GetValue() - _T_BeatenCounter.GetValue()

 

And your declarations should be there too (just in case). Also check if they are correctly set under properties in the CK. You dont want to know, how often I missed them :D

Spoiler

ActorValue Property Charisma Auto

GlobalVariable Property _T_CurrentAppearance auto

GlobalVariable Property _T_Appearance auto

GlobalVariable Property _T_BeatenCounter auto


If you want to get proper info ingame, add this line below every change:

Spoiler

Debug.Notification("_T_CurrentAppearance was set to " + Math.Floor(_T_CurrentAppearance.GetValue()) + "!")

You can put a Utility.Wait(1.0) if this goes to fast.

 

But as I read again, there might be another issue. If _T_Appearance is at 0, your result will always be 0. Because: 

 

;Current Appearance calculation
       _T_CurrentAppearance.SetValue() = _T_Appearance.GetValue() - _T_BeatenCounter.GetValue() ; This makes 0 minus X and results in a 0 or even a negative value
       If Game.GetPlayer().GetValue(Charisma) >= 7
           _T_CurrentAppearance.Mod(2) (it may become something between -x and 2 here)
       Elseif Game.GetPlayer().GetValue(Charisma) >= 3
           _T_CurrentAppearance.Mod(1) (between -x and 1)
       Endif

       If (_T_CurrentAppearance.GetValue()) as int >= 11
          _T_CurrentAppearance.SetValue(10) will not be applied, because we are lower

       Elseif (_T_CurrentAppearance.GetValue()) as int < 0
          _T_CurrentAppearance.SetValue(0) 
       Endif

Edited by Heinzelman
Posted
Quote

_T_CurrentAppearance.SetValue() = _T_Appearance.GetValue() - _T_BeatenCounter.GetValue()

 

I had it like this before, which is the most logical way, but didn't made any difference.

 

Quote

And your declarations should be there too (just in case). Also check if they are correctly set under properties in the CK.

 

These are also set up properly.

 

Quote

Debug.Notification("_T_CurrentAppearance was set to " + Math.Floor(_T_CurrentAppearance.GetValue()) + "!")

You can put a Utility.Wait(1.0) if this goes to fast.

 

I will try this to debug the thing. I'm away for the weekend, so it's a problem for Future Me.

I will also comment everything out and start with just a simple change of _T_CurrentAppearance. It's baffling to me, because I believe I'm setting everything right. I'll try and find a tutorial to check if there's an obvious step I missed somehow.

Thanks for the help!

Posted (edited)
28 minutes ago, JohnyBurner said:

 

I had it like this before, which is the most logical way, but didn't made any difference.

 

 

These are also set up properly.

 

 

I will try this to debug the thing. I'm away for the weekend, so it's a problem for Future Me.

I will also comment everything out and start with just a simple change of _T_CurrentAppearance. It's baffling to me, because I believe I'm setting everything right. I'll try and find a tutorial to check if there's an obvious step I missed somehow.

Thanks for the help!

If we're taking bets, I would bet you didn't link the Global Variable property properly in the script to its counterpart GlobalVariable in the ESP. So that's why it stays uninitialized no matter what values you write in it. 

And things will fall into place once you do link it correctly :)
Or if you use local variables instead of script properties.
 

 

It would be helpful to see the declaration block.

Edited by MSM_Alice
Posted (edited)
3 hours ago, JohnyBurner said:

 

And I'll check this one. I've set up a property called charisma and added "charisma" to it in the script properties. You are saying there's an actual charisma actor value that I should have put there instead?

What does " added "charisma" to it in the script properties."  mean specifically? 

Depending on how you did that, it can be very right or very wrong. :)

The Charisma ActorValue has a unique formid and is unique throughout Fallout 4. That is what you need to add there. 
And it needs to be  ActorValue Property ( not another type of property) 


Game.GetCharismaAV() is an elegant way to get exactly that specific form, properly cast to ActorValue type.

Edited by MSM_Alice
Posted (edited)
1 hour ago, MSM_Alice said:

What does " added "charisma" to it in the script properties."  mean specifically? 

Depending on how you did that, it can be very right or very wrong. :)

The Charisma ActorValue has a unique formid and is unique throughout Fallout 4. That is what you need to add there. 
And it needs to be  ActorValue Property ( not another type of property) 


Game.GetCharismaAV() is an elegant way to get exactly that specific form, properly cast to ActorValue type.

 

The charisma linked in properties is the ActorValue one.

The globals declaration is like so:
 

    GlobalVariable Property _T_AndSoItBegins Auto    
    GlobalVariable Property _T_Appearance Auto const
    GlobalVariable Property _T_CurrentAppearance Auto

 

Curiously, the "Use" window for the new global looks like this:
image.png.5363652f958f62d1297a4aa1868e1ad1.png

 

There should be a use count for the quest, shouldn't it? So I did mess something up setting up the variable.

Edit: The _T_Appearance shows the same thing, so it's not that either.

Edited by JohnyBurner
Posted
8 hours ago, JohnyBurner said:

 

The charisma linked in properties is the ActorValue one.

The globals declaration is like so:
 

    GlobalVariable Property _T_AndSoItBegins Auto    
    GlobalVariable Property _T_Appearance Auto const
    GlobalVariable Property _T_CurrentAppearance Auto

 

Curiously, the "Use" window for the new global looks like this:
image.png.5363652f958f62d1297a4aa1868e1ad1.png

 

There should be a use count for the quest, shouldn't it? So I did mess something up setting up the variable.

Edit: The _T_Appearance shows the same thing, so it's not that either.

If you go into the Properties window for that script and open it,  what are you seeing in terms of which properties are linked/populated?
For instance, is your Charisma property there, and is it populated,m something like this ( except, naturally, populate it with the Charisma AV, not the Strength one like in my example)?
Similar for the GlobalVariable that refuses to change (except, of course, populate it with a GlobalVariable type asset)



image.thumb.png.4ab4ae0f24dc805f8af38dcf2bbd1f23.png

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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