Jump to content

Understanding dynamic array correctly


SMB92

Recommended Posts

Despite these arrays not filling/holding my variables, my functions are completing to the end, the debugs are telling me this. Arrays always 0 length but. Well, on the version that has the struct array as a property, as previously said i get weird results. Now with the dynamic struct array it doesnt hold at all.

 

Ok. Assuming I'm using the latest version of your script code I see a few issues. The problems you're having with the arrays is that you initialize them as empty and are not using Add to add new entries. If you want to use the method of adding that you have, then you need to initialize with a starting size.

 

Example:

SomeType[] someArray = new Array[0] ; valid creation but has no entries so length = 0
int iPosition = 0
someArray[iPosition] = someData ; invalid. iPosition = 0. You've never created an index 0 entry in the array so it fails
 
someArray.Add(someData) ; this will create a new entry at the end of the array.
 
;if you want to use the positioner you have to define a size first and increment the counter
SomeType[] someArray = new Array[10] ; create array with 10 indexes starting 0-9
while (iPosition < 10)
    someArray[iPosition] = someData
endwhile

Kitkat81 being confused about the usage of the iPosition variable is understandable because of how it was incorrectly used. The first code snippet that is problematic at first glance is:

 

 

; from ASC_SP_Random_R1
 

Function SpawnEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
    Debug.Notification("Spawning Enemy Actors")
    ;Form kMarker = Game.GetFormFromFile(0x00002ce2, "Fallout4.ESM")  old system for patroling based on physical marker network
    ;ObjectReference kPatrolMarker = Game.FindClosestReferenceOfTypeFromRef(kMarker, Self as ObjectReference, 32.0)
    Actor Spawned = None
    int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = 0
    int iPosition = 0
    ;bool bSpawnSuccess = false ;obsolete, was for checking old reroll system was allowed
    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)
                Actor akSpawned = Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]);Other way to do it, left for reference
                GroupList[iPosition] = akSpawned
                ;GroupList.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                iPosition = GroupList.Length - 1
                (MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList[iPosition])  ;new system for patrols NOTE change to travel aliases
            endif
            iSpawnCounter += 1
        endwhile
        Debug.Notification("Array Add Success. Actor count now: " + iPosition)
        Debug.Notification("Non Boss Group Spawned")
        if bBossAllowed == 1
            iSpawnCounter = 0 ; reuse var. memory efficient
            while (iSpawnCounter < iMaxBossCount)
                if (Utility.RandomInt(1,100) <= iBossChance)
                    Spawned = Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])
                    GroupList[iPosition] = Spawned
                    ;GroupList.Add(Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                    iPosition = GroupList.Length - 1
                    ;GroupList[iPosition].SetLinkedRef(kPatrolMarker)
                    (MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList[iPosition])
                endif
                iSpawnCounter += 1
            endwhile
        endif
        Debug.Notification("Array Add Success. Actor count now: " + iPosition)
        Debug.Notification("Enemies should be spawned")
        if (iRerollAllowed == 1) && (iRerollCount < iRerollLimit) && (Utility.RandomInt(1,100) <= iRerollChance)  ;iRerollLimit is a universal value, only 1 global per region, not per type
            (MasterQuest as ASC_MasterRandomQuestScript).SpawnAnotherGroupR1(Self)
            iRerollCount += 1
            Debug.Notification("Rerolling for another group!")
        else
            Debug.Notification("Reroll 1 failed")
        endif
EndFunction

In here you set position to 0, initialize array of 0 length, then try to set the value of an increasing index that doesn't exist. If you swap back in the GroupList.Add line instead of your 2 line Actor akSpawned and GroupList[iPosition] it should go back to building the array.
For the other part of your problem, in the ASC_MasterRandomQuestScript FillArrays() function you have the same problem. You initialize a zero length array and then try to set the value of an index that doesn't exist every time. That function needs to be wholly changed. Try this:

Function FillArrays() ;Fills the struct arrays with only the types allowed. Called by update event and initial initialization of the mod. May need to be called every startup.
    ; Int iPosition = 0 ; remove this
    ; ActorTypesRandomR1 = new ActorTypeStruct[iPosition] ; changed see below
    ActorTypesRandomR1 = new ActorTypeStruct[0]
    ActorTypeStruct tmpStruct
        if ASC_Allowed_Raider_R1.GetValueInt() == 1
            tmpStruct = new ActorTypeStruct ; create a new temporary var of the struct type
            tmpStruct.LvlActorBase = LvlRaider
            tmpStruct.LvlActorBossBase = LvlRaiderBoss
            tmpStruct.ASC_Allowed_Boss = ASC_Allowed_Boss_Raider_R1
            tmpStruct.ASC_Max_Allowed = ASC_Max_Allowed_Raider_R1
            tmpStruct.ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Raider_R1
            tmpStruct.ASC_Chance = ASC_Chance_Spawn_Raider_R1
            tmpStruct.ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Raider_R1
            tmpStruct.ASC_Reroll_Allowed = ASC_Reroll_Allowed_Raider_R1
            tmpStruct.ASC_Reroll_Chance = ASC_Reroll_Chance_Raider_R1
            tmpStruct.ASC_EZ_Lvl = ASC_EZ_Raider_R1
            ActorTypesRandomR1.Add(tmpStruct) ; add the temporary struct to the master array
        else
            ;Nothing, ActorType does not enter the array
        endif
        if ASC_Allowed_Gunner_R1.GetValueInt() == 1
            tmpStruct = new ActorTypeStruct
            tmpStruct.LvlActorBase = LvlGunner
            tmpStruct.LvlActorBossBase = LvlGunnerBoss
            tmpStruct.ASC_Allowed_Boss = ASC_Allowed_Boss_Gunner_R1
            tmpStruct.ASC_Max_Allowed = ASC_Max_Allowed_Gunner_R1
            tmpStruct.ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Gunner_R1
            tmpStruct.ASC_Chance = ASC_Chance_Spawn_Gunner_R1
            tmpStruct.ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Gunner_R1
            tmpStruct.ASC_Reroll_Allowed = ASC_Reroll_Allowed_Gunner_R1
            tmpStruct.ASC_Reroll_Chance = ASC_Reroll_Chance_Gunner_R1
            tmpStruct.ASC_EZ_Lvl = ASC_EZ_Gunner_R1
            ActorTypesRandomR1.Add(tmpStruct)
        else
            ;Nothing, ActorType does not enter the array
        endif
        if ASC_Allowed_Forged_R1.GetValueInt() == 1
            tmpStruct = new ActorTypeStruct
            tmpStruct.LvlActorBase = LvlForged
            tmpStruct.LvlActorBossBase = LvlForged_Boss
            tmpStruct.ASC_Allowed_Boss = ASC_Allowed_Boss_Forged_R1
            tmpStruct.ASC_Max_Allowed = ASC_Max_Allowed_Forged_R1
            tmpStruct.ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Forged_R1
            tmpStruct.ASC_Chance = ASC_Chance_Spawn_Forged_R1
            tmpStruct.ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Forged_R1
            tmpStruct.ASC_Reroll_Allowed = ASC_Reroll_Allowed_Forged_R1
            tmpStruct.ASC_Reroll_Chance = ASC_Reroll_Chance_Forged_R1
            tmpStruct.ASC_EZ_Lvl = ASC_EZ_Forged_R1
            ActorTypesRandomR1.Add(tmpStruct)
        else
            ;Nothing, ActorType does not enter the array
        endif
        if ASC_Allowed_Triggerman_R1.GetValueInt() == 1
            tmpStruct = new ActorTypeStruct
            tmpStruct.LvlActorBase = LvlTriggerman
            tmpStruct.LvlActorBossBase = LvlTriggerman
            tmpStruct.ASC_Allowed_Boss = ASC_Allowed_Boss_Triggerman_R1
            tmpStruct.ASC_Max_Allowed = ASC_Max_Allowed_Triggerman_R1
            tmpStruct.ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Triggerman_R1
            tmpStruct.ASC_Chance = ASC_Chance_Spawn_Triggerman_R1
            tmpStruct.ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Triggerman_R1
            tmpStruct.ASC_Reroll_Allowed = ASC_Reroll_Allowed_Triggerman_R1
            tmpStruct.ASC_Reroll_Chance = ASC_Reroll_Chance_Triggerman_R1
            tmpStruct.ASC_EZ_Lvl = ASC_EZ_Triggerman_R1
            ActorTypesRandomR1.Add(tmpStruct)
        else
            ;Nothing, ActorType does not enter the array
        endif
    Debug.Notification("Array of Structs is filled")
EndFunction

Link to comment
Share on other sites

  • Replies 111
  • Created
  • Last Reply

Top Posters In This Topic

This was the latest (a few pages have past since I posted it lol)

 

 

 

Scriptname ASC_SP_Random_R1 extends ObjectReference
{Region 1 Random Type SpawnPoint Marker Script}

import ASC_MainStruct

ASC_MasterRandomQuestScript Property MasterQuest Auto Const
GlobalVariable Property ASC_Main_ModEnabled Auto Const
GlobalVariable Property ASC_Main_Enabled_Random_R1 Auto Const
GlobalVariable Property ASC_Main_Random_Chance_R1 Auto Const
GlobalVariable Property ASC_Main_Random_DisableOnBlock_R1 Auto Const
GlobalVariable Property ASC_Main_Difficulty_R1 Auto Const
GlobalVariable Property ASC_Main_Reroll_Limit_R1 Auto Const
FormList Property ASC_ResetList_R1 Auto Const
Actor Property PlayerRef Auto Const


bool bSpawnPointLoaded = false ;bool for cleanup event
bool Group2Loaded = false
bool Group3Loaded = false
int iRerollLimit = 0
int iRerollCount = 0
Actor[] GroupList  ; Array to track and cleanup all aspawned actors later, as well as apply new features in future
Actor[] GroupList2 ;if 1st reroll attempt successful, assign spawns here
Actor[] Grouplist3 ;2nd reroll attempt actors here, limit of rerolls is 2, hardcapped. 

Event OnCellAttach()
	bSpawnPointLoaded = true
	if (Self.IsDisabled() == false) && (ASC_Main_ModEnabled.GetValueInt() == 1) && (ASC_Main_Enabled_Random_R1.GetValueInt() == 1)
		SPActivate()
		Debug.Notification("All Functions Done")
	else
		Debug.Notification("SpawnPoint Failed")
	endif
EndEvent

Event OnCellDetach() ;idea is to stop cleanup from happening while potentially in combat with group while potentially leaving the cell their spawnmarker is in. Cleans up all data generated during spawn. 
    bSpawnPointLoaded = false
    Utility.Wait(10)
		while (PlayerRef.IsInCombat()) ; also may not be necessary but reference for sanity check.
			; Do nothing until combat is over, then check if we are still in the loaded area
			Utility.Wait(0.1)
		endwhile
		if bSpawnPointLoaded == false ;if we are not in the loaded area, start cleaning up. Event will be called again if we aren't so no worries
			int iCounter = 0
			while iCounter < GroupList.Length
				;GroupList[iCounter].SetLinkedRef(None) ;old, prior to using AI package
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.RemoveFromRef(GroupList[iCounter])
				GroupList[iCounter].DeleteWhenAble()
				iCounter += 1
			endwhile
			iCounter = 0
		endif
		if Group2Loaded == true
			int iCounter = 0
			while iCounter < GroupList2.Length
				;GroupList2[iCounter].SetLinkedRef(None) ;old, prior to using AI package
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.RemoveFromRef(GroupList2[iCounter])
				GroupList2[iCounter].DeleteWhenAble()
				iCounter += 1
			endwhile
			iCounter = 0
		endif
		if Group3Loaded == true
			int iCounter = 0
			while iCounter < GroupList3.Length
				;GroupList3[iCounter].SetLinkedRef(None) ;old, prior to using AI package
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.RemoveFromRef(GroupList3[iCounter])
				GroupList3[iCounter].DeleteWhenAble()
				iCounter += 1
			endwhile
			iCounter = 0
		endif
		Debug.Notification("SpawnPoint cleaned up")
EndEvent

Function SPActivate()  ;This may not be necessary but it looks neat. Main roll chance and disabling happens here
	iRerollLimit = ASC_Main_Reroll_Limit_R1.GetValueInt()
	int iChanceToSpawn = Utility.RandomInt(1,100)
    if (iChanceToSpawn <= ASC_Main_Random_Chance_R1.GetValueInt())
		Debug.Notification("Spawn Function called on script!")
        Self.Disable()
        ASC_ResetList_R1.AddForm(Self)
		(MasterQuest as ASC_MasterRandomQuestScript).SpawnR1(Self)
		Debug.Notification("Spawn function has completed")
    elseif (iChanceToSpawn >= ASC_Main_Random_Chance_R1.GetValueInt()) && (ASC_Main_Random_DisableOnBlock_R1.GetValueInt() == 1)
        Self.Disable()
        ASC_ResetList_R1.AddForm(Self)
		Debug.Notification("SpawnPoint failed and disabled")
    else
        Debug.Notification("SpawnPoint failed but still armed")
    endif
EndFunction

Function SpawnEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
	Debug.Notification("Spawning Enemy Actors")
    ;Form kMarker = Game.GetFormFromFile(0x00002ce2, "Fallout4.ESM")  old system for patroling based on physical marker network
	;ObjectReference kPatrolMarker = Game.FindClosestReferenceOfTypeFromRef(kMarker, Self as ObjectReference, 32.0)
	Actor Spawned = None
	int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = 0
    ;bool bSpawnSuccess = false ;obsolete, was for checking old reroll system was allowed
    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)
				Actor akSpawned = Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]);Other way to do it, left for reference
				GroupList[iSpawnCounter] = akSpawned
                ;GroupList.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])) ; commented out during tests. same as above result though
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList[iSpawnCounter])  ;new system for patrols NOTE change to travel aliases
            endif
			iSpawnCounter +=1
        endwhile
		Debug.Notification("Array Add Success. Actor count now: " + GroupList.Length)
		Debug.Notification("Non Boss Group Spawned")
        if bBossAllowed == 1
            iSpawnCounter = 0 ; reuse var. memory efficient
            while (iSpawnCounter < iMaxBossCount)
                if (Utility.RandomInt(1,100) <= iBossChance)
                    Spawned = Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])
					GroupList[iSpawnCounter] = Spawned
					;GroupList.Add(Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                    ;GroupList[iSpawnCounter].SetLinkedRef(kPatrolMarker)
					(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList[iSpawnCounter])
                endif
				iSpawnCounter +=1
            endwhile
        endif
		Debug.Notification("Array Add Success. Actor count now: " + iSpawnCounter)
		Debug.Notification("Enemies should be spawned")
		if (iRerollAllowed == 1) && (iRerollCount < iRerollLimit) && (Utility.RandomInt(1,100) <= iRerollChance)  ;iRerollLimit is a universal value, only 1 global per region, not per type
			(MasterQuest as ASC_MasterRandomQuestScript).SpawnAnotherGroupR1(Self)
			iRerollCount += 1
			Debug.Notification("Rerolling for another group!")
		else
			Debug.Notification("Reroll 1 failed")
		endif
EndFunction

Function SpawnMoreEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
    ;Form kMarker = Game.GetFormFromFile(0x00002ce2, "Fallout4.ESM")  old system for patroling based on physical marker network
	;ObjectReference kPatrolMarker = Game.FindClosestReferenceOfTypeFromRef(kMarker, Self as ObjectReference, 32.0)
	Actor Spawned = None
	int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = 0
    GroupList2 = new Actor[iSpawnCounter] ; 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)
                Spawned = Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])
				GroupList2[iSpawnCounter] = Spawned
				;GroupList2.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                ;GroupList[iSpawnCounter].SetLinkedRef(kPatrolMarker) old sytem
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList2[iSpawnCounter])  ;new system for patrols
            endif
			iSpawnCounter +=1
        endwhile
		Group2Loaded = true
        if bBossAllowed == 1
            iSpawnCounter = 0 ; reuse var. memory efficient
            while (iSpawnCounter < iMaxBossCount)
                if (Utility.RandomInt(1,100) <= iBossChance)
					Spawned = Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])
					GroupList2[iSpawnCounter] = Spawned
                    ;GroupList2.Add(Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                    ;GroupList2[iSpawnCounter].SetLinkedRef(kPatrolMarker)
					(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList2[iSpawnCounter])
                endif
				iSpawnCounter +=1
            endwhile
        endif
		if (iRerollCount < iRerollLimit) && (Utility.RandomInt(1,100) <= iRerollChance)
			(MasterQuest as ASC_MasterRandomQuestScript).SpawnYetAnotherGroupR1(Self)
			iRerollCount += 1
			Debug.Notification("Rerolling for yet another group!")
		else
			Debug.Notification("Reroll 2 failed")
		endif
EndFunction

Function SpawnEvenMoreEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
    ;Form kMarker = Game.GetFormFromFile(0x00002ce2, "Fallout4.ESM")  old system for patroling based on physical marker network
	;ObjectReference kPatrolMarker = Game.FindClosestReferenceOfTypeFromRef(kMarker, Self as ObjectReference, 32.0)
	Actor Spawned = None
	int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = 0
    GroupList3 = 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)
                Spawned = Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])
				GroupList3[iSpawnCounter] = Spawned
				;GroupList3.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                ;GroupList3[iSpawnCounter].SetLinkedRef(kPatrolMarker) old sytem
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList3[iSpawnCounter])  ;new system for patrols
            endif
			iSpawnCounter +=1
        endwhile
		Group3Loaded = true
        if bBossAllowed == 1
            iSpawnCounter = 0 ; reuse var. memory efficient
            while (iSpawnCounter < iMaxBossCount)
                if (Utility.RandomInt(1,100) <= iBossChance)
                    Spawned = Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel])
					GroupList3[iSpawnCounter] = Spawned
					;GroupList3.Add(Self.PlaceActorAtMe(varBossActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                    ;GroupList[iSpawnCounter].SetLinkedRef(kPatrolMarker)
					(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList3[iSpawnCounter])
                endif
				iSpawnCounter +=1
            endwhile
        endif
EndFunction

 

 

 

The Add method was doing the same thing, so I just put the 2 line method in there for testing. I'll apply said fixes and test it out again.

 

BTW I am using a clean save game, initializing the mod each time so no funny savegame business :)

Link to comment
Share on other sites

This was the latest (a few pages have past since I posted it lol)

 

[snip]

 

The Add method was doing the same thing, so I just put the 2 line method in there for testing. I'll apply said fixes and test it out again.

 

BTW I am using a clean save game, initializing the mod each time so no funny savegame business :smile:

 

For code readability sake, every place you have '(MasterQuest as ASC_MasterRandomQuestScript)' you can just use MasterQuest because you already cast it when defining the property with 'ASC_MasterRandomQuestScript Property MasterQuest Auto Const'.

 

There could be a lot of things going on about why it's failing. So first I'd ask, does it even spawn an actor at all? Even if it's failing to build the array. Do you have any errors in the papyrus log?

 

The way you're using the loop counter will get it so screwed up if it doesn't have 100% spawn chance. I had a separate counter for the index of the entry on purpose.

 

From your latest code you have

 

[code

GroupList[iSpawnCounter] = akSpawned

[/code]

 

This is going to fail anyway you look at it. As I just mentioned, you never created an entry in the index for it to change. Besides that, the iSpawnCounter is incremented even if the random chance check causes the actor not to spawn. So you're potentially further trying to write to a higher index than should be there.

 

I think there's a way to refactor your 3 spawn functions back down to 1 so you don't have 3 copies of the same code. That just seems inefficient to me. I suppose a simple way would be to use a temp array inside the spawn function. Then at the of the function set one of the real group arrays to be your temp array. This would need a passing of some kind of int and then a simple if/elseif tree to pick which to set. I miss multidimensional arrays. I'll think on that one for a bit. Maybe there's something better out there.

Link to comment
Share on other sites

Well, on the version of the code that uses the struct array as a full property filled in ck, actors spawn but array on object script is always 0. It either spawned no actors, all 4 (maxcount) or 1 boss (maxbosscount). IPosition variable was still intact then.

After i saw your post in the other thread I swapped back to making the struct array dynamic. No spawns at all so far. Originally I still had the iPosition variable intact, after I saw kitcats post and looked at the code again I thought the same thing so I removed it. Same result though. Logs now show Array out of index etc, nothing in the quest scripts array.

I've tried both the .Add method and my 2 assigning lines of code, same result. I just wanted to be sure that wasn't it.

I totally get everything you've advised, I'll be sitting down at the PC in 10 minutes to clean it up with mentioned fixes.

Also the idea of the 3 functions is to have 3 separate arrays of enemies, for the reroll function. I wanted to have more than 1 opportunity to reroll for users who might have good enough rigs to afford large scale vattoes from time to time. I am not happy with the way it is myself, but that was the best way I could come up with. EDIT; Yeah sorry, would be good if that could be rolled into 1 function safely.

 

Edit; By the way, with the version of code that had the struct array as a full property, I actually did try initializing the array at a value of 10, so it would have 11 slots, just to see if it would fill with either method. Still was 0. Just thought it was worth a mention.

Link to comment
Share on other sites

Sure give me a sec

 

Any chance you'd be willing to PM me a link to a zipped copy of the mod I could look at. Trying to figure it out piece meal is kind of difficult when you only see part of it.

Link to comment
Share on other sites

You're fixes work! Everything works just fine from what I can tell, the array returns a size, the actors get cleaned up and the chance settings are working, I can get different numbers of npcs at the point. I'm stoked :)

 

I'll stack 10 points together and see what happens :D

Link to comment
Share on other sites

Just a few notes :

GroupList = new Actor[0] ; - you don`t need this line at all, your array was defined under the script properties section.

BigAndFlabby gave the proper example of defining an array, but as you already defined it ouside of functions and events (so you can use it as a storage), you just don`t need to define it again.

You can use his example to create a temporary array inside of the function (in this case you won`t be able to use this array ouside of the function/event where it was defined)

 

You can use "placeatme" to create a temporary actors. I saw vanilla scripts using placeatme with no problems. I don`t see the reason why you need to use placeactoratme and then to run "deletewhenable".

 

If you move all functions to the quest, you can always undate and change the script and it won`t break the mod.

There are different ways to make it work . But for example you can do it this way :

 

Create a reference alias for the marker . When you want to use one of markers to spawn something on them, apply the alias to the marker(ForceRefTo) and then run the spawn function from any script that has the alias defined in properties ( ReferenceAlias Property MyAlias Auto Const):

MyAlias.GetReference().PlaceAtMe(someActor,1)

 

 

The spawning script functions can be moved to reference alias script or to the quest script.

This can reduce the number of script copies in the game to 1.

 

If you just tell the main goals you want to achieve there can be some better ways.

Link to comment
Share on other sites

@SMB92 - I'm aware this looks like I'm rudely interrupting the discussion and going off topic, but I've been following this conversation since I found the thread. Would you object if I tried to get it moved to the CK section? I'm sure other people would be interested in this, but I bet a lot of them don't wander out of the CK forum and a search there wouldn't find this.

 

Hi, BigAndFlabby :)

Link to comment
Share on other sites

@SMB92 - I'm aware this looks like I'm rudely interrupting the discussion and going off topic, but I've been following this conversation since I found the thread. Would you object if I tried to get it moved to the CK section? I'm sure other people would be interested in this, but I bet a lot of them don't wander out of the CK forum and a search there wouldn't find this.

 

Hi, BigAndFlabby :smile:

Sure, I don't mind at all. I didn't bother to post there as didn't think it was that active.

 

By the way, BnF showed me the errors with the quest script and how to make the struct/array work the way I wanted, and then he refactored the spawn code back down to 2 functions :) So all working again.

 

Now to look into more alias packages, Vertibird attacks and a few other interesting things

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...