Navigation data/meshes

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
Doldol
Senior Member
Posts: 200
Joined: Sat Jul 07, 2012 7:09 pm
Location: Belgium

Navigation data/meshes

Postby Doldol » Thu Jun 04, 2015 9:20 pm

Long story short, I was working on a death match spawn system and dreading the thought of having to setup spawn points for it, but then I realised that .nav files essentially already have detailed data of this kind, and I was thinking about just using locations marked hiding spots in the nav data as spawn points.

I was searching/looking through the forums and the repo, but I couldn't really find anything related to this. I would rather not have to completely study the nav files and parse them, as I'd think the engine already has to know all the navigation data from the map since it has to control the bots, I would rather ask the engine, if that's the case.
necavi
Developer
Posts: 129
Joined: Wed Jan 30, 2013 9:51 pm

Postby necavi » Thu Jun 04, 2015 9:30 pm

https://github.com/AnthonyIacono/War3SourceV2/tree/master/Nav Here's some information on how to parse it if you can't find anything easily accessible in the engine.
User avatar
Doldol
Senior Member
Posts: 200
Joined: Sat Jul 07, 2012 7:09 pm
Location: Belgium

Postby Doldol » Fri Jun 05, 2015 12:32 am

necavi wrote:https://github.com/AnthonyIacono/War3SourceV2/tree/master/Nav Here's some information on how to parse it if you can't find anything easily accessible in the engine.


Yup, I think I got it to work, quickly but dirty (my map version was 9, I only translated the code applicable to that version).

(Class is from Active State)

Syntax: Select all

import struct

class BinaryReaderEOFException(Exception):
def __init__(self):
pass
def __str__(self):
return 'Not enough bytes in file to satisfy read request'


class BR:
# Map well-known type names into struct format characters.
typeNames = {
'int8' :'b',
'uint8' :'B',
'int16' :'h',
'uint16' :'H',
'int32' :'i',
'uint32' :'I',
'int64' :'q',
'uint64' :'Q',
'float' :'f',
'double' :'d',
'char' :'s'}


def __init__(self, fileName):
self.file = open(fileName, 'rb')

def read(self, typeName):
typeFormat = BR.typeNames[typeName.lower()]
typeSize = struct.calcsize(typeFormat)
value = self.file.read(typeSize)
if typeSize != len(value):
raise BinaryReaderEOFException
return struct.unpack(typeFormat, value)[0]

def __del__(self):
self.file.close()


NAV_DIR = ["North", "East", "South", "West"]
LADDER_DIRS = ["Up", "Down"]


def read_nav_file(filename):
f = BR(filename)
magic = f.read('uint32')
version = f.read('uint32')
savebspsize = f.read('uint32')


placecount = f.read('uint16')
places = dict()
for placeindex in range(placecount):
placenamesize = f.read('uint16')
placenamechars = list()
for x in range(placenamesize):
placenamechars.append(f.read('char'))
placename = b''.join(placenamechars)
places[placeindex] = placename


areacount = f.read('uint32')
areas = dict()
for areaindex in range(areacount):
areas[areaindex] = dict()
areas[areaindex]["id"] = f.read('uint32')
areas[areaindex]["flags"] = f.read('uint16')


x1 = f.read('float')
y1 = f.read('float')
z1 = f.read('float')
x2 = f.read('float')
y2 = f.read('float')
z2 = f.read('float')
areas[areaindex]["box"] = ((x1, y1, z1), (x2, y2, z2))




NEcornerz = f.read('float')
SWcornerz = f.read('float')
areas[areaindex]["corner"] = dict()
areas[areaindex]["corner"]["NE"] = NEcornerz
areas[areaindex]["corner"]["SW"] = SWcornerz


areas[areaindex]["directions"] = dict()
for index, direction in enumerate(NAV_DIR):
connectioncount = f.read('uint32')
areas[areaindex]["directions"][direction] = {'connectioncount' : connectioncount}

areas[areaindex]["directions"][direction]["connections"] = dict()
for connectionindex in range(connectioncount):
connectingareaindex = f.read('uint32')
areas[areaindex]["directions"][direction]["connections"][connectionindex] = connectingareaindex

hidingspotcount = f.read("uint8")
areas[areaindex]["hidingspotcount"] = hidingspotcount
areas[areaindex]["hidingspots"] = dict()
for hidingspotindex in range(hidingspotcount):
hidingspotid = f.read('uint32')
areas[areaindex]["hidingspots"][hidingspotindex] = {"id" : hidingspotid}


x = f.read('float')
y = f.read('float')
z = f.read('float')
areas[areaindex]["hidingspots"][hidingspotindex]["point"] = (x, y, z)


hidingspotflags = f.read("uint8")
areas[areaindex]["hidingspots"][hidingspotindex]["flags"] = hidingspotflags


approachareacount = f.read("uint8")
areas[areaindex]["approachareacount"] = approachareacount
areas[areaindex]["approachareas"] = dict()
for approachareaindex in range(approachareacount):
approachHereID = f.read('uint32')
approachPrevID = f.read('uint32')
approachType = f.read("uint8")
approachNextID = f.read('uint32')
approachHow = f.read("uint8")
areas[areaindex]["approachareas"][approachareaindex] = {"id": approachHereID, "previd": approachPrevID, "type": approachType, "nextid": approachNextID, "how": approachHow}


encounterPathcount = f.read("uint32")
areas[areaindex]["encounterpathcount"] = encounterPathcount
areas[areaindex]["encounterpaths"] = dict()
for encounterPathindex in range(encounterPathcount):
encounterFromID = f.read('uint32')
encounterFromDirection = f.read("uint8")
encounterToID = f.read('uint32')
encounterToDirection = f.read("uint8")
areas[areaindex]["encounterpaths"][encounterPathindex] = {"fromid": encounterFromID, "toid": encounterToID, "fromdir": encounterFromDirection, "todir": encounterToDirection,}


encounterSpotcount = f.read("uint8")
areas[areaindex]["encounterpaths"][encounterPathindex]["encounterspotcount"] = encounterPathcount
areas[areaindex]["encounterpaths"][encounterPathindex]["encounterspots"] = dict()
for encounterSpotindex in range(encounterSpotcount):
encounterSpotOrderId = f.read('uint32')
encounterSpotT = f.read("uint8")
encounterSpotParametricDistance = encounterSpotT / 255.0


areas[areaindex]["encounterpaths"][encounterPathindex]["encounterspots"][encounterSpotindex] = {"orderid": encounterSpotOrderId, "T": encounterSpotT,"parametricdistance": encounterSpotParametricDistance}


placeID = f.read("uint16")
areas[areaindex]["placeid"] = placeID


for index, direction in enumerate(LADDER_DIRS):
ladderConnectionCount = f.read('uint32')
for ladderconnectionindex in range(ladderConnectionCount):
ladderConnectID = f.read('uint32')


earliestOccupyTimeFirstTeam = f.read('float')
earliestOccupyTimeSecondTeam = f.read('float')
areas[areaindex]["team1eop"] = earliestOccupyTimeFirstTeam
areas[areaindex]["team2eop"] = earliestOccupyTimeSecondTeam


laddercount = f.read('uint32')


return {"areas": areas,
"places": places,
"laddercount": laddercount,
"filename": filename,
"magic": magic,
"version": version,
"savebspsize": savebspsize,
"areacount": areacount,
"placecount": placecount
}


# And ladder stuff goes here


Thaaankksss!

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 62 guests