def load_map(self, map): """Load a map.""" #Unload the current map first self.unload_map() #Locate the XML file for the map Logger.info("Loading map '{}'...".format(map)) map_file = os.path.join(map, os.path.basename(map) + ".xml") if not os.path.exists(map_file): Logger.error("Failed to load map file '{}'.".format(map_file)) return False #Load the map XML file xml = etree.parse(map_file) root = xml.getroot() for child in root: #Terrain? if child.tag == "terrain": #Validate terrain if not ("size" in child.attrib and "spawnpos" in child.attrib and "heightmap" in child.attrib): Logger.error( "Terrain section must define 'size', 'spawnpos', and 'heightmap'." ) return False #Load terrain self.size = parse_vec(child.attrib["size"], 3) self.spawnpos = parse_vec(child.attrib["spawnpos"], 2) heightmap = os.path.join(map, child.attrib["heightmap"]) self.terrain = GeoMipTerrain("Terrain") self.terrain.set_block_size(64) self.terrain.set_bruteforce(True) if not self.terrain.set_heightfield(heightmap): Logger.error("Failed to load heightmap for terrain.") self.terrain = None return False self.terrain_np = self.terrain.get_root() self.terrain_np.set_scale(self.size[0] / 512, self.size[1] / 512, self.size[2]) tex = loader.load_texture( "./data/textures/terrain/grass_tex2.png") self.terrain_np.set_texture(tex) self.terrain_np.set_tex_scale(TextureStage.get_default(), self.size[0] / 512, self.size[1] / 512) tex.set_wrap_u(Texture.WM_repeat) tex.set_wrap_v(Texture.WM_repeat) self.terrain_np.reparent_to(render) self.terrain.generate() base.camera.set_pos(self.size[0] / 2, self.size[1] / 2, self.size[2]) #Portal? elif child.tag == "portal": #Validate portal if not ("pos" in child.attrib and "destmap" in child.attrib): Logger.warning("Portal must define 'pos' and 'destmap'.") continue #Load portal pos = parse_vec(child.attrib["pos"], 3) radius = parse_float( child.attrib["radius"]) if "radius" in child.attrib else 1 destmap = child.attrib["destmap"] self.add_portal(pos, radius, destmap) #Gate? elif child.tag == "gate": #Validate gate if not ("pos" in child.attrib and "destmap" in child.attrib and "destvec" in child.attrib): Logger.warning( "Gate must define 'pos', 'destmap', and 'destvec'.") continue #Load gate pos = parse_vec(child.attrib["pos"], 3) destmap = child.attrib["destmap"] destvec = parse_vec(child.attrib["destvec"], 3) material = child.attrib[ "material"] if "material" in child.attrib else "" self.add_gate(pos, destmap, destvec, material) #Object? elif child.tag == "object": #Validate object if not ("mesh" in child.attrib and "pos" in child.attrib): Logger.warning("Object must define 'mesh' and 'pos'.") continue #Load object mesh = child.attrib["mesh"] pos = parse_vec(child.attrib["pos"], 3) rot = parse_vec(child.attrib["rot"], 3) if "rot" in child.attrib else [0, 0, 0] scale = parse_vec(child.attrib["scale"], 3) if "scale" in child.attrib else [1, 1, 1] material = child.attrib[ "material"] if "material" in child.attrib else "" sound = child.attrib["sound"] if "sound" in child.attrib else "" self.add_object(mesh, pos, rot, scale, material, sound) #Object Group? elif child.tag == "objectgroup": #Validate object group if not ("mesh" in child.attrib): Logger.warning("Object group must define 'mesh'.") continue #Load object group mesh = child.attrib["mesh"] material = child.attrib[ "material"] if "material" in child.attrib else "" self.load_object_group(child, mesh, material) #Unknown? else: Logger.warning( "Unknown tag '{}' encountered in map '{}'.".format( child.tag, map)) #Map loaded Logger.info("Map '{}' loaded.".format(map)) return True