Script Extending Question

Post » Wed Jun 20, 2012 10:51 pm

If I have a Script, lets call it Menu, and I extend it from Quest and it has a function called say...

Function MenuExecuted(int index)
return 0
EndFunction

Now, lets say I extend Menu to a new quest in another plugin, ex "MyMenu extends Menu"

and I override the function

Function MenuExecuted(int index)
return 1
EndFunction

The concept of extending should allow this, if I call MenuExecuted it should return 1... But it doesn't really specify if I have to cast to the new type (Trying to figure out if this works like virtual in OOP)

If I store a FormList of the quests and I want to re-iterate over that list, they will all be of the "Form" type, in which case I have to cast to the "Menu" type, but after casting to the Menu type, will calling MenuExecuted call the child overridden function in MyMenu, or the parent function in Menu?

Judging by the simplicity of this language I would assume I have to cast to "MyMenu" rather than "Menu" to get the overridden result, but it would be much better if I could get the child result as the parent caller. Casting to MyMenu is not an option when you don't know it exists yet.
User avatar
Angela Woods
 
Posts: 3336
Joined: Fri Feb 09, 2007 2:15 pm

Post » Wed Jun 20, 2012 11:09 am

I'd say you have to cast it to MyMenu in papyrus unfortunately. I know you sayed you don't know about it but does that mean it may be in another mod? If you just don't know if it is or not of type MYMenu it may be usefull to know that a casting attempt won't give you an error, it will just return None.
If is a quest in other mod I once had such isue and a workaround was to start that quest via Story manager. The base mod (containing Menu) was using keyword.SendStoryEvent[AndWait](....) and the second mod (containing the derived script MyMenu) used a OnStoryScript to start MyMenu. This way your base mod could start a quest of which it doesn't know about, they just have to know both the keyword and the parameters used. Is not a nice way to use it and I didn't used it for the problem you described but you may find something on this direction if nothing else works for you.
User avatar
maya papps
 
Posts: 3468
Joined: Mon Aug 07, 2006 3:44 pm

Post » Wed Jun 20, 2012 2:40 pm

Hmm, well not the greatest way to do it, but this definitely would work as a workaround. Just enough parameters that I could simply pass them in, and if it wasn't enough I could attach a script to a known object and add more properties to the object.

The idea was to have a common function between the two so I could extend my mods main menu to modded-in menus without editing the quest as a whole creating conflict. I think this would work fine if I had the main menu send a story event and have the modded menus catch the event and work off the parameters.

Thanks for the tip!
User avatar
An Lor
 
Posts: 3439
Joined: Sun Feb 18, 2007 8:46 pm

Post » Wed Jun 20, 2012 10:10 pm

Functions in Papyrus are always “virtual” (to use C++ terminology). It will always call the most derived version of a function that it can find on the script that your variable is pointing at. If you want one of your derived scripts to call a parent’s version of the function, you can use the http://www.creationkit.com/Function_Reference#Special_Variables to call your parent’s version of the function.

There is one little caveat though, since Papyrus allows multiple scripts attached to the same in-game object.

If you have multiple scripts attached to the same in-game object and they extend the same parent script, and your variable type is the parent script, it is (relatively) random which script you are actually pointing at and you shouldn’t rely on pointing at one or the other unless you casted from the derived script yourself. (Converting the variable to a string will tell you, if you need to debug such a situation)
User avatar
My blood
 
Posts: 3455
Joined: Fri Jun 16, 2006 8:09 am

Post » Wed Jun 20, 2012 11:52 am

Functions in Papyrus are always “virtual” (to use C++ terminology). It will always call the most derived version of a function that it can find on the script that your variable is pointing at. If you want one of your derived scripts to call a parent’s version of the function, you can use the http://www.creationkit.com/Function_Reference#Special_Variables to call your parent’s version of the function.

There is one little caveat though, since Papyrus allows multiple scripts attached to the same in-game object.

If you have multiple scripts attached to the same in-game object and they extend the same parent script, and your variable type is the parent script, it is (relatively) random which script you are actually pointing at and you shouldn’t rely on pointing at one or the other unless you casted from the derived script yourself. (Converting the variable to a string will tell you, if you need to debug such a situation)

If you have two scripts on the same object (Say for the sake of argument, both of them extend ObjectReference) and one of them does a RegisterForUpdate, will BOTH of them get the update event, or only the particular script that registered? Also, could you have a look at the problem I've been having with global variables in a quest scripthttp://www.gamesas.com/topic/1362320-ok-im-stumpedfunction-not-calling/ I'm not sure what I did wrong, but something's not working right...you can call member functions on a quest script from a correctly set property on that script, right? For some reason it doesn't seem to be working...
User avatar
m Gardner
 
Posts: 3510
Joined: Sun Jun 03, 2007 8:08 pm

Post » Wed Jun 20, 2012 3:09 pm

Functions in Papyrus are always “virtual” (to use C++ terminology). It will always call the most derived version of a function that it can find on the script that your variable is pointing at. If you want one of your derived scripts to call a parent’s version of the function, you can use the http://www.creationkit.com/Function_Reference#Special_Variables to call your parent’s version of the function.

There is one little caveat though, since Papyrus allows multiple scripts attached to the same in-game object.

If you have multiple scripts attached to the same in-game object and they extend the same parent script, and your variable type is the parent script, it is (relatively) random which script you are actually pointing at and you shouldn’t rely on pointing at one or the other unless you casted from the derived script yourself. (Converting the variable to a string will tell you, if you need to debug such a situation)

Well thats good that they will always use the most derived version, from what I understood of your explanation, doing this should work:

Script Menu Extends Quest
Function Execute() return 1

Script FirstMenu Extends Menu
Function Execute() return 2

Script SecondMenu Extends Menu
Function Execute() return 3

Quest Property QPointer Auto

QPointer = FirstMenu
(QPointer as Menu).Execute() -- Should return 2
QPointer = SecondMenu
(QPointer as Menu).Execute() -- Should return 3

Even though they were casted to the parent, they are derived objects that override the parent function so they will call the most derived function.

Where the problem would occur is if I had multiple scripts attached to either FirstMenu, or SecondMenu, that were derived from Menu, in which case the resulting script would be ambiguous.
User avatar
James Wilson
 
Posts: 3457
Joined: Mon Nov 12, 2007 12:51 pm

Post » Wed Jun 20, 2012 8:32 am

QPointer = FirstMenu
(QPointer as Menu).Execute() -- Should return 2
QPointer = SecondMenu
(QPointer as Menu).Execute() -- Should return 3

I'm confused, does that happens?
I thought you sayed you tested and it doesn't, hence my suggestion, and also that was my impression but didn't tested that too much on my own.
User avatar
Dina Boudreau
 
Posts: 3410
Joined: Thu Jan 04, 2007 10:59 pm

Post » Wed Jun 20, 2012 6:20 am

If you declare your property as the child object, then you'll get the derived functions.

SecondMenu Property QPointer Auto

Form
Quest
Menu
FirstMenu
SecondMenu

You can cast Qpointer up to the parent objects and access the overridden functions. So if you cast to Menu, it should return 1. That's how I read this.

It will always call the most derived version of a function that it can find on the script that your variable is pointing at.
User avatar
Gwen
 
Posts: 3367
Joined: Sun Apr 01, 2007 3:34 am


Return to V - Skyrim