SMB92 Posted May 24, 2017 Author Share Posted May 24, 2017 You don`t needÃÂ to keepÃÂ anyone as a variableÃÂ unless you areÃÂ going to run some other functions on them later. And youÃÂ needÃÂ ÃÂ toÃÂ run the function onÃÂ eachÃÂ spawned actor ( because you can have more than 1 spawned actors, ).ÃÂ Just a question, why doÃÂ ÃÂ youÃÂ need a linked ref?ÃÂ Actors usually have a default package to stay near editor location. ( the location where they were spawned in this case) ÃÂ While SpawnCounter > 0 ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ IfÃÂ ; your conditions for spawningÃÂ here ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ActorÃÂ MyActor = Self.PlaceActorAtMe(your data here, but the quantity should be 1)ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ MyActor.DeleteWhenAble() ; mark the actor as temporary so the game deletes him when the cell is detached ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ EndIf SpawnCounter = SpawnCounter - 1 ; doing this outside the "if" block allows to shorten the script EndWhileI link them to a patrol marker dynamically and they start patrolling the network of markers I have in place. Some spawns that I don't want to patrol will not have this code. Reason why I have made this network is that it is strongly noted by users of WOTC patrol AI was broken at some point. I was hoping that doing this would ensure it worked well always, and provided a patrol marker network other modders could use as well. And yes, I will probably want to run other functions later on, it will definitely be handy. Thanks for the optimization there too Link to comment Share on other sites More sharing options...
kitcat81 Posted May 24, 2017 Share Posted May 24, 2017 (edited) And yes, I will probably want to run other functions later on, it will definitely be handy. Thanks for the optimization there too I link them to a patrol marker dynamically and they start patrolling the network of markers I have in place. Some spawns that I don't want to patrol will not have this code. Reason why I have made this network is that it is strongly noted by users of WOTC patrol AI was broken at some point. I was hoping that doing this would ensure it worked well always, and provided a patrol marker network other modders could use as well.Not al all. Just note that setting linked ref creates persistence. And keeping/storing actors as variables makes them persistent too. You can`t delete a persistent ref while something keeps it persistent. It will get "D" flag (deleted) and it might become invisible, but it will be still be there untill you clear the variable or remove something that keeps it in the world. Edited May 24, 2017 by kitcat81 Link to comment Share on other sites More sharing options...
SMB92 Posted May 24, 2017 Author Share Posted May 24, 2017 And yes, I will probably want to run other functions later on, it will definitely be handy. Thanks for the optimization there too I link them to a patrol marker dynamically and they start patrolling the network of markers I have in place. Some spawns that I don't want to patrol will not have this code. Reason why I have made this network is that it is strongly noted by users of WOTC patrol AI was broken at some point. I was hoping that doing this would ensure it worked well always, and provided a patrol marker network other modders could use as well.Not al all. Just note that setting linked ref creates persistence. And keeping/storing actors as variables makes them persistent too. You can`t delete a persistent ref while something keeps it persistent. It will get "D" flag (deleted) and it might become invisible, but it will be still be there untill you clear  the variable or remove something that keeps it in the world.Ah very good! I'll unlink them as well, I would of missed that :P Link to comment Share on other sites More sharing options...
kitcat81 Posted May 24, 2017 Share Posted May 24, 2017 :) Good luck with it Link to comment Share on other sites More sharing options...
SMB92 Posted May 24, 2017 Author Share Posted May 24, 2017 Okay so learned the hard way Add() and Remove() no work on these arrays lol. Anyway this is the new script (compiled) for anyone interested: Scriptname ASC_SP_Random_R1 extends ObjectReference GlobalVariable Property ASC_Main_ModEnabled Auto GlobalVariable Property ASC_Main_RandomEnabled_R1 Auto GlobalVariable Property ASC_Main_Random_Chance_R1 Auto GlobalVariable Property ASC_Main_Random_DisableOnBlock_R1 Auto FormList Property ASC_ResetList_R1 Auto Actor Property PlayerRef Auto ActorBase property LvlRaider Auto ActorBase Property LvlGunner Auto ActorBase Property LvlForged Auto ActorBase Property LvlTriggerman Auto ObjectReference Property PatrolMarker Auto GlobalVariable Property ASC_Main_Difficulty_R1 Auto GlobalVariable Property ASC_Allowed_Raider_R1 Auto GlobalVariable Property ASC_Allowed_RaiderBoss_R1 Auto GlobalVariable Property ASC_Max_Allowed_Raider_R1 Auto GlobalVariable Property ASC_Max_Allowed_RaiderBoss_R1 Auto GlobalVariable Property ASC_Chance_Raider_R1 Auto GlobalVariable Property ASC_Reroll_Allowed_Raider_R1 Auto GlobalVariable Property ASC_Reroll_Chance_Raider_R1 Auto GlobalVariable Property ASC_Chance_RaiderBoss_R1 Auto GlobalVariable Property ASC_Allowed_Gunner_R1 Auto GlobalVariable Property ASC_Allowed_GunnerBoss_R1 Auto GlobalVariable Property ASC_Max_Allowed_Gunner_R1 Auto GlobalVariable Property ASC_Max_Allowed_GunnerBoss_R1 Auto GlobalVariable Property ASC_Chance_Gunner_R1 Auto GlobalVariable Property ASC_Reroll_Allowed_Gunner_R1 Auto GlobalVariable Property ASC_Reroll_Chance_Gunner_R1 Auto GlobalVariable Property ASC_Chance_GunnerBoss_R1 Auto GlobalVariable Property ASC_Allowed_Forged_R1 Auto GlobalVariable Property ASC_Allowed_ForgedBoss_R1 Auto GlobalVariable Property ASC_Max_Allowed_Forged_R1 Auto GlobalVariable Property ASC_Max_Allowed_ForgedBoss_R1 Auto GlobalVariable Property ASC_Chance_Forged_R1 Auto GlobalVariable Property ASC_Reroll_Allowed_Forged_R1 Auto GlobalVariable Property ASC_Reroll_Chance_Forged_R1 Auto GlobalVariable Property ASC_Chance_ForgedBoss_R1 Auto GlobalVariable Property ASC_Allowed_Tmen_R1 Auto GlobalVariable Property ASC_Allowed_TmenBoss_R1 Auto GlobalVariable Property ASC_Max_Allowed_Tmen_R1 Auto GlobalVariable Property ASC_Max_Allowed_TmenBoss_R1 Auto GlobalVariable Property ASC_Chance_Tmen_R1 Auto GlobalVariable Property ASC_Reroll_Allowed_Tmen_R1 Auto GlobalVariable Property ASC_Reroll_Chance_Tmen_R1 Auto GlobalVariable Property ASC_Chance_TmenBoss_R1 Auto GlobalVariable Property ASC_Reroll_Main_Chance_R1 Auto GlobalVariable Property ASC_Reroll_Main_R1 Auto GlobalVariable Property ASC_DeleteTimer_R1 Auto Int ChanceToSpawn = 0 Int Difficulty = 0 Int WhoToSpawn = 0 Int SpawnCounter = 0 Int SpawnCounterBoss = 0 Bool SpawnSuccess = false Bool Rerolled = false Actor Spawn = None Actor[] GroupList Int RespawnTimerTest = 10 Int GroupMember = 0 Bool SpawnPointLoaded = false Event OnCellAttach() SpawnPointLoaded = true if (Self.IsDisabled() == false) && (ASC_Main_ModEnabled.GetValueInt() == 1) && (ASC_Main_RandomEnabled_R1.GetValueInt() == 1) BeginActivation() endif EndEvent Event OnTimerGameTime(int aiTimerID) if aiTimerID == RespawnTimerTest Self.Enable() Debug.Notification("Point Rearmed") endif EndEvent Event OnCellDetach() SpawnPointLoaded = false Utility.Wait(10) if (SpawnPointLoaded == false) && (PlayerRef.IsInCombat() == false) while GroupMember > -1 GroupList[GroupMember].SetLinkedRef(None) GroupList[GroupMember].DeleteWhenAble() GroupList[GroupMember] = None GroupMember = GroupMember - 1 Debug.Notification("Member Removed From List") endwhile Debug.Notification("All members cleared from array") endif EndEvent Function BeginActivation() ChanceToSpawn = Utility.RandomInt(1,100) if (ChanceToSpawn <= ASC_Main_Random_Chance_R1.GetValueInt()) Spawn() Self.Disable() ASC_ResetList_R1.AddForm(Self) Debug.Notification("Controller Disabled and added to formlist") StartTimerGameTime(1, RespawnTimerTest) Debug.Notification("Respawn Timer On") elseif (ChanceToSpawn >= ASC_Main_Random_Chance_R1.GetValueInt()) && (ASC_Main_Random_DisableOnBlock_R1.GetValueInt() == 1) Self.Disable() ASC_ResetList_R1.AddForm(Self) else ;Nothing endif EndFunction Function RerollOnSuccess() if (SpawnSuccess == true) && (Rerolled == false) && (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) Spawn() Debug.Notification("Spawning another group!") else Difficulty = 0 WhoToSpawn = 0 SpawnSuccess = false Rerolled = false Spawn = none SpawnCounter = 0 SpawnCounterBoss = 0 Debug.Notification("Failed to Reroll another group!") endif EndFunction Function Spawn() Difficulty = ASC_Main_Difficulty_R1.GetValueInt() WhoToSpawn = Utility.RandomInt(1,4) if (WhoToSpawn == 1) && (ASC_Allowed_Raider_R1.GetValueInt() == 1) SpawnRaider() elseif (WhoToSpawn == 1) && (ASC_Allowed_Raider_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Raider_R1.GetValueInt() == 1) RerollRaiderR1() elseif (WhoToSpawn == 2) && (ASC_Allowed_Gunner_R1.GetValueInt() == 1) SpawnGunner() elseif (WhoToSpawn == 2) && (ASC_Allowed_Gunner_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Gunner_R1.GetValueInt() == 1) RerollGunnerR1() elseif (WhoToSpawn == 3) && (ASC_Allowed_Forged_R1.GetValueInt() == 1) SpawnForged() elseif (WhoToSpawn == 3) && (ASC_Allowed_Forged_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Forged_R1.GetValueInt() == 1) RerollForgedR1() elseif (WhoToSpawn == 4) && (ASC_Allowed_Tmen_R1.GetValueInt() == 1) SpawnTmen() elseif (WhoToSpawn == 4) && (ASC_Allowed_Tmen_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Tmen_R1.GetValueInt() == 1) RerollTmenR1() endif EndFunction Function SpawnRaider() SpawnCounter = ASC_Max_Allowed_Raider_R1.GetValueInt() GroupList = new Actor[GroupMember] Debug.Notification("Raider Spawning") while (SpawnCounter > 0) if (Utility.RandomInt(1,100) <= ASC_Chance_Raider_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounter = SpawnCounter - 1 endwhile if ASC_Allowed_RaiderBoss_R1.GetValueInt() == 1 SpawnCounterBoss = ASC_Max_Allowed_RaiderBoss_R1.GetValueInt() while (SpawnCounterBoss) > 0 if (Utility.RandomInt(1,100) <= ASC_Chance_RaiderBoss_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounterBoss = SpawnCounterBoss - 1 endwhile endif if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) RerollOnSuccess() endif EndFunction Function RerollRaiderR1() if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Raider_R1.GetValueInt()) Spawn() Rerolled = true Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Rerolling after Raiders Blocked") else Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Reroll on blocked Raiders denied") endif EndFunction Function SpawnGunner() SpawnCounter = ASC_Max_Allowed_Gunner_R1.GetValueInt() GroupList = new Actor[GroupMember] Debug.Notification("Gunner Spawning") while (SpawnCounter > 0) if (Utility.RandomInt(1,100) <= ASC_Chance_Gunner_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlGunner, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounter = SpawnCounter - 1 endwhile if ASC_Allowed_GunnerBoss_R1.GetValueInt() == 1 SpawnCounterBoss = ASC_Max_Allowed_GunnerBoss_R1.GetValueInt() while (SpawnCounterBoss) > 0 if (Utility.RandomInt(1,100) <= ASC_Chance_GunnerBoss_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlGunner, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounterBoss = SpawnCounterBoss - 1 endwhile endif if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) RerollOnSuccess() endif EndFunction Function RerollGunnerR1() if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Gunner_R1.GetValueInt()) Spawn() Rerolled = true Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Rerolling after Gunners Blocked") else Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Reroll on blocked Gunners denied") endif EndFunction Function SpawnForged() SpawnCounter = ASC_Max_Allowed_Forged_R1.GetValueInt() GroupList = new Actor[GroupMember] Debug.Notification("Forged Spawning") while (SpawnCounter > 0) if (Utility.RandomInt(1,100) <= ASC_Chance_Forged_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlForged, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounter = SpawnCounter - 1 endwhile if ASC_Allowed_ForgedBoss_R1.GetValueInt() == 1 SpawnCounterBoss = ASC_Max_Allowed_ForgedBoss_R1.GetValueInt() while (SpawnCounterBoss) > 0 if (Utility.RandomInt(1,100) <= ASC_Chance_ForgedBoss_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlForged, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounterBoss = SpawnCounterBoss - 1 endwhile endif if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) RerollOnSuccess() endif EndFunction Function RerollForgedR1() if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Forged_R1.GetValueInt()) Spawn() Rerolled = true Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Rerolling after Forgeds Blocked") else Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Reroll on blocked Forgeds denied") endif EndFunction Function SpawnTmen() SpawnCounter = ASC_Max_Allowed_Tmen_R1.GetValueInt() GroupList = new Actor[GroupMember] Debug.Notification("Tmen Spawning") while (SpawnCounter > 0) if (Utility.RandomInt(1,100) <= ASC_Chance_Tmen_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlTriggerman, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounter = SpawnCounter - 1 endwhile if ASC_Allowed_TmenBoss_R1.GetValueInt() == 1 SpawnCounterBoss = ASC_Max_Allowed_TmenBoss_R1.GetValueInt() while (SpawnCounterBoss) > 0 if (Utility.RandomInt(1,100) <= ASC_Chance_TmenBoss_R1.GetValueInt()) Spawn = Self.PlaceActorAtMe(LvlTriggerman, Utility.RandomInt(1,Difficulty), None) GroupList[GroupMember] = Spawn as Actor GroupList[GroupMember].SetLinkedRef(PatrolMarker) Debug.Notification("Array Success") Spawn = None SpawnSuccess = True endif GroupMember = GroupMember + 1 SpawnCounterBoss = SpawnCounterBoss - 1 endwhile endif if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) RerollOnSuccess() endif EndFunction Function RerollTmenR1() if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Tmen_R1.GetValueInt()) Spawn() Rerolled = true Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Rerolling after Tmens Blocked") else Difficulty = 0 WhoToSpawn = 0 Debug.Notification("Reroll on blocked Tmens denied") endif EndFunction Link to comment Share on other sites More sharing options...
kitcat81 Posted May 24, 2017 Share Posted May 24, 2017 Add and remove do work for arrays. May be it does not work for a reference, I did not try that, but it works for a form for sure. Link to comment Share on other sites More sharing options...
SMB92 Posted May 24, 2017 Author Share Posted May 24, 2017 Add and remove do work for arrays. May be  it does not work for a reference, I did not try that, but it works for a form for sure. Compiler carried on it wasn't a known function lol. So I done it like how you see above. I'm glad you mentioned the SetLinkedRef thing, because this Array is not working properly. It's not setting the LinkedRef to None. It's saying the Index is out of range in papyrus logs as well. Perhaps I should be declaring it as an array property, maybe it's not saving at the end of the function. Edit - maybe because I have declared it at a size of 0. Maybe i should declare it at the max spawn size first, and use the groupmember int to get where its actually filled to. That kind seems like its not a dynamic array though to me. Name of topic lol. Link to comment Share on other sites More sharing options...
JonathanOstrus Posted May 25, 2017 Share Posted May 25, 2017 (edited) Add and remove doà work for arrays.à May beà à it does not work for a reference, I did not try that, but ità works for aà form for sure.ÃCompiler carried on it wasn't a known function lol. So I done it like how you see above.à I'm glad you mentioned the SetLinkedRef thing, because this Array is not working properly. It's not setting the LinkedRef to None. It's saying the Index is out of range in papyrus logs as well. Perhaps I should be declaring it as an array property, maybe it's not saving at the end of the function.à Edit - maybe because I have declared it at a size of 0. Maybe i should declare it at the max spawn size first, and use the groupmember int to get where its actually filled to. That kind seems like its not a dynamic array though to me. Name of topic lol. I think the way you were addressing the arrays for add/remove was incorrect which was giving you problems. Your last posting with your updated script for adding entries to the array is possibly the better solution. I'm not sure of the performance impact of using Add on an array vs pre-defining the size and directly addressing the index. If you know ahead of time pre-defining might make the script a little faster. But Add will work regardless and in cases where you need to redefine the size. Though the removal could be done a few different ways. Here's some options. This sample code isn't complete as it's missing quite a few variable definitions. But using the same naming as your script it should be pretty easy to follow. Did I mention I tend to write more comment than code. Actor[] GroupList int iMaxGroupMembers Function addActors() GroupList = new Actor[0] int counter = 0 iMaxGroupMembers = 10 ; loop will be <, not <= because we want exactly 10 ; entries and the first index will be 0 so we want 0-9 while counter < maxCount GroupList.Add(self.placeActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), None)) ; counter is the index we just added because we just initialized the ; array. If you were adding to an existing one you would need to set ; some var to keep track of the position separate from the loop counter ; then use that here instead. That could be done with something like ; int iPosition = GroupList.Length - 1 ; use Length - 1 if you define after the add. GroupList[counter].SetLinkedRef(PatrolMarker) counter += 1 endWhile ; our GroupList is now Length of 10 with 10 unique instances of LvlRaider base. endFunction Function destroyActors1() ; we don't need a counter here because we're going to keep removing index 0 ; as long as our array has entries in it. while GroupList.Length > 0 GroupList[0].SetLinkedRef(None) GroupList[0].DeleteWhenAble() GroupList.Remove(0) ; this removes the first index we manipulated and ; shifts the entire index count. depending on the ; array size, using option 2 below might end up ; being faster. Profile testing would be needed. endWhile endFunction Function destroyActors2() ; this method will loop the entire array then just destroy the array int counter = 0 int iLength = GroupList.Length while counter < iLength GroupList[counter].SetLinkedRef(None) GroupList[counter].DeleteWhenAble() ; you don't need to set each index to none unless you wanted to hold ; the index and re-use it's position later for some reason counter += 1 endWhile GroupList = none ; could also just do GroupList.Clear() depending ; what you want the result to be. An empty array ; or an uninitialized array variable. endFunction Your original code Hi folks. I'm doing some study into using arrays with Papyrus, currently I'm looking at how I can use a dynamic array to do what I want. I've got a bout 6 or so wiki pages up that I've been reading through, as well as various example code I've looked at in War of the Commonwealth. I was hoping to get some advice on what I've learnt so far. First I'll say what I want to do with this and then I'll post the example code I just made. What we want to do is, dynamically create a list of Actors that spawn at a spawn point (that I've made) so I can do things with them later, such as disable them/delete them when they have been unloaded for some time. And I also want to destroy the array in that particular case so it's not making my spawnpoint persistent forever. You might say I can do that with PlaceAtMe function, but I need to use PlaceActorAtMe function, so I need to do this instead. Here is example/test code I wrote, with commentary: Event OnCellAttach ;Do what I need to do to get to Function Spawn(), if we do Spawn() EndEvent Function Spawn() if (WhoToSpawn == 1) && (1S_Allowed_Raiders_R1.GetValueInt() == 1) ;1 = Raiders, and are we allowed to spawn Raiders according to user settings SpawnCounter = 1S_Max_Allowed_Raiders_R1.GetValueInt() ;Maximum allowed units to spawn while (SpawnCounter > 0) if (Utility.RandomInt(1,100) >= 1S_Chance_Raiders_R1.GetValueInt()) ;Chance of a unit actually spawning (makes the spawn amounts a bit more dynamic) Actor[] SpawnList = new Actor[0] ;The list of Actors that will be controlled, maybe I should make this straight after the function call instead of in this block Spawn = Self.PlaceActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), R1_EZ) ;Place the spawn Spawn.SetLinkedRef(PatrolMarker) ;Set the NPC to use the Patrol marker network I've created, there is a starting marker next to each point (we use GetClosest function rather than property) SpawnList[GroupMembers].Add(Spawn as Actor) ;Add the spawnpoint to the array, GroupMarkers is a declared Int starting at 0. Not sure if this is correct method but for example only GroupMembers = GroupMembers + 1 ;Increment the index number + 1 SpawnCounter = SpawnCounter - 1 ;Lower spawn count remaining Spawn = None ;Ready for next actor SpawnSuccess = True ;This value is used for another function else SpawnCounter = SpawnCounter - 1 ;Lower spawn count on unsuccessful dice roll for dynamic group size endif endwhile endif EndFunction Event OnCellDetach SpawnPointLoaded = false Utility.Wait(10) if (SpawnPointLoaded = true) && (Player.IsInCombat == true) ;I'll figure out how to loop this efficiently eventually elseif (SpawnPointLoaded == false) && Player.IsInCombat == false) ;We can disable/delete or do stuff to the Actors in array if true) while GroupMemebers > -1 ;Not sure if this is what you do here SpawnList[GroupMembers].Remove() ;Remove the highest index actor from the list GroupMembers = GroupMembers - 1 ;And count down until the list is empty endwhile ; Whats the best way to destroy the array here so it's not saved endif EndEvent Your use of SpawnList[GroupMembers].Add(Spawn as Actor) is incorrect. You never defined anything that would match to SpawnList[GroupMembers]. The Add function needs the base array, in this case SpawnList. It adds to the end so GroupMembers is irrelevant here. You would do the entire add loop and then at the end of the loop set GroupMembers = SpawnList.Length. Though you could get the length at any time that way without needing the additional variable. The removal in your OP is workable if you specify the index to remove. array.Remove() is invalid. array.Remove(0) removes the first index. You can also use array.RemoveLast() which takes off the last entry. Edited May 25, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
tomomi1922 Posted May 25, 2017 Share Posted May 25, 2017 Wow, this looks complex. I haven't started learning coding for FO4 yet. But this looks like a variation of C. In most programming languages I know, if you declare a private variable, it will vanish along with the function once function finishes its operation? So instead of creating a global variable that lingers, why not creating a custom variable type and pass this array around like parameters between functions. Too many global variables can increase memory load, and if not cleaning properly can cause problems. Link to comment Share on other sites More sharing options...
JonathanOstrus Posted May 25, 2017 Share Posted May 25, 2017 (edited) Wow, this looks complex. I haven't started learning coding for FO4 yet. But this looks like a variation of C. In most programming languages I know, if you declare a private variable, it will vanish along with the function once function finishes its operation? So instead of creating a global variable that lingers, why not creating a custom variable type and pass this array around like parameters between functions. Too many global variables can increase memory load, and if not cleaning properly can cause problems.Yeah I generally dislike using Globals if possible. But in Papyrus GlobalVariable is something actually global to the game not the script. So it's a little different context. Then you have "local script variables" which are global to any functions in the script. Then there's local function variables. Which are exactly as it sounds. I was bored so I took the last piece of code and did some refactoring to make it a bit smaller. This is the refactored code. Also grouped the properties. If we wanted to get more advanced you could define a struct then pass an array of the struct then have the script loop the array of struct to decide what to spawn rather than having to hard code each type individually. The changes to the script aren't all that complex but having to re-input everything in the plugin would be tedious. The benefit to do this would be that adding additional spawn types later would be as easy as just setting the variables in CK. No script changes needed since it pulls it all from the vars. I'd also like to point out that the code originally (and still) uses the same lvl list to spawn both regular and boss actors. For future use you'd probably want to add additional boss lists. I also converted all the properties to const. This way if the plugin was ever updated the values would pass to the script. Otherwise when the script first fires and starts running it saves all those values inside the save file. If it's attached to a quest then it would never terminate and restart unless the quest was stopped and then restarted. Scriptname ASC_SP_Random_R1 extends ObjectReference GlobalVariable Property ASC_Main_ModEnabled Auto Const GlobalVariable Property ASC_Main_RandomEnabled_R1 Auto Const GlobalVariable Property ASC_Main_Random_Chance_R1 Auto Const GlobalVariable Property ASC_Main_Random_DisableOnBlock_R1 Auto Const FormList Property ASC_ResetList_R1 Auto Const Actor Property PlayerRef Auto Const ObjectReference Property PatrolMarker Auto Const GlobalVariable Property ASC_Main_Difficulty_R1 Auto Const GlobalVariable Property ASC_Reroll_Main_Chance_R1 Auto Const GlobalVariable Property ASC_Reroll_Main_R1 Auto Const GlobalVariable Property ASC_DeleteTimer_R1 Auto Const Group RaiderParams ActorBase property LvlRaider Auto Const GlobalVariable Property ASC_Allowed_Raider_R1 Auto Const GlobalVariable Property ASC_Allowed_RaiderBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Raider_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_RaiderBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Raider_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Raider_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Raider_R1 Auto Const GlobalVariable Property ASC_Chance_RaiderBoss_R1 Auto Const EndGroup Group GunnerParams ActorBase Property LvlGunner Auto Const GlobalVariable Property ASC_Allowed_Gunner_R1 Auto Const GlobalVariable Property ASC_Allowed_GunnerBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Gunner_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_GunnerBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Gunner_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Gunner_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Gunner_R1 Auto Const GlobalVariable Property ASC_Chance_GunnerBoss_R1 Auto Const EndGroup Group ForgedParams ActorBase Property LvlForged Auto Const GlobalVariable Property ASC_Allowed_Forged_R1 Auto Const GlobalVariable Property ASC_Allowed_ForgedBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Forged_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_ForgedBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Forged_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Forged_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Forged_R1 Auto Const GlobalVariable Property ASC_Chance_ForgedBoss_R1 Auto Const EndGroup Group TriggermenParams ActorBase Property LvlTriggerman Auto Const GlobalVariable Property ASC_Allowed_Tmen_R1 Auto Const GlobalVariable Property ASC_Allowed_TmenBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Tmen_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_TmenBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Tmen_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Tmen_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Tmen_R1 Auto Const GlobalVariable Property ASC_Chance_TmenBoss_R1 Auto Const EndGroup Bool Rerolled = false Actor[] GroupList Int RespawnTimerTest = 10 Bool SpawnPointLoaded = false Event OnCellAttach() SpawnPointLoaded = true if (Self.IsDisabled() == false) && (ASC_Main_ModEnabled.GetValueInt() == 1) && (ASC_Main_RandomEnabled_R1.GetValueInt() == 1) BeginActivation() endif EndEvent Event OnTimerGameTime(int aiTimerID) if aiTimerID == RespawnTimerTest Self.Enable() Debug.Notification("Point Rearmed") endif EndEvent Event OnCellDetach() SpawnPointLoaded = false Utility.Wait(10) if (SpawnPointLoaded == false) && (PlayerRef.IsInCombat() == false) int iCounter = 0 while iCounter < GroupList.Length GroupList[iCounter].SetLinkedRef(None) GroupList[iCounter].DeleteWhenAble() iCounter += 1 endwhile GroupList.Clear() Debug.Notification("All members cleared from array") endif EndEvent Function BeginActivation() int ChanceToSpawn = Utility.RandomInt(1,100) if (ChanceToSpawn <= ASC_Main_Random_Chance_R1.GetValueInt()) Spawn() Self.Disable() ASC_ResetList_R1.AddForm(Self) Debug.Notification("Controller Disabled and added to formlist") StartTimerGameTime(1, RespawnTimerTest) Debug.Notification("Respawn Timer On") elseif (ChanceToSpawn >= ASC_Main_Random_Chance_R1.GetValueInt()) && (ASC_Main_Random_DisableOnBlock_R1.GetValueInt() == 1) Self.Disable() ASC_ResetList_R1.AddForm(Self) else ;Nothing endif EndFunction Function RerollOnSuccess(bool bSuccess) if (bSuccess == true) && (Rerolled == false) && (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) Spawn() Debug.Notification("Spawning another group!") else Rerolled = false Debug.Notification("Failed to Reroll another group!") endif EndFunction Function Spawn() int WhoToSpawn = Utility.RandomInt(1,4) if (WhoToSpawn == 1) && (ASC_Allowed_Raider_R1.GetValueInt() == 1) SpawnEnemyActors(ASC_Max_Allowed_Raider_R1.GetValueInt(), ASC_Chance_Raider_R1.GetValueInt(), LvlRaider, ASC_Allowed_RaiderBoss_R1.GetValue() as Bool, ASC_Max_Allowed_RaiderBoss_R1.GetValueInt(), ASC_Chance_RaiderBoss_R1.GetValueInt(), LvlRaider) elseif (WhoToSpawn == 1) && (ASC_Allowed_Raider_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Raider_R1.GetValueInt() == 1) RerollCheck(ASC_Reroll_Chance_Raider_R1.GetValueInt()) elseif (WhoToSpawn == 2) && (ASC_Allowed_Gunner_R1.GetValueInt() == 1) SpawnEnemyActors(ASC_Max_Allowed_Gunner_R1.GetValueInt(), ASC_Chance_Gunner_R1.GetValueInt(), LvlGunner, ASC_Allowed_GunnerBoss_R1.GetValue() as Bool, ASC_Max_Allowed_GunnerBoss_R1.GetValueInt(), ASC_Chance_GunnerBoss_R1.GetValueInt(), LvlGunner) elseif (WhoToSpawn == 2) && (ASC_Allowed_Gunner_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Gunner_R1.GetValueInt() == 1) RerollCheck(ASC_Reroll_Chance_Gunner_R1.GetValueInt()) elseif (WhoToSpawn == 3) && (ASC_Allowed_Forged_R1.GetValueInt() == 1) SpawnEnemyActors(ASC_Max_Allowed_Forged_R1.GetValueInt(), ASC_Chance_Forged_R1.GetValueInt(), LvlForged, ASC_Allowed_ForgedBoss_R1.GetValue() as Bool, ASC_Max_Allowed_ForgedBoss_R1.GetValueInt(), ASC_Chance_ForgedBoss_R1.GetValueInt(), LvlForged) elseif (WhoToSpawn == 3) && (ASC_Allowed_Forged_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Forged_R1.GetValueInt() == 1) RerollCheck(ASC_Reroll_Chance_Forged_R1.GetValueInt()) elseif (WhoToSpawn == 4) && (ASC_Allowed_Tmen_R1.GetValueInt() == 1) SpawnEnemyActors(ASC_Max_Allowed_Tmen_R1.GetValueInt(), ASC_Chance_Tmen_R1.GetValueInt(), LvlTriggerman, ASC_Allowed_TmenBoss_R1.GetValue() as Bool, ASC_Max_Allowed_TmenBoss_R1.GetValueInt(), ASC_Chance_TmenBoss_R1.GetValueInt(), LvlTriggerman) elseif (WhoToSpawn == 4) && (ASC_Allowed_Tmen_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Tmen_R1.GetValueInt() == 1) RerollCheck(ASC_Reroll_Chance_Tmen_R1.GetValueInt()) endif EndFunction ; call this with something like SpawnEnemyActors(ASC_Max_Allowed_Raider_R1.GetValueInt(), ASC_Chance_Raider_R1.GetValueInt(), LvlRaider, ASC_Allowed_RaiderBoss_R1.GetValue() as Bool, ASC_Max_Allowed_RaiderBoss_R1.GetValueInt(), ASC_Chance_RaiderBoss_R1.GetValueInt(), LvlRaider) ; iMaxSpawnCount = how many spawned actors you want ; iChance = chance for a spawn to happen ; varBaseActor = any value that PlaceActorAtMe will accept. ActorBase, LvlList, etc. ; bBossAllowed = whether to allow boss ; iMaxBossCount = max number of bosses to roll spawns for ; iBossChance = chance per roll for a boss ; varBossActor = any value that PlaceActorAtMe will accept. ActorBase, LvlList, etc. Function SpawnEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor) int Difficulty = ASC_Main_Difficulty_R1.GetValueInt() int iSpawnCounter = 0 int iPosition = 0 bool bSpawnSuccess = false GroupList = new Actor[0] ; since we don't have 100% chance of spawning actors, we need this to be an accumulating array Debug.Notification("Spawning enemies") ; unless we add a function parameter for text this had to be changed to be something generic while (iSpawnCounter < iMaxSpawnCount) if (Utility.RandomInt(1,100) <= iChance) GroupList.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,Difficulty), None)) iPosition = GroupList.Length - 1 GroupList[iPosition].SetLinkedRef(PatrolMarker) Debug.Notification("Array Add Success. Actor count now: " + iPosition) bSpawnSuccess = True endif iSpawnCounter += 1 endwhile if bBossAllowed == 1 iSpawnCounter = 0 ; reuse var. memory efficient while (iSpawnCounter < iMaxBossCount) if (Utility.RandomInt(1,100) <= iBossChance) GroupList.Add(Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,Difficulty), None)) iPosition = GroupList.Length - 1 GroupList[iPosition].SetLinkedRef(PatrolMarker) Debug.Notification("Array Add Success. Actor count now: " + iPosition) bSpawnSuccess = True endif iSpawnCounter += 1 endwhile endif if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) RerollOnSuccess(bSpawnSuccess) endif EndFunction Function RerollCheck(int iRerollChance) if (Rerolled == false) && (Utility.RandomInt(1,100) <= iRerollChance) Spawn() Rerolled = true Debug.Notification("Rerolling after block") else Debug.Notification("Reroll on block denied") endif EndFunction This is as much of the original code in tact with the refactor and the redundant stuff commented out for reference. I did group the properties though. Scriptname ASC_SP_Random_R1 extends ObjectReference GlobalVariable Property ASC_Main_ModEnabled Auto Const GlobalVariable Property ASC_Main_RandomEnabled_R1 Auto Const GlobalVariable Property ASC_Main_Random_Chance_R1 Auto Const GlobalVariable Property ASC_Main_Random_DisableOnBlock_R1 Auto Const FormList Property ASC_ResetList_R1 Auto Const Actor Property PlayerRef Auto Const ObjectReference Property PatrolMarker Auto Const GlobalVariable Property ASC_Main_Difficulty_R1 Auto Const GlobalVariable Property ASC_Reroll_Main_Chance_R1 Auto Const GlobalVariable Property ASC_Reroll_Main_R1 Auto Const GlobalVariable Property ASC_DeleteTimer_R1 Auto Const Group RaiderParams ActorBase property LvlRaider Auto Const GlobalVariable Property ASC_Allowed_Raider_R1 Auto Const GlobalVariable Property ASC_Allowed_RaiderBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Raider_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_RaiderBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Raider_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Raider_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Raider_R1 Auto Const GlobalVariable Property ASC_Chance_RaiderBoss_R1 Auto Const EndGroup Group GunnerParams ActorBase Property LvlGunner Auto Const GlobalVariable Property ASC_Allowed_Gunner_R1 Auto Const GlobalVariable Property ASC_Allowed_GunnerBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Gunner_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_GunnerBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Gunner_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Gunner_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Gunner_R1 Auto Const GlobalVariable Property ASC_Chance_GunnerBoss_R1 Auto Const EndGroup Group ForgedParams ActorBase Property LvlForged Auto Const GlobalVariable Property ASC_Allowed_Forged_R1 Auto Const GlobalVariable Property ASC_Allowed_ForgedBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Forged_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_ForgedBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Forged_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Forged_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Forged_R1 Auto Const GlobalVariable Property ASC_Chance_ForgedBoss_R1 Auto Const EndGroup Group TriggermenParams ActorBase Property LvlTriggerman Auto Const GlobalVariable Property ASC_Allowed_Tmen_R1 Auto Const GlobalVariable Property ASC_Allowed_TmenBoss_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_Tmen_R1 Auto Const GlobalVariable Property ASC_Max_Allowed_TmenBoss_R1 Auto Const GlobalVariable Property ASC_Chance_Tmen_R1 Auto Const GlobalVariable Property ASC_Reroll_Allowed_Tmen_R1 Auto Const GlobalVariable Property ASC_Reroll_Chance_Tmen_R1 Auto Const GlobalVariable Property ASC_Chance_TmenBoss_R1 Auto Const EndGroup ;Int ChanceToSpawn = 0 ; moved to local var ;Int Difficulty = 0 ; you don't need this global. moved to local inside spawnactor function ;Int WhoToSpawn = 0 ; moved to local ; Int SpawnCounter = 0 ; you don't need this global ;Int SpawnCounterBoss = 0 ; you don't need this global ; Bool SpawnSuccess = false ; moved local and passed as parameter Bool Rerolled = false ; Actor Spawn = None ; you don't need this global Actor[] GroupList Int RespawnTimerTest = 10 ;Int GroupMember = 0 ; don't need this Bool SpawnPointLoaded = false Event OnCellAttach() SpawnPointLoaded = true if (Self.IsDisabled() == false) && (ASC_Main_ModEnabled.GetValueInt() == 1) && (ASC_Main_RandomEnabled_R1.GetValueInt() == 1) BeginActivation() endif EndEvent Event OnTimerGameTime(int aiTimerID) if aiTimerID == RespawnTimerTest Self.Enable() Debug.Notification("Point Rearmed") endif EndEvent Event OnCellDetach() SpawnPointLoaded = false Utility.Wait(10) if (SpawnPointLoaded == false) && (PlayerRef.IsInCombat() == false) int iCounter = 0 ;while GroupMember > -1 ; GroupList[GroupMember].SetLinkedRef(None) ; GroupList[GroupMember].DeleteWhenAble() ; GroupList[GroupMember] = None ; GroupMember = GroupMember - 1 ; Debug.Notification("Member Removed From List") ;endwhile while iCounter < GroupList.Length GroupList[iCounter].SetLinkedRef(None) GroupList[iCounter].DeleteWhenAble() iCounter += 1 endwhile GroupList.Clear() Debug.Notification("All members cleared from array") endif EndEvent Function BeginActivation() int ChanceToSpawn = Utility.RandomInt(1,100) if (ChanceToSpawn <= ASC_Main_Random_Chance_R1.GetValueInt()) Spawn() Self.Disable() ASC_ResetList_R1.AddForm(Self) Debug.Notification("Controller Disabled and added to formlist") StartTimerGameTime(1, RespawnTimerTest) Debug.Notification("Respawn Timer On") elseif (ChanceToSpawn >= ASC_Main_Random_Chance_R1.GetValueInt()) && (ASC_Main_Random_DisableOnBlock_R1.GetValueInt() == 1) Self.Disable() ASC_ResetList_R1.AddForm(Self) else ;Nothing endif EndFunction Function RerollOnSuccess(bool bSuccess) if (bSuccess == true) && (Rerolled == false) && (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) Spawn() Debug.Notification("Spawning another group!") else ;Difficulty = 0 ;WhoToSpawn = 0 ;SpawnSuccess = false Rerolled = false ;Spawn = none ;SpawnCounter = 0 ;SpawnCounterBoss = 0 Debug.Notification("Failed to Reroll another group!") endif EndFunction Function Spawn() int WhoToSpawn = Utility.RandomInt(1,4) if (WhoToSpawn == 1) && (ASC_Allowed_Raider_R1.GetValueInt() == 1) ;SpawnRaider() SpawnEnemyActors(ASC_Max_Allowed_Raider_R1.GetValueInt(), ASC_Chance_Raider_R1.GetValueInt(), LvlRaider, ASC_Allowed_RaiderBoss_R1.GetValue() as Bool, ASC_Max_Allowed_RaiderBoss_R1.GetValueInt(), ASC_Chance_RaiderBoss_R1.GetValueInt(), LvlRaider) elseif (WhoToSpawn == 1) && (ASC_Allowed_Raider_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Raider_R1.GetValueInt() == 1) ;RerollRaiderR1() RerollCheck(ASC_Reroll_Chance_Raider_R1.GetValueInt()) elseif (WhoToSpawn == 2) && (ASC_Allowed_Gunner_R1.GetValueInt() == 1) ;SpawnGunner() SpawnEnemyActors(ASC_Max_Allowed_Gunner_R1.GetValueInt(), ASC_Chance_Gunner_R1.GetValueInt(), LvlGunner, ASC_Allowed_GunnerBoss_R1.GetValue() as Bool, ASC_Max_Allowed_GunnerBoss_R1.GetValueInt(), ASC_Chance_GunnerBoss_R1.GetValueInt(), LvlGunner) elseif (WhoToSpawn == 2) && (ASC_Allowed_Gunner_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Gunner_R1.GetValueInt() == 1) ;RerollGunnerR1() RerollCheck(ASC_Reroll_Chance_Gunner_R1.GetValueInt()) elseif (WhoToSpawn == 3) && (ASC_Allowed_Forged_R1.GetValueInt() == 1) ;SpawnForged() SpawnEnemyActors(ASC_Max_Allowed_Forged_R1.GetValueInt(), ASC_Chance_Forged_R1.GetValueInt(), LvlForged, ASC_Allowed_ForgedBoss_R1.GetValue() as Bool, ASC_Max_Allowed_ForgedBoss_R1.GetValueInt(), ASC_Chance_ForgedBoss_R1.GetValueInt(), LvlForged) elseif (WhoToSpawn == 3) && (ASC_Allowed_Forged_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Forged_R1.GetValueInt() == 1) ;RerollForgedR1() RerollCheck(ASC_Reroll_Chance_Forged_R1.GetValueInt()) elseif (WhoToSpawn == 4) && (ASC_Allowed_Tmen_R1.GetValueInt() == 1) ;SpawnTmen() SpawnEnemyActors(ASC_Max_Allowed_Tmen_R1.GetValueInt(), ASC_Chance_Tmen_R1.GetValueInt(), LvlTriggerman, ASC_Allowed_TmenBoss_R1.GetValue() as Bool, ASC_Max_Allowed_TmenBoss_R1.GetValueInt(), ASC_Chance_TmenBoss_R1.GetValueInt(), LvlTriggerman) elseif (WhoToSpawn == 4) && (ASC_Allowed_Tmen_R1.GetValueInt() == 0) && (ASC_Reroll_Allowed_Tmen_R1.GetValueInt() == 1) ;RerollTmenR1() RerollCheck(ASC_Reroll_Chance_Tmen_R1.GetValueInt()) endif EndFunction ; call this with something like SpawnEnemyActors(ASC_Max_Allowed_Raider_R1.GetValueInt(), ASC_Chance_Raider_R1.GetValueInt(), LvlRaider, ASC_Allowed_RaiderBoss_R1.GetValue() as Bool, ASC_Max_Allowed_RaiderBoss_R1.GetValueInt(), ASC_Chance_RaiderBoss_R1.GetValueInt(), LvlRaider) ; iMaxSpawnCount = how many spawned actors you want ; iChance = chance for a spawn to happen ; varBaseActor = any value that PlaceActorAtMe will accept. ActorBase, LvlList, etc. ; bBossAllowed = whether to allow boss ; iMaxBossCount = max number of bosses to roll spawns for ; iBossChance = chance per roll for a boss ; varBossActor = any value that PlaceActorAtMe will accept. ActorBase, LvlList, etc. Function SpawnEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor) int Difficulty = ASC_Main_Difficulty_R1.GetValueInt() int iSpawnCounter = 0 int iPosition = 0 bool bSpawnSuccess = false GroupList = new Actor[0] ; since we don't have 100% chance of spawning actors, we need this to be an accumulating array Debug.Notification("Spawning enemies") ; unless we add a function parameter for text this had to be changed to be something generic while (iSpawnCounter < iMaxSpawnCount) if (Utility.RandomInt(1,100) <= iChance) GroupList.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,Difficulty), None)) iPosition = GroupList.Length - 1 GroupList[iPosition].SetLinkedRef(PatrolMarker) Debug.Notification("Array Add Success. Actor count now: " + iPosition) ; Spawn = None ; you don't need to do this bSpawnSuccess = True endif iSpawnCounter += 1 endwhile if bBossAllowed == 1 iSpawnCounter = 0 ; reuse var. memory efficient while (iSpawnCounter < iMaxBossCount) if (Utility.RandomInt(1,100) <= iBossChance) GroupList.Add(Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,Difficulty), None)) iPosition = GroupList.Length - 1 GroupList[iPosition].SetLinkedRef(PatrolMarker) Debug.Notification("Array Add Success. Actor count now: " + iPosition) ;Spawn = None bSpawnSuccess = True endif iSpawnCounter += 1 endwhile endif if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) RerollOnSuccess(bSpawnSuccess) endif EndFunction Function RerollCheck(int iRerollChance) if (Rerolled == false) && (Utility.RandomInt(1,100) <= iRerollChance) Spawn() Rerolled = true Debug.Notification("Rerolling after block") else Debug.Notification("Reroll on block denied") endif EndFunction ;Function SpawnRaider() ; SpawnCounter = ASC_Max_Allowed_Raider_R1.GetValueInt() ; GroupList = new Actor[GroupMember] ; Debug.Notification("Raider Spawning") ; while (SpawnCounter > 0) ; if (Utility.RandomInt(1,100) <= ASC_Chance_Raider_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounter = SpawnCounter - 1 ; endwhile ; if ASC_Allowed_RaiderBoss_R1.GetValueInt() == 1 ; SpawnCounterBoss = ASC_Max_Allowed_RaiderBoss_R1.GetValueInt() ; while (SpawnCounterBoss) > 0 ; if (Utility.RandomInt(1,100) <= ASC_Chance_RaiderBoss_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlRaider, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounterBoss = SpawnCounterBoss - 1 ; endwhile ; endif ; if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) ; RerollOnSuccess() ; endif ;EndFunction ;Function RerollRaiderR1() ; if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Raider_R1.GetValueInt()) ; Spawn() ; Rerolled = true ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Rerolling after Raiders Blocked") ; else ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Reroll on blocked Raiders denied") ; endif ;EndFunction ;Function SpawnGunner() ; SpawnCounter = ASC_Max_Allowed_Gunner_R1.GetValueInt() ; GroupList = new Actor[GroupMember] ; Debug.Notification("Gunner Spawning") ; while (SpawnCounter > 0) ; if (Utility.RandomInt(1,100) <= ASC_Chance_Gunner_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlGunner, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounter = SpawnCounter - 1 ; endwhile ; if ASC_Allowed_GunnerBoss_R1.GetValueInt() == 1 ; SpawnCounterBoss = ASC_Max_Allowed_GunnerBoss_R1.GetValueInt() ; while (SpawnCounterBoss) > 0 ; if (Utility.RandomInt(1,100) <= ASC_Chance_GunnerBoss_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlGunner, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounterBoss = SpawnCounterBoss - 1 ; endwhile ; endif ; if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) ; RerollOnSuccess() ; endif ;EndFunction ;Function RerollGunnerR1() ; if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Gunner_R1.GetValueInt()) ; Spawn() ; Rerolled = true ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Rerolling after Gunners Blocked") ; else ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Reroll on blocked Gunners denied") ; endif ;EndFunction ;Function SpawnForged() ; SpawnCounter = ASC_Max_Allowed_Forged_R1.GetValueInt() ; GroupList = new Actor[GroupMember] ; Debug.Notification("Forged Spawning") ; while (SpawnCounter > 0) ; if (Utility.RandomInt(1,100) <= ASC_Chance_Forged_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlForged, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounter = SpawnCounter - 1 ; endwhile ; if ASC_Allowed_ForgedBoss_R1.GetValueInt() == 1 ; SpawnCounterBoss = ASC_Max_Allowed_ForgedBoss_R1.GetValueInt() ; while (SpawnCounterBoss) > 0 ; if (Utility.RandomInt(1,100) <= ASC_Chance_ForgedBoss_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlForged, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounterBoss = SpawnCounterBoss - 1 ; endwhile ; endif ; if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) ; RerollOnSuccess() ; endif ;EndFunction ;Function RerollForgedR1() ; if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Forged_R1.GetValueInt()) ; Spawn() ; Rerolled = true ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Rerolling after Forgeds Blocked") ; else ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Reroll on blocked Forgeds denied") ; endif ;EndFunction ;Function SpawnTmen() ; SpawnCounter = ASC_Max_Allowed_Tmen_R1.GetValueInt() ; GroupList = new Actor[GroupMember] ; Debug.Notification("Tmen Spawning") ; while (SpawnCounter > 0) ; if (Utility.RandomInt(1,100) <= ASC_Chance_Tmen_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlTriggerman, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounter = SpawnCounter - 1 ; endwhile ; if ASC_Allowed_TmenBoss_R1.GetValueInt() == 1 ; SpawnCounterBoss = ASC_Max_Allowed_TmenBoss_R1.GetValueInt() ; while (SpawnCounterBoss) > 0 ; if (Utility.RandomInt(1,100) <= ASC_Chance_TmenBoss_R1.GetValueInt()) ; Spawn = Self.PlaceActorAtMe(LvlTriggerman, Utility.RandomInt(1,Difficulty), None) ; GroupList[GroupMember] = Spawn as Actor ; GroupList[GroupMember].SetLinkedRef(PatrolMarker) ; Debug.Notification("Array Success") ; Spawn = None ; SpawnSuccess = True ; endif ; GroupMember = GroupMember + 1 ; SpawnCounterBoss = SpawnCounterBoss - 1 ; endwhile ; endif ; if (ASC_Reroll_Main_R1.GetValueInt() == 1) && (Utility.RandomInt(1,100) <= ASC_Reroll_Main_Chance_R1.GetValueInt()) ; RerollOnSuccess() ; endif ;EndFunction ;Function RerollTmenR1() ; if (Rerolled == false) && (Utility.RandomInt(1,100) <= ASC_Reroll_Chance_Tmen_R1.GetValueInt()) ; Spawn() ; Rerolled = true ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Rerolling after Tmens Blocked") ; else ; ;Difficulty = 0 ; ;WhoToSpawn = 0 ; Debug.Notification("Reroll on blocked Tmens denied") ; endif ;EndFunction Edited May 25, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
Recommended Posts