Jump to content

Desperately Need Help Scripting!


elseagoat

Recommended Posts

Basically, I have 3 IMODs. An Intro, Loop, and Outro.

 

 

I have a Magic Effect (place hazard) spell. It has a duration of 40.

 

I have tried this numerous times in different ways, but this is what I need to happen.

 

 

Quote

When I cast the spell, it should place an activator at the player's location with a script. Some script, attached to something somewhere, needs to do the following.

 

If the player enters a radius around the activator, it plays the Intro IMOD, then pops to the Loop.

 

If the player exits the radius, it pops the Loop to the Outro.

 

If the duration of the magic effect ends (40s) while the player is within the radius, then the activator should be deleted and the Loop IMOD should pop to Outro.

 

If the duration of the magic effect ends (40s) while the player is outside the radius, then the activator should be deleted, no IMOD.

 

If the Player prematurely casts the same spell again thus creating another activator of the same type, while within the radius, it should remove the previous activator only.

 

If the player prematurely casts the same spell again thus creating another activator of the same type, while outside of the radius, it should remove the previous activator AND play Intro, and then pop to Loop.

 

If the player fast travels away, or goes to a loading screen, the activator is removed and all IMODs are removed.

 

 

I have almost given up on this. No matter what I do it wont work. I have tried putting scripts on the activator, to no avail. Then I can't seem to do anything about the caster prematurely casting another spell creating a new activator before the old one despawns, thus causing them to fight each other and do crazy things to the IMODs.

 

I tried putting it on the magic effect of the spell. This didn't work at all, the activator spawns, the IMOD intro goes and then pops to the loop, then I am permanently stuck in the IMOD and the activator stays permanently, either that, OR the activator doesnt get disabled when I recast the spell despite Event OnEffectFinish() DisableNoWait() Delete(), it is like recasting the spell does zilch to the previous effect when it should be ending it.

 

I tried making a brand new magic effect that modifies a null peak value.

 

I tried using keywords to dispel the previous effect if you cast it again.

 

Nothing seems to work.

 

 

 

Thank you for your time reading this, I am really getting desperate here.

Link to comment
Share on other sites

That's a lot of stuff. Hard to get a good feel for the whole picutre. Have you looked at that guys mod with his soul harvest spell? he has a lot of the elements you're talking about. Also detects pretty well when actors leave his area. The thread is right around here somewhere... post named something about looking for feedback on new spell.
Link to comment
Share on other sites

That's a lot of stuff. Hard to get a good feel for the whole picutre. Have you looked at that guys mod with his soul harvest spell? he has a lot of the elements you're talking about. Also detects pretty well when actors leave his area. The thread is right around here somewhere... post named something about looking for feedback on new spell.

 

 

I am that guy XD.

 

 

The spell works, I am just trying to make it flashier and all my attempts have failed.

 

 

I'll try more specific questions.

 

Is there some function or some way to send an event to a script attached to another object reference somewhere in the world? Other than updating it? Or perhaps is there a way to set a variable from false to true through a script attached to something else?

 

 

Say I spawn an activator with a script on it, that does an onupdate event every second. I need to be able to send some sort of information, either by triggering an event on that activator or changing a bool variable from true to false when the character casts a spell. Can you make your own global variables? Is it possible to send information from one script to another through properties by maybe doing a full property inside of an event so that the property does get() each time the event runs?

Link to comment
Share on other sites

It's possible to access the properties and functions of one script through another script, provided that you know what the other script is attached to.

 

ScriptName MyActivatorScript extends ObjectReference


Event OnLoad()

;below is some code to figure out if there's another activator within a 1 cell radius
;we try to find a random activator in the radius with our base object
;so the random activator might even be ourself!
;that's why we give 25 tries to find one that's not ourself
;pretty unlikely to only find ourself in 25 tries unless there isn't another activator
int count = 0
while (count < 25)
	ObjectReference OldActivator = Game.FindRandomReferenceOfTypeFromRef(GetBaseObject(), Self, 4096.0)
	if (OldActivator != Self)
		count = 25
	endif
endwhile
if (OldActivator != Self)	;we found another activator than ourself!
	(OldActivator as MyActivatorScript).DoSomething()
	;we used casting to tell the OldActivator to run the DoSomething() function from its MyActivatorScript
	;if the OldActivator does not have MyActivatorScript, nothing happens
endif

EndEvent


Function DoSomething()

Disable()
Delete()

EndFunction

Link to comment
Share on other sites

It's possible to access the properties and functions of one script through another script, provided that you know what the other script is attached to.

 

ScriptName MyActivatorScript extends ObjectReference


Event OnLoad()

;below is some code to figure out if there's another activator within a 1 cell radius
;we try to find a random activator in the radius with our base object
;so the random activator might even be ourself!
;that's why we give 25 tries to find one that's not ourself
;pretty unlikely to only find ourself in 25 tries unless there isn't another activator
int count = 0
while (count < 25)
	ObjectReference OldActivator = Game.FindRandomReferenceOfTypeFromRef(GetBaseObject(), Self, 4096.0)
	if (OldActivator != Self)
		count = 25
	endif
endwhile
if (OldActivator != Self)	;we found another activator than ourself!
	(OldActivator as MyActivatorScript).DoSomething()
	;we used casting to tell the OldActivator to run the DoSomething() function from its MyActivatorScript
	;if the OldActivator does not have MyActivatorScript, nothing happens
endif

EndEvent


Function DoSomething()

Disable()
Delete()

EndFunction

 

 

Is "self" something i can use in any objectreference script to refer to the specific reference the script is running on? Because I never saw that in the wiki and it is that kind of simple stuff that I always get stumped on because the wiki seems to just assume that we know that, if I am correct in understanding.

 

I am unfamiliar with "Casting." The wiki is rather vague, or rather, it uses terminology that I do not know. I have no experience with programming or scripting of any kind, so can this be explained in idiot terms for me?

 

 

 

So with this script, what would be an appropriate radius to search for? Would it instead be possible to use locations (if I am correct in understanding locations, they are the names of the areas you are in rather than XYZ) so that way you wouldn't have to use some redicuously large radius like 999999999.9 to ensure the player isn't casting the spell far away?

 

 

Also, I have been trying to reliably create a way to determine when a player enters or exits a certain range of the activator and this is causing some problems. Sould I just repeatedly use registerforsingleupdate() and onupdate() while using some boolean with if statements to make sure that it only triggers once when the player enters or exits rather than continuously while the player remains in or out of the radius?

 

One last question. Is it at all possible to "delay" the execution of a function, say, the IMOD PopTo function, without pausing the entire script with Utility.Wait()?

 

 

You are amazing dude for your help, this script you posted really helps me out, I didn't even realize half that stuff existed. I have been hesitant to use while loops but you showed me how simple it is to emulate a break function as there is in other scripting languages. If Self does what I think it does, then that is immensely helpful as well. Once I understand casting, that looks to be immensely useful.

Edited by elseagoat
Link to comment
Share on other sites

Self does mean what you think it does. Of course, you should only use it in ObjectReference or Actor scripts. Using it in a magic effect or reference alias script won't get you anything.

 

I've never used casting before trying out Papyrus either. How to explain it... Well first I think I need to explain inheritance.

 

You could think of some scripts as parents of another script. For example, the Actor script extends the ObjectReference script. That means you can think of ObjectReference as the parent of Actor. So actors can use any functions that will work for object references. And since the Form script is the script that every other script extends, any script can use functions from the Form script..

 

So now you know about inheritance. Casting would be trying to get it to do things in reverse. So if you cast an ObjectReference as an Actor, you can use the Actor functions on the ObjectReference. Of course, the casting wouldn't be successful unless the ObjectReference really was an actor.

 

You might wonder why would you need casting instead of just declaring the ObjectReference as an Actor in the first place. Well, if you used an OnActivate event for example, it gives an ObjectReference as whatever did the activation. So even though you're sure it was an actor who activated the object, you would need to cast that ObjectReference as an Actor.

 

Another way to simulate a break function is to just use the 'Return' commnad. But I didn't use it in this case because if I did, it wouldn't process any of the code I wrote after the while loop either.

 

As I've already said, I have never even looked at an IMOD before. No idea how to get that working for you, sorry.

Link to comment
Share on other sites

Self does mean what you think it does. Of course, you should only use it in ObjectReference or Actor scripts. Using it in a magic effect or reference alias script won't get you anything.

 

I've never used casting before trying out Papyrus either. How to explain it... Well first I think I need to explain inheritance.

 

You could think of some scripts as parents of another script. For example, the Actor script extends the ObjectReference script. That means you can think of ObjectReference as the parent of Actor. So actors can use any functions that will work for object references. And since the Form script is the script that every other script extends, any script can use functions from the Form script..

 

So now you know about inheritance. Casting would be trying to get it to do things in reverse. So if you cast an ObjectReference as an Actor, you can use the Actor functions on the ObjectReference. Of course, the casting wouldn't be successful unless the ObjectReference really was an actor.

 

You might wonder why would you need casting instead of just declaring the ObjectReference as an Actor in the first place. Well, if you used an OnActivate event for example, it gives an ObjectReference as whatever did the activation. So even though you're sure it was an actor who activated the object, you would need to cast that ObjectReference as an Actor.

 

Another way to simulate a break function is to just use the 'Return' commnad. But I didn't use it in this case because if I did, it wouldn't process any of the code I wrote after the while loop either.

 

As I've already said, I have never even looked at an IMOD before. No idea how to get that working for you, sorry.

 

 

 

Makes perfect sense! Thanks!

 

IMODs are pretty simple. Think of them like a sheet of clear colored plastic that you can slide over the lens of a camera to film stuff tinted in a different color. Most spells cause them to happen, so you get a brief "blue" tint when casting a banish spell, for example.

 

THey can also be animated, so you can have an IMOD that fades from normal veiw to a darker veiw, and IMODs also control cool stuff like contrast, color, blur, and even the brightness of the sun. My first attempt, as seen in the video, simply placed a dark black color overlay on the screen, which is why it looks like crap. After playing with the saturation, blur, sunlight values, I have made an intro, outro, and looping IMOD that looks good and I can successfuly get them to play. I just have trouble when you cast the spell before the previous one has ended, causing the scripts to do conflicting things, such as removing IMODs prematurely.

 

How they are scripted to work is a little confusing to me. Most spells don't have scripts that make them appear on your screen, yet somehow they do.

 

Banish is a good example.

 

I have reason to believe that vanilla spells have some sort of quest script or something (which I am unfamiliar with, I don't even know where to go to find vanilla quest scripts or what they are attached to. I guess there is a quest dropdown in the object window that has that stuff. But anyways, I guess there is some quest that is always active which checks the keywords on the player when he is casting.

 

The reason I think this is because when you look at vanilla master spells, like Blizzard, where you wind up a two handed cast and cannot move while you are casting it and play a special animation, this is actually caused by a keyword attached to the magic effect.

 

The keyword is either WISpellDangerous or RitualSpellEffect, and I do not know which. So something is looking for that keyword and forcing the caster to play the unique animation and prevent him from moving. I would wager the same thing is happening with most IMODs.

 

 

 

However, you can do something like write a magic effect script that causes IMODs to appear as well. I have had good success in timing them so that the loop IMOD plays immediately when the intro one finishes, and whatnot. IMODs can be referenced through properties and they have their own functions, such as PopTo, Play, and Remove. So in a script, you simple have your normal events and functions and if statements like any other, and just put in the popto and remove functions when you want a specific imod to play or go away. Its that simple.

 

 

 

 

So when I ask if it is possible to delay a function other than using utility.wait(), so that the script keeps running but the specific function just happens after some period of time, I mean for any function, not just imods.

 

Again, many thanks!

Link to comment
Share on other sites

That's a lot of stuff. Hard to get a good feel for the whole picutre. Have you looked at that guys mod with his soul harvest spell? he has a lot of the elements you're talking about. Also detects pretty well when actors leave his area. The thread is right around here somewhere... post named something about looking for feedback on new spell.

 

 

I am that guy XD.

 

Lol! I was so thinking that when I typed that. I was just too lazy to go check.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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