Jump to content

Cant use RegisterforSingleUpdate on quest script? help?


Recommended Posts

Hi guys, im trying to follow the instructions for dynamically attaching scripts to objects here... https://www.creationkit.com/index.php?title=Dynamically_Attaching_Scripts

 

I made the first quest like the site instructs, and put a script on a reference alias pointing to a formlist of trees, that compiles fine but for some reason i dont get the debug when hitting a tree with the woodcutters axe -

Scriptname SM_Woodcutter_QST extends ReferenceAlias

FormList Property SM_Tree_Cut_List Auto
FormList Property SM_Tree_Harvist_List Auto
Keyword property Woodcutter_Axe Auto

Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack,  bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
;	If akTarget
  		 RegisterForHitEvent(Self)
			Debug.notification("player hit something")
;	Endif
	if (akAggressor == Game.GetPlayer())
		if (akSource.HasKeyword(WoodCutter_Axe) || akSource.HasKeyword(Woodcutter_axe))
			Debug.notification("player hit a tre")
		endif
	endif
EndEvent

I figure that i might not be getting the debug becaus the aliases need to be reset or something, so the site says to make a second quest that will periodically reset the aliases...

 

But ive ran into a huge problem...

When trying to comiple the second quest that the site instructs me to make i get a compile error saying -

(6,1): RegisterForSingleUpdate is not a function or does not exist
(21,1): RegisterForSingleUpdate is not a function or does not exist
(9,0): new event onupdate cannot be defined because the script is not flagged as native
Compilation failed.

This is the second quest script im trying to compile, its almost a direct copy paste from the site.

Scriptname SM_Woodcutter_Qst_Reset extends Quest

Quest Property SM_Woodcutter_Qst Auto
 
Event OnInit()
	RegisterForSingleUpdate(5)
EndEvent
 
Event OnUpdate()
    SM_Woodcutter_Qst.Stop()
        int i = 0
        while !SM_Woodcutter_Qst.IsStopped() && i < 50
            Utility.Wait(0.1)
            i += 1
        endWhile
 
    SM_Woodcutter_Qst.Start()
	RegisterForSingleUpdate(5)
EndEvent

Does anyone know why RegisterforSingleUpdate is not recognised?

Is the second Quest script strictly necissary?

and most importantly... how can i get this to work?

 

Link to comment
Share on other sites

A reference alias stores only one reference, for what you want to do you would need to use a RefCollection Alias.

Scriptname SM_Woodcutter_QST extends RefCollectionAlias

FormList Property SM_Tree_Cut_List Auto ; you would need to set this list as condition for the collection (IsInList) so it gets filled by objects that match the ones in this list
FormList Property SM_Tree_Harvist_List Auto ; and another collection for this type
Keyword property Woodcutter_Axe Auto

Event OnHit(ObjectReference akSenderRef, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	If akAggressor == Game.GetPlayer() && akSource.HasKeyword(Woodcutter_axe)
		Debug.notification("Player hit on " + akSenderRef + " with a  Weapon, Spell, Explosion, Ingredient, Potion, or Enchantment that has the keyword Woodcutter_axe")
	Endif
EndEvent

This other script is unnecessary, because what it does is restart the quest so the reference alias is filled with another object, since the previous script is for a refcollectionalias you don't need to do that, but just in case you want to use a referencealias instead: The OnUpdate event is for Skyrim, in fallout 4 you need to use OnTimer instead:

Scriptname SM_Woodcutter_Qst_Reset extends Quest

Quest Property SM_Woodcutter_Qst Auto
 
int myTimerId = 33; its just an identificator for the timer, it is optional, just to know what timer has arrived in OnTimer.

Event OnQuestInit()
	StartTimer(5, myTimerId)
EndEvent
 
Event OnTimer(int aiTimerID)
	If myTimerId == aiTimerID
		SM_Woodcutter_Qst.Stop()
		Int i = 0
		while !SM_Woodcutter_Qst.IsStopped() && i < 50
			Utility.Wait(0.1)
			i += 1
		endWhile
		SM_Woodcutter_Qst.Start()
		StartTimer(5, myTimerId)
	EndIf
EndEvent
Link to comment
Share on other sites

ah damn, im not sure what's going wrong but it still doesnt seem to work :sad:

 

I've put formlists in ReferenceCollectionAlias's for the trees, and attached this script to each CollectionAlias -

I've also added the "IsInList" condition for each CollectionAlias -

Scriptname SM_Woodcutter_QST extends RefCollectionAlias

FormList Property SM_Tree_Multiple_List Auto
FormList Property SM_Tree_Big_List Auto
FormList Property SM_Tree_Small_List Auto

FormList Property SM_Tree_Harvist_List Auto
Keyword property Woodcutter_Axe Auto

;	Event OnHit(ObjectReference akSenderRef, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)

	If akAggressor == Game.GetPlayer() && akSource.HasKeyword(Woodcutter_axe)
		Debug.notification("Player hit tree with axe")
	;		if SM_Tree_Multiple_List.HasForm(akSenderRef)
			if SM_Tree_Multiple_List.HasForm(akTarget)
				Debug.notification("Multiple trees detected")
			EndIf
	;		if SM_Tree_Big_List.HasForm(akSenderRef)
			if SM_Tree_Big_List.HasForm(akTarget)
				Debug.notification("Big tree detected")
			EndIf
	;		if SM_Tree_Small_List.HasForm(akSenderRef)
			if SM_Tree_Small_List.HasForm(akTarget)
				Debug.notification("Small tree detected")
			EndIf
	Endif
EndEvent

i had to mark out the lines with "akSenderRef" and replace it with "akTarget" because i was getting this compile error when trying the "akSenderRef" version of the code you wrote for me.

(10,0): the parameter types of function onhit in the empty state on script sm_woodcutter_qst do not match the original script scriptobject
No output generated for SM_Woodcutter_QST, compilation failed.

I have a feeling that it will not work with akTarget, and that akSenderRef is correct, but i cant get the OnHit event to compile with a different paramitor other than "akTarget".

 

i also made that second quest script, even though you say its not necissary, just incase it makes a difference... and it doesnt make any difference, i still cant get the debug from hitting a tree :sad: ((here it is anyway))

Scriptname SM_Woodcutter_Tree_Cut_Qst_Reset extends Quest

Quest Property SM_Woodcutter_Tree_Cut_Qst Auto
 
int myTimerId = 33

Event OnQuestInit()
	StartTimer(5, myTimerId)
EndEvent
 
Event OnTimer(int aiTimerID)
	If myTimerId == aiTimerID
		SM_Woodcutter_Tree_Cut_Qst.Stop()
		Int i = 0
		while !SM_Woodcutter_Tree_Cut_Qst.IsStopped() && i < 50
			Utility.Wait(0.1)
			i += 1
		endWhile
		SM_Woodcutter_Tree_Cut_Qst.Start()
		StartTimer(5, myTimerId)
	EndIf
EndEvent

((i changed the quest names so they looked better in the ck, but that is the only change i made))

 

Try as i might i just cant get this functioning, and i cant get the debug :sad:

 

-

-

-

EDIT**

 

i managed to get the "akSenderRef" version of OnHit compiling like this ->

Event OnHit(ObjectReference akSenderRef, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)

it seems i needed "string apMaterial" as a parameter, and not necissarily "akTarget"

...

but ive just tested it in game and i still dont get a debug from hitting a tree.

Any idea whats going wrong here?

Edited by SandMouseAnarchy
Link to comment
Share on other sites

Well, debug it... First check what references are actually filling the RefCollection alias, you can use a quest script like this:

 

RefCollectionAlias Property MyCollectionOfTrees Auto

 

Event OnQuestInit()

Debug.MessageBox("There are " + MyCollectionOfTrees.GetCount() + " trees in the collection")

EndEvent

 

Or, in the RefCollection Script, set a shader to the trees in the onload event

 

EffectShader Property MyEffectShader Auto

 

Event OnLoad(ObjectReference akSenderRef)

MyEffectShader.Play(akSenderRef)

EndEvent

 

You need to make sure that your collection is being filled.

Edited by DieFeM
Link to comment
Share on other sites

ah, i really do learn something new everytime you reply DieFeM haha, thankyou again mate!!

 

ok, so, i did as you said, i added the code to a quest, and added a fireFX shader to the alias. it all compiled, and when testing it in game i got a message pop up saying that one single tree is in the collection... i was stood at the redrocket for testing, but i couldnt see a burning tree anywhere.

 

but hey, some limited success, so now i know atleast one tree is in the collection.

 

ill experiment with different shaders to see if i can spot this singular tree in my collection ((the fire fx i used might not be showing for whatever crazy reason)) and see if i can indeed get a hit event from it.

but it raises the question - how do i get every tree in the loaded area into my collection? ((every tree in game is already in my formlist for testing))

Link to comment
Share on other sites

ah yes, you are a legend DieFeM, i wouldnt have thought to put "0" in the "Max Initial Fill Count"!

 

So, i did that and now i get a message in game saying some 530 trees are now in the collection. Perfect!

But, i cant see a fire effect shader on any of them, and i still dont get a debug notification from hitting the tree. very, very odd.

 

Im not sure at all what is stopping the OnHit event from firing, but atleast we know the collection is being filled.

Im going to try stripping the script down again and see what happens...

 

Any ideas on where to go next mate?

 

 

 

 

-

EDIT**

Ive now tried a bunch of different fx shaders for the trees, and none of them are showing on the trees, i have tried walking the whole map hitting every tree on the way - nothing - i even took a stroll off the map, did some saving and loading and fast travelling to different cells, but still nothing.

 

I tried stripping the script down to debug ->


FormList Property SM_Tree_Multiple_List Auto
Keyword property Woodcutter_Axe Auto
EffectShader Property MyEffectShader Auto


Event OnLoad(ObjectReference akSenderRef)
    MyEffectShader.Play(akSenderRef)
EndEvent


Event OnHit(ObjectReference akSenderRef, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
	Debug.notification(" hit tree ")

	If akAggressor == Game.GetPlayer()
		Debug.notification("Player is agressor ")
	EndIf
	If akSource.HasKeyword(Woodcutter_axe)
		Debug.notification("aksource is woodcutter axe ")
	EndIf

	if SM_Tree_Multiple_List.HasForm(akSenderRef)
	        Debug.notification("Multiple trees detected")
	EndIf
EndEvent

And i still dont get a notification from hitting the trees :sad:

i dont get the akAgressor debug, i dont get the axe keyword debug, i dont even get the "hit tree" debug right after the OnHit event... its leading me to believe that the problem is with the OnHit event itself, but im not sure how to debug this script any further?

 

Edit2**

 

Ive also tried ->

Event OnHit(ObjectReference akSenderRef, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
    akAggressor = Game.GetPlayer()
	Debug.notification(" hit tree ")
EndEvent

But still noting...

Edited by SandMouseAnarchy
Link to comment
Share on other sites

Well, the collection automatically listens for ObjectReference events and, if the alias is an actor, also for Actor events.

But if you look at the documentation you would notice that the OnHit event is an ScriptObject event, so you need to register for it.

 

Function RegisterForHitEvent(ScriptObject akTarget, ScriptObject akAggressorFilter = None, Form akSourceFilter = None, \
Form akProjectileFilter = None, int aiPowerFilter = -1, int aiSneakFilter = -1, int aiBashFilter = -1, int aiBlockFilter = -1, \
bool abMatch = true) native

 

Looking at the description of the arguments for RegisterForHitEvent you'll see:

 

akTarget: The ObjectReference, ReferenceAlias or RefCollectionAlias that is being hit.

 

So, instead of registering for it in the collection script I would do it in the quest script, using the RefCollectionAlias as akTarget.

RefCollectionAlias Property MyCollectionOfTrees1 Auto
RefCollectionAlias Property MyCollectionOfTrees2 Auto
Keyword property Woodcutter_Axe Auto

Event OnQuestInit()
	Debug.MessageBox("There are " + MyCollectionOfTrees1.GetCount() + " trees in the collection 1")
	Debug.MessageBox("There are " + MyCollectionOfTrees2.GetCount() + " trees in the collection 2")
	
	RegisterForHitEvent(akTarget = MyCollectionOfTrees1, akAggressorFilter = Game.GetPlayer(), akSourceFilter = Woodcutter_Axe)
	RegisterForHitEvent(akTarget = MyCollectionOfTrees2, akAggressorFilter = Game.GetPlayer(), akSourceFilter = Woodcutter_Axe)
EndEvent

Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
	If MyCollectionOfTrees1.Find(akTarget) > -1
		;Do something for trees in collection 1
	EndIf
	If MyCollectionOfTrees2.Find(akTarget) > -1
		;Do something for trees in collection 2
	EndIf
EndEvent
Link to comment
Share on other sites

  • Recently Browsing   0 members

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