SKKmods Posted February 9, 2023 Share Posted February 9, 2023 Have an odd one where trying to define script properties for exterior cells fails, interior cells work fine. The script which compiles fine and the properties all autofill: Cell Property pDiamondCityExt Auto Const Mandatory ;0000e50c Cell Property pDiamondCityExt01 Auto Const Mandatory ;0000e50b Cell Property pDiamondCityExt03 Auto Const Mandatory ;0000e097 Cell Property pGoodneighborExt Auto Const Mandatory ;0000e50d Cell Property pGoodneighborExt02 Auto Const Mandatory ;0000e078 Cell Property pGoodneighborExt03 Auto Const Mandatory ;0000e079 The runtime papyrus error log: error: Property pDiamondCityExt on script SKK_TarkovQuestScript attached to SKK_TarkovQuest (19000F99) cannot be bound because <nullptr form> (0000E50C) is not the right type error: Property pDiamondCityExt03 on script SKK_TarkovQuestScript attached to SKK_TarkovQuest (19000F99) cannot be bound because <nullptr form> (0000E50B) is not the right type error: Property pGoodneighborExt02 on script SKK_TarkovQuestScript attached to SKK_TarkovQuest (19000F99) cannot be bound because <nullptr form> (0000E097) is not the right type error: Property pDiamondCityExt01 on script SKK_TarkovQuestScript attached to SKK_TarkovQuest (19000F99) cannot be bound because <nullptr form> (0000E50D) is not the right type error: Property pGoodneighborExt03 on script SKK_TarkovQuestScript attached to SKK_TarkovQuest (19000F99) cannot be bound because <nullptr form> (0000E078) is not the right type error: Property pGoodneighborExt on script SKK_TarkovQuestScript attached to SKK_TarkovQuest (19000F99) cannot be bound because <nullptr form> (0000E079) is not the right typeEh ? Link to comment Share on other sites More sharing options...
LarannKiar Posted February 9, 2023 Share Posted February 9, 2023 (edited) I think it's because the game can't see unloaded exterior cells, only the interior ones. (Not sure about this as I mostly use script functions on interior cells). I guess Diamond City and Goodneighbor are not loaded by the time the script initializes so the virtual machine fails to initialize their cell properties. CGF "MyScript.IsPlayerInCell" DD60 only works if SanctuaryExt is loaded. CGF "MyScript.IsPlayerInCell" 1E58 works always. Scriptname MyScript ; CGF "MyScript.IsPlayerInCell" TheCell ; DD60 = SanctuaryExt ; 1E58 = DmndPlayerHome01 Function IsPlayerInCell(Cell TheCell) Global If Game.GetPlayer().GetParentCell() == TheCell Debug.MessageBox("True") Else Debug.MessageBox("False") EndIf EndFunction GetInCell (the Console/Condition equivalent) should give the same result. Edited February 9, 2023 by LarannKiar Link to comment Share on other sites More sharing options...
SKKmods Posted February 10, 2023 Author Share Posted February 10, 2023 It looks very much like external cells can not be referenced in script unless they are loaded or preloaded. To preload a cell one has to find (or make) an object in it persistent though :sad: Step though this test script with debug log results inserted to learn more: ObjectReference Property pDmndGateRef Auto Const Mandatory ; property makes it persistent Cell Property pDiamondCityExt Auto Const Mandatory ;Error: ... cannot be bound because <nullptr form> (0000E50C) is not the right type] Function CellTest() DebugOnly ; cqf SKK_testCellQuest "SKK_testCellQuestScript.Celltest" Debug.Trace("SKK_testCellScript.pDmndGateRefPROPERTY " + pDmndGateRef) ;RESULT SKK_testCellScript.pDmndGateRefPROPERTY [ObjectReference < (00077A87)>] Debug.Trace("SKK_testCellScript.pDiamondCityExtPROPERTY " + pDiamondCityExt) ;RESULT SKK_testCellScript.pDiamondCityExtPROPERTY None Cell DiamondCityExtSTATIC = Game.GetFormFromFile(0x0000e50c, "Fallout4.esm") as Cell Debug.Trace("SKK_testCellScript.DiamondCityExtSTATIC " + DiamondCityExtSTATIC) ;RESULT SKK_testCellScript.DiamondCityExtSTATIC None Cell DiamondCityExtDYNAMICnoPreload = pDmndGateRef.GetParentCell() Debug.Trace("SKK_testCellScript.DiamondCityExtDYNAMICnoPreload " + DiamondCityExtDYNAMICnoPreload) ;RESULT SKK_testCellScript.DiamondCityExtDYNAMICnoPreload None pDmndGateRef.PreloadExteriorCell() Cell DiamondCityExtDYNAMICyesPreload = pDmndGateRef.GetParentCell() Debug.Trace("SKK_testCellScript.DiamondCityExtDYNAMICyesPreload " + DiamondCityExtDYNAMICyesPreload) ;RESULT SKK_testCellScript.DiamondCityExtDYNAMICyesPreload [Cell <DiamondCityExt (0000E50C)>] EndFunction Link to comment Share on other sites More sharing options...
PJMail Posted February 14, 2023 Share Posted February 14, 2023 That is a very interesting observation, particularly reguarding an obscure effect being discussed on Discord concerning Cell records and Partial Forms(That just adding the presistent cell override to a mod, no refs even required, seems to cause any other cell overrides in that mod to act differently).- this 'could' be related somehow to your assertion - "To preload a cell one has to find (or make) an object in it persistent". What have you seen that suggests this? pDmndGateRef is already defined as persistent, yet the cell is not preloaded until you manually do it via PreloadExteriorCell(). I am also struggling with the difference between "Loaded" and "Attached" (for cells), and what it actually means in-game. Link to comment Share on other sites More sharing options...
SKKmods Posted February 14, 2023 Author Share Posted February 14, 2023 It is not the persistence of the object in the cell that does anything to the cell, rather: To BE ABLE to preload an external cell one needs to be able to REFER TO IT in script. BUT, if the external cell is not loaded then it can not be REFERED TO in script. The only time an unloaded external cell can be referred to is if it is loaded. Amusingly a script property cant be used to test if it is loaded as the script is unlikly to initalize just when the player happens to be in that specific cell. So GetFormFromFile has to be used, but to work that EXPENSIVE function has to be run as every cell loads to then test if it fills and if it is that cell. So *technically* possible, but totally insane. So the only way to REFER TO an external cell in script is to get a handle to an object that is in the cell and use that as the proxy: pDmndGateRef < --- The object I have a direct script handle on to be persistent.GetParentCell() <----- The probably unloaded cell I can not get a direct handle to If the object is already persistent GetFormFromFile can be used for a dynamic fill. If not, it needs to be made a Script.Property, Quest.ReferenceAlias or put in a FromList to make it statically persistent. I ignore the attached state as it is not well defined. Down the pub I would suggest it may be in the cell buffer to load or unload, but what that means to the objects in it is unqualified and I have not tested. ps handle == pointer Link to comment Share on other sites More sharing options...
PJMail Posted February 14, 2023 Share Posted February 14, 2023 Thanks SKK. I understood your code, but took your sentence as implying more than it did.Just grasping at straws trying to work out this weird partial Cell behavior. Would prefer to be down the Pub. Anyway, your code has given me an avenue for further tests - even though I still don't know what "Attached" really signifies - though the creationkit docs say "Loaded and !attached" = "preloaded" (another undefined state). Link to comment Share on other sites More sharing options...
lee3310 Posted February 15, 2023 Share Posted February 15, 2023 (edited) There is this script that is supposed to be more reliable than using "OnCellLoad()" on the player alias and also resource friendly but the question is, how to check if the current cell is the one that you are looking for if you can't use a property or getform every time ? is it possible to manually store the cell ID as "Int" and use GetParentCell().GetFormID ==. Edited February 15, 2023 by lee3310 Link to comment Share on other sites More sharing options...
lee3310 Posted February 15, 2023 Share Posted February 15, 2023 Thanks SKK. I understood your code, but took your sentence as implying more than it did.Just grasping at straws trying to work out this weird partial Cell behavior. Would prefer to be down the Pub. Anyway, your code has given me an avenue for further tests - even though I still don't know what "Attached" really signifies - though the creationkit docs say "Loaded and !attached" = "preloaded" (another undefined state).People seem to use isAttached() as an alternative to isLoaded() in their scripts but i can't tell which fires first ? OnCellLoad() or OnCellAttach() (it can be verified with a little test.) Link to comment Share on other sites More sharing options...
SKKmods Posted February 15, 2023 Author Share Posted February 15, 2023 A trace of all object and cell script events attached to persistent WorkshopRefs. Running at 300 units/sec (not sprinting) from NW map corner past Sanctuary past RR to Carla. Totally vanilla base game.uGridsToLoad = 5 ;default 10240 radius uExterior Cell Buffer=36 ;default 24576 radius Linear sequence split into Sanctuary and RedRocket, Abernathy removed. Last value is distance from player. OnLoad[workshopscript < (000250FE)>] [Cell <SanctuaryExt (0000DD60)>] 3d True 11314 OnCellAttach [workshopscript < (000250FE)>] [Cell <SanctuaryExt (0000DD60)>] 3d True 11302 OnCellLoad [workshopscript < (000250FE)>] [Cell <SanctuaryExt (0000DD60)>] 3d True 11288 OnCellDetach[workshopscript < (000250FE)>] 17796 OnUnload[workshopscript < (000250FE)>] 17810 ;cell buffer not full yet ? OnLoad[workshopscript < (00054BAE)>] [Cell <RedRocketExt02 (0000DDA0)>] 3d True 11322 OnCellAttach [workshopscript < (00054BAE)>] [Cell <RedRocketExt02 (0000DDA0)>] 3d True 11302 OnCellLoad [workshopscript < (00054BAE)>] [Cell <RedRocketExt02 (0000DDA0)>] 3d True 11291 OnCellDetach[workshopscript < (00054BAE)>] 13940 OnUnload[workshopscript < (00054BAE)>] 13954 ;cell buffer full ? Which is why I have always used OnLoad/OnUnload events on my object scripts (yes it still fires when object is disabled). Link to comment Share on other sites More sharing options...
lee3310 Posted February 15, 2023 Share Posted February 15, 2023 A trace of all object and cell script events attached to persistent WorkshopRefs. Running at 300 units/sec (not sprinting) from NW map corner past Sanctuary past RR to Carla. Totally vanilla base game.uGridsToLoad = 5 ;default 10240 radius uExterior Cell Buffer=36 ;default 24576 radius Linear sequence split into Sanctuary and RedRocket, Abernathy removed. Last value is distance from player. OnLoad[workshopscript < (000250FE)>] [Cell <SanctuaryExt (0000DD60)>] 3d True 11314 OnCellAttach [workshopscript < (000250FE)>] [Cell <SanctuaryExt (0000DD60)>] 3d True 11302 OnCellLoad [workshopscript < (000250FE)>] [Cell <SanctuaryExt (0000DD60)>] 3d True 11288 OnCellDetach[workshopscript < (000250FE)>] 17796 OnUnload[workshopscript < (000250FE)>] 17810 ;cell buffer not full yet ? OnLoad[workshopscript < (00054BAE)>] [Cell <RedRocketExt02 (0000DDA0)>] 3d True 11322 OnCellAttach [workshopscript < (00054BAE)>] [Cell <RedRocketExt02 (0000DDA0)>] 3d True 11302 OnCellLoad [workshopscript < (00054BAE)>] [Cell <RedRocketExt02 (0000DDA0)>] 3d True 11291 OnCellDetach[workshopscript < (00054BAE)>] 13940 OnUnload[workshopscript < (00054BAE)>] 13954 ;cell buffer full ? Which is why I have always used OnLoad/OnUnload events on my object scripts (yes it still fires when object is disabled). So the order is OnLoad -> OnCellAttach -> OnCellLoad. Cell attaches before Cell loads :thumbsup: Link to comment Share on other sites More sharing options...
Recommended Posts