Medabev Posted August 5, 2018 Share Posted August 5, 2018 (edited) 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 August 6, 2018 by Juebev Link to comment Share on other sites More sharing options...
TheWormpie Posted August 6, 2018 Share Posted August 6, 2018 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 More sharing options...
Medabev Posted August 6, 2018 Author Share Posted August 6, 2018 (edited) 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 August 6, 2018 by Juebev Link to comment Share on other sites More sharing options...
TheWormpie Posted August 6, 2018 Share Posted August 6, 2018 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 More sharing options...
Medabev Posted August 6, 2018 Author Share Posted August 6, 2018 (edited) 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 August 6, 2018 by Juebev Link to comment Share on other sites More sharing options...
TheWormpie Posted August 7, 2018 Share Posted August 7, 2018 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 More sharing options...
Medabev Posted August 7, 2018 Author Share Posted August 7, 2018 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 More sharing options...
Medabev Posted August 8, 2018 Author Share Posted August 8, 2018 (edited) 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 August 8, 2018 by Juebev Link to comment Share on other sites More sharing options...
Evangela Posted August 8, 2018 Share Posted August 8, 2018 (edited) 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 August 8, 2018 by Rasikko Link to comment Share on other sites More sharing options...
Medabev Posted August 8, 2018 Author Share Posted August 8, 2018 (edited) 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 August 8, 2018 by Juebev Link to comment Share on other sites More sharing options...
Recommended Posts