Blicking Effect Shader

Post » Mon Aug 30, 2010 8:34 am

I'm having a bit of trouble with a shader effect. Here's a screenshot of the parameters:
http://img13.imageshack.us/img13/1746/shadera.jpg

I'm using it in a mod that adds heat vision, and whenever the heat vision is active this effect is attached to all actors that are around. The problem is that it does occasionally blink (the membrane effect is gone and reappears again). The more particles I add, the more likely the blinking. If i deactive the particle shader, the blinking is gone completely. I also suspect it might have something to do with the way I refresh the effect every second (remove and add again), but again: no particle shader - no problems. Is there something I can do about it other than to decrease the particle count, and what excactly is the problem anyway?

E: Oh no, topic typo... cool new forum, doesnt even let you edit the topic... *blames someone else* :D
User avatar
HARDHEAD
 
Posts: 3499
Joined: Sun Aug 19, 2007 5:49 am

Post » Mon Aug 30, 2010 6:30 am

Is there no way you can refrain from refreshing the effect every second? I would bet that is the problem. If you could just keep the effect 'on' until such time you turn it 'off' I believe it would stop flckering. How are you refeshing it? What's the script or settings look like that perform the refresh? Perhaps there is a better way.
User avatar
Kortniie Dumont
 
Posts: 3428
Joined: Wed Jan 10, 2007 7:50 pm

Post » Mon Aug 30, 2010 8:50 am

I think you're right about the refreshing. Here's the relevant part of the script:
;--------------------------------------------------------------------; 21 - Heat vision - idleelseif state == 21	if shaderTimer > 0		set shaderTimer to shaderTimer - getSecondsPassed	else		set shaderTimer to 2		set depth to (player.isInInterior == 0)		set obj to apple		set obj to (getFirstRef 200 depth 0)		Label 1		if obj != 0			if obj.getIsCreatureType 6 == 0				if obj.getDead == 0					obj.sms HPOVHeatVisionShader					obj.pms HPOVHeatVisionShader 10				else					obj.sms HPOVHeatVisionShader2					obj.pms HPOVHeatVisionShader2 10				endif			endif							set obj to apple			set obj to getNextRef			goto 1		endif	endif	if switchMode == 0 && reset == 0		return	endif	set switchMode to 0	set state to 22	return


What's missing is some sort of isShaderPlaying. I have to refresh it constantly because new actors may join the perimeter, so I thought that this might actually be the easiest solution. I could try it with tokens but normally I wanted to avoid that.
User avatar
Travis
 
Posts: 3456
Joined: Wed Oct 24, 2007 1:57 am

Post » Mon Aug 30, 2010 10:53 am

Since your using a duration for your PMS, why do you need the SMS? Could you not just re-apply the PMS and skip the SMS? Or would that then play the shader twice. Sorry, I haven't tried that myself to know the answer.

As an alternative, and to overly complicate things, could you add the Actor references to a form list with http://geck.gamesas.com/index.php/ListAddReference, play the shader indefinitely upon those actors, then when the effect is ended (I don't know if these are equipped glasses or whatever), go through the form list and apply the sms to all entries in the list?

Or just apply SMS to those references that get too far away?
User avatar
Nicole M
 
Posts: 3501
Joined: Thu Jun 15, 2006 6:31 am

Post » Sun Aug 29, 2010 11:36 pm

Since your using a duration for your PMS, why do you need the SMS? Could you not just re-apply the PMS and skip the SMS? Or would that then play the shader twice. Sorry, I haven't tried that myself to know the answer.

As an alternative, and to overly complicate things, could you add the Actor references to a form list with http://geck.gamesas.com/index.php/ListAddReference, play the shader indefinitely upon those actors, then when the effect is ended (I don't know if these are equipped glasses or whatever), go through the form list and apply the sms to all entries in the list?

Or just apply SMS to those references that get too far away?

Re-applying wont work, the effects are stacking :( At first I thought the same about using lists (too complicated), but after reading what you said I thought about it again and it should only require a few extra lines to make that work, so I'll give it a try. Thanks :)
User avatar
Soku Nyorah
 
Posts: 3413
Joined: Tue Oct 17, 2006 1:25 pm

Post » Mon Aug 30, 2010 3:39 am

If your effect is a long duration, like an equipped armor or the like, that form list can get huge and become a problem, so you may have to have an additional way of having actors removed from the list and the SMS applied to them (like being out of sight http://cs.elderscrolls.com/constwiki/index.php/GetLOS or the like).
User avatar
Matthew Barrows
 
Posts: 3388
Joined: Thu Jun 28, 2007 11:24 pm

Post » Mon Aug 30, 2010 10:00 am

If your effect is a long duration, like an equipped armor or the like, that form list can get huge and become a problem, so you may have to have an additional way of having actors removed from the list and the SMS applied to them (like being out of sight http://cs.elderscrolls.com/constwiki/index.php/GetLOS or the like).

Yes, I was thinking something like 2 form lists A B, B contains the actors found during the last ref walk and A the ones for the current.
Then:
(Phase 1: Tracking of new actors)
1. Clear A.
2. Ref walk: add all found actors to A. For every actor in A and not in B play shader visuals on him.
(Phase 2: Removing old actors)
1. List walk B. If actor is in B but not in A stop shader visuals
2. Clear B and copy A to B.
User avatar
Eddie Howe
 
Posts: 3448
Joined: Sat Jun 30, 2007 6:06 am

Post » Sun Aug 29, 2010 9:18 pm

Very crafty idea! I'd like to hear how it goes.
User avatar
Hannah Whitlock
 
Posts: 3485
Joined: Sat Oct 07, 2006 12:21 am

Post » Mon Aug 30, 2010 2:35 am

Groar.. rage :D

Where is the problem:
PrintToConsole "Obj: %i", objset i to (obj.listAddReference HPOVVisionModeAList)PrintToConsole "Index: %.0f", iset check to listGetNthForm HPOVVisionModeAList iPrintToConsole "Check: %i", checkset i to (obj.isInList HPOVVisionModeAList)PrintToConsole "inList: %.0f", iset i to (listGetFormIndex HPOVVisionModeAList obj)PrintToConsole "index: %.0f", i


Output:
Obj: #12345678
Index: 0
Check: #12345678
inList: 0
index: -1

Shouldn't at least listGetFormIndex return 0 here? I tried about every combination, it's always the same :(
User avatar
Robert Garcia
 
Posts: 3323
Joined: Thu Oct 11, 2007 5:26 pm

Post » Mon Aug 30, 2010 4:26 am

After spending some 4+ hours on this, trying it out myself, I have come to this conclusion:

You may be able to add references to form lists, but you cannot get references from form lists. In the end, I tried this out in a cell with only one NPC, Frank.
I added him sucessfully, using ListAddReference command in a Ref Walk, but when I tried to get the Ref from the form list, the game reported it was an Enclave HellFire Trooper whose ID was FF000800. This made no sense to me at all as my Ref ID for Frank was 0604BA7E. Also, the ListGetNthForm is one less than the reported Count of the Form list. When I used ListGetCount on my form list, it returned 1. But to get any results with ListGetNthForm, I had to use (Count - 1). So the form index seems to starts at 0. All in all, unless I am missing something fundamental, ListAddReference is useless.
User avatar
OnlyDumazzapplyhere
 
Posts: 3445
Joined: Wed Jan 24, 2007 12:43 am

Post » Mon Aug 30, 2010 6:33 am

Thanks for testing it, good to know it wasn't caused by a mistake a made somewhere. I also noticed that the index is off by one when iterating through the list, but for the first index it seems to match, so maybe something like:
0: element 1
1: element 1
2: element 2
...
The problem is not only listAddReference. Any attempt to add an NPC found during a ref walk to a list and then using isInList or listgetformindex failed. This also hold when waiting several frames. For example:

(Just a messy debug code snapshot:)
				PrintToConsole "Obj: %i", obj				if once == 0								set once to 1								listAddForm HPOVVisionModeAList obj				endif				set check to listGetNthForm HPOVVisionModeAList 0				PrintToConsole "Check: %i", check				set mylist to HPOVVisionModeAList				set i to (obj.isInList mylist)				PrintToConsole "inList: %.0f", i				set i to (listGetFormIndex mylist obj)				PrintToConsole "index: %.0f", i				set i to (obj == check)				PrintToConsole "equal: %.0f", i				set i to ListGetCount HPOVVisionModeAList				PrintToConsole "count: %.0f", i

Output:

Obj: #12345678
Check: #12345678
inList: 0
index: -1
equal: 1
count: 1

I will implement a isInList function myself as getNthForm & equal seem to work to some extend, so at list I should not get any false negatives. However, based on the observation with the hellfire formid, it might produce false positives, but I'll see.

Did you find any combination of functions that fulfil
add(list, npcRef) -> isInList(list, npcRef) == true
?
User avatar
Alkira rose Nankivell
 
Posts: 3417
Joined: Tue Feb 27, 2007 10:56 pm

Post » Mon Aug 30, 2010 4:12 am

None what so ever. It seems that the only function that relates to references is the ListAddReference. All the other functions like IsInList & ListGetNthForm require that the form list be made up of base forms and not references. So, again, I have no idea what use ListAddReference is without the ability to retrieve or compare the information. Its like we need RefIsInList & ListGetNthRef commands instead. I might just look through the FOSE thread for any info on that and/or ask them wtf ListAddReference is used for.

You could store the reference's base form, but then how would you aplpy effects on a single reference. You couldn't. You'd have to apply them to all instances of that form which would, again, make it useless.

If I were you, I'd try another approach than using form lists (even though it was a great idea). Unfortunately, at the current moment, I can't think of any. :rolleyes:
User avatar
Ash
 
Posts: 3392
Joined: Tue Jun 13, 2006 8:59 am

Post » Mon Aug 30, 2010 1:03 am

If I were you, I'd try another approach than using form lists (even though it was a great idea). Unfortunately, at the current moment, I can't think of any. :rolleyes:

Well I could always just a custom function to check if the reference is in a list. I tried it like that and it seemed to work, though using built-in functions should be faster thats why I rather wanted to use one of those. But if there's no other way...
; 21 - Heat vision - idleelseif state == 21	if shaderTimer > 0		set shaderTimer to shaderTimer - getSecondsPassed	else		set shaderTimer to 2		set depth to (player.isInInterior == 0)		set obj to apple		set obj to (getFirstRef 200 depth 0)		Label 210		; Phase 1		if obj != 0			if obj.getIsCreatureType 6 == 0				obj.listAddReference HPOVVisionModeAList				set HPOVListManager.inputList to HPOVVisionModeBList 				set HPOVListManager.element to obj				setStage HPOVListManager 12				if HPOVListManager.found == 0					PrintToConsole "P1: Not in list B, starting shader"					obj.pms HPOVHeatVisionShader				endif			endif							set obj to apple			set obj to getNextRef			goto 210		endif		; Phase 2		set i to 0		set size to (listGetCount HPOVVisionModeBList)		Label 211		if i <= size			set obj to listGetNthForm HPOVVisionModeBList i			set HPOVListManager.inputList to HPOVVisionModeAList 			set HPOVListManager.element to obj			setStage HPOVListManager 12			if HPOVListManager.found == 0				PrintToConsole "P2: Not in list A, stopping shader"				obj.sms HPOVHeatVisionShader			endif				set i to i + 1			goto 211		endif		; Clear B		set HPOVListManager.inputList to HPOVVisionModeBList		setStage HPOVListManager 10		; Move A to B		set HPOVListManager.inputList to HPOVVisionModeAList		set HPOVListManager.outputList to HPOVVisionModeBList		setStage HPOVListManager 11	endif	if switchMode == 0 && reset == 0		return	endif	set switchMode to 0	set state to 22	return

Judging from the debug output, on cell transition old shaders are removed and new ones start playing, and the blinking is gone too (at least it seems so as of now)
User avatar
Cat
 
Posts: 3451
Joined: Mon Dec 18, 2006 5:10 am

Post » Mon Aug 30, 2010 9:05 am

I'd be interested to see how you setup set HPOVListManager in regards to this statement:

set HPOVListManager.inputList to HPOVVisionModeBList

Correct me if I'm wrong, but it looks like you set a quest variable to a form list. That would be news to me. Could you post the relavent quest script or the like? I am baffled as to how you did this.
User avatar
Richard Dixon
 
Posts: 3461
Joined: Thu Jun 07, 2007 1:29 pm

Post » Sun Aug 29, 2010 10:35 pm

I'd be interested to see how you setup set HPOVListManager in regards to this statement:

set HPOVListManager.inputList to HPOVVisionModeBList

Correct me if I'm wrong, but it looks like you set a quest variable to a form list. That would be news to me. Could you post the relavent quest script or the like? I am baffled as to how you did this.

It's one way to create callable functions (the other would be using onactivate, but I prefer stage functions). In case you didn't know it it's explained in the oblivion cs wiki somewhere (stage functions).

Since I'm using a lot of lists (and lists of lists), HPOVListManager contains utility functions for that. The quest script only contains the input/output parameters of the functions:
scn HPOVListManagerScript; - Permanent lists -; Stage 0 - For given list of lists and element, get the index of the first list containing element, or -1; Stage 1 - For given list of lists, element and index, save element in list at index and remove it from all other lists; Stage 2 - For given list of lists, element and index, remove element from list at index; Stage 3 - For given list of lists, element and index, add element to list at index; Stage 4 - For given list of lists, element and index, check if the element is in list at index; Stage 5 - For given list of lists, element, remove element from all lists; - Transient actor lists -; Stage 10 - For given list, delete all elements from input list; Stage 11 - For given lists, move all elements from input list to output list; Stage 12 - For given list and actor, is actor in list; In/Outref elementref inputListref outputListshort indexshort found


One example for a stage script (stage 12):
; Is element in list; Local Varsshort ishort sizeref inputListref elementref currentElement; Read & Clear Inputset inputList to HPOVListManager.inputListset element to HPOVListManager.elementset HPOVListManager.inputList to 0set HPOVListManager.element to 0set HPOVListManager.found to 0set i to 0set size to (listGetCount inputList)label 1if i <= size	set currentElement to listGetNthForm inputList i	if currentElement == element		set HPOVListManager.found to 1		return	endif		set i to i + 1	goto 1endifset HPOVListManager.found to 0


To see everything in context you can download the latest released version of the mod where this is used: http://fallout3nexus.com/downloads/file.php?id=11474
This doesn't contain the improved shader tracking yet though, but the ListManager is used for other stuff as well.

I hope this was indeed your question, and not just why a formlist can be assigned to a ref variable. For that I'd say that basically anything with a distinct formid can be assigned to a ref variable.
User avatar
laila hassan
 
Posts: 3476
Joined: Mon Oct 09, 2006 2:53 pm

Post » Sun Aug 29, 2010 10:14 pm

I am going to download your mod and take a good hard look at it. The part that most interests me is that you are somehow being able to use the List functions on references via your stage scripts where they (at least to me) would not work directly. I find this fascinating. To put it bluntly, I want to know how your were able to retrieve a reference from a form list using a stage script when using ListGetNthForm would not return a reference from a list. I don't understand how doing it from a quest stage script is any different than doing it directly. You obviously know something that I don't.

Cheers, and thanks
User avatar
Kayleigh Williams
 
Posts: 3397
Joined: Wed Aug 23, 2006 10:41 am

Post » Mon Aug 30, 2010 11:35 am

You said it yourself here, listgetNthForm works?
Also, the ListGetNthForm is one less than the reported Count of the Form list. When I used ListGetCount on my form list, it returned 1. But to get any results with ListGetNthForm, I had to use (Count - 1). So the form index seems to starts at 0.

(I think I misread that. Indices always start at 0, but with npcs it seemed to me that they were off by + or - 1, don't really remember)

That fact that listGetNthForm works has nothing to do with the stage function, it's just for convenience. My oberservation was: isInList or getFormListIndex always return false/-1, even if the actor was in the list. But getNthForm actually returns the reference (maybe at the wrong index though). So you can iterate through the list and search the element yourself.

E: So maybe when you tested it you added a reference to a list, tried to get it from the index position you assumed it was added to, and it did return something else/random. So you assumed that this function is completely broken for references, when in fact, the added element was somewhere in the list, just not at the position you were looking for.
User avatar
Casey
 
Posts: 3376
Joined: Mon Nov 12, 2007 8:38 am

Post » Mon Aug 30, 2010 12:46 am

Actually for every instance of a ref I added, ListGetNthForm returned the same value of FF000800. So that is why I thought it was broken. I could see past the index starting at 0, I just could not get ListGetNthForm to return a reference. I still can't. I have subsequently tried an alternate approach with ListRemoveNthForm wich does seem to return the reference. Perhaps I am not using ListGetNthForm in the right way. If you say it works, then I should do some more testing...
User avatar
-__^
 
Posts: 3420
Joined: Mon Nov 20, 2006 4:48 pm

Post » Mon Aug 30, 2010 2:39 am

Actually for every instance of a ref I added, ListGetNthForm returned the same value of FF000800. So that is why I thought it was broken. I could see past the index starting at 0, I just could not get ListGetNthForm to return a reference. I still can't. I have subsequently tried an alternate approach with ListRemoveNthForm wich does seem to return the reference. Perhaps I am not using ListGetNthForm in the right way. If you say it works, then I should do some more testing...


(Edit: Nevermind what was here before, it was my coding mistake)

Ok i tested it again, with 3 random references returned by an actor ref walk so the debug output is still readable.

1. add 3 elements:

Label 210; Phase 1if obj != 0 && count < 3 	if obj.getIsCreatureType 6 == 0 	obj.listAddReference HPOVVisionModeAList 	set count to count + 1 	PrintToConsole "Added %i", objendif


2. iterate through list and print elements
set i to 0set size to (listGetCount HPOVVisionModeAList)PrintToConsole "v1 Size: %.0f" sizeLabel 215if i <= size 	set obj to (listGetNthForm HPOVVisionModeAList i) 	PrintToConsole "v1 i:%.0f - %i" i, obj 	set i to i + 1 	goto 215endif


3. do the same inside a previously called stage function
set i to 0set size to (listGetCount inputList)PrintToConsole "v2 size: %.0f" sizelabel 1if i <= size 	set currentElement to listGetNthForm inputList i 	PrintToConsole "v2 i:%.0f - %i" i, currentElement  	set i to i + 1 	goto 1endif


Output screenshot:
http://img716.imageshack.us/img716/3646/formlist.jpg
(the trailing 0000000 is because i walked one index more than necessary just to be sure

Just so you see that I'm not making this up, iterating the list actually works for me.

.....

omg... the forum destroyed my post?
User avatar
Vicki Blondie
 
Posts: 3408
Joined: Fri Jun 16, 2006 5:33 am

Post » Sun Aug 29, 2010 7:51 pm

omg... the forum destroyed my post?

Lol, I've had a few of these myself.

Okay, so I don't know why, but now ListGetNthForm is returning the proper refs. I can only guess as to why it did not work for me earlier. I did have a more complex script and I was removing references from one list and trying to put them in another. But I swear I tried earlier to just do a ref walk and then display the refs via printc. Whatever, I see that ListGetNthForm does work. Funny, this thread started and I thought I was helping you, as it turns out, you are helping me.

Now to get a substitute for IsInList that works for refs.
User avatar
Raymond J. Ramirez
 
Posts: 3390
Joined: Sun Oct 14, 2007 8:28 am

Post » Mon Aug 30, 2010 12:44 am

omg... the forum destroyed my post?

Lol, I've had a few of these myself.

Okay, so I don't know why, but now ListGetNthForm is returning the proper refs. I can only guess as to why it did not work for me earlier. I did have a more complex script and I was removing references from one list and trying to put them in another. But I swear I tried earlier to just do a ref walk and then display the refs via printc. Whatever, I see that ListGetNthForm does work. Funny, this thread started and I thought I was helping you, as it turns out, you are helping me.

Now to get a substitute for IsInList that works for refs.

Who helps who... I say in the end we're both smarter than before :) About the fact that I didnt work previously, there were some strange things when I was testing too, and I suspected it was caused by saving/making changes/loading or something like that. And there's always the chance that saving screws up something with these lists, though I hope not. I saved and loaded a few times with the same version now, and it seems stable to me.
User avatar
Laurenn Doylee
 
Posts: 3427
Joined: Sun Dec 03, 2006 11:48 am

Post » Sun Aug 29, 2010 7:56 pm

I figured out why it didn't work for me before. It was my ref walking. I used this in the ref walk:

ListAddReference UCFXListNew rCurRef

Then changed to this:

rCurRef.ListAddReference UCFXListNew

The first compiled alright, but must not have been a correct syntax. Just me being oblivious.
User avatar
Shaylee Shaw
 
Posts: 3457
Joined: Wed Feb 21, 2007 8:55 pm

Post » Mon Aug 30, 2010 1:48 am

One question.

Wouldnt the nature of the list also effect this behavior? Meaning whether the list is an "Ordered" List or not. When it is NOT an ordered list, maybe when you add references, the formList puts them into order by FormID, so you can't be sure where it will be added.

Maybe to keep the order the way you want, you need to make sure the FormList is using the naming convention "xxxxxOrderedList"

Just a thought.
User avatar
Rik Douglas
 
Posts: 3385
Joined: Sat Jul 07, 2007 1:40 pm


Return to Fallout 3