/** * Can we see this location? * * @param mapX * @param mapY * @param positive If non null, if this entity is detected, algorithm returns true * @param targetFlying If true, and positive is a flying gidrah, we ignore walls and simply return * true * @return true if there is a LOS to the specified map location */ public boolean canSee(float mapX, float mapY, Entity positive, boolean targetFlying) { if (targetFlying && positive != null && positive.isFlying()) { return true; } WormGameState gameState = Worm.getGameState(); GameMap map = gameState.getMap(); ArrayList<Entity> entities = gameState.getEntities(); int n = entities.size(); // Create a list of solid entities we think are somewhere in the LOS ENTITYCACHE.clear(); for (int i = 0; i < n; i++) { Entity e = entities.get(i); if (e != this && e.isActive() && e.isSolid()) { double dist = Util.distanceFromLineToPoint(getX(), getY(), mapX, mapY, e.getX(), e.getY()); if (dist >= 0.0 && dist <= e.getRadius()) { ENTITYCACHE.add(e); } } } int numCachedEntities = ENTITYCACHE.size(); BRESENHAM.plot((int) getX(), (int) getY(), (int) mapX, (int) mapY); int oldMapX = -1, oldMapY = -1; while (BRESENHAM.next()) { int x = BRESENHAM.getX() / MapRenderer.TILE_SIZE; int y = BRESENHAM.getY() / MapRenderer.TILE_SIZE; if (x != oldMapX || y != oldMapY) { for (int z = 0; z < GameMap.LAYERS; z++) { Tile tile = map.getTile(x, y, z); if (tile != null && !tile.isBulletThrough()) { // Tile blocks LOS return false; } } oldMapX = x; oldMapY = y; } // Check entity list if (positive != null) { for (int i = 0; i < numCachedEntities; i++) { Entity e = ENTITYCACHE.get(i); if (e == positive && e.getDistanceTo(BRESENHAM.getX(), BRESENHAM.getY()) < e.getRadius()) { return true; } } } // Skip 4 pixels at a time if (!BRESENHAM.next()) { break; } if (!BRESENHAM.next()) { break; } if (!BRESENHAM.next()) { break; } } return true; }
/** * Get the distance to another entity * * @param xx * @param yy * @return distance, in pixels */ public float getDistanceTo(Entity e) { return Vector2f.sub(new Vector2f(e.getX(), e.getY()), new Vector2f(getX(), getY()), null) .length(); }