OK, I'm stumped...function not calling.

Post » Wed Jun 20, 2012 5:34 pm

OK, I have a function in my Global Variable storage quest:

Scriptname RedwoodsTools extends Quest{ Global functions used by Redwood's Mods }import gameimport utilityimport math; Variables for Linked List implementationActivator property NodeType Auto ; what type of object are we using as default nodes? Make sure to attach the linked list node script to said object type!FormList property RandomNodeType Auto ; Optional list of random object types for the nodes. Make sure the linked list node script is attatched to all such objects!LinkedListControls property LList Auto ; Dummy node used to call the node creation functions.ObjectReference property NodeAxis AutoActivator Property NodeAxisType Auto ; What type of object is the node axis?ObjectReference Property NodeAxisHideSpot Auto ; Where do we hide the node axis?LLNOrgItem Property NodeOrgItem Auto ; Tvar.NodeOrgItem = For the linked list testing spell, to handle list organization outside the effect.Activator Property NodeOrgItemType Auto ; = The item type for the above organizer item.LLNNavOrgScript Property NavigationOrgItem Auto; Tvar.NavigationOrgItem = The organizer item for Navigatiion node linked lists.Activator Property NavNodeOrgItemType Auto ; = The Item type for the above organizer item.\Bool Property MapRequest=False Auto ; Is there a map using reference trying to get a map and unable to find the map controller?LinkedListControls Property NavMapList Auto ; Gvar.NavMapList = List of maps for navigation control. Ordinary vanilla linked list.ObjectReference Function InitializeLL(ObjectReference NodeAxis,Activator NodeAxisType) Global	ObjectReference NewAxis	if !NodeAxis ; We haven't got a place to put node lists yet!		NewAxis = FindClosestReferenceOfTypeFromRef(NodeAxisType,Game.GetPlayer(),100000) ; Look for one.		if !NewAxis ; None in the cell!			NewAxis = Game.GetPlayer().PlaceAtMe(NodeAxisType,1,true) ; Emergency...make one!		endif	endif	return NewAxisEndFunctionLinkedListControls Function SetLList(ObjectReference NodeAxis,Activator NodeType) global ; Function to make a dummy node.	LinkedListControls NewLList	while !NewLList		NewLList = (NodeAxis.PlaceAtMe(NodeType,1,true) as LinkedListControls) ; Dummy Linked List node just to use to call functions.	endwhile	return NewLListEndFunctionEvent OnInit()	RegisterForSingleUpdate(1)EndEventbool  Property MapRequestBool AutoFunction MapRequest()Debug.Notification("Map request Function Call") ; This never shows.	If !MapRequestBool ; Will prevent multiple registrations		MapRequestBool = True		UnRegisterForUpdate()		RegisterForSingleUpdate(1)	Endif	Wait(5)	MapRequestBool = FalseEndFunctionEvent OnUpdate() ; Checks periodically to make sure important global variables get filled when needed.	if !NodeAxis		NodeAxis = InitializeLL(NodeAxis,NodeAxisType)		NodeAxis.MoveTo(NodeAxisHideSpot)	endif	if !LList		LList = SetLList(NodeAxis,NodeType)	endif	if !NavigationOrgItemDebug.Notification("Global Variable Quest OnUpdate: Make Navigation Org Item")		NavigationOrgItem = (NodeAxis.PlaceAtme(NavNodeOrgItemType,1) as LLNNavOrgScript)	endif	if !NodeAxis || !LList || !NavigationOrgItem		RegisterForSingleUpdate(5)	endifEndEvent

that is being called in this OnInit Event in another script:

RedwoodsTools Property Gvar AutoEvent OnInit()	setMotionType(Motion_Keyframed, TRUE) ; Only move when I tell you to move!		while !MapController ; Don't try to do anything until we have a map controller working.			While !Gvar.NavigationOrgItem ; Global reference to map controller is empty! ; Can't make it here...too many of these in existance!				Wait(RandomFloat(0,3.0)) ; Prevent synchronized threads in multiple map getting attempts.				if !Gvar.MapRequestBoolDebug.Notification(name+": Sending Map request") ; Get spammed with this, but the function call isn't happening.					Gvar.MapRequest()				endif			EndWhile			MapController = Gvar.NavigationOrgItem		endwhile; Important code it never gets to hereEndEvent

I've been wasting a lot of my vacation time tracking this down, but now I'm utterly stuck. I'm using a completely clean savegame, so there's no bad savegame problem. When I log in, I get repeatedly spammed with the "Sending Map Request" message, but the notification inside the function doesn't show up! For some reason, the map request call is failing, and I haven't been able to figure out why. The Boolean is clearly "False", or the notification wouldn't show at all.

the really Weird part is, the initial update in the quest init DOES print out the notification that the navigation node org item is being created, and only prints it once. Which means that I SHOULDN'T be seeing the other loop at all.
User avatar
Andy durkan
 
Posts: 3459
Joined: Fri Aug 03, 2007 3:05 pm

Post » Wed Jun 20, 2012 1:05 pm

You didn't declare maprequest as global.
User avatar
Euan
 
Posts: 3376
Joined: Mon May 14, 2007 3:34 pm

Post » Wed Jun 20, 2012 5:50 am

You didn't declare maprequest as global.

In order to do so, I would have to pass all the variables in, and I have plenty of other nonglobal functions that I can call this way. And if it was a global function, I don't think RegisterForUpdate() would work.

It can obviously see the function, since it compiles just fine, and the quest is running (it always is, since it's my global variable quest), so the call SHOULD be working.

And yes, Gvar is correctly assigned to the global variable quest.

And even if making it a global funtion was an issue, that doesn't explain how it gets in the loop in the first place, since the Global quest definitely initialised the variable. If it hadn't it would keep spamming it's own message, and it doesn't.
User avatar
Portions
 
Posts: 3499
Joined: Thu Jun 14, 2007 1:47 am

Post » Wed Jun 20, 2012 9:56 pm

I feel like I'm giving the same answer to all questions recently (edit: which isn't a dig at you, BTW; just me musing), but have you tried casting the quest that the function's script is attached to as the script, rather than calling the script directly?

A script can be attached to more than just one quest, and each "instance" of the script has its own local properties. If you call the script directly, you're calling the core datatype; the engine can't know which instance of the script you mean. So what I think you need to do is call an instance of that datatype, by specifying which quest it is attached to.

Quest Property MyQuest Auto

(MyQuest as RedwoodsTools).MapRequest()

etc.

A lot of the work you're doing is much more advanced than anything I have yet done with the language, though, so this may or may not work for what you're trying to do.
User avatar
Rebecca Dosch
 
Posts: 3453
Joined: Thu Jan 18, 2007 6:39 pm

Post » Wed Jun 20, 2012 11:51 am

I feel like I'm giving the same answer to all questions recently, but have you tried casting the quest that the function's script is attached to as the script, rather than calling the script directly?

A script can be attached to more than just one quest, and each "instance" of the script has its own local properties. If you call the script directly, you're calling the core datatype; the engine can't know which instance of the script you mean. So what I think you need to do is call an instance of that datatype, by specifying which quest it is attached to.

Quest Property MyQuest Auto

(MyQuest as RedwoodsTools).MapRequest()

etc.

This script isn't attached to any other quests. It's my global variable script, and there is, therefore, only one instance of it running.

Quest Property GVarQuest Auto ; Assigned to the quest in the properties tab

...

(GvarQuest as RedwoodsTools).Maprequest()


is therefore exactly functionally identical to

RedwoodsTools property Gvar Auto ; Assigned to the quest in the properties tab

...

Gvar.MapRequest()

, Just a lot harder to read in the code.

Just to humor you, I tried it...no effect, exact same result.
User avatar
Victoria Bartel
 
Posts: 3325
Joined: Tue Apr 10, 2007 10:20 am

Post » Wed Jun 20, 2012 9:31 pm

Ah, gotcha. Sorry I couldn't help, then.
User avatar
Avril Louise
 
Posts: 3408
Joined: Thu Jun 15, 2006 10:37 pm

Post » Wed Jun 20, 2012 5:32 pm

Ok, this should be completely unnecessary (If the quest is running, you should be able to call member functions on it, but that's apparenlty not the root cause anyway)

Function MapRequest(RedwoodsTools SelfIn) GlobalDebug.Notification("Map request Function Call")    If !SelfIn.MapRequestBool ; Will prevent multiple registrations        SelfIn.MapRequestBool = True        SelfIn.UnRegisterForUpdate()        SelfIn.RegisterForSingleUpdate(1)    Endif    Utility.Wait(5)    SelfIn.MapRequestBool = FalseEndFunction

But it still gets Stuck in the while loop. The update IS running each time, and I'm not getting the notification that the global was unfilled during the update...so why is the while loop telling me the variable is unfilled? I've been using globals for quite a while now, and I've never had this happen...the Global quest says the reference is filled, but the other script reads it in and says it's empty.
User avatar
Mandy Muir
 
Posts: 3307
Joined: Wed Jan 24, 2007 4:38 pm

Post » Wed Jun 20, 2012 10:32 am

The main question here is, WHY can't this particular script see the correct values on the global variable script? Every other time I've used globals, I could read in the variable values with Gvar.(variablename)...in this script, they're coming back empty (when they're being correctly loaded fine in other scripts)
User avatar
Tania Bunic
 
Posts: 3392
Joined: Sun Jun 18, 2006 9:26 am

Post » Wed Jun 20, 2012 11:47 am

I'm like DreamKing, your code is so much more advanced than anything I've tried. But from what you say, it sounds like the problem is with your while loop, not the function in your global quest script.

Maybe the '!Gvar.NavigationOrgItem' and '!Gvar.MapRequestBool' just don't evaluate correctly. What if you tried changing it to 'Gvar.NavigationOrgItem == None' and 'Gvar.MapRequestBool == False'?
User avatar
Chloe :)
 
Posts: 3386
Joined: Tue Jun 13, 2006 10:00 am

Post » Wed Jun 20, 2012 7:11 pm

If a function call is failing, it is 90% because you don't have a valid reference to that Object, in this case I am not certain you can be certain you are calling on a invalid/nonexistant reference.


I'm looking at your code, how can you be sure you have the RedwoodTools script? Could you point this out to me? I would have a magic number property in the scipt initlized on OnInit() and printed so you know it, then when you want to see if the reference is valid and pointing to the right Object, check that number.

Script's OnInit{

magicNumber = Random.next();
print(magicNumber);

}

I just want to know how you are 100% sure you have a valid reference to that script object before calling any of its methods.
User avatar
Robert DeLarosa
 
Posts: 3415
Joined: Tue Sep 04, 2007 3:43 pm

Post » Wed Jun 20, 2012 6:25 am

There is always a valid reference to a running quest. I haven't needed any "magic number" to use the other globals I have in the script (Cropped them out above because they don't relate to anything in the scripts being affected...if you really NEED to see them, here is the complete script (though the only variable I'm having trouble with ATM is NavigationOrgItem - it sets in the first update cycle, as evidenced by the fact that the quest's initial update cycle stops and doesn't updata again until the function call.

Becuase it IS initializing, I shouldn't NEED to ever call the function. The !Gvar.NavigationOrgItem check should be false. I only put the check in there in the first place because somehow it wasn't loading the rest of the variables later on.

Why this particular script can't call member functions of an obviously running quest (The global variable quest is always running, by definition) I reallly don't know. This has worked before, and I don't know why it isn't now.

Spoiler
Scriptname RedwoodsTools extends Quest{ Global functions used by Redwood's Mods }import gameimport utilityimport mathbool Function IsBetween(Float B, Float A, Float C) global	if A > C &&  ( A > B && B > C)		return TRUE	elseif A < C && (A < B &&  B < C)		return TRUE	elseif A == C && A == B ; Special case,all equal		return TRUE	endif	return FALSEendFunctionFloat Function DistanceBetween(Objectreference A,ObjectReference B) global ; Returns the distance between 2 objectreferences	return A.GetDistance(B) ; Really just a way to call it without referencing one of the objects in the call.EndFunctionint function RollDice(int Number, int type) global ; Return the result of rolling number Dice with type sides each.	int count=0	int Value=http://forums.bethsoft.com/topic/1362320-ok-im-stumpedfunction-not-calling/0	while count < Number		Value += RandomInt(1,type)		count += 1	endwhile	return Valueendfunctionfunction BounceItem(ObjectReference Item) global ; Add a random Havok Impulse to the item.	float X = (RollDice(1,360) as float)	float Y = (RollDice(1,360) as float)	float Z = (RollDice(1,360) as float)	float Force = (RollDice(1,99) as Float)	Item.ApplyHavokImpulse(X,Y,Z,Force)Endfunction; Variables for Linked List implementationActivator property NodeType Auto ; what type of object are we using as default nodes? Make sure to attach the linked list node script to said object type!FormList property RandomNodeType Auto ; Optional list of random object types for the nodes. Make sure the linked list node script is attatched to all such objects!LinkedListControls property LList Auto ; Dummy node used to call the node creation functions.ObjectReference property NodeAxis AutoActivator Property NodeAxisType Auto ; What type of object is the node axis?ObjectReference Property NodeAxisHideSpot Auto ; Where do we hide the node axis?LLNOrgItem Property NodeOrgItem Auto ; Tvar.NodeOrgItem = For the linked list testing spell, to handle list organization outside the effect.Activator Property NodeOrgItemType Auto ; = The item type for the above organizer item.LLNNavOrgScript Property NavigationOrgItem Auto; Tvar.NavigationOrgItem = The organizer item for Navigatiion node linked lists.Activator Property NavNodeOrgItemType Auto ; = The Item type for the above organizer item.\Bool Property MapRequest=False Auto ; Is there a ship trying to get a map and unable to find the map controller?LinkedListControls Property NavMapList Auto ; Gvar.NavMapList = List of maps for navigation control. Ordinary vanilla linked list.PyramidLLNControllerScript  Property RoomNodeControlItem Auto ; The Node Controller for the Pyramid Maze linked listsActivator Property RoomNodeControllerItemType Auto ; The Item Type for the above controller item.ObjectReference Function InitializeLL(ObjectReference NodeAxis,Activator NodeAxisType) Global	ObjectReference NewAxis	if !NodeAxis ; We haven't got a place to put node lists yet!		NewAxis = FindClosestReferenceOfTypeFromRef(NodeAxisType,Game.GetPlayer(),100000) ; Look for one.		if !NewAxis ; None in the cell!			NewAxis = Game.GetPlayer().PlaceAtMe(NodeAxisType,1,true) ; Emergency...make one!		endif	endif	return NewAxisEndFunctionLinkedListControls Function SetLList(ObjectReference NodeAxis,Activator NodeType) global ; Function to make a dummy node.	LinkedListControls NewLList	while !NewLList		NewLList = (NodeAxis.PlaceAtMe(NodeType,1,true) as LinkedListControls) ; Dummy Linked List node just to use to call functions.	endwhile	return NewLListEndFunctionEvent OnInit()	RegisterForSingleUpdate(1)EndEventbool  Property MapRequestBool AutoLLNNavOrgScript Function GetLLNO(RedwoodsTools SelfIn) Global	Return SelfIn.NavigationOrgItemEndFunctionFunction MapRequest(RedwoodsTools SelfIn) GlobalDebug.Notification("Map request Function Call");	If !SelfIn.MapRequestBool ; Will prevent multiple registrations;		SelfIn.MapRequestBool = True;		SelfIn.UnRegisterForUpdate();		SelfIn.RegisterForSingleUpdate(1);	Endif;	Utility.Wait(5);	SelfIn.MapRequestBool = FalseEndFunctionEvent OnUpdate() ; Checks periodically to make sure important global variables get filled when needed.Debug.Notification("Quest OnUpdate")	if !NodeAxisDebug.Notification("Quest OnUpdate: Initialize Node Axis")		NodeAxis = InitializeLL(NodeAxis,NodeAxisType)		NodeAxis.MoveTo(NodeAxisHideSpot)	elseDebug.Notification("Quest OnUpdate: Node Axis Initialized")	endif	if !LListDebug.Notification("Quest OnUpdate: Make Dummy Item")		LList = SetLList(NodeAxis,NodeType)	elseDebug.Notification("Quest OnUpdate: Dummy Item Initialized")	endif	if !NavigationOrgItemDebug.Notification("Quest OnUpdate: Make Navigation Org Item")		NavigationOrgItem = (NodeAxis.PlaceAtme(NavNodeOrgItemType,1) as LLNNavOrgScript)	elseDebug.Notification("Quest OnUpdate: Navigation Org Item Initialized")	endif	if !NodeAxis || !LList || !NavigationOrgItem		RegisterForSingleUpdate(5)	endifEndEvent; RedwoodsTools Property Gvar Auto  ; Insert this in any script using these globals.
User avatar
Nicole Kraus
 
Posts: 3432
Joined: Sat Apr 14, 2007 11:34 pm

Post » Wed Jun 20, 2012 4:55 pm

Yeah the quest seems to be running ok. (I'm assuming that it initialises long before the callers appear)

I'd try moving the calling objects code out of the OnInit event.

event OnInit()
registerforsingleupdate(1)
endevent

auto state startup
event OnUpdate()
; your old OnInit code here.
gotostate("")
endevent
endstate
User avatar
Nicole Mark
 
Posts: 3384
Joined: Wed Apr 25, 2007 7:33 pm


Return to V - Skyrim