SMB92 Posted May 31, 2017 Share Posted May 31, 2017 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 More sharing options...
vkz89q Posted May 31, 2017 Share Posted May 31, 2017 (edited) 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 May 31, 2017 by vkz89q Link to comment Share on other sites More sharing options...
SMB92 Posted June 1, 2017 Author Share Posted June 1, 2017 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 More sharing options...
SMB92 Posted June 1, 2017 Author Share Posted June 1, 2017 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 More sharing options...
vkz89q Posted June 1, 2017 Share Posted June 1, 2017 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 More sharing options...
SMB92 Posted June 2, 2017 Author Share Posted June 2, 2017 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 More sharing options...
Reneer Posted June 2, 2017 Share Posted June 2, 2017 (edited) 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 June 2, 2017 by Reneer Link to comment Share on other sites More sharing options...
SMB92 Posted June 2, 2017 Author Share Posted June 2, 2017 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 More sharing options...
JonathanOstrus Posted June 3, 2017 Share Posted June 3, 2017 (edited) 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 June 3, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
SMB92 Posted June 3, 2017 Author Share Posted June 3, 2017 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 More sharing options...
Recommended Posts