Jump to content

Small function to grab local workshop reference


niston

Recommended Posts

Need to grab a reference to the local workshop, from a script on one of your workshop items? Here you go:

ObjectReference Function GetLocalWorkshopRef()
  ; will hold the reference
  ObjectReference refLocalWorkshop = none
  
  ; acquire the reference
  Keyword kwdWorkshopItem = Game.GetFormFromFile(0x54BA6, "Fallout4.esm") as Keyword
  If (kwdWorkshopItem == none)
    Debug.Trace(Self + ": ERROR - Failed to load kwdWorkshopItem. Local workshop reference will be unavailable.")
  Else
    refLocalWorkshop = Self.GetLinkedRef(kwdWorkshopItem) as ObjectReference
    If (refLocalWorkshop == none)
      Debug.Trace(Self + ": ERROR - Failed to acquire local workshop reference.")
    Else
      Debug.Trace(Self + ": Local workshop reference " + refLocalWorkshop + " acquired.")
    EndIf
  EndIf

  ; return the reference, or none in case of failure
  Return refLocalWorkshop
EndIf

Uses no extra script property and will work regardless of the cell's location tag. Merry xmas and a happy new year to all!

Link to comment
Share on other sites

Handy resource, and to extend that my Workshop Utilities do all sorts of workshop lookups for testing and validation, here are the most frequently used methods from fast to slow:

;Datum may be a workshop object ~ 0.05 seconds
ObjectReference WorkshopREF
If (DatumRef.GetLinkedRef(pWorkshopItemKeyword) != None)
   WorkshopRef = DatumRef.GetLinkedRef(pWorkshopItemKeyword)
EndIf


;Registered Workshops that have correct location keywords ~ 0.1 second
ObjectReference WorkshopRef
If (DatumRef.GetcurrentLocation().Haskeyword(pLocTypeWorkshop))
   WorkshopRef = (pWorkshopParent as WorkshopParentScript).GetWorkshopFromLocation(DatumRef.GetcurrentLocation() ) as ObjectReference
EndIf


;Area Scan around a datum to find registered and isolated workshops 2 workshops ~ 0.2 seconds
ObjectReference WorkshopRef
ObjectReference[] FoundWorkshops = DatumRef.FindAllReferencesWithKeyword(pWorkshopKeyword, 10240)
If (FoundWorkshops.Length > 0)
   Int iIndex = 0 
   Float fDistance = 10240
   While iIndex < FoundWorkshops.Length
      If (FoundWorkshops[iIndex] is workshopscript) && (DatumRef.GetDistance(FoundWorkshops[iIndex]) < fDistance)
         WorkshopREF = FoundWorkshops[iIndex]
         fDistance = DatumRef.GetDistance(FoundWorkshops[iIndex])
      EndIf
      iIndex +=1
   EndWhile
EndIf


;Registered Workshops build areas 30 workshops ~ 0.5 seconds
ObjectReference WorkshopREF
WorkshopScript[] FoundWorkshops = (pWorkshopParent as WorkshopParentScript).Workshops
Int iIndex = 0
While iIndex < FoundWorkshops.Length && (DatumRef.Is3DLoaded() == TRUE) ;only works if 3d is loaded on datum and target
   If ((FoundWorkshops[iIndex] as ObjectReference).Is3DLoaded() == TRUE) && (DatumRef.IsWithinBuildableArea(FoundWorkshops[iIndex]) == TRUE) 
      WorkshopREF = FoundWorkshops[iIndex] as ObjectReference
      iIndex = 128 ;early bail out 
   EndIf
   iIndex += 1 
EndWhile
Link to comment
Share on other sites

 

Handy resource, and to extend that my Workshop Utilities do all sorts of workshop lookups for testing and validation, here are the most frequently used methods from fast to slow:

;Datum may be a workshop object ~ 0.05 seconds
ObjectReference WorkshopREF
If (DatumRef.GetLinkedRef(pWorkshopItemKeyword) != None)
   WorkshopRef = DatumRef.GetLinkedRef(pWorkshopItemKeyword)
EndIf

 

Why are you getting the linked ref twice here? What's even the point of that if? If getLinkedRef returns none, WorkshopREF stays none, just like if you were to assign to it right away.

And even if you need to do something differently if it's none, why don't put the assignment first, and then put WorkshopREF into the if?

Link to comment
Share on other sites

 

Why are you getting the linked ref twice here? What's even the point of that if? If getLinkedRef returns none, WorkshopREF stays none, just like if you were to assign to it right away.

 

(a) It fails faster, taking one less frame than evaluating if (WorkshopREF == None)

(b) To provide a fast clean entry point for a user message.

© To avoid potentially generating an error in the debug log.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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