Пример #1
0
    def connect_teleporters(self):
        """
        Creates area connections for teleporter line types.
        """
        
        count = 0
        rect = Rectangle()
        
        for teleporter in self.map_data.teleporters:
            target_area = None
            
            # Get the area that the teleporter target is in.
            if teleporter.kind == Teleporter.TELEPORTER_THING:
                floorz = self.map_data.get_floor_z(teleporter.dest.x, teleporter.dest.y)
                target_area = self.get_area_at(teleporter.dest, floorz)
            if teleporter.kind == Teleporter.TELEPORTER_LINE:
                dest = Vector2()
                dest.x, dest.y = self.map_data.get_line_center(teleporter.dest_line)
                floorz = self.map_data.get_floor_z(teleporter.dest.x, teleporter.dest.y)
                target_area = self.get_area_at(dest, floorz)

            # Ignore missing teleport targets.
            if target_area is None:
                print 'Teleporter linedef {} does not point to a place on the map with navigation areas.'.format(teleporter.source_line)
                continue
            
            # Create the teleport connection line from the linedef vertices.
            linedef = self.map_data.linedefs[teleporter.source_line]           
            rect.set(
                linedef.vertex1.x,
                linedef.vertex1.y,
                linedef.vertex2.x,
                linedef.vertex2.y
            )

            # Place a teleporter connection in all intersecting source areas.
            areas = self.get_areas_intersecting(rect)
            for area in areas:
                connection = Connection()
                connection.rect.copy_from(rect)
                connection.area_a = area
                connection.area_b = target_area
                connection.linedef = teleporter.source_line
                connection.flags = Connection.FLAG_AB | Connection.FLAG_TELEPORTER
                
                area.connections.append(connection)
            
            count += 1
        
        print 'Connected {} teleporters.'.format(count)
Пример #2
0
 def read(self, filename, map_data):
     """
     Reads a mesh from a file.
     """
     
     with open(filename, 'rb') as f:
         data = Mesh.FILE_HEADER.unpack(f.read(Mesh.FILE_HEADER.size))
         file_id = data[0]
         file_version = data[1]
         
         data_hash = data[2]
         if data_hash != map_data.data_hash:
             self.outdated = True
             print 'Warning: the navigation mesh is out of date or the wrong map is loaded.'
         else:
             self.outdated = False
         
         # Validate header.
         if file_id != Mesh.FILE_ID:
             print 'Invalid mesh file.'
             return
         if file_version > Mesh.FILE_VERSION:
             print 'Unsupported mesh version {}.'.format(file_version)
             return
         
         area_hashes = {}
         plane_hashes = {}
         connection_hashes = {}
         self.areas = []
         
         # Read planes.
         planes_count = Mesh.FILE_PLANES_HEADER.unpack(f.read(Mesh.FILE_PLANES_HEADER.size))[0]
         for _ in range(planes_count):
             plane = Plane()
             plane_hash, plane.a, plane.b, plane.c, plane.d, plane.invc = Mesh.FILE_PLANE.unpack(f.read(Mesh.FILE_PLANE.size))
             plane_hashes[plane_hash] = plane
         
         # Read area connections.
         connections_count = Mesh.FILE_CONNECTIONS_HEADER.unpack(f.read(Mesh.FILE_CONNECTIONS_HEADER.size))[0]
         for _ in range(connections_count):
             connection = Connection()
             connection_hash, left, top, right, bottom, area_a_hash, area_b_hash, linedef, flags = Mesh.FILE_CONNECTION.unpack(f.read(Mesh.FILE_CONNECTION.size))
             
             if linedef == -1:
                 linedef = None
             
             connection.rect.set(left, top, right, bottom)
             connection.center = connection.rect.get_center()
             connection.area_a = area_a_hash
             connection.area_b = area_b_hash
             connection.linedef = linedef
             connection.flags = flags
             connection_hashes[connection_hash] = connection
         
         # Read mesh areas.
         area_count = Mesh.FILE_AREAS_HEADER.unpack(f.read(Mesh.FILE_AREAS_HEADER.size))[0]
         for index in range(area_count):
             area_hash, left, top, right, bottom, z, plane_hash, sector_index, flags, connection_count = Mesh.FILE_AREA.unpack(f.read(Mesh.FILE_AREA.size))
             
             area = Area(left, top, right, bottom, z)
             if sector_index == -1:
                 sector_index = None
             area.sector = sector_index
             area.flags = flags
             area.index = index
             if plane_hash != 0:
                 area.plane = plane_hashes[plane_hash]
             
             for _ in range(connection_count):
                 connection_hash = Mesh.FILE_AREA_CONNECTION.unpack(f.read(Mesh.FILE_AREA_CONNECTION.size))[0]
                 area.connections.append(connection_hashes[connection_hash])
             
             self.areas.append(area)
             area_hashes[area_hash] = area
         
         # Set connection objects. 
         for connection in connection_hashes.itervalues():
             if connection.area_a != 0:
                 connection.area_a = area_hashes[connection.area_a]
             else:
                 connection.area_a = None
             if connection.area_b != 0:
                 connection.area_b = area_hashes[connection.area_b]
             else:
                 connection.area_b = None
     
     self.map_data = map_data