Jump to content

Trouble accessing quest script function from object script


SMB92

Recommended Posts

Hi again folks,

 

I'm having a seriously hard time trying to move some functions from my Object script to my Master quest script, and access those functions from the object. I was up until 3am this morning scouring Google for examples and what not and I can't see what I am doing wrong here.

 

I'll post some simple examples of what I have tried, and further below I'll post the full script.

 

So we have

 

ASC_MasterRandomQuest with ASC_MasterRandomQuestScript attached and we have ASC_SP_Random (an XmarkerHeading duplicated and reformed) with ASC_SP_RandomScript attached. I am trying to move one of the preliminary functions to the Quest script, because that functions needs to see the dynamic array of structs on the Quest, and return parameters to the Object scripts function, if that makes sense.

 

Here's what I tried so far

 

Simplified example of quest script:

 

 

ScriptName ASC_MasterRandomQuestScript extends Quest

PROPERTIES BLABLA

ActorTypeStruct[] ActorTypesRandomR1 ; local array of struct on the Quest script which is the reason this function needs to be on the quest, this is filled on startup stage and update stage, cleared on uninstall stage

Function Spawn()
     Get Array of struct details and send to SpawnEnemyActors function in local scripts version of it
EndFunction

BLABLABLA etc etc


 

 

 

Attempts at grabbing function from quest script:

 

 

Scriptname ASC_SP_Random_Script extends ObjectReference

Attempt 1

ASC_MasterRandomQuestScript Property ASC_MasterRandomQuest Auto

Function SPActivate()
    ;some code
    ASC.MasterRandomQuest.Spawn()
AND ALSO TRIED
    (ASC.MasterRandomQuest as ASC_MasterRandomQuestScript).Spawn()

DOES NOT COMPILE, ERROR "Spawn() is not a function does not exist" etc

Attempt 2

ASC_MasterRandomQuestScript Property ASC_MasterRandomQuest Auto

Function SPActivate()
    ASC_MasterRandomQuestScript masterQuest = ASC_MasterRandomQuest as ASC_MasterRandomQuestScript
    ;some code
    masterQuest.Spawn()

DOES NOT COMPILE FOR SAME REASON. IF I DECLARE masterQuest as a variable in the Empty state to store it, error will be "ASC_MasterRandomQuestScript is not a defined varaiable"
Also tried various combinations of this and proeprties

Attempt 3 (this is the current attempt where I left it at, just for fun, but same error "is not a function etc"

Quest Property ASC_MasterRandomQuest Auto
ASC_MasterRandomQuestScript Property MasterQuest Auto

ASC_MasterRandomQuestScript MasterScript = ASC_MasterRandomQuest as ASC_MasterRandomQuestScript
    ;some code
   MasterScript.Spawn() OR MasterQuest.Spawn() NO WORK


ETC ETC ETC

 

 

 

I might not have covered every combination of things I have tried to cast, but I believe I have tried everything. None of the casting methods I have seen (apart from LinkedRef and using an Alias etc etc which I have not tried because I thought this should work?). Surely this has to be a simple error or oversight on my part?

 

Anyhow here is the Quest script (Yes it is compiled in CK and all properties filled in it's current state)

 

 

Scriptname ASC_MasterRandomQuestScript extends Quest

;Import ASC_MainStruct
;Import ASC_DynMainStruct

Struct ActorTypeStruct
	ActorBase LvlActorBase
	ActorBase LvlActorBossBase
	GlobalVariable ASC_Allowed_Boss
	GlobalVariable ASC_Max_Allowed
	GlobalVariable ASC_Max_Allowed_Boss
	GlobalVariable ASC_Chance
	GlobalVariable ASC_Chance_Boss
	GlobalVariable ASC_Reroll_Allowed
	GlobalVariable ASC_Reroll_Chance
	GlobalVariable ASC_EZ_Lvl
EndStruct

GlobalVariable Property ASC_Main_ModEnabled Auto Const
GlobalVariable Property ASC_Timer_Reset_R1 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R2 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R3 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R4 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R5 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R6 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R7 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R8 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R9 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R10 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R11 Auto Const
;GlobalVariable Property ASC_Timer_Reset_R12 Auto Const
FormList Property ASC_ResetList_R1 Auto Const
;FormList Property ASC_ResetList_R2 Auto Const
;FormList Property ASC_ResetList_R3 Auto Const
;FormList Property ASC_ResetList_R4 Auto Const
;FormList Property ASC_ResetList_R5 Auto Const
;FormList Property ASC_ResetList_R6 Auto Const
;FormList Property ASC_ResetList_R7 Auto Const
;FormList Property ASC_ResetList_R8 Auto Const
;FormList Property ASC_ResetList_R9 Auto Const
;FormList Property ASC_ResetList_R10 Auto Const
;FormList Property ASC_ResetList_R11 Auto Const
;FormList Property ASC_ResetList_R12 Auto Const
ReferenceAlias Property ASC_PatrolPackageAlias Auto
ActorBase property LvlRaider Auto Const
ActorBase property LvlRaiderBoss Auto Const
GlobalVariable Property ASC_Allowed_Raider_R1 Auto Const
GlobalVariable Property ASC_Allowed_Boss_Raider_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Raider_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Boss_Raider_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Raider_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Boss_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_EZ_Raider_R1 Auto Const
ActorBase property LvlGunner Auto Const
ActorBase property LvlGunnerBoss Auto Const
GlobalVariable Property ASC_Allowed_Gunner_R1 Auto Const
GlobalVariable Property ASC_Allowed_Boss_Gunner_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Gunner_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Boss_Gunner_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Gunner_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Boss_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_EZ_Gunner_R1 Auto Const
ActorBase property LvlForged Auto Const
ActorBase property LvlForged_Boss Auto Const
GlobalVariable Property ASC_Allowed_Forged_R1 Auto Const
GlobalVariable Property ASC_Allowed_Boss_Forged_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Forged_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Boss_Forged_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Forged_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Boss_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_EZ_Forged_R1 Auto Const
ActorBase property LvlTriggerman Auto Const
GlobalVariable Property ASC_Allowed_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Allowed_Boss_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Max_Allowed_Boss_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Chance_Spawn_Boss_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Reroll_Allowed_Triggerman_R1 Auto Const
GlobalVariable Property ASC_Reroll_Chance_Triggerman_R1 Auto Const
GlobalVariable Property ASC_EZ_Triggerman_R1 Auto Const

;ActorTypeStruct[] Property ActorTypesRandomR1 Auto Const
;ActorTypeStruct[] Property ActorTypesR2 Auto Const
;ActorTypeStruct[] Property ActorTypesR3 Auto Const
;ActorTypeStruct[] Property ActorTypesR4 Auto Const
;ActorTypeStruct[] Property ActorTypesR5 Auto Const
;ActorTypeStruct[] Property ActorTypesR6 Auto Const
;ActorTypeStruct[] Property ActorTypesR7 Auto Const
;ActorTypeStruct[] Property ActorTypesR8 Auto Const
;ActorTypeStruct[] Property ActorTypesR9 Auto Const
;ActorTypeStruct[] Property ActorTypesR10 Auto Const
;ActorTypeStruct[] Property ActorTypesR11 Auto Const
;ActorTypeStruct[] Property ActorTypesR12 Auto Const
EncounterZone[] Property EzArray Auto Const

ActorTypeStruct[] ActorTypesRandomR1

bool bTimersRunning = false
Int iResetTimerR1 = 1
;Int iResetTimerR2 = 2
;Int iResetTimerR3 = 3
;Int iResetTimerR4 = 4
;Int iResetTimerR5 = 5
;Int iResetTimerR6 = 6
;Int iResetTimerR7 = 7
;Int iResetTimerR8 = 8
;Int iResetTimerR9 = 9
;Int iResetTimerR10 = 10
;Int iResetTimerR11 = 11
;Int iResetTimerR12 = 12

Event OnStageSet(int auiStageID, int auiItemID)
	if (auiStageID == 10) && (bTimersRunning == false)
		StartTimerGameTime(ASC_Timer_Reset_R1.GetValueInt(), iResetTimerR1)
		Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R2.GetValueInt(), iResetTimerR2)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R3.GetValueInt(), iResetTimerR3)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R4.GetValueInt(), iResetTimerR4)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R5.GetValueInt(), iResetTimerR5)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R6.GetValueInt(), iResetTimerR6)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R7.GetValueInt(), iResetTimerR7)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R8.GetValueInt(), iResetTimerR8)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R9.GetValueInt(), iResetTimerR9)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R10.GetValueInt(), iResetTimerR10)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R11.GetValueInt(), iResetTimerR11)
		;Utility.Wait(0.1)
		;StartTimerGameTime(ASC_Timer_Reset_R12.GetValueInt(), iResetTimerR12)
		bTimersRunning = true
		FillArrays()
		ASC_Main_ModEnabled.SetValue(1.0)
	elseif (auiStageID == 100)
		ASC_Main_ModEnabled.SetValue(0.0)
		CancelTimerGameTime(iResetTimerR1)
		;CancelTimerGameTime(iResetTimerR2)
		;CancelTimerGameTime(iResetTimerR3)
		;CancelTimerGameTime(iResetTimerR4)
		;CancelTimerGameTime(iResetTimerR5)
		;CancelTimerGameTime(iResetTimerR6)
		;CancelTimerGameTime(iResetTimerR7)
		;CancelTimerGameTime(iResetTimerR8)
		;CancelTimerGameTime(iResetTimerR9)
		;CancelTimerGameTime(iResetTimerR10)
		;CancelTimerGameTime(iResetTimerR11)
		;CancelTimerGameTime(iResetTimerR12)
		bTimersRunning = false
		ClearAllArrays()
	endif
EndEvent

Event OnTimerGameTime(int aiTimerID)
	if aiTimerID == iResetTimerR1
		Int iIndex = 0
		While (iIndex < ASC_ResetList_R1.GetSize())
			ObjectReference kMarker = ASC_ResetList_R1.GetAt(iIndex) as ObjectReference
			kMarker.EnableNoWait()
			iIndex += 1
		EndWhile
		ASC_ResetList_R1.Revert()
	;elseif aiTimerID == iResetTimerR2
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R2.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R2.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R2.Revert()
	;elseif aiTimerID == iResetTimerR3
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R3.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R3.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R3.Revert()
	;elseif aiTimerID == iResetTimerR4
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R4.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R4.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R4.Revert()
	;elseif aiTimerID == iResetTimerR5
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R5.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R5.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R5.Revert()
	;elseif aiTimerID == iResetTimerR6
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R6.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R6.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R6.Revert()
	;elseif aiTimerID == iResetTimerR7
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R7.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R7.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R7.Revert()
	;elseif aiTimerID == iResetTimerR8
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R8.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R8.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R8.Revert()
	;elseif aiTimerID == iResetTimerR9
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R9.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R9.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R9.Revert()
	;elseif aiTimerID == iResetTimerR10
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R10.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R10.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R10.Revert()
	;elseif aiTimerID == iResetTimerR11
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R11.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R11.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R11.Revert()
	;elseif aiTimerID == iResetTimerR12
	;	Int iIndex = 0
	;	While (iIndex < ASC_ResetList_R12.GetSize())
	;		ObjectReference kMarker = ASC_ResetList_R12.GetAt(iIndex) as ObjectReference
	;		kMarker.EnableNoWait()
	;		iIndex += 1
	;	EndWhile
	;	ASC_ResetList_R12.Revert()
	endif
EndEvent

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
	ActorTypesRandomR1 = new ActorTypeStruct[iPosition]
		if ASC_Allowed_Raider_R1.GetValueInt() == 1
			ActorTypesRandomR1[iPosition].LvlActorBase = LvlRaider
			ActorTypesRandomR1[iPosition].LvlActorBossBase = LvlRaiderBoss
			ActorTypesRandomR1[iPosition].ASC_Allowed_Boss = ASC_Allowed_Boss_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed = ASC_Max_Allowed_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_Chance = ASC_Chance_Spawn_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Allowed = ASC_Reroll_Allowed_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Chance = ASC_Reroll_Chance_Raider_R1
			ActorTypesRandomR1[iPosition].ASC_EZ_Lvl = ASC_EZ_Raider_R1
			iPosition += 1
		else
			;Nothing, ActorType does not enter the array
		endif
		if ASC_Allowed_Gunner_R1.GetValueInt() == 1
			ActorTypesRandomR1[iPosition].LvlActorBase = LvlGunner
			ActorTypesRandomR1[iPosition].LvlActorBossBase = LvlGunnerBoss
			ActorTypesRandomR1[iPosition].ASC_Allowed_Boss = ASC_Allowed_Boss_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed = ASC_Max_Allowed_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_Chance = ASC_Chance_Spawn_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Allowed = ASC_Reroll_Allowed_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Chance = ASC_Reroll_Chance_Gunner_R1
			ActorTypesRandomR1[iPosition].ASC_EZ_Lvl = ASC_EZ_Gunner_R1
			iPosition += 1
		else
			;Nothing, ActorType does not enter the array
		endif
		if ASC_Allowed_Forged_R1.GetValueInt() == 1
			ActorTypesRandomR1[iPosition].LvlActorBase = LvlForged
			ActorTypesRandomR1[iPosition].LvlActorBossBase = LvlForged_Boss
			ActorTypesRandomR1[iPosition].ASC_Allowed_Boss = ASC_Allowed_Boss_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed = ASC_Max_Allowed_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_Chance = ASC_Chance_Spawn_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Allowed = ASC_Reroll_Allowed_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Chance = ASC_Reroll_Chance_Forged_R1
			ActorTypesRandomR1[iPosition].ASC_EZ_Lvl = ASC_EZ_Forged_R1
			iPosition += 1
		else
			;Nothing, ActorType does not enter the array
		endif
		if ASC_Allowed_Triggerman_R1.GetValueInt() == 1
			ActorTypesRandomR1[iPosition].LvlActorBase = LvlTriggerman
			ActorTypesRandomR1[iPosition].LvlActorBossBase = LvlTriggerman
			ActorTypesRandomR1[iPosition].ASC_Allowed_Boss = ASC_Allowed_Boss_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed = ASC_Max_Allowed_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_Max_Allowed_Boss = ASC_Max_Allowed_Boss_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_Chance = ASC_Chance_Spawn_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_Chance_Boss = ASC_Chance_Spawn_Boss_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Allowed = ASC_Reroll_Allowed_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_Reroll_Chance = ASC_Reroll_Chance_Triggerman_R1
			ActorTypesRandomR1[iPosition].ASC_EZ_Lvl = ASC_EZ_Triggerman_R1
			iPosition += 1
		else
			;Nothing, ActorType does not enter the array
		endif
EndFunction

Function ClearAllArrays()
	ActorTypesRandomR1.Clear()
EndFunction

Function SpawnR1() ;called/cast on each marker as Self, so that parameters will be passed to subsequent local functions
    int iNumSpawnTypes = ActorTypesRandomR1.Length ; how many types of spawning actors can we support
    int iWhoToSpawn = Utility.RandomInt(1,iNumSpawnTypes) ; changed to use the size of our array of actor types
    ActorTypeStruct spawnDetails = ActorTypesRandomR1[iWhoToSpawn]
    SpawnEnemyActors(spawnDetails.ASC_Max_Allowed.GetValueInt(), spawnDetails.ASC_Chance.GetValueInt(), spawnDetails.LvlActorBase, spawnDetails.ASC_Allowed_Boss.GetValue() as Bool, spawnDetails.ASC_Max_Allowed_Boss.GetValueInt(), spawnDetails.ASC_Chance_Boss.GetValueInt(), spawnDetails.LvlActorBossBase, spawnDetails.ASC_EZ_Lvl.GetValueInt(), spawnDetails.ASC_Reroll_Allowed.GetValueInt(), spawnDetails.ASC_Reroll_Chance.GetValueInt())
EndFunction

Function SpawnAnotherGroupR1() ;this simulates spawning battles between two groups, or possibly a really large group of the same enemy. 
	int iNumSpawnTypes = ActorTypesRandomR1.Length ; how many types of spawning actors can we support
    int iWhoToSpawn = Utility.RandomInt(1,iNumSpawnTypes) ; changed to use the size of our array of actor types
    ActorTypeStruct spawnDetails = ActorTypesRandomR1[iWhoToSpawn]
    SpawnMoreEnemyActors(spawnDetails.ASC_Max_Allowed.GetValueInt(), spawnDetails.ASC_Chance.GetValueInt(), spawnDetails.LvlActorBase, spawnDetails.ASC_Allowed_Boss.GetValue() as Bool, spawnDetails.ASC_Max_Allowed_Boss.GetValueInt(), spawnDetails.ASC_Chance_Boss.GetValueInt(), spawnDetails.LvlActorBossBase, spawnDetails.ASC_EZ_Lvl.GetValueInt(), spawnDetails.ASC_Reroll_Allowed.GetValueInt(), spawnDetails.ASC_Reroll_Chance.GetValueInt())
EndFunction

Function SpawnYetAnotherGroupR1() ;this simulates spawning battles between two groups, or possibly a really large group of the same enemy. 
	int iNumSpawnTypes = ActorTypesRandomR1.Length ; how many types of spawning actors can we support
    int iWhoToSpawn = Utility.RandomInt(1,iNumSpawnTypes) ; changed to use the size of our array of actor types
    ActorTypeStruct spawnDetails = ActorTypesRandomR1[iWhoToSpawn]
    SpawnEvenMoreEnemyActors(spawnDetails.ASC_Max_Allowed.GetValueInt(), spawnDetails.ASC_Chance.GetValueInt(), spawnDetails.LvlActorBase, spawnDetails.ASC_Allowed_Boss.GetValue() as Bool, spawnDetails.ASC_Max_Allowed_Boss.GetValueInt(), spawnDetails.ASC_Chance_Boss.GetValueInt(), spawnDetails.LvlActorBossBase, spawnDetails.ASC_EZ_Lvl.GetValueInt(), spawnDetails.ASC_Reroll_Allowed.GetValueInt(), spawnDetails.ASC_Reroll_Chance.GetValueInt())
EndFunction

Function SpawnEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
	;Empty so local script uses it's version so arrays on the marker are individual to each marker
EndFunction

Function SpawnMoreEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
	;Empty so local script uses it's version so arrays on the marker are individual to each marker
EndFunction

Function SpawnEvenMoreEnemyActors(int iMaxSpawnCount, int iChance, ActorBase varBaseActor, bool bBossAllowed, int iMaxBossCount, int iBossChance, ActorBase varBossActor, int iEzLevel, int iRerollAllowed, int iRerollChance)
	;Empty so local script uses it's version so arrays on the marker are individual to each marker
EndFunction

 

 

 

 

And here is the Object script (which still reflects the insane attempt at casting from my examples above, have not fixed yet but all the same lol)

 

 

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

;import ASC_MainStruct

Quest Property ASC_MasterRandomQuest Auto
ASC_MasterRandomQuestScript Property MasterQuest Auto

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

Actor[] GroupList  ; Array to track and cleanup all aspawned actors later, as well as apply new features in future
bool bSpawnPointLoaded = false ;bool for cleanup event
bool Group2Loaded = false
bool Group3Loaded = false
int iRerollLimit = 0
int iRerollCount = 0
Actor[] GroupList2
Actor[] Grouplist3

Event OnCellAttach()
	bSpawnPointLoaded = true
	if (Self.IsDisabled() == false) && (ASC_Main_ModEnabled.GetValueInt() == 1) && (ASC_Main_Enabled_Random_R1.GetValueInt() == 1)
		SPActivate()
	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
		while (PlayerRef.IsInCombat())
		; Do nothing until combat is over, then check if we are still in the loaded area
		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
				GroupList[iCounter].DeleteWhenAble()
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.RemoveFromRef(GroupList[iCounter])
				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
				GroupList2[iCounter].DeleteWhenAble()
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.RemoveFromRef(GroupList2[iCounter])
				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
				GroupList3[iCounter].DeleteWhenAble()
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.RemoveFromRef(GroupList3[iCounter])
				iCounter += 1
			endwhile
			iCounter = 0
		endif
EndEvent

Function SPActivate()  ;This may not be necessary but it looks neat. Main roll chance and disabling happens here
	ASC_MasterRandomQuestScript MasterScript = ASC_MasterRandomQuest as ASC_MasterRandomQuestScript
	iRerollLimit = ASC_Main_Reroll_Limit_R1.GetValueInt()
	int iChanceToSpawn = Utility.RandomInt(1,100)
    if (iChanceToSpawn <= ASC_Main_Random_Chance_R1.GetValueInt())
        MasterScript.Spawn()
        Self.Disable()
        ASC_ResetList_R1.AddForm(Self)
		MasterScript = None
    elseif (iChanceToSpawn >= ASC_Main_Random_Chance_R1.GetValueInt()) && (ASC_Main_Random_DisableOnBlock_R1.GetValueInt() == 1)
        Self.Disable()
        ASC_ResetList_R1.AddForm(Self)
    else
        ;Nothing, exit function
    endif
EndFunction

;Function Spawn()
	;iRerollLimit = ASC_Main_Reroll_Limit_R1.GetValueInt()
    ;int iNumSpawnTypes = (MasterQuest as ASC_MasterRandomQuestScript).ActorTypesR1.Length ; how many types of spawning actors can we support
    ;int iWhoToSpawn = Utility.RandomInt(1,iNumSpawnTypes) ; changed to use the size of our array of actor types
    ;ActorTypeStruct spawnDetails = (MasterQuest as ASC_MasterRandomQuestScript).ActorTypesR1[iWhoToSpawn]
    ;SpawnEnemyActors(spawnDetails.ASC_Max_Allowed.GetValueInt(), spawnDetails.ASC_Chance.GetValueInt(), spawnDetails.LvlActorBase, spawnDetails.ASC_Allowed_Boss.GetValue() as Bool, spawnDetails.ASC_Max_Allowed_Boss.GetValueInt(), spawnDetails.ASC_Chance_Boss.GetValueInt(), spawnDetails.LvlActorBossBase, spawnDetails.ASC_EZ_Lvl.GetValueInt(), spawnDetails.ASC_Reroll_Allowed.GetValueInt(), spawnDetails.ASC_Reroll_Chance.GetValueInt())
;EndFunction

Function SpawnEnemyActors(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)
	int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = iMaxSpawnCount
	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)
                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
                Debug.Notification("Array Add Success. Actor count now: " + iPosition)
            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,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                    iPosition = GroupList.Length - 1
                    ;GroupList[iPosition].SetLinkedRef(kPatrolMarker)
					(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList[iPosition])
                    Debug.Notification("Array Add Success. Actor count now: " + iPosition)
                endif
                iSpawnCounter += 1
            endwhile
        endif
		if (iRerollAllowed == 1) && (iRerollCount < iRerollLimit) && (Utility.RandomInt(1,100) <= iRerollChance)  ;iRerollLimit is a universal value, only 1 global per region, not per type
			ASC_MasterRandomQuestScript MasterScript = ASC_MasterRandomQuest as ASC_MasterRandomQuestScript
			MasterScript.SpawnAnotherGroup()
			iRerollCount += 1
			MasterScript = None
		else
			;Nothing, exit function
		endif
EndFunction

;Function SpawnAnotherGroup()  ;this simulates spawning battles between two groups, or possibly a really large group of the same enemy. 
	;int iNumSpawnTypes = (MasterQuest as ASC_MasterRandomQuestScript).ActorTypesR1.Length ; how many types of spawning actors can we support
    ;int iWhoToSpawn = Utility.RandomInt(1,iNumSpawnTypes) ; changed to use the size of our array of actor types
    ;ActorTypeStruct spawnDetails = (MasterQuest as ASC_MasterRandomQuestScript).ActorTypesR1[iWhoToSpawn]
    ;SpawnMoreEnemyActors(spawnDetails.ASC_Max_Allowed.GetValueInt(), spawnDetails.ASC_Chance.GetValueInt(), spawnDetails.LvlActorBase, spawnDetails.ASC_Allowed_Boss.GetValue() as Bool, spawnDetails.ASC_Max_Allowed_Boss.GetValueInt(), spawnDetails.ASC_Chance_Boss.GetValueInt(), spawnDetails.LvlActorBossBase, spawnDetails.ASC_EZ_Lvl.GetValueInt(), spawnDetails.ASC_Reroll_Allowed.GetValueInt(), spawnDetails.ASC_Reroll_Chance.GetValueInt())
;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)
	int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = iMaxSpawnCount
	int iPosition = 0
    GroupList2 = 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)
                GroupList2.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                iPosition = GroupList.Length - 1
                ;GroupList[iPosition].SetLinkedRef(kPatrolMarker) old sytem
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList2[iPosition])  ;new system for patrols
                Debug.Notification("Array Add Success. Actor count now: " + iPosition)
            endif
            iSpawnCounter += 1
        endwhile
		Group2Loaded = true
        if bBossAllowed == 1
            iSpawnCounter = 0 ; reuse var. memory efficient
            while (iSpawnCounter < iMaxBossCount)
                if (Utility.RandomInt(1,100) <= iBossChance)
                    GroupList2.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(GroupList2[iPosition])
                    Debug.Notification("Array Add Success. Actor count now: " + iPosition)
                endif
                iSpawnCounter += 1
            endwhile
        endif
		if (iRerollAllowed == 1) && (iRerollCount < iRerollLimit) && (Utility.RandomInt(1,100) <= iRerollChance)
			ASC_MasterRandomQuestScript MasterScript = ASC_MasterRandomQuest as ASC_MasterRandomQuestScript
			MasterScript.SpawnYetAnotherGroup()
			iRerollCount += 1
			MasterScript = None
		else
			;Nothing, exit function
		endif
EndFunction

;Function SpawnYetAnotherGroup()  ;this simulates spawning battles between two groups, or possibly a really large group of the same enemy. 
	;int iNumSpawnTypes = (MasterQuest as ASC_MasterRandomQuestScript).ActorTypesR1.Length ; how many types of spawning actors can we support
    ;int iWhoToSpawn = Utility.RandomInt(1,iNumSpawnTypes) ; changed to use the size of our array of actor types
    ;ActorTypeStruct spawnDetails = (MasterQuest as ASC_MasterRandomQuestScript).ActorTypesR1[iWhoToSpawn]
    ;SpawnEvenMoreEnemyActors(spawnDetails.ASC_Max_Allowed.GetValueInt(), spawnDetails.ASC_Chance.GetValueInt(), spawnDetails.LvlActorBase, spawnDetails.ASC_Allowed_Boss.GetValue() as Bool, spawnDetails.ASC_Max_Allowed_Boss.GetValueInt(), spawnDetails.ASC_Chance_Boss.GetValueInt(), spawnDetails.LvlActorBossBase, spawnDetails.ASC_EZ_Lvl.GetValueInt(), spawnDetails.ASC_Reroll_Allowed.GetValueInt(), spawnDetails.ASC_Reroll_Chance.GetValueInt())
;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)
	int iDifficulty = ASC_Main_Difficulty_R1.GetValueInt()
    int iSpawnCounter = iMaxSpawnCount
	int iPosition = 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)
                GroupList3.Add(Self.PlaceActorAtMe(varBaseActor, Utility.RandomInt(1,iDifficulty), (MasterQuest as ASC_MasterRandomQuestScript).EzArray[iEzLevel]))
                iPosition = GroupList.Length - 1
                ;GroupList[iPosition].SetLinkedRef(kPatrolMarker) old sytem
				(MasterQuest as ASC_MasterRandomQuestScript).ASC_PatrolPackageAlias.ApplyToRef(GroupList3[iPosition])  ;new system for patrols
                Debug.Notification("Array Add Success. Actor count now: " + iPosition)
            endif
            iSpawnCounter += 1
        endwhile
		Group3Loaded = true
        if bBossAllowed == 1
            iSpawnCounter = 0 ; reuse var. memory efficient
            while (iSpawnCounter < iMaxBossCount)
                if (Utility.RandomInt(1,100) <= iBossChance)
                    GroupList3.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(GroupList3[iPosition])
                    Debug.Notification("Array Add Success. Actor count now: " + iPosition)
                endif
                iSpawnCounter += 1
            endwhile
			;Nothing, exit function
        endif
EndFunction

 

 

 

 

Any pointers here is much appreciated :) I can revert back to using a full property for the array of struct, but I am attempting to make the mod a bit more dynamic.

Link to comment
Share on other sites

Your attempt 1 has property of ASC_ and when you try to call function ASC. ? _ vs .

 

I have several scripts that use functions from other scripts and all work just like this:

ScriptNameSpelledRight Property SomeName Auto

Event SomeRandomEvent()

SomeName.SomeFunction()

EndEvent

This same method I call ReferenceAlias script function from magic effect for example and it works.

 

Make sure your script property is filled and the script name is 100% correct. Casting As xxxxScript I don't have much experience.. other than copying what game does for companions like:

(Alias_Companion.GetActorReference() as CompanionActorScript).SetHasLeftPlayerPermanently()
Edited by vkz89q
Link to comment
Share on other sites

Soz thats just a spelling mistake the ASC. Vs ASC_ in my example.

 

It simply not working in this way, maybe the script has to be in an alias. The casting as technique is mentioned a few places but WOTC makes ample use of it. Basically it goes Scriptname TempVariable = QuestProperty as Scriptname. I have the property prefilled on the object script when trying to compile. Always errors that its not a function. Even when I uncomment the original function on the object script, so it definitely recognizes/is trying to pull the function from the quest script. As mentioned the quest is setup and its script compiled.

 

Seems very strange to me. I bet theres some small technicality to it

Link to comment
Share on other sites

PROBLEM SOLVED. Guess I needed the 8 hours away from this to see the blatant mistake. Compiled now :) Just have to test what comes out the other end in game.

 

Note To Self: When moving functions to another script and renaming them, REMEMBER TO RENAME THEM IN THE DEPENDANT SCRIPTS!! (Can't find Spawn() in Questscript, because it is renamed SpawnR1() rofl)

 

(Proceeds to chastise)

 

Thanks vkz for confirming :)

Link to comment
Share on other sites

Good good. I just renamed all my scripts and fragments on one of my mods. I wanted them to be organized. Let me tell you that was a HUGE pain with all the scripts that access other scripts, lol. But finally all is nice and clean :happy:

Link to comment
Share on other sites

Lol. I guess I have to figure out now how to pass down the parameters (as full properties) to the object script, the way it is written now I don't think it can be done. You can go up the chain but not back down....

Link to comment
Share on other sites

The simple way to pass "down" Quest properties to your object would be to simply look at the Quest properties, like so (in your Object script):

ASC_MasterRandomQuestScript Property MRQScript Auto
 
ObjectReference objref = MRQScript.ObjRef
Edit: Looking closer at your object code, you already refer to the Quest Script. So you're already accessing the quest's properties and can pass them "down" to your objects. Edited by Reneer
Link to comment
Share on other sites

The simple way to pass "down" Quest properties to your object would be to simply look at the Quest properties, like so (in your Object script):

ASC_MasterRandomQuestScript Property MRQScript Auto
 
ObjectReference objref = MRQScript.ObjRef
Edit: Looking closer at your object code, you already refer to the Quest Script. So you're already accessing the quest's properties and can pass them "down" to your objects.

 

The problem I'm having now is that the Spawn() function starts the SpawnEnemyActors() function, but in my testing it goes straight to the Quests version of it, so it doesn't use the Objects version of it like it would a child script. This is what I'm currently investigating.

 

Maybe I'm a little confused about this too, but I've made the ActorTypeStruct[] a "private" variable on the Quest. But all the contents in it are properties of the script, so I'm thinking I should be able to pass those as parameters to the SpawnEnemyActors() function even if it is on another script?

 

I'm at work for a few more hours, but I ws gonna try making an extension script and attachingthat to the object as well, and try some casting techniques but I'm not sure how that would play out. Looking at the wiki earlier, I wrote down these notes regarding what I was thinking, based on its example:

 

 

Scriptname Horse extends Actor
 
Event OnSeeWolf()
  Debug.Notification("Horse runs away.")
EndEvent



Scriptname WarHorse extends Horse
 
Event OnSeeWolf()
  Debug.Notification("Horse attacks wolf.")
EndEvent



(MeanWarhorse as Horse).OnSeeWolf()
;Is this code in the WarHorse script which extends the Horse script, and attached to MeanWarHorse? 
;Or is a new script that extending Actor attached to MeanWarhorse along with WarHorse, so both attached?
;If the first is true, than perhaps the objectscript(MeanWarHorse) needs to be directly converted to extensionscript(WarHorse)
;But how does it get the OnCellAttach Event and Spawn on itself (the object/marker)?
;Maybe all we need to do is cast (Self/ObjectScriptName as ParentScript) and it will act as a childscript?
;But in that case, how will it use Private (Variables) proeprties on the quest script? 

 

 

Link to comment
Share on other sites

 

The simple way to pass "down" Quest properties to your object would be to simply look at the Quest properties, like so (in your Object script):

ASC_MasterRandomQuestScript Property MRQScript Auto
 
ObjectReference objref = MRQScript.ObjRef
Edit: Looking closer at your object code, you already refer to the Quest Script. So you're already accessing the quest's properties and can pass them "down" to your objects.

 

The problem I'm having now is that the Spawn() function starts the SpawnEnemyActors() function, but in my testing it goes straight to the Quests version of it, so it doesn't use the Objects version of it like it would a child script. This is what I'm currently investigating.

 

Maybe I'm a little confused about this too, but I've made the ActorTypeStruct[] a "private" variable on the Quest. But all the contents in it are properties of the script, so I'm thinking I should be able to pass those as parameters to the SpawnEnemyActors() function even if it is on another script?

 

I'm at work for a few more hours, but I ws gonna try making an extension script and attachingthat to the object as well, and try some casting techniques but I'm not sure how that would play out. Looking at the wiki earlier, I wrote down these notes regarding what I was thinking, based on its example:

 

 

Scriptname Horse extends Actor
 
Event OnSeeWolf()
  Debug.Notification("Horse runs away.")
EndEvent



Scriptname WarHorse extends Horse
 
Event OnSeeWolf()
  Debug.Notification("Horse attacks wolf.")
EndEvent



(MeanWarhorse as Horse).OnSeeWolf()
;Is this code in the WarHorse script which extends the Horse script, and attached to MeanWarHorse? 
;Or is a new script that extending Actor attached to MeanWarhorse along with WarHorse, so both attached?
;If the first is true, than perhaps the objectscript(MeanWarHorse) needs to be directly converted to extensionscript(WarHorse)
;But how does it get the OnCellAttach Event and Spawn on itself (the object/marker)?
;Maybe all we need to do is cast (Self/ObjectScriptName as ParentScript) and it will act as a childscript?
;But in that case, how will it use Private (Variables) proeprties on the quest script? 

 

 

OMG my beautiful code, what did you do? Just kidding. Glad to see you're making some headway. Why would you have a SpawnEnemyActors function in both scripts?

 

To do what I think you want to do, you need to pass the calling object's reference to the quest when you call spawn() so that inside spawn() it can call back to the object's SpawnEnemyActors. Like this:

 

 

 

Scriptname ASC_SP_Random_Script extends ObjectReference
 
ASC_MasterRandomQuestScript Property ASC_MasterRandomQuest Auto

Function SpawnEnemyActors(arguments...)
    ;some stuff here
EndFunction

Function SPActivate()
    ;(ASC_MasterRandomQuest as ASC_MasterRandomQuestScript).Spawn()
    ASC_MasterRandomQuest.Spawn(self) ; you don't have to cast this because the property is already cast just make sure you spell it right :)
EndFunction

 

 

 

 

 


ScriptName ASC_MasterRandomQuestScript extends Quest
 
;PROPERTIES BLABLA
 
ActorTypeStruct[] ActorTypesRandomR1 ; local array of struct on the Quest script which is the reason this function needs to be on the quest, this is filled on startup stage and update stage, cleared on uninstall stage
 
Function Spawn(ASC_SP_Random_Script akCallingObject) ; assuming you will ALWAYS be calling this function from ASC_SP_Random_Script
     Get Array of struct details and send to SpawnEnemyActors function in local scripts version of it
akCallingObject.SpawnEnemyActors(arguments...)
EndFunction
 
;BLABLABLA etc etc

 

 

 

Let me know if that doesn't make sense or work. Gimme your current code and I'll see what's up.

 

I should point out that using this type of method is considered blocking. It will prevent another object from calling the quest script until the first object is completely finished and returns back to the quest, and it then in turn finishes and returns out of it's called function. One way around this (but it has it's own issues) would be to setup a callback function which sets variables in the object script and then returns to the quest. Then have the quest send a CustomEvent (http://www.creationkit.com/fallout4/index.php?title=Custom_Papyrus_Events) that the object is listening for. That causes a separate thread to activate to call the event listener. The event listener then pulls the (now local) variables and calls the SpawnEnemyActors in it's own script context. The issue is that if you at any point had more than one object registered for the CustomeEvent, as soon as the quest sends the event they all get it at the same time. So the best procedure here would be to

in object script:
    ;somewhere immediately before calling quest to spawn()
    register for event
    call quest.spawn(self)
    ;if you setup spawn() correctly it will send the event triggering our event before returning
 
 
;somewhere else in the same script
in the event handler:
    ;immediately after being called
    unregister for event
    ;then
    do other stuff like call SpawnEnemyActors()

A good practice would be to clear out the variables before calling the quest spawn and then in the event handler put a check to see if the variables are set. If they're not then it should just return out of the function as to keep listening. Because another event should be coming. It was probably meant for another object. If it is then it should unregister and proceed since it was probably the event meant for itself.

Edited by BigAndFlabby
Link to comment
Share on other sites

Hahaha I just gave up on that approach and ran into a roadblock with the code as it was before (just posted back over at the other thread).


I didn't try that approach, casting the object, but lemme tell ya, I tried everything else lol, but no matter what I couldn't get those private variables outta the quest!


Let's try this way then :smile:

Edit - i like that blocking feature, I was concerned what would happen if 2 points accessed it at the same time. I'd like to learn that workaround though

 

Edit 2 - akCallingObject.SpawnEnemyActors(arguments...)

Can't believe that's all I needed. Quest script wouldn't compile, said missing function. I tried adding a bogus function to the quest, thinking the Object script would act as a child script, but of course that won't happen.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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