package vooga.rts.leveleditor.components; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import vooga.rts.util.Location3D; import vooga.rts.util.Pixmap; /** * the loader that transform a xml file to a real map * @author Richard Yang * */ public class MapLoader { private EditableMap myMap; private Map<Integer, String> myTileName; private Map<Integer, String> myTerrainName; private Map<Integer, String> myResourceName; private Map<Integer, String> myTileImageName; private Map<Integer, String> myTerrainImageName; private Map<Integer, String> myResourceImageName; private Map<Integer, BufferedImage> myTileImage; private Map<Integer, BufferedImage> myTerrainImage; private Map<Integer, BufferedImage> myResourceImage; private Map<Integer, String> myTerrainWalkAbility; private Map<Integer, String> myResourceAmount; private DocumentBuilderFactory myFactory; private DocumentBuilder myBuilder; private Document myDocument; /** * constructor * @throws ParserConfigurationException exception */ public MapLoader() throws ParserConfigurationException { myFactory = DocumentBuilderFactory.newInstance(); myBuilder = myFactory.newDocumentBuilder(); // yolo myTileName = new HashMap<Integer, String>(); myTerrainName = new HashMap<Integer, String>(); myResourceName = new HashMap<Integer, String>(); myTileImageName = new HashMap<Integer, String>(); myTerrainImageName = new HashMap<Integer, String>(); myResourceImageName = new HashMap<Integer, String>(); myTileImage = new HashMap<Integer, BufferedImage>(); myTerrainImage = new HashMap<Integer, BufferedImage>(); myResourceImage = new HashMap<Integer, BufferedImage>(); myTerrainWalkAbility = new HashMap<Integer, String>(); myResourceAmount = new HashMap<Integer, String>(); } public void loadMapFile(String mapfile) throws Exception { URI f = getClass().getResource(mapfile).toURI(); loadMapFile(new File(f)); } /** * * @param resourceFile source file * @throws Exception exception */ public void loadMapFile(File resourceFile) throws Exception { String xmlPath = resourceFile.getPath(); String xmlFileName = resourceFile.getName(); String path = xmlPath.substring(0, xmlPath.indexOf(xmlFileName)); myDocument = myBuilder.parse(resourceFile); Element root = myDocument.getDocumentElement(); loadSizeInfo(root); loadInfo(root); loadTypeInfo(root, path); loadTiles(root); loadTerrains(root); loadResources(root, path); } /** * load all information from the xml file * @param root root element */ public void loadInfo(Element root) { NodeList nameList = root.getElementsByTagName("Name"); Node nameNode = nameList.item(0); myMap.setMapName(nameNode.getTextContent()); NodeList descriptionList = root.getElementsByTagName("Desc"); Node descriptionNode = descriptionList.item(0); myMap.setMapName(descriptionNode.getTextContent()); NodeList playerList = root.getElementsByTagName("Player"); for (int i = 0; i < playerList.getLength(); i++) { Node playerNode = playerList.item(i); NamedNodeMap attributes = playerNode.getAttributes(); String x = attributes.item(1).getNodeValue(); String y = attributes.item(2).getNodeValue(); myMap.addPlayer(Integer.parseInt(x), Integer.parseInt(y)); } } /** * load all size information from the xml file * @param root root element */ public void loadSizeInfo(Element root) { NodeList tileSizeList = root.getElementsByTagName("tilesize"); NodeList tileAmountList = root.getElementsByTagName("tileamount"); Node tileSizeNode = tileSizeList.item(0); Node tileAmountNode = tileAmountList.item(0); int x = Integer.parseInt(tileAmountNode.getAttributes().item(0).getNodeValue()); int y = Integer.parseInt(tileAmountNode.getAttributes().item(1).getNodeValue()); int width = Integer.parseInt(tileSizeNode.getAttributes().item(1).getNodeValue()); int height = Integer.parseInt(tileSizeNode.getAttributes().item(0).getNodeValue()); myMap = new EditableMap("", "", x, y, width, height); } /** * load all type information from the xml file * @param root root element */ public void loadTypeInfo(Element root, String path) throws IOException { NodeList tileTypeList = root.getElementsByTagName("tiletype"); NodeList terrainTypeList = root.getElementsByTagName("terraintype"); NodeList resourceTypeList = root.getElementsByTagName("resourcetype"); String tileImagePath = path + "images/tiles/"; String terrainImagePath = path + "images/terrains/"; String resourceImagePath = path + "images/resources/"; for (int i = 0; i < tileTypeList.getLength(); i++) { Node tileTypeNode = tileTypeList.item(i); NamedNodeMap attributes = tileTypeNode.getAttributes(); String tileID = attributes.item(0).getNodeValue(); String tileImageName = attributes.item(1).getNodeValue(); String tileName = attributes.item(2).getNodeValue(); BufferedImage tileImage = ImageIO.read(new File(tileImagePath + tileImageName)); myTileName.put(Integer.parseInt(tileID), tileName); myTileImageName.put(Integer.parseInt(tileID), tileImageName); myTileImage.put(Integer.parseInt(tileID), tileImage); } for (int i = 0; i < terrainTypeList.getLength(); i++) { Node terrainTypeNode = terrainTypeList.item(i); NamedNodeMap attributes = terrainTypeNode.getAttributes(); String terrainID = attributes.item(0).getNodeValue(); String terrainImageName = attributes.item(1).getNodeValue(); String terrainName = attributes.item(2).getNodeValue(); String terrainWalkAbility = attributes.item(3).getNodeValue(); BufferedImage terrainImage = ImageIO.read(new File(terrainImagePath + terrainImageName)); myTerrainName.put(Integer.parseInt(terrainID), terrainName); myTerrainImageName.put(Integer.parseInt(terrainID), terrainImageName); myTerrainWalkAbility.put(Integer.parseInt(terrainID), terrainWalkAbility); myTerrainImage.put(Integer.parseInt(terrainID), terrainImage); } for (int i = 0; i < resourceTypeList.getLength(); i++) { Node resourceTypeNode = resourceTypeList.item(i); NamedNodeMap attributes = resourceTypeNode.getAttributes(); String resourceID = attributes.item(0).getNodeValue(); String resourceAmount = attributes.item(1).getNodeValue(); String resourceImageName = attributes.item(2).getNodeValue(); String resourceName = attributes.item(3).getNodeValue(); BufferedImage resourceImage = ImageIO.read(new File (resourceImagePath + resourceImageName)); myResourceName.put(Integer.parseInt(resourceID), resourceName); myResourceImageName.put(Integer.parseInt(resourceID), resourceImageName); myResourceAmount.put(Integer.parseInt(resourceID), resourceAmount); myResourceImage.put(Integer.parseInt(resourceID), resourceImage); } } /** * load all terrains from the xml file * @param root root element */ public void loadTiles(Element root) { NodeList tileList = root.getElementsByTagName("tile"); int y = myMap.getMyYsize(); for (int i = 0; i < tileList.getLength(); i++) { int myX = i / y; int myY = i % y; Node tileNode = tileList.item(i); NamedNodeMap attributes = tileNode.getAttributes(); int tileID = Integer.parseInt(attributes.item(0).getNodeValue()); String tileName = myTileName.get(tileID); String tileImageName = myTileImageName.get(tileID); Pixmap tileImage = new Pixmap(myTileImage.get(tileID)); myMap.addTile(myX, myY, tileID, tileName, tileImageName, tileImage); } } /** * load all terrains from the xml file * @param root root element */ public void loadTerrains(Element root) { NodeList terrainList = root.getElementsByTagName("terrain"); for(int j = 0 ; j < terrainList.getLength() ; j++) { Node terrainNode = terrainList.item(j); if(terrainNode.hasAttributes()) { NamedNodeMap attributes = terrainNode.getAttributes(); int terrainID = Integer.parseInt(attributes.item(0).getNodeValue()); int x = Integer.parseInt(attributes.item(1).getNodeValue()); int y = Integer.parseInt(attributes.item(2).getNodeValue()); int z = Integer.parseInt(attributes.item(3).getNodeValue()); String terrainName = myTerrainName.get(terrainID); String terrainImageName = myTerrainImageName.get(terrainID); Pixmap terrainImage = new Pixmap(myTerrainImage.get(terrainID)); int terrainWalkAbility = Integer.parseInt(myTerrainWalkAbility.get(terrainID)); myMap.addTerrain(terrainImage, new Location3D(x,y,z), terrainID, terrainName, terrainImageName, terrainWalkAbility); } } } /** *print everything in this map, used for testing * */ public void printEverything() { myMap.printMatrix(); for (int i = 0 ; i < myMap.getResourceSize() ; i++) { EditableResource res = myMap.getResource(i); System.out.print(res.getMyID()); System.out.print(" "); System.out.print(res.getType()); System.out.print(" "); System.out.print(res.getMyImageName()); System.out.print(" "); System.out.print(res.getWorldLocation().getX()); System.out.print(" "); System.out.print(res.getWorldLocation().getY()); System.out.print(" "); System.out.print(res.getWorldLocation().getZ()); System.out.println(); } for (int i = 0 ; i < myMap.getTerrainSize() ; i++) { EditableTerrain res = myMap.getTerrain(i); System.out.print(res.getMyID()); System.out.print(" "); System.out.print(res.getMyName()); System.out.print(" "); System.out.print(res.getMyImageName()); System.out.print(" "); System.out.print(res.getWorldLocation().getX()); System.out.print(" "); System.out.print(res.getWorldLocation().getY()); System.out.print(" "); System.out.print(res.getWorldLocation().getZ()); System.out.println(); } } /** * load resources from the file * @param root root element * @param path path of the image files */ public void loadResources(Element root, String path) { NodeList resourceList = root.getElementsByTagName("resource"); for (int i = 0; i < resourceList.getLength(); i++) { Node resourceNode = resourceList.item(i); NamedNodeMap attributes = resourceNode.getAttributes(); int resourceID = Integer.parseInt(attributes.item(0).getNodeValue()); int x = Integer.parseInt(attributes.item(1).getNodeValue()); int y = Integer.parseInt(attributes.item(2).getNodeValue()); int z = Integer.parseInt(attributes.item(3).getNodeValue()); String resourceName = myResourceName.get(resourceID); String resourceImageName = myResourceImageName.get(resourceID); Pixmap resourceImage = new Pixmap(myResourceImage.get(resourceID)); int resourceAmount = Integer.parseInt(myResourceAmount.get(resourceID)); myMap.addResource(resourceImage, new Location3D(x,y,z), resourceID, resourceName, resourceImageName, resourceAmount); } } /** * get the loaded editable map * @return */ public EditableMap getMyMap() { return myMap; } }