Jump to content

Photo

Export list of all objects in cell for each cell in worldspace?

xedit

  • Please log in to reply
33 replies to this topic

#21
dylbill

dylbill

    Resident poster

  • Premium Member
  • 2,948 posts

If obj checks if the Obj exists, ie if there's at least one object in the cell. It's the same as doing if Obj != None



#22
YouDoNotKnowMyName

YouDoNotKnowMyName

    Overseer of Vault 114 / Destroyer of Precombines

  • Members
  • PipPipPipPip
  • 1,902 posts

Ah, ok, makes sense!

 

And this script will take A LOT longer to finish because it will go through every object and check if it is in the "current" cell, then go through all the objects again and check if they are in the "next cell" and so on ...

So it will take about 14884 times as long as the first script. (there are 14884 cells in the Tamriel worldspace, at least in the "playable area").

 

I will let you know if it worked or not when it is done ...



#23
dylbill

dylbill

    Resident poster

  • Premium Member
  • 2,948 posts

Cool sounds good. It shouldn't take longer than the last version, as it checks only 1 object in the currentCell, if that 1 object is in MyWorldSpace, then it traces the data for that cell. Otherwise it moves on to the next cell.



#24
YouDoNotKnowMyName

YouDoNotKnowMyName

    Overseer of Vault 114 / Destroyer of Precombines

  • Members
  • PipPipPipPip
  • 1,902 posts

So, I let the script run over night and in the morning it still has not finished.

I closed the game and checked the logs and nothing.

 

So I added some debug messages to see at which point the script fails.

 

And it turns out that the "int i = AllCells.Length" returns 0.

Yes, I filled the property for the worldspace.

 

What could be the cause of this?

 

Isn't there a limit to how many elements can be in an array?



#25
dylbill

dylbill

    Resident poster

  • Premium Member
  • 2,948 posts

Ok, so the problem is using GetAllForms for formtype 60, which is cells, doesn't work. I tested and it does work for other form types. So here's another sort of hackish method that combines the 2 methods. 

 

Uses skyPal to get all refs. 

If a ref is in MyWorldSpace and it's parent cell is none, moves player to ref. 

If the ref's parent cell hasn't been printed yet, prints the cell obj data. 

 

I also switched over to TraceUser so all the data is grouped together in one file. 

 

You can change the UserLog string to something else if you want. 

 

WorldSpace Property MyWorldSpace Auto


Event OnInit()
    RegisterForKey(42) ;left shift
EndEvent


Form[] CheckedRefs
Form[] CheckedCells


int CheckedRefsIndex = 0 
Int CheckedCellsIndex = 0
    
String UserLog = "myUserLog"


Bool Busy


    
Event OnKeyDown(Int keyCode)
    If Busy == True 
       return 
    Endif 
   
    Busy = True 
    
    Debug.OpenUserLog(UserLog)


    Actor PlayerRef = Game.GetPlayer()
    ObjectReference[] AllRefs = SkyPal_References.All()
    int i = AllRefs.Length
    CheckedRefs = Utility.CreateFormArray(i)
    CheckedCells = Utility.CreateFormArray(i) 
    
    CheckedRefsIndex = 0 
    CheckedCellsIndex = 0
    
    Debug.Notification(i)
    
    While i > 0 
        i -= 1 
        If i % 100 == 0 ;moniter progess. If i is divisible by 100
            Debug.Notification(i)
        Endif
        
        ObjectReference Obj = AllRefs[i] 
        If Obj 
            If Obj.GetWorldSpace() == MyWorldSpace 
                if CheckedRefs.Find(obj) == -1 ;obj not yet printed
                    Cell ObjCell = Obj.GetParentCell()
                    
                    If ObjCell == none ;move player to obj if parent cell not found / loaded
                        PlayerRef.MoveTo(Obj)
                        Utility.Wait(0.5)
                        ObjCell = Obj.GetParentCell() 
                        Int ii = 0 
                        While ObjCell == None && ii < 50 
                            ii += 1
                            Utility.Wait(0.5)
                            ObjCell = Obj.GetParentCell() 
                        EndWhile
                    Endif 
                    
                    If ObjCell == None
                        CheckedRefs[CheckedRefsIndex] = Obj
                        CheckedRefsIndex += 1
                        Debug.TraceUser(UserLog, Obj + DbMiscFunctions.ConvertIntToHex(Obj.GetFormId()) + " Parent cell not found")
                        
                    Elseif CheckedCells.Find(ObjCell) == -1 ;cell not yet printed
                        CheckedCells[CheckedCellsIndex] = ObjCell
                        CheckedCellsIndex += 1
                        TraceCellObjData(ObjCell)
                    Endif
                Endif
            Endif 
        Endif
    EndWhile
    
    Busy = False
    Debug.MessageBox("Done Printing")
EndEvent

Function TraceCellObjData(Cell akCell)
    Debug.TraceUser(UserLog, "Cell ID: " + DbMiscFunctions.ConvertIntToHex(akCell.GetFormId()))
    Int i = akCell.GetNumRefs() 
    While i > 0 
        i -= 1 
        ObjectReference Obj = akCell.GetNthRef(i) 
        CheckedRefs[CheckedRefsIndex] = Obj
        CheckedRefsIndex += 1
        String S = ("Type: " + Obj.GetType() + ", ID: " + DbMiscFunctions.ConvertIntToHex(Obj.GetFormId()) + ", Name: " + Obj.GetBaseObject().GetName() + \
        ", X: " + Obj.GetPositionX() + ", Y: " + Obj.GetPositionY() + ", Z: " + Obj.GetPositionZ() + \
        ", XAngle: " + Obj.GetAngleX() + ", YAngle: " + Obj.GetAngleY() + ", ZAngle: " + Obj.GetAngleZ() + ", Scale: " + Obj.GetScale())
        
        Debug.TraceUser(UserLog, S)
    EndWhile
EndFunction

Oh yeah, and it uses OnkeyDown (left shift) to start the function.

 

Edit: Forgot to mention enable god mode before starting the function, also this will take a while. When I tested there's over 60,000 object refs in the game. Also using Utility.CreateFormArray() doesn't have an element limit, same with the skypal and papyrus extender functions.



#26
YouDoNotKnowMyName

YouDoNotKnowMyName

    Overseer of Vault 114 / Destroyer of Precombines

  • Members
  • PipPipPipPip
  • 1,902 posts

Thanks, I will try this in the evening (or if I sleep a bit during the afternoon), I need my PC in a useable state when I am awake.

 

;-)

 

 

Entering the console command TCL to turn off collision would probably also be a good idea before starting the script.



#27
YouDoNotKnowMyName

YouDoNotKnowMyName

    Overseer of Vault 114 / Destroyer of Precombines

  • Members
  • PipPipPipPip
  • 1,902 posts

Can I do a save, close the game and later load that save to continue "scanning" where the script stopped?

Not a quicksave, I know that that messes with scripts, a proper save.

 

Because if there are about 14884 cells and it takes lets say 10 seconds for each cell the script would take almost two days to run.

 

I used Mod Organizer 2 to run SSE, so I can't just alt tab out of SSE and play other games.

And I would love to play some regular Skyrim right now ...



#28
dylbill

dylbill

    Resident poster

  • Premium Member
  • 2,948 posts

Not sure if that'll work, you can try it though.



#29
YouDoNotKnowMyName

YouDoNotKnowMyName

    Overseer of Vault 114 / Destroyer of Precombines

  • Members
  • PipPipPipPip
  • 1,902 posts

So I have been running the script for some time now, with a few "breaks" (save, close the game, load).

 

I noticed some problems in the logs:

 

error: Array index 99305 is out of range (0-60871)

What was that about arrays not having limits?

Seems like they do ...

But it is a strange number ...

I would expect a number that is 2^N not some seemingly arbitrary number.

 

does not have any 3d and so cannot be moved to

Seems like some "objects" can't be moved to

(Can't think of any "objects" that are in the worldspace but don't have a 3d mesh, even markers have meshes)

 

 

So again, the script will have to be reworked ...

Maybe my "just going through cell by cell by moving the player left / right / forward / backwards" approach?

 

Or do you have any other tricks up your sleeve?


Edited by YouDoNotKnowMyName, 02 June 2022 - 07:24 PM.


#30
dylbill

dylbill

    Resident poster

  • Premium Member
  • 2,948 posts

Hmm, that might be your best bet. If moving around like that, you can do something like this: 

 

Formlist Property PrintedCells Auto
String UserLog = "MyUserLog"

Event OnInit() 
   RegisterForKey(42) ;left shift 
   Debug.OpenUserLog(UserLog)
EndEvent 

Event OnKeyDown(Int keyCode)
    Cell[] AttachedCells = PO3_SKSEFunctions.GetAttachedCells() 
    Int i = AttachedCells.Length 
    While i > 0 
        i -= 1
        Cell akCell = AttachedCells[i]
        If PrintedCells.HasForm(akCell) == false 
            PrintedCells.AddForm(akCell)
            TraceCellObjData(akCell) 
        Endif
        Debug.Notification(i)
    EndWhile 
    
    Debug.Notification("Done")
EndEvent

Function TraceCellObjData(Cell akCell)
    Debug.TraceUser(UserLog, "Cell ID: " + DbMiscFunctions.ConvertIntToHex(akCell.GetFormId()))
    Int i = akCell.GetNumRefs() 
    While i > 0 
        i -= 1 
        ObjectReference Obj = akCell.GetNthRef(i) 
        String S = ("Type: " + Obj.GetType() + ", ID: " + DbMiscFunctions.ConvertIntToHex(Obj.GetFormId()) + ", Name: " + Obj.GetBaseObject().GetName() + \
        ", X: " + Obj.GetPositionX() + ", Y: " + Obj.GetPositionY() + ", Z: " + Obj.GetPositionZ() + \
        ", XAngle: " + Obj.GetAngleX() + ", YAngle: " + Obj.GetAngleY() + ", ZAngle: " + Obj.GetAngleZ() + ", Scale: " + Obj.GetScale())
        
        Debug.TraceUser(UserLog, S)
    EndWhile
EndFunction






Also tagged with one or more of these keywords: xedit

IPB skins by Skinbox
Page loaded in: 1.070 seconds