This was something someone requested for a long time ago, that I secretly took upon myself in trying to create.
This is mostly unfinished, and I don't have the motivation in me anymore to continue it, I have been at it for close to 7 months. Hoping someone takes my concept and turns it into a useful function for Skyrim scripting. Totally rewritting it or whatever, all that is important is what I have written so that you have a direction to go in.
The request was for a true way to get the parent location of a cell. As you probably don't know, none of the location based functions will return the parent. And isChild() doesn't tell the truth either, especially if you call TamrielLocation on it. I became obsessed with Locations and did A LOT of research on them and how they are connected to each other - and there is a lot of documentation on it. On the side I even tried figuring out how to return the Cell of a location(still does not exist even in Fallout) to no avail. However it doesn't live up to its name "GetParentLocation" but should be called "GetHoldLocation". But with some tweaking of code, you can use it to get the parent location of any cell, not just holds.
This uses a lot of arrays and properties, and I have provided the properties in there proper forms, you can just copy paste to your script and hit Auto-fill all.
Documentation:
http://www.creationkit.com/index.php?title=Location_Hierarchy
http://www.creationkit.com/index.php?title=IsChild_-_Location <- additional info about this function for further clarification.
The function GetParentLocation(warning, it's a huge code):
Spoiler
Scriptname ParentLocationScript extends Quest
Location property DawnstarLocation auto
Location property MarkarthLocation auto
Location property RiftenLocation auto
Location property FalkreathLocation auto
Location property RiverwoodLocation auto
Location property SolitudeLocation auto
Location property RoriksteadLocation auto
Location property MorthalLocation auto
Location property IvarsteadLocation auto
Location property HelgenLocation auto
Location property WinterholdLocation auto
Location property WindhelmLocation auto
Location property WhiterunLocation auto
Location[] City
Location property WhiterunHoldLocation auto
Location property ReachHoldLocation auto
Location property RiftHoldLocation auto
Location property FalkreathHoldLocation auto
Location property PaleHoldLocation auto
Location property WinterholdHoldLocation auto
Location property HaafingarHoldLocation auto
Location property EastmarchHoldLocation auto
Location property HjaalmarchHoldLocation auto
Location[] Hold
WorldSpace property TamrielWorldSpace auto
Event OnInit()
debug.notification("Initializing arrays..")
City = new Location[13]
City[0] = DawnstarLocation
City[1] = MarkarthLocation
City[2] = RiftenLocation
City[3] = FalkreathLocation
City[4] = RiverwoodLocation
City[5] = SolitudeLocation
City[6] = RoriksteadLocation
City[7] = MorthalLocation
City[8] = IvarsteadLocation
City[9] = HelgenLocation
City[10] = WinterholdLocation
City[11] = WindhelmLocation
City[12] = WhiterunLocation
Hold = new Location[9]
Hold[0] = WhiterunHoldLocation
Hold[1] = ReachHoldLocation
Hold[2] = RiftHoldLocation
Hold[3] = FalkreathHoldLocation
Hold[4] = PaleHoldLocation
Hold[5] = WinterholdLocation
Hold[6] = HaafingarHoldLocation
Hold[7] = EastmarchHoldLocation
Hold[8] = HjaalmarchHoldLocation
EndEvent
Location Function GetParentLocation(ObjectReference akRef)
Int iCity
Int iHold
Int iWSHold
Int iCityIndex = City.Length
Int iHoldIndex = Hold.Length
Int iWSHoldIndex = WSHold.Length
if (akRef.GetCurrentLocation() != none)
; First check if this cell has a location at all before moving..
debug.notification("This cell has a location. Next check..")
else
debug.notification("This cell has no location. Returning none..")
; return none if this cell doesn't have a location.
return none
endif
; Moving to next block.. This block is for when you want to know what Hold is the parent of this exterior cell and part of the Tamriel World Space.
if !(akRef.isInInterior()) && akRef.GetWorldSpace() == TamrielWorldSpace
; if we are outside..we will return the parent of this location.
debug.notification("The cell is not an interior, and the cell is in the Tamriel World Space")
; First we will check if the CURRENT LOCATION matches a city.
While iCity < iCityIndex
if City[iCity] == akRef.GetCurrentLocation()
debug.trace("::::GETPARENTLOCATION:::::STORING CITY LOCATION INDEX::::" +iCity)
Int iCityStored = iCity
; Now we will check to see if A HOLD is the PARENT of THE CURRENT LOCATION.
While iHold < iHoldIndex
if Hold[iHold].isChild(City[iCityStored])
debug.trace("::::GETPARENTLOCATION:::::RETURNING HOLD LOCATION INDEX::::" +iHold)
return Hold[iHold]
endif
iHold += 1
EndWhile
endif
iCity += 1
EndWhile
; Moving to next block.. This block is for when you want to know what Hold is the parent of this interior cell and not part of the Tamriel World Space.
; Like for example, Riverwood Trader.
elseif akRef.isInInterior() == true && akRef.GetWorldSpace() != TamrielWorldSpace
; If we are inside..we will return the parent of this interior location.
debug.notification("You are in an interior. Returning hold if possible..")
While iHold < iHoldIndex
if Hold[iHold].isChild(akRef.GetCurrentLocation())
debug.trace("::::GETPARENTLOCATION:::::RETURNING HOLD LOCATION INDEX::::" +iHold)
return Hold[iHold]
endif
iHold += 1
EndWhile
; Moving to next block.. This block if for when you want to know what hold is the parent of this cell behaving like an exterior, but you are not in the Tamriel Worldspace.
elseif !(akRef.isInInterior()) && akRef.GetWorldSpace() != TamrielWorldSpace
debug.notification("The cell is an interior, and the cell is not the Tamriel World Space")
; First we will check if the CURRENT LOCATION matches a city.
While iWSHold < iWSHoldIndex
if WSHold[iWSHold] == akRef.GetCurrentLocation()
debug.trace("::::GETPARENTLOCATION:::::STORING CURRENT LOCATION INDEX::::" +iWSHold)
Int iWSStored = iWSHold
; Now we will check to see if A HOLD is the PARENT of THE CURRENT LOCATION.
While iHold < iHoldIndex
if Hold[iHold].isChild(WSHold[iWSStored])
debug.trace("::::GETPARENTLOCATION:::::RETURNING HOLD LOCATION INDEX::::" +iHold)
return Hold[iHold]
endif
iHold += 1
EndWhile
endif
iWSHold += 1
EndWhile
else
; Either you are in an interior but it's behaving like an exterior, or you are not in the Tamriel World Space.
debug.notification("Returning none..")
return none
endif
EndFunction
The very last bit of the code is unfinished. I think there needs to be some worldspace checking instead for places like BloatedMansGrottoLocation, where isInterior will return false, because BloatedMansGrotto is in a world space. A way around that is discussed here: http://www.creationkit.com/index.php?title=Talk:IsInInterior_-_ObjectReference
I've only tested the method of calling this function though a Quest/Quest script. The code mostly works as expected, except for what I mentioned above.
I believe you can call it from any script or use it within a script, so long as you have the properties to go with it.
Either way that's it..