public void draw(Graphics2D g, int layer) { for (int row = rowOffset; row < rowOffset + numRowsToDraw; row++) { if (row >= numRows) break; for (int col = colOffset; col < colOffset + numColsToDraw; col++) { if (col >= numCols) break; if (mapList.get(layer - 1)[row][col] == null) continue; if (mapList.get(layer - 1)[row][col].getTile() == 0) continue; MapTile rc = mapList.get(layer - 1)[row][col]; int r = rc.getTile() / numTilesAcross; int c = rc.getTile() % numTilesAcross; g.drawImage( tiles[r][c].getImage(), (int) x + col * tileSize, (int) y + row * tileSize, null); } } }
/** * Do the obstruction check of a tile. So this means that all tiles are hidden in case there is a * tile above them and they are fully invisible anyway. Tiles below the level of the player are * removed, since they won't be displayed ever anyway. The tiles at or above the players location * are possibly shown in case the char steps into a building or something. * * @param tile the tile that is checked * @param key the location key of the checked tile * @return <code>true</code> in case the tile got removed */ private boolean checkObstruction(final MapTile tile, final long key) { final Location playerLoc = World.getPlayer().getLocation(); final Location tileLoc = tile.getLocation(); final int topLimit = playerLoc.getScZ() + 2; int currX = tileLoc.getScX(); int currY = tileLoc.getScY(); int currZ = tileLoc.getScZ(); while (currZ < topLimit) { currX -= MapDisplayManager.TILE_PERSPECTIVE_OFFSET; currY += MapDisplayManager.TILE_PERSPECTIVE_OFFSET; currZ++; final boolean remove = (currZ < (topLimit - 2)); final MapTile foundTile = parent.getMapAt(currX, currY, currZ); if ((foundTile != null) && foundTile.isOpaque() && !foundTile.isHidden()) { if (remove) { parent.removeTile(key); return true; } tile.setObstructed(true); return false; } } if (tile.isObstructed()) { tile.setObstructed(false); addAllBelow(tileLoc, playerLoc.getScZ() - 2); } return false; }
/** * Load the mapFile and prepare the map * * @param mapFilePath * @return the GameObjects present on the map * @throws IOException */ public List<GameObject> initializeMap(String mapFilePath) throws IOException { final List<GameObject> gameObjectList = new ArrayList<>(); final File mapFile = new File(mapFilePath); BufferedReader br = null; try { GameMap.LOGGER.info("Starting to load the map : " + mapFilePath); br = new BufferedReader(new FileReader(mapFile)); String line; int lineNbr = 0; while ((line = br.readLine()) != null) { // each element of the array represent one square of the map final String[] split = line.split(this.mapTileSeparator); // In addition to the map, the array contains the position of the game objects // presents on the map for (int i = 0; i < split.length; i++) { final String mapSquare = split[i]; // If a tile is successfully found, it is put on the map. // If not, the default tile is left if (!mapSquare.trim().isEmpty()) { // The first letter is the mapTile, after if there is a game object at this // coordinates, it follows (without any separation) (example : Se mean an // exit in tile of type sky) this.map[lineNbr][i] = MapTile.getMapTypeByCode(mapSquare.trim().substring(0, 1)); if (mapSquare.trim().length() != 1) { final GameObject gameObject = this.getGameObjectFromCode(mapSquare.trim().substring(1, 2), i, lineNbr); if (gameObject != null) { gameObjectList.add(gameObject); } } } } lineNbr++; } } catch (final IOException e) { GameMap.LOGGER.log( Level.SEVERE, "While loading the map " + mapFilePath + " : " + e.toString(), e); throw e; } finally { if (br != null) { br.close(); } } GameMap.LOGGER.info("Map loaded"); return gameObjectList; }
protected void useAbility(Unit U, Ability A, GPoint T) { // uses the selected ability on the selected target // code copied from player class // decrement action points U.usePoints(A.getCost()); // get the tiles that were affected by the attack List<AttackedTile> tilesAffected = A.getTilesAffected(U, T, map); for (int j = 0; j < tilesAffected.size(); j++) { MapTile tile = map.getTile(tilesAffected.get(j).tile); if (tile.hasUnit()) { // there is a unit on the tile int unitId = tile.getUnit_id(); Unit unit = map.getUnit(unitId); // reduce unit health by attack dmg if (unit != null) { DamageDealt damageDone = unit.takeDamage(tilesAffected.get(j).damageTaken, map); healthIndicators.add( new HealthIndicator( map, new GPoint(tilesAffected.get(j).tile.row, tilesAffected.get(j).tile.col), 30, damageDone.healthDamage, indicatorPaint, false)); if (damageDone.isAttack && damageDone.armorDamage < 0) { healthIndicators.add( new HealthIndicator( map, new GPoint(tilesAffected.get(j).tile.row, tilesAffected.get(j).tile.col), 0, damageDone.armorDamage, indicatorPaint, true)); } if (U != unit && damageDone.isAttack) // don't send indicator for heals map.sendHitIndicator(new HitIndicator(U, A, unit, tilesAffected.get(j).tile, map), unit); } } } }
public int getType(int row, int col) { try { MapTile rc = mapList.get(0)[row][col]; // System.out.println(row + " " + col + " " + mapList.get(0)[row][col].getTile()); int r = rc.getTile() / numTilesAcross; int c = rc.getTile() % numTilesAcross; return tiles[r][c].getType(); } catch (ArrayIndexOutOfBoundsException e) { System.out.println( "Actual [row : columns]: " + numRows + ":" + numCols + " - Referred: " + row + ":" + col); e.printStackTrace(); } return 0; }
/** * Search all surrounding tiles and the tile below and look for a tile that is currently hidden. * * @param searchLoc the location where the search starts * @return <code>true</code> in case a hidden tile was found */ private boolean searchHiddenNeighbour(final Location searchLoc) { for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { if ((x == 0) && (y == 0)) { continue; } final MapTile foundTile = parent.getMapAt(searchLoc.getScX() + x, searchLoc.getScY() + y, searchLoc.getScZ()); if ((foundTile != null) && foundTile.isHidden()) { return true; } } } MapTile foundTile = parent.getMapAt(searchLoc.getScX(), searchLoc.getScY(), searchLoc.getScZ() + 1); if ((foundTile != null) && foundTile.isHidden()) { return true; } foundTile = parent.getMapAt(searchLoc.getScX(), searchLoc.getScY(), searchLoc.getScZ() - 1); return (foundTile != null) && foundTile.isHidden(); }
/** * Loads from an external file a new GameMap object for use within the game. A GameMap is the * primary object which house each MapCanvas object (that is, each elevation level in the map) and * in turn, each MapTile object (that is, each unique texture block). * * @param file * @return The newly created GameMap */ public void loadMap(String file) { XMLParser mapFile = new XMLParser(file); for (Node mapEl : mapFile.root.children) { for (Node el : mapEl.children) { if (el.name.equals("tileDimensions")) GameMap.MAP.setTileDimension(el.readInt()); else if (el.name.equals("lightLevel")) GameMap.MAP.setLightLevel(el.readFloat()); else if (el.name.equals("tile")) { MapTile mt = new MapTile(); for (Node tileChild : el.children) { if (tileChild.name.equals("id")) mt.id = tileChild.readInt(); else if (tileChild.name.equals("file")) mt.loadTexture(tileChild.readString()); else if (tileChild.name.equals("collidable")) mt.collidable = tileChild.readBoolean(); } mt.width = mt.height = GameMap.MAP.tileDimensions; GameMap.MAP.tiles.put(mt.id, mt); } else if (el.name.equals("canvas")) GameMap.MAP.parseCanvas(el.data); else if (el.name.equals("entity")) { GameEntity entity = null; for (Node entityEl : el.children) { if (entityEl.name.equals("file")) { entity = loadEntity(entityEl.readString()); } else if (entityEl.name.equals("position")) entity.setPosition(entityEl.readFloatArray()); } addEntity(entity); } else if (el.name.equals("player")) { for (Node playerNode : el.children) { if (playerNode.name.equals("position")) MANAGER.playerFocusEntity.setPosition(playerNode.readFloatArray()); } } } } }
/** * Check if the tile needs to be hidden because the player is inside a cave or a house or * something like this. * * @param tile the tile that is checked * @param key the location key of the checked tile * @return <code>true</code> in case the tile was handled */ @SuppressWarnings("nls") private boolean checkHidden(final MapTile tile, final long key) { final Location playerLoc = World.getPlayer().getLocation(); final Location tileLoc = tile.getLocation(); if ((playerLoc == null) || (tileLoc == null)) { // something is very wrong. Put this entry back into the unchecked // list and try it again later. reportUnchecked(key); return true; } /* * And now we start with the inside check. In case the tile is below the * level of the player its never hidden for sure. */ if (tileLoc.getScZ() <= playerLoc.getScZ()) { if (tile.isHidden()) { tile.setHidden(false); addAllBelow(tileLoc, playerLoc.getScZ() - 2); addAllNeighbours(tileLoc); } return true; } /* * Now generate the index in the list of inside states and check if the * tile is on a level that is hidden or not. If the tile is on such a * level it does not mean for sure that it really needs to be hidden. */ final int insideIndex = tileLoc.getScZ() - playerLoc.getScZ() - 1; if ((insideIndex < 0) || (insideIndex > 1)) { LOGGER.warn("Invalid inside index: " + insideIndex); return true; } /* * Tile is not on a inside level. In case its hidden, show it again. */ if (!insideStates[insideIndex]) { if (tile.isHidden()) { tile.setHidden(false); addAllBelow(tileLoc, playerLoc.getScZ() - 2); addAllAbove(tileLoc, playerLoc.getScZ() + 2); addAllNeighbours(tileLoc); } return true; } /* * Now check if the tile is directly above the player. In this case it * needs to be hidden. */ if ((tileLoc.getScX() == playerLoc.getScX()) && (tileLoc.getScY() == playerLoc.getScY()) && (tileLoc.getScZ() > playerLoc.getScZ()) && !tile.isHidden()) { tile.setHidden(true); addAllBelow(tileLoc, playerLoc.getScZ() - 2); addAllAbove(tileLoc, playerLoc.getScZ() + 2); addAllNeighbours(tileLoc); return true; } if (!tile.isHidden() && searchHiddenNeighbour(tileLoc)) { tile.setHidden(true); addAllBelow(tileLoc, playerLoc.getScZ() - 2); addAllAbove(tileLoc, playerLoc.getScZ() + 2); addAllNeighbours(tileLoc); return true; } return false; }
/** * Do the clipping check of a tile. * * @param tile the tile that is checked * @param key the location key of the checked tile * @return <code>true</code> in case the tile was clipped away */ private boolean checkClipping(final MapTile tile, final long key) { if (!World.getPlayer().hasValidLocation()) { return false; } final Location playerLoc = World.getPlayer().getLocation(); final Location tileLoc = tile.getLocation(); /* * Start checking the clipping of the tiles. In case a tile is found * outside the clipping range, its deleted. */ if ((playerLoc.getScZ() + 2) < tileLoc.getScZ()) { parent.removeTile(key); LOGGER.debug("Removed tile at location " + tileLoc.toString() + " (tile.x > player.z + 2)"); return true; } if ((playerLoc.getScZ() - 2) > tileLoc.getScZ()) { parent.removeTile(key); LOGGER.debug("Removed tile at location " + tileLoc.toString() + " (tile.x < player.z - 2)"); return true; } final MapDimensions mapDim = MapDimensions.getInstance(); if ((playerLoc.getCol() + mapDim.getClippingOffsetLeft()) > tileLoc.getCol()) { parent.removeTile(key); LOGGER.debug( "Removed tile at location " + tileLoc.toString() + " (outside of left clipping)"); LOGGER.debug( "Ply Col: " + Integer.toString(playerLoc.getCol()) + " Clipping Left: " + Integer.toString(mapDim.getClippingOffsetLeft()) + " Tile Col: " + Integer.toString(tileLoc.getCol())); return true; } if ((playerLoc.getCol() + mapDim.getClippingOffsetRight()) < tileLoc.getCol()) { parent.removeTile(key); LOGGER.debug( "Removed tile at location " + tileLoc.toString() + " (outside of right clipping)"); LOGGER.debug( "Ply Col: " + Integer.toString(playerLoc.getCol()) + " Clipping Right: " + Integer.toString(mapDim.getClippingOffsetRight()) + " Tile Col: " + Integer.toString(tileLoc.getCol())); return true; } final int level = Math.abs(tileLoc.getScZ() - playerLoc.getScZ()) * 6; if ((playerLoc.getRow() + mapDim.getClippingOffsetTop()) < (tileLoc.getRow() - level)) { parent.removeTile(key); LOGGER.debug("Removed tile at location " + tileLoc.toString() + " (outside of top clipping)"); LOGGER.debug( "Ply Row: " + Integer.toString(playerLoc.getRow()) + " Clipping Top: " + Integer.toString(mapDim.getClippingOffsetTop()) + " Tile Row: " + Integer.toString(tileLoc.getRow())); return true; } if ((playerLoc.getRow() + mapDim.getClippingOffsetBottom()) > (tileLoc.getRow() + level)) { parent.removeTile(key); LOGGER.debug( "Removed tile at location " + tileLoc.toString() + " (outside of bottom clipping)"); LOGGER.debug( "Ply Row: " + Integer.toString(playerLoc.getRow()) + " Clipping Bottom: " + Integer.toString(mapDim.getClippingOffsetBottom()) + " Tile Row: " + Integer.toString(tileLoc.getRow())); return true; } return false; }