Jump to content

MCGUFIN

  • entries
    13
  • comments
    0
  • views
    1818

Room Mapping System


Monoman1

136 views

This system uses the navmesh to build a picture of what kind of shape an interior cell takes. This allows you to ask questions like: 

  • How many rooms in this cell? 
  • What room am I in? 
  • Who's in this room with me? 
  • What kind of things are in this room?
  • What rooms are adjacent to this room? 
  • How many exits does this room have? 
  • Where are the exits from this room?
  • Where are the exits from this cell?
  • Roughly what size is a room? And by extension which room is the biggest/smallest? 
  • Roughly where is the center?
  • How far is the actual path between two actors? (They may be physically close but there might also be a wall in the way). 

 

Any actor or object ref can be tracked for room change events. 

If Belethor room == 1 & Player room == 1 then Belethor and the player are in the same room. 
If Player room changes to 2. Should Belethor follow the player?

 

I hope to eventually be able to give you an idea of the purpose of the room though this could never be absolutely definitive. 

 

Here's a video of me plodding around a couple of cells. The player is tracked for room change events. Every time the player changes room we get an event to tell you which room I was in and which room I'm in now. AutoRoomMap is turned on so every time I change room the system maps out the current room with soul gems - It's a visual debugging functionality to make sure the map is right. 

 

 



API surface thus far:
 

Spoiler
;========================================================================================
; Room Detection (Experimental)(WIP) ====================================================
;========================================================================================

; Register a form for reference room change events. 
; Registrations survive save + reload. 
; Event On_MGF_ActorRoomChange(Actor akActor, Int OldRoom, Int NewRoom)
; akActor: The actor that changed room. 
; OldRoom: The index of the room akActor came from. 
; NewRoom: The index of the room akActor is now in. 
Function RoomTrackActor(Form akForm, ObjectReference ObjRef) Global Native

; Unregister this for reference for room change events. 
Function RoomUntrackActor(Form akForm, ObjectReference ObjRef) Global Native

; Untrack all references. 
Function RoomUntrackAll(Form akForm) Global Native

; Is this reference registered for room change events on this form. 
Bool Function RoomIsTrackedActor(Form akForm, ObjectReference akRef) Global Native

; Returns a list of all references registered for tracking on this form. 
ObjectReference[] Function RoomGetTrackedActors(Form akForm) Global Native

; Returns whether this form has been registered in the room system. 
; Returns 0 = opening, 1 = stair, -1 = not registered. 
Int Function RoomIsRegisteredStatic(Form akForm) Global Native

; RoomRegisterStatic(Form akForm, int aiType, string asFile). 
; When registering an opening, stand in the center of the opening and face the 'door jamb', so that you're facing parallel
; with the dividing wall and at 90 degrees from the angle of the opening. 
; The more centered you are in both the x, y axis the better the results generally. 
; Type: 0 = opening, 1 = stair
; FileName: filename only (no path separators). Eg: "mymod.json"
Function RoomRegisterStatic(ObjectReference akRef, Int Type, String FileName) Global Native

; Attempts to add a boundary where akActor is standing. Returns true for success. 
; Stand in the center of the opening and face parallel with the dividing wall. 
; The system will try to find the closest, parallel edge to create a new boundary. 
; Boundaries are saved to json <FileName>
Bool Function RoomAddBoundary(String FileName) Global Native

; Attempts to remove a boundary within Radius of the player. Returns true for success. 
; Removes all manual boundaries within <Radius> from all jsons.  
Bool Function RoomRemoveBoundary(Float Radius = 64.0) Global Native

; Returns how many manual boundaries in the current cell. 
Int Function RoomGetOverrideCount() Global Native

Function RoomRegisterObjectsAs(Form[] akForms, int aiRole, string asModName) native global
Function RoomUnregisterMod(string asModName) native global
String[] Function RoomGetClassificationScores(int aiRoom) Global Native

Function RoomUnregisterStatic(ObjectReference akRef) Global Native

; Remap the current cell again. 
Function RoomRemapCell() Global Native

; Force the system to ignore a particular door reference. 
; Need to call RoomRemapCell() afterwards to update the room map. 
; Added this after discovering a door buried in a wall in Dragonsreach messing up the room mapping...
; Unlike RoomIsIgnoredDoorEid() this affects a single reference. 
Function RoomIgnoreDoorRef(ObjectReference ObjRef) Global Native

; Opposite of RoomIgnoreDoorRef(). 
Function RoomUnignoreDoorRef(ObjectReference ObjRef) Global Native

; Returns true if this reference is in MGF's door reference ignore list. 
Bool Function RoomIsIgnoredDoorRef(ObjectReference ObjRef) Global Native

; Is defined (via json) as a 'weird door' the system should ignore. Eg: Display cases, shackles. 
; This is essentially a string check of ObjRef's base EditorID against MGF's list of strings to ignore. 
Bool Function RoomIsIgnoredDoorEid(ObjectReference ObjRef) Global Native

; Returns boundary midpoints as flat [x,y,z, ...] float array. 
; These are the positions of the entrances/exits to a room. 
; RoomIndex: The index of the room to check. 
Float[] Function RoomGetBoundaryMidpoints(Int RoomIndex) Global Native

; Returns the navmesh triangle count of the room. 
; RoomIndex: The index of the room to check. 
Int Function RoomGetTriangleCount(Int RoomIndex) Global Native

Int Function RoomGetTriangleForRef(ObjectReference ObjRef) Global Native

Int Function RoomGetTriangleFlags(ObjectReference ObjRef) Global Native

; Tries to return the center position of the navmesh for the room with the specified clearance around it. 
; Useful for placing markers etc. Always check the returned array.Length > 0 to check for failure. 
; Function will always try to return the best point even if the clearance isn't fully met or a clearance of 0.0 is requested. 
; Note that this is the navmesh center and not the room center really. 
Float[] Function RoomGetCenter(Int RoomIndex, Float Clearance = 0.0) Global Native

; This would be a more 'exact' center of the room geometrically. Probably still not perfect because of the navmesh shape. 
; Though it might be floating in air a bit or inside some object like a pillar or fireplace etc. 
; Also check that length > 0 for failure. 
Float[] Function RoomGetCentroid(Int RoomIndex) Global Native

; Get the area covered by the navmesh associated with this room. 
; Not the actual area of the room. But should be a decent indicator of room size. 
Float Function RoomGetArea(Int RoomIndex) Global Native

; Returns total number of rooms detected in player's current cell
Int Function RoomGetCount() Global Native

; Returns the indices of all connecting rooms. 
; RoomIndex: The index of the room to check. 
Int[] Function RoomGetAdjacentRooms(Int RoomIndex) Global Native

; Returns index of actor's room within the cell. 
Int Function RoomGetIndexForActor(Actor akActor) Global Native

; ; Returns index of reference's room within the cell.
Int Function RoomGetIndexForRef(ObjectReference akRef) Global Native

; Gets the number of entrances/exits to a room. Includes load doors, interior doors, door arches (without doors) and stairs. 
; RoomIndex: The index of the room to check. 
; ExpandOverOpenBoundary: False - Don't go past any of the rooms boundaries. 
; 						  True - Expand over open boundaries like door arches and stairs. 
; If RoomGetExitCount = 1 && RoomGetDoors == 1 then it's probably (but not certainly) a room with a single entrance with a door. 
; If RoomGetExitCount = 1 && RoomGetDoors == 0 then it's probably (but not certainly) a room with a single 'open' entrance. 
Int Function RoomGetExitCount(Int RoomIndex, Bool ExpandOverOpenBoundary = False) Global Native

; Returns door references that are associated with a room. 
; DoorTypes: 0 - any, 1 - non-load doors only, 2 - load doors only
; ExpandOverOpenBoundary: False - Don't go past any of the rooms boundaries. 
; 						  True - Expand over open boundaries like door arches and stairs. 
ObjectReference[] Function RoomGetDoors(Int RoomIndex, Int DoorTypes, Bool ExpandOverOpenBoundary = False) Global Native

; Returns all furniture references in a room. 
; RoomIndex: The index of the room to check. 
; ExpandOverOpenBoundary: False - Don't go past any of the rooms boundaries. 
; 						  True - Expand over open boundaries like door arches and stairs. 
ObjectReference[] Function RoomGetFurniture(Int RoomIndex, Bool ExpandOverOpenBoundary = False) Global Native

; Returns a list of object references with any of the listed keywords. 
; RoomIndex: The index of the room to check. 
; ExpandOverOpenBoundary: False - Don't go past any of the rooms boundaries. 
; 						  True - Expand over open boundaries like door arches and stairs. 
ObjectReference[] Function RoomGetRefsWithKeywords(Int RoomIndex, Keyword[] akKwds, Bool ExpandOverOpenBoundary = False) Global Native

; Same as RoomGetRefsWithKeywords but only returns a count. 
Int Function RoomCountRefsWithKeywords(Int RoomIndex, Keyword[] akKwds, Bool ExpandOverOpenBoundary = False) Global Native

; Returns references in <RoomIndex> of type <FormType>. 
; FormType: https://ck.uesp.net/wiki/GetType_-_Form
; ExpandOverOpenBoundary: False - Don't go past any of the rooms boundaries. 
; 						  True - Expand over open boundaries like door arches and stairs. 
ObjectReference[] Function RoomGetRefsOfType(Int RoomIndex, Int FormType, Bool ExpandOverOpenBoundary = False) Global Native

; Returns all actors in a room. 
; RoomIndex: The index of the room to check. 
; ExpandOverOpenBoundary: False - Don't go past any of the rooms boundaries. 
; 						  True - Expand over open boundaries like door arches and stairs. 
Actor[] Function RoomGetActors(Int RoomIndex, Bool ExpandOverOpenBoundary = False) Global Native

; Approximate navmesh path distance in game units between the positions of the two references. 
; Returns -1.0 if:	either ref is null / outside the navmesh. 
;					they are in different cells. 
;					the room data isn't ready yet
;					no path exists within the A* node budget (8192 triangles)

; GetDistance will always be <= than RoomGetPathDistance. What's the point of this function?
; RoomGetPathDistance(PlayerRef, ObjRef) / PlayerRef.GetDistance(ObjRef) > ~1.4 means that there is a significant difference between
; direct distance to the object and the pathing distance to the object. 
; IE: Object could be through a wall or on another floor. 

; Despite the name this works in exterior cells too though be aware that it has a distance limit due to the triangle budget above and
; the object must be in the same cell. 

; Same navmesh island:	A* on triangle adjacency graph.
; Different islands:	Dijkstra on the room boundary graph, straight-line between boundary midpoints.
;                      	Less precise but handles multi-level cells.
Float Function RoomGetPathDistance(ObjectReference ObjRef1, ObjectReference ObjRef2) Global Native

; Returns a flat array of the navmesh vertices that constitute this room. 
; Array elements are in triplets. [0] = x1, [1] = y1, [3] = z1, [4] = x2, [5] = y2, [6] = z2 etc
Float[] Function RoomGetNavmeshVertices(Int RoomIndex) Global Native

; Places MarkerForms at every vertex that constitute the room. 
; Easy visualization of the room limits. References are spawned with persist = false. 
; But it's your responsibility to manage the returned object references (cleanup). 
ObjectReference[] Function RoomMap(Int RoomIndex, Form MarkerForm) Global Native

 

 

Edited by Monoman1

0 Comments


Recommended Comments

There are no comments to display.

×
×
  • Create New...