package vooga.rts.map; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.TreeSet; import util.Location; import vooga.rts.gamedesign.sprite.gamesprites.GameEntity; import vooga.rts.gamedesign.sprite.gamesprites.GameSprite; import vooga.rts.gamedesign.sprite.map.Terrain; import vooga.rts.gamedesign.state.OccupyState; import vooga.rts.state.GameState; import vooga.rts.util.Camera; import vooga.rts.util.Location3D; /** * The Node class represents the smallest thing that the game needs to know * about. This will be used for generating a path for units to follow and also * be responsible for painting all game entities in their correct location. * * @author Jonathan Schmidt * @author Challen Herzberg-Brovold * */ public class Node { public static int NODE_SIZE = 16; private int myHeight; private int myTier; private int myX; private int myY; private Rectangle myBounds; private Location3D myCenter; private List<GameSprite> myContents; /** * Creates a Node at the specified index and in the specified tier. * * @param x * The X index * @param y * The Y index * @param tier * The level that the node is at */ public Node (int x, int y, int tier) { myX = x; myY = y; myTier = tier; myBounds = new Rectangle(myX * NODE_SIZE, myY * NODE_SIZE, NODE_SIZE, NODE_SIZE); myContents = new ArrayList<GameSprite>(); myCenter = new Location3D(myX * NODE_SIZE + NODE_SIZE / 2, myY * NODE_SIZE + NODE_SIZE / 2, tier); } /** * Creates a Node at a specified index. The level is set to 0. * * @param x * The X index * @param y * The Y index */ public Node (int x, int y) { this(x, y, 0); } public Location3D getCenter () { return myCenter; } public int getX () { return myX; } public int getY () { return myY; } public double getTier () { return myTier; } // This return statement could potentially be cleaned up, but still will // wait for patter to // clear up. public boolean connectsTo (Node other) { return getTier() == other.getTier() || other.getTier() < 0; } /** * * @return the height of the node based on anything inside of it (ie. * IObstructions) */ public int getHeight () { return myHeight; } /** * Returns whether a location is contained within this node. * * @param world * The location to check * @return Whether it is in the node or not */ public boolean contains (Location3D world) { return world.getX() >= myBounds.getMinX() && world.getX() <= myBounds.getMaxX() && world.getY() >= myBounds.getMinY() && world.getY() <= myBounds.getMaxY(); } public void addSprite (GameSprite sprite) { if (!myContents.contains(sprite)) { myContents.add(sprite); if (sprite instanceof Terrain) { myTier++; } } } public void removeSprite (GameSprite sprite) { if (myContents.contains(sprite)) { myContents.remove(sprite); if (sprite instanceof Terrain) { myTier--; } } } public List<GameSprite> getContents () { return new ArrayList<GameSprite>(myContents); } public boolean containsSprite (GameSprite sprite) { return myContents.contains(sprite); } @SuppressWarnings("unchecked") public <T extends GameEntity> List<T> filterGameSprites (Class<T> other, int teamID, boolean same) { List<T> resultList = new ArrayList<T>(); for (GameSprite item : myContents) { if (!(item instanceof GameEntity)) { continue; } GameEntity ge = (GameEntity) item; if (ge.getEntityState().getOccupyState() == OccupyState.OCCUPYING) { continue; } int otherTeam = GameState.getPlayers().getTeamID(ge.getPlayerID()); if (other.isAssignableFrom(ge.getClass())) { if (same) { if (otherTeam == teamID) { resultList.add((T) ge); } } else { if (otherTeam != teamID) { resultList.add((T) ge); } } } } return resultList; } public void paint (Graphics2D pen) { for (GameSprite gs : myContents) { gs.paint(pen); } } /** * Paints the Node with a ellipse surrounding it. This is used for testing * purposes. Also prints the index of the node which can be the order that * the node was painted. * * @param pen * The Graphics 2D to paint with * @param index * The index of the node */ public void paint (Graphics2D pen, int index) { Point2D screen = Camera.instance().worldToView(new Location3D(myX * NODE_SIZE, myY * NODE_SIZE, 0)); if (myX % 10 == 0 || myY % 10 == 0) { pen.fill(new Ellipse2D.Double(screen.getX(), screen.getY(), NODE_SIZE, NODE_SIZE)); } else { pen.draw(new Ellipse2D.Double(screen.getX(), screen.getY(), NODE_SIZE, NODE_SIZE)); } pen.setColor(Color.red); pen.setFont(new Font("Arial", Font.PLAIN, 10)); pen.drawString(Integer.toString(index), (int) screen.getX(), (int) screen.getY()); pen.setColor(Color.blue); pen.setFont(new Font("Arial", Font.PLAIN, 12)); pen.drawString("(" + myX + ", " + myY + ")", (int) screen.getX(), (int) screen.getY() + NODE_SIZE / 2 + 6); pen.setColor(Color.black); paint(pen); } }