Jump to content

[LE] (TIMED) Magical Ambush Script. A Script I wanted to Share (and possibly some input on improving it!))


Medabev

Recommended Posts

Hello everyone! Hope all is well. :laugh:

 

Been working on my Worldspace project on and off for awhile and I'm int the midst of polishing. However one thing I wanted for a long long time was Night time spawns. Even though There's a system like this already in vanilla - I have no idea how to use the Story Manager(find it too confusing) and I find Night time spawns in Vanilla to be alittle too "slowpace" for my liking. I couldn't find exactly what I was looking for to get an idea what I wanted or how to get this thing working. I've learned about Events and functions and what not, but I'm still "new" at this. Well after many hours and months of trial, error and frustration, I finally did it.

 

I created this Trigger so that when the player enters, there's a chance (Currently set at 50% Chance out of 100) they are jumped by 8 enemies, (Along with an explosion and player Stagger) not only that but there's a setting to make sure that this trigger activates and deactivates based off the ingame time.

 

I've read about "player.placeatme" how it can cause savebloat though its not really an issue if the placed references are deleted when no longer needed. I've tried to do this but I was unsuccessful. so I modified another script that does something similar and instead have NPC's in a separate Cell and will always move to the player if its the appropriate chance.

 

I've been testing it out in-game and it works really good. I still can't believe it compiled to be honest. Here it is:

Scriptname NTS_MagicAmbushScript extends ObjectReference  
{Thank you David Brashers for Public Domain Script)
{Magic Ambush Script, Used to spawn Random ambushes depending on time of day, needs a seperate cell to hook up NPCs}
;***************************************************

Actor Property PlayerRef  Auto  

Actor Property AABRREF1  Auto  
Actor Property AABRREF2  Auto  
Actor Property AABRREF3  Auto  
Actor Property AABRREF4  Auto
Actor Property AABRREF5  Auto  
Actor Property AABRREF6  Auto  
Actor Property AABRREF7  Auto  
Actor Property AABRREF8  Auto   

GlobalVariable Property GameHour  auto
{You need to autofill this property from the CK}

Int Property iChance auto
{Set Chance for Ambush to happen}

float Property EnableTime = 6.0 auto
{Enable me at about 6am by default}

float Property DisableTime = 24.0 auto
{Disable me at about midnight by default}

bool Property DeleteMe = TRUE auto
{Delete me after disabling me}

Explosion Property ExplosionIllusionLight01 Auto
{Explosion when Ambush Appears}
Explosion Property ExplosionIllusionMassiveLight01 Auto
{Big Explosion when Ambush Appears}


;***************************************************

Event OnInit()
{A bit of idiot proofing...}

; make sure sensible values have been set
If EnableTime < 0.0 || EnableTime > 24.0
EnableTime = 6.0 ; failsafe default
EndIf

; make sure sensible values have been set
If DisableTime < 0.0 || DisableTime > 24.0
DisableTime = 24.0 ; failsafe default
EndIf

EndEvent


;***************************************************

Event OnLoad()

CheckTime() ; check the time and spawn/disable me as required
; Debug.Notification("[TimedSpawnControl] OnLoad Completed.")

EndEvent

;***************************************************

Event OnUpdateGameTime()

CheckTime() ; check the time and spawn/disable me at calculated intervals

EndEvent

;***************************************************


Event OnTriggerEnter(ObjectReference akActionRef)
if(akActionRef == Game.GetPlayer())
If IsActiveTime()
Int iRandom = Utility.RandomInt(1,100)
If (iRandom <= iChance)
self.placeAtMe(ExplosionIllusionLight01)
utility.wait(0.75)
self.placeAtMe( ExplosionIllusionMassiveLight01)
self.KnockAreaEffect(1, 900)

AABRREF1.Resurrect()
AABRREF1.Disable()
AABRREF1.Enable()
AABRREF1.SetAV ("Aggression", 2)
AABRREF1.MoveTo(PlayerREF)
AABRREF2.Resurrect()
AABRREF2.Disable()
AABRREF2.Enable()
AABRREF2.SetAV ("Aggression", 2)
AABRREF2.MoveTo(PlayerREF)
AABRREF3.Resurrect()
AABRREF3.Disable()
AABRREF3.Enable()
AABRREF3.SetAV ("Aggression", 2)
AABRREF3.MoveTo(PlayerREF)
AABRREF4.Resurrect()
AABRREF4.Disable()
AABRREF4.Enable()
AABRREF4.SetAV ("Aggression", 2)
AABRREF4.MoveTo(PlayerREF)
AABRREF5.Resurrect()
AABRREF5.Disable()
AABRREF5.Enable()
AABRREF5.SetAV ("Aggression", 2)
AABRREF5.MoveTo(PlayerREF)
AABRREF6.Resurrect()
AABRREF6.Disable()
AABRREF6.Enable()
AABRREF6.SetAV ("Aggression", 2)
AABRREF6.MoveTo(PlayerREF)
AABRREF7.Resurrect()
AABRREF7.Disable()
AABRREF7.Enable()
AABRREF7.SetAV ("Aggression", 2)
AABRREF7.MoveTo(PlayerREF)
AABRREF8.Resurrect()
AABRREF8.Disable()
AABRREF8.Enable()
AABRREF8.SetAV ("Aggression", 2)
AABRREF8.MoveTo(PlayerREF)
endif
endif
endif
EndEvent


;***************************************************

Function CheckTime()
{Decide whether to spawn the actor or disable and delete it}

; Debug.notification("[TimedSpawnControl] CheckTime was called.")

If IsActiveTime()
If !PlayerRef
; Debug.Notification("[TimedSpawnControl] Spawning an actor...")
AABRREF1.Resurrect()
AABRREF1.SetAV ("Aggression", 2)
AABRREF1.MoveTo(PlayerREF)
AABRREF2.Resurrect()
AABRREF2.SetAV ("Aggression", 2)
AABRREF2.MoveTo(PlayerREF)
AABRREF3.Resurrect()
AABRREF3.SetAV ("Aggression", 2)
AABRREF3.MoveTo(PlayerREF)
AABRREF4.Resurrect()
AABRREF4.SetAV ("Aggression", 2)
AABRREF4.MoveTo(PlayerREF)
AABRREF5.Resurrect()
AABRREF5.SetAV ("Aggression", 2)
AABRREF5.MoveTo(PlayerREF)
AABRREF6.Resurrect()
AABRREF6.SetAV ("Aggression", 2)
AABRREF6.MoveTo(PlayerREF)
AABRREF7.Resurrect()
AABRREF7.SetAV ("Aggression", 2)
AABRREF7.MoveTo(PlayerREF)
AABRREF8.Resurrect()
AABRREF8.SetAV ("Aggression", 2)
AABRREF8.MoveTo(PlayerREF)

If AABRREF1.IsDisabled()
If AABRREF2.IsDisabled()
If AABRREF3.IsDisabled()
If AABRREF4.IsDisabled()
If AABRREF5.IsDisabled()
If AABRREF6.IsDisabled()
If AABRREF7.IsDisabled()
If AABRREF8.IsDisabled()

; Debug.Notification("[TimedSpawnControl] Actor was disabled. Enabling.")
AABRREF1.Enable()
AABRREF2.Enable()
AABRREF3.Enable()
AABRREF4.Enable()
AABRREF5.Enable()
AABRREF6.Enable()
AABRREF7.Enable()
AABRREF8.Enable()
Else
; Debug.Notification("[TimedSpawnControl] Actor exists, enabling it...")
AABRREF1.Enable()
AABRREF2.Enable()
AABRREF3.Enable()
AABRREF4.Enable()
AABRREF5.Enable()
AABRREF6.Enable()
AABRREF7.Enable()
AABRREF8.Enable()
EndIf
EndIf
Else
EndIf
EndIf
Else
If AABRREF1.Disable()
AABRREF1= NONE
If AABRREF2.Disable()
AABRREF2= NONE
If AABRREF3.Disable()
AABRREF3= NONE
AABRREF3.Disable()
If AABRREF4.Disable()
AABRREF4= NONE
If AABRREF5.Disable()
AABRREF5= NONE
AABRREF5.Disable()
If AABRREF6.Disable()
AABRREF6= NONE
If AABRREF7.Disable()
AABRREF7= NONE
If AABRREF8.Disable()
AABRREF8= NONE
EndIf
EndIf
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
EndFunction

;***************************************************

bool Function IsActiveTime()
{Returns TRUE if current time is within the active time range}

bool bTimeRange = false
float fGHour = GameHour.GetValue()

If (DisableTime >= EnableTime)
bTimeRange = (fGHour >= EnableTime) && (fGHour < DisableTime)
Else
bTimeRange = (fGHour >= EnableTime) || (fGHour < DisableTime)
EndIf

; Debug.Notification("[TimedSpawnControl] IsActiveTime returned: " + bTimeRange)

Return bTimeRange

EndFunction

;***************************************************

float Function GetInterval()
{Calculate the time interval for the next update call}

float int1
float int2
float newinterval
float fGHour = GameHour.GetValue()

; Debug.Notification("[TimedSpawnControl] GetInterval called")

If EnableTime >= fGHour
Int1 = EnableTime - fGHour
Else
Int1 = EnableTime - fGHour +24
EndIf
                
If DisableTime >= fGHour
Int2 = DisableTime - fGHour
Else
Int2 = DisableTime - fGHour +24
EndIf

If Int1 <= Int2 ; choose the smallest time interval
newinterval = Int1
Else
newinterval = int2
EndIf

If newinterval < 0.167
newinterval = 0.167 ; set the minimum update interval to about 10 game minutes
EndIf

; Debug.Notification("[TimedSpawnControl] The next update will be in " + newinterval + " hours.")
Return newinterval

EndFunction

;***************************************************

 

 

 

Anyway I'm pretty happy with the script all things considering and I wanted to share it just in case someone out there needed something similar. If there's any glaring issues with the script, let me know! I'm still testing it but I feel its pretty good right now to share. Thank you all for reading and I hope you all have a great week and enjoy the script for those looking for a "niche" Script such as this :tongue:

 

EDIT: Cleaned up abit thanks to wormple12! Many thanks friend.

 

 

 

PS: If you're reading this, Thank you to ReDragon2013, Steve40 for your assistance making this Frankenstein of a script. Your input helped me make this thing and learn quite abit about scripting allowing me to go back and modify and improve other aspects of my project.

Edited by Juebev
Link to comment
Share on other sites

Allright, first of all, you should really use a property array for your actors, and utilize while loops to make your script shorter and more readable.

 

So instead of using 8 different properties, use:

Actor[] property AABRREFs auto ; array containing all of your actors

Then you can change a lots of things to while loops, for instance in the OnTriggerEnter part of the script:

; after self.KnockAreaEffect

int iCount = 0
while iCount < AABRREFs.Length ; this meaning: do the following as long as iCount is less than the number of actors placed in my array (the length)

  AABRREF[iCount].Resurrect()
  AABRREF[iCount].Disable() ; disablenowait() might be faster here
  AABRREF[iCount].Enable() ; enablenowait() might be faster here
  AABRREF[iCount].SetAV("Aggression", 2)
  AABRREF[iCount].MoveTo(PlayerRef)
  iCount += 1 ; add 1 to iCount

endwhile

Also, you should only Delete() your actors if they were placed via PlaceAtMe. Otherwise, it's enough to just disable them and move them back to their editor location, so that they are ready to be used again. Anyway, now that I'm looking at it, it appears to me that the DeleteMe variable, and the part of the script linked to that, might just be leftovers from when you started with PlaceAtMe?

Link to comment
Share on other sites

Heya Wormple.

 

Ah, you know I didn't even think about making the script shorter while working on it if I intended to share it. I'll have to go back and try cleaning up with the property array then cause I do agree its a lot right now. The Delete() was originally used when I attempted to use placeatme (and a failed attempt to randomize actors) but then I realize it was probably better to keep it there to clean up corpses. But your right, it doesn't need that cause it doesn't use placeatme so I'll go and tweak that too - Right now I have a problem with ash piles and Ghostly remains being everywhere but I realize thats probably something else dealing with vanilla and with the script.

Thanks a lot! I'll try and post a more cleaner version of the script if I manage to get it to complile haha.

 

 

EDIT: Got rid of Delete() and it still works! so I'm happy about that. I'll update the OP if I manage to get the Array working

	Else
		If 	AABRREF1.Disable()
			AABRREF1= NONE
	If 		AABRREF2.Disable()
			AABRREF2= NONE
	If 		AABRREF3.Disable()
			AABRREF3= NONE
			AABRREF3.Disable()
	If 		AABRREF4.Disable()
			AABRREF4= NONE
	If 		AABRREF5.Disable()
			AABRREF5= NONE
			AABRREF5.Disable()
	If 		AABRREF6.Disable()
			AABRREF6= NONE
If 			AABRREF7.Disable()
			AABRREF7= NONE
If 			AABRREF8.Disable()
			AABRREF8= NONE
			EndIf
		EndIf
	endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
EndFunction
Edited by Juebev
Link to comment
Share on other sites

 

Some things I'm concern about however :

 

-I've been placing a ton of them of varying sizes around and notice with bigger boxes the explosion will appear faraway within the box though the ambush will still appear. It works fine if the box is smaller but I'm wondering if I place too many trigger boxes will it ruin my stability of the game.

-using Leveled Actors, Npc's do change(every new saved game and would most= likely change with a cell reset.) , but with placeatme I'm sure they would change everytime a ambush appears. Not really a big deal.

 

-I would like to have a "Int chance" property that allows you to change the chance of an ambush without going in the source and modifying it, though I'm not sure if thats possible.

 

1. The first issue is because you place the explosions at "self" (the triggerbox itself), which means it will probably spawn at the center point of the triggerbox, while you spawn the actors at the player. OnTriggerEnter happens as soon as the player enters the border regions of the trigger box - this means that the bigger the box, the further away is the center point from the player, and therefore the further away the explosions will spawn from the player (and where the actors spawn). To solve this problem, you could make sure you spawn the explosions and the actors the same place. With a bit of math, one could also choose to spawn them at another specific point between the player and the triggerbox center. I can find the math for you if you want (I've just been helped by another user in this exact matter ;) )

 

2. When you've made optimized the script a bit, as you say you will, I can help you add the PlaceAtMe functionality, so that it's possible for you to get more variation in your ambushes via Leveled Actors.

 

3. This should be rather simple. Create a int property (I'm calling it "iChance" in this instance), then replace your lines with

Int iRandom = Utility.RandomInt(1,100)
If (iRandom <= iChance)
Link to comment
Share on other sites

Heya again wormple!


Wow I can't believe that was the case when it comes to the explosions, one time I tried it I suspected that but thought it was far too simple to actually be the cause; guessed I overthinked it haha. It's a simple thing, I'll just make sure I position the triggerbox properly along the terrain. I cleaned it up alittle bit and I just LOVE the fact now I can adjust the Chance now, It's so much more fun. I'm just little aggravated that all I had to do was had a int property; again me over thinking stuff again. I updated the OP with the iChance function as its much superior to what I had originally.



As far as the property array, I've added a new property,rewrote OnTriggerEnter section (along with the other parts of the script) but it's not compiling and it insists that its a function. I have no doubt I'm doing something wrong but I'll keep at it. I just hope whoever may want to use the script can read it , if they plan on making changes for their own needs in the meantime.
Edited by Juebev
Link to comment
Share on other sites

Yep, thankfully, not everything is as complicated as one might think :)

 

As far as the property array, I've added a new property,rewrote OnTriggerEnter section (along with the other parts of the script) but it's not compiling and it insists that its a function. I have no doubt I'm doing something wrong but I'll keep at it. I just hope whoever may want to use the script can read it , if they plan on making changes for their own needs in the meantime.

 

When you think you've done what you can on your own, and the compiler still complains, you're welcome to drop your updated script in here (perhaps inside a 'spoiler', this can be chosen with the Special BBCode button in the upper left corner.) Then I'll have a look and tell what you're missing.

Link to comment
Share on other sites

Yep, thankfully, not everything is as complicated as one might think :smile:

 

As far as the property array, I've added a new property,rewrote OnTriggerEnter section (along with the other parts of the script) but it's not compiling and it insists that its a function. I have no doubt I'm doing something wrong but I'll keep at it. I just hope whoever may want to use the script can read it , if they plan on making changes for their own needs in the meantime.

 

When you think you've done what you can on your own, and the compiler still complains, you're welcome to drop your updated script in here (perhaps inside a 'spoiler', this can be chosen with the Special BBCode button in the upper left corner.) Then I'll have a look and tell what you're missing.

 

 

Wow thanks alot, I really appreciate it! I've been on a positive high cause of that script I got caught up clean up my other ones! Right now I'm attempting to polish another one of my scripts; cause you know its funny, when I first started doing this it was extremely daunting and frustrating. But spending some time learning how this stuff works is extremely satisfying and rewarding.

 

After I'm done with my project, I would love to release documents and scripting knowledge I learned to help anyone else who may need it. But yeah I feel like I'm making some progress with the script, I think I'll spend a day or so with trail and error and If I don't get it I'll contact you or just post on this thread if its still around!

Link to comment
Share on other sites

One of my older scripts are being real difficult with me right now. It was working fine before but then It won't work now, if it has the same time like the script above., for instance putting it with the same time (ex: 19.0 - 5.) will cause the script to do absolutely nothing. Setting it to (6. -24.) however and it works fine. It's weird and frustrating. Just posting this here just incase , I don't think this script has anything to do with it but it's extremely weird it won't work if it has the same time.

Anyway the original script I had just hid certain objects at certain times, It should be a relatively simple script and I assumed it wouldn't give me problems. I found this script awhile ago on the wiki and I really liked it. I don't know why it decided not to work if I set the script above to have the same time as this one.

 

My Magical ambush script still works great this entire time at least, so it leads me to believe maybe theres a conflict or something?

 

Scriptname Secret_Objects_Script extends ObjectReference  
;====================================================

Bool Property bEnableStuff Auto
Float Property fHourToDisable Auto ; Desired enable time/18.0 for example's sake
Float Property fHourToEnable Auto ; Desired enable time/6.0 for example's sake
Float Property fUpdateInterval Auto ; 15.0 works well and isn't too frantic.
GlobalVariable Property GameHour Auto
ObjectReference Property kYourObject Auto ; Pointed to your statue or object that is to enable
ObjectReference Property kYourObject2 Auto ; Pointed to your statue or object that is to enable
ObjectReference Property kYourObject3 Auto ; Pointed to your statue or object that is to enable
ObjectReference Property kYourObject4 Auto ; Pointed to your statue or object that is to enable

 
Event OnInit()
	RegisterForSingleUpdate(fUpdateInterval)
	bEnableStuff = !kYourObject.IsDisabled()
	bEnableStuff = !kYourObject2.IsDisabled()
	bEnableStuff = !kYourObject3.IsDisabled()
	bEnableStuff = !kYourObject4.IsDisabled()	
	ToggleEnableStateIfApplicable()
EndEvent
 
Event OnUpdate()
	ToggleEnableStateIfApplicable()
	RegisterForSingleUpdate(fUpdateInterval)
EndEvent
 
Function ToggleEnableStateIfApplicable()
	Float fTime = GameHour.GetValue()
	If bEnableStuff != (fTime > fHourToEnable && fTime < fHourToDisable)
		bEnableStuff = !bEnableStuff
		If bEnableStuff
			kYourObject.Enable()
			kYourObject2.Enable()
			kYourObject3.Enable()
			kYourObject4.Enable()
		Else
			kYourObject.Disable()
			kYourObject2.Disable()
			kYourObject3.Disable()
			kYourObject4.Disable()
		EndIf
	EndIf
EndFunction

 

 

Edited by Juebev
Link to comment
Share on other sites

I'm assuming you are reversing the enable/disable state of the four objects before everything else, as they are being assigned to the same variable. What's going on there is, the variable will contain the last property. I've never seen such logic used before. I would have made a bool array and stored the return values from all 4 objects.

Edited by Rasikko
Link to comment
Share on other sites

Well good news and Bad news and what I'm currently doing:
Good news, I believe I have a better grasp on arrays and I can see how they would be extremely useful when handling multiple objects. I believe I manage to declare an array and I even have access to the UI window. Now I can see how it easy it would be just to add items into that list and let the script do the rest.

Bad news, trying to modify the above script has been rather confusing using this new knowledge:

 

 

 

Scriptname Secret_Objects_Script extends ObjectReference

 

ObjectReference[] Property MyObjects Auto
 
Bool Property bEnableStuff Auto
Float Property fHourToDisable Auto ; Desired enable time/18.0 for example's sake
Float Property fHourToEnable Auto ; Desired enable time/6.0 for example's sake
Float Property fUpdateInterval Auto 
GlobalVariable Property GameHour Auto
 
;=============================
 
 
Event OnInit()
RegisterForSingleUpdate(fUpdateInterval)
int iCount = 0
while iCount <  MyObjects.Length ; 
MyObjects [iCount]
MyObjects[iCount].Disable()
MyObjects[iCount].Enable()
  iCount += 1 ; add 1 to iCount
ToggleEnableStateIfApplicable()
Endwhile
EndEvent
 
 
;==============================
 
 
 
Event OnUpdate()
ToggleEnableStateIfApplicable()
RegisterForSingleUpdate(fUpdateInterval)
EndEvent
 
 
 
;=============Function============
 
Function ToggleEnableStateIfApplicable()
Float fTime = GameHour.GetValue()
If bEnableStuff != (fTime > fHourToEnable && fTime < fHourToDisable)
bEnableStuff = !bEnableStuff
If bEnableStuff
MyObjects.Enable()
Else
MyObjects.Disable()
endIf
endIf
EndFunction

 

 

 

 

 

Basically getting these compiled errors

Enable is not a function or does not exist
Disable is not a function or does not exist

So I'm assuming that its not as easy as I thought it would off the bat and I'm most likely screwing up my functions somehow. I do know that I gotta let the script know how many objects I want it to handle, but then I'm not sure because I could just select whatever through the UI property window.

 

 

But I'll keep at it; at least it feels like I'm making progress to making this thing work

Edited by Juebev
Link to comment
Share on other sites

  • Recently Browsing   0 members

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