Jump to content

Understanding dynamic array correctly


SMB92

Recommended Posts

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
  EndWhile
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.

 

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

  • Replies 111
  • Created
  • Last Reply

Top Posters In This Topic

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 by kitcat81
Link to comment
Share on other sites

 

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

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

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

 

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 by BigAndFlabby
Link to comment
Share on other sites

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

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 by BigAndFlabby
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...