Jump to content

[Skyrim Modding] Displaying Global Variable (Without Checking For Conditions


Ashenfire

Recommended Posts

I am using the creation kit and all I see is how to get a global variable and then check for a condition to display it.

 

I don't want to write 100 conditions to anticipate every number the global variable is. I just want to display its current number

 

to give me an idea of what is going on with my script (troubleshooting).

 

 

How can I display the global variable's content, in this case an integer; without checking for every possible value it might be?

 

 

Edit / UPDATE:

 

I don't know all the ways, but I was successful using Debug.Notification.

GlobalVariable.psc already has the built in functions so no need to declare a function.

 

Look for the variable you want to display in the creation kit / under Miscellaneous / Global

For instance the value held in the GlobalVariableGV auto that will return the value of HasHireling.

 

1. Define a variable similar to the name of the global variable you want to display.

Example: GlobalVariable Property GlobalHasHirelingGV auto.

 

2. Declare a temporary variable that will get the value of your GlobalVariable.

Example: int HasHirelingValue=(GlobalHasHirelingGV.getValue() as int)

 

3. Display the temporary value in a debug statement so user can see the test in the game.

Example: Debug.notification (" Current Hireling Global : " + HasHirelingValue.GetValue() as int)

 

 

4. Compile

 

5. Declare the property GlobalVariable GlobalHasHirelingGV as "HasHireling"

 

6. Place the script on an activator, like a lever that has animation, Name the script that extends object reference conditional.

I did this for a duplicated Norlevl01 lever.

Edited by Ashenfire
Link to comment
Share on other sites

That's a bit more complicated than it should need to be. A script like this should work.

ScriptName SomeScript Extends ObjectReference

GlobalVariable Property HasHireling Auto

Event OnActivate(ObjectReference akActionRef)
	Debug.Notification("Variable is currently: "+HasHireling.GetValueInt())
EndEvent

Also, for adding a script to an activator, you don't need to duplicate the lever itself. Just place a new copy of the lever in the world and add the script to that specific copy. This will leave all other levers 100% unaffected, but this new lever will work the way you need. Without making a completely separate lever, which isn't really needed. Of course, making a duplicate doesn't really hurt anything, it's just unnecessary.

 

And the reason I named the property as exactly HasHireling instead of something similar is because if it's exactly the same name as a form of that type, then you can click Auto Fill or Auto Fill All and it'll fill the property/properties without having to manually sort through the list.

 

And finally, I used "GetValueInt()" instead of "GetValue()" because you're casting to an int, and that is exactly what "GetValueInt()" does. It's a shortcut function for "GV.GetValue() as Int" just like "GetAV()" is shorthand for "GetActorValue()". To be fair, "GetValueInt()" will be slightly slower, but since it's on an activator, that's not going to matter. It's not being called 100 times per second, so it won't be noticeable.

Link to comment
Share on other sites

The lever was duplicated so it would be easy to understand what the lever did. It is for mod testing anyways.

If you have 30 items you are testing for, then it is just easier to drop the lever already named for what it does.

So in actual game time, I would not being doing that. I would be doing what you had suggested.

 

I did attempt earlier what you typed for the script, for some reason I couldn't get it to work.

I will try it again since you vouched for it.

 

I understand the autofill comment. It just didn't work out for what I was doing; for 'being clear'.

 

Lastly, the steps that I used also work for values that are not used in global functions.

You can still declare the value of a faction for instance (you cant use a function to call it).

 

string PotentialHirelingNumber=(PotentialHireling as string)

Debug.notification("Potential Hireling Number =" + PotentialHirelingNumber)

 

If you can explain how to do 'non functions' easier than what I depicted, I don't mind.

This is all I could come up with that worked for items that had functions attached, and ones that did not.

 

Thanks for feedback.

Edited by Ashenfire
Link to comment
Share on other sites

For being clear, yeah, it definitely makes sense to do it the longer way and not use auto-fill (but possibly explain it). If I recall, however, the most confusing thing about learning papyrus (for me personally) had nothing to do with whether or not something could be auto-filled or whether or not it was called via a function or via casting or anything like that. The problem I had was with properties. Everyone described them as something so special and unique. The problem is that they're not. They're basically global variables that can be set to specific pointers before run-time. To explain what I mean, this script has both a variable and a property.

ScriptName SomeScript Extends ObjectReference

Actor Property SomeActor Auto
Actor SomeStoredActor

Event OnInit()
  SomeStoredActor = SomeActor
EndEvent

SomeActor can be set to a specific actor before the game runs by using the property manager. SomeStoredActor can't. And it can't be accessed globally. So, properties are just global variables able to be set before run-time. But everyone treated them like they were something totally new and unique to papyrus and I spent forever trying to figure out how they were so special and what I was missing. (This has nothing to do with your post... I'll get back on topic in a moment...)

 

You don't really need to try it the way I suggested. If you want to try it just to figure out how to make it work that way (because in the future, it'd be a simpler way of doing it) then feel free, but the way you did it works, you say, so there's really no reason to change it unless you want to.

 

For things that don't have a function, that's as easy as it gets (the way you did it, I mean). However, I've actually never seen calling a faction as a string to get the number members. That's interesting.

Link to comment
Share on other sites

I only declared the faction properties as strings because the compiler wouldn't let me make them integers.

This is the problem I am having right now. In the game, the 'string' factions only display "[Faction"

Looks incomplete. I shorten the line and that still gets cut off. So apparently I need another solution.

 

I guess I am 'in the same boat' as you explained. Instead, its the variables that look like they follow their own rules in casting.

I can't apply the same rules I used with functions, to just getting a standard variable's content.

Edited by Ashenfire
Link to comment
Share on other sites

What precisely are you trying to do that isn't currently working? Are you trying to find a way to determine the number of members of a faction as I suspected? Because I wouldn't expect the way you did it to work. When I saw it, I was surprised it worked. If it doesn't, that actually makes more sense.

 

The thing about casting is that certain types of variables can be cast only to certain other variable types. Some can be cast from anything (bools and strings), but others can only be cast from certain things (ints and floats). So, you can't cast an object (a faction is an object) to an int, but ANYTHING can be cast to a string. If you cast an object to a string, it returns "[scriptName <EditorID (FormID)>]" where ScriptName is the name of the script governing that object. Every object type is a script. There is a tree script, a spell script, a quest script, and so on. There's also a Utility script, and a Game script, and a Debug script. When you call "Variable as Spell", it checks to see if the Variable contains something whose script is either Spell or a parent of Spell. Every script has a parent script except a few, which are the highest of their kind.

 

To make this make a little more sense, see these two pages.

http://www.creationkit.com/Cast_Reference

http://www.creationkit.com/Category:Script_Objects

 

So, casting a faction as a string is only ever going to return "[Faction <EditorID (FormID)>". If you want to get the number of members, it would be really difficult unless there's a specific function for that, which there isn't. If you're dead set on doing that, let me know and I'll see if I can think of a way to manage it. Otherwise, just explain what you're actually trying to do and I'll see if I can help with that, which will hopefully be easier. Now that I'm sure I've probably confused you with near-incoherence, I'll wait for your response.

 

EDIT: If your'e just trying to get the name, then you need to call GetName(). It's a function on the Form script, and as such, it works on every type of form, including factions. It may not return what you expect, but it'll always be applicable. This doesn't mean it'll apply to any variable. If you call it on an int, it'll fail and throw an error. But it'll work on any variable whose type is a form of some sort.

Edited by Xander9009
Link to comment
Share on other sites

I examined all scripts. I even looked for hidden scripts to verify I am not missing anything.

My plans are this:

 

1. Create a sure fire way of creating scripts that detect anything I need them to do, for troubleshooting.

2. My current project is to help myself and Allannaa make multiple hirelings and multiple followers without modifying core dialogue.

I just replicated DialogueFollowers and DialogueViews and am now trying to find out why playerfollowercount is not being observed.

Which means I changed the code to never increment playerfollowercount; the followers did all dialogue, but the minute I hired a hireling;

The previous hireling would update a package and unhire herself; even though she did not mention I already had someone hired.

I was trying to use debug.notification to tell me what the values of all the factions hirelings have, playerfollowercount; HasHirelingGV; etc.

 

3. I know old school programming so this Casting is driving me crazy. I live on Creationkit.com and I mostly have global variables called

by functions; figured out. I am looking for some kind of chart or some way to understand what 'environments' each operate on.

It just baffles me that a single item like playerfollowercount can not just be displayed; when it has code to be able to check for a

condition.

 

 

 

By the way, I re entered the global function script mentioned earlier; I finally got it working and replaced the way I did it for Globals.

Now I am trying to find something better than casting a value as a string. It isn't working, as you already knew. I am trying

to find out the 'laws of casting' so to speak. So I can translate any casting variable to any other type when I need it.

Link to comment
Share on other sites

Side note, I already saw those pages you mentioned. Its all greek to me. There is no structure to actually teach it, just raw code. So I am learning very slowly.

Link to comment
Share on other sites

I think the biggest problem here is that I can probably make a script do most anything you need it to, but explaining all of the ins and outs of doing so is really difficult. For casting, it's basically like this: you can cast one variable type to another if it would make sense. There are some exceptions to this rule, but not too many.

 

A faction being an object is why it can't be cast as a string and get any useful information. If I have a fancy armor named "Dragonhide", and I ask "What number is this armor?" the game won't do it because that doesn't make any sense. If I ask "What word is this armor?" it still doesn't make sense, but it gives it a shot. It doesn't tell you "Dragonhdie", though. It tells you "Armor". You can ask "What's this thing's name?" though. "thing" in this case is Form. A Form is anything with a FormID, and GetName() can be called on any Form. In the same way, Armor, Weapon, Ingredient; they're all nouns. And for any noun, you could ask "What's this 'noun's' name?"

 

You can cast anything to a bool. For numbers, it just checks if it's 0 or not. For non-numbers, it checks if the variable is empty or not.

 

You can cast anything to a string. For numbers, they remain the same, but they get treated as text. For bools, it returns true or false like you'd expect. For objects, it returns the name of the type of object it is. If you want the specific object's name, rather than the type's name, you need to use GetName().

 

Retrieving the contents of a variable comes in two forms. Automatic and function-driven. GlobalVariables are function driven. Technically, the global variable is a form. It's an object, and idea. The game uses it as such. So, when you call "Debug.Notification(SomeGV)", it doesn't understand, because you're asking it to 'say' this GV. But it can't 'say' it because it's not a string (numbers and bools are automatically converted (cast) to strings, so those would work). Instead, you need to ask what was last stored inside of that GV using GetValue(). All other variable retrieval is automatic. If you set the variable Var1 to 3 and then later in your script you have "Var1", the contents are immediately returned without the need for GetValue() because the game understands this command. It's actually exactly what it did for the GV. You called the name of the variable, and it returned the variable's contents. With Var1, the contents are "3". With the GV, the contents are "ThisGLobalVariable", NOT the number the GV is set to. A GV is literally a variable pointing to another variable. (Your in-script variable points to the global variable.)

 

I'm not sure how much help any of that will be, though. I think the best way to help would be to remove some of the abstractness here. Post a script and explain exactly what you need it to do and exactly what it's doing wrong.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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