/** * Changes the position of an entity on the map, by specifying the coordinates of its origin * point. * * @param entity an entity * @param x x coordinate of the origin point * @param y y coordinate of the origin point * @throws MapException if the coordinates are not multiple of 8 */ public void setEntityPosition(MapEntity entity, int x, int y) throws MapException { entity.setPositionInMap(x, y); entity.updateImageDescription(); setChanged(); notifyObservers(); }
/** * Changes the position of a group of entities. * * @param entities the entities to move * @param dx number of pixels to move on x * @param dy number of pixels to move on y * @throws MapException if the coordinates of an entity are not multiple of 8 */ public void moveEntities(List<MapEntity> entities, int dx, int dy) throws MapException { for (MapEntity entity : entities) { entity.move(dx, dy); } setChanged(); notifyObservers(); }
/** * Returns the highest layer where a specified rectangle overlaps an existing entity. * * @param rectangle a rectangle * @return the highest layer where an entity exists in this rectangle, or Layer.LOW if there is * nothing here */ public Layer getLayerInRectangle(Rectangle rectangle) { Layer[] layers = {Layer.HIGH, Layer.INTERMEDIATE, Layer.LOW}; for (Layer layer : layers) { for (MapEntity entity : allEntities[layer.getId()]) { if (rectangle.intersects(entity.getPositionInMap())) { return layer; } } } return Layer.LOW; }
/** * Changes the direction of an entity. * * @param entity the entity to change the direction * @param direction the new direction * @throws MapException if this entity has no direction */ public void setEntityDirection(MapEntity entity, int direction) throws MapException { int oldDirection = entity.getDirection(); if (direction != oldDirection) { entity.setDirection(direction); entity.updateImageDescription(); setChanged(); notifyObservers(); } }
/** * Returns the first entity under a point of the map, in the specified layer. * * @param layer the layer * @param x x of the point * @param y y of the point * @return the entity found, or null if there is no entity here */ public MapEntity getEntityAt(Layer layer, int x, int y) { MapEntities entities = allEntities[layer.getId()]; ListIterator<MapEntity> iterator = entities.listIterator(entities.size()); while (iterator.hasPrevious()) { MapEntity entity = iterator.previous(); if (entity.containsPoint(x, y)) { return entity; } } return null; }
/** * Changes the layer of an entity. You should call this method instead of calling directly * MapEntity.setLayer(), because the entity of the 3 layers are stored in 3 different structures. * If the entity is not known by the map (yet), this method just calls MapEntity.setLayer(). * * @param entity the entity to change the layer * @param layer the new layer */ public void setEntityLayer(MapEntity entity, Layer layer) { Layer oldLayer = entity.getLayer(); if (layer != oldLayer) { entity.setLayer(layer); if (allEntities[oldLayer.getId()].remove(entity)) { allEntities[layer.getId()].add(entity); } setChanged(); notifyObservers(); } }
/** * Changes the position of an entity on the map, by specifying two points. The entity is resized * (i.e. repeatX and repeatY are updated) so that it fits exactly in the rectangle formed by the * two points. * * @param entity an entity * @param x1 x coordinate of the first point * @param y1 y coordinate of the first point * @param x2 x coordinate of the second point * @param y2 y coordinate of the second point * @throws MapException if the entity is not resizable of the rectangle width or its height is * zero or the coordinates or the coordinates are not multiple of 8 */ public void setEntityPosition(MapEntity entity, int x1, int y1, int x2, int y2) throws MapException { entity.setPositionInMap(x1, y1, x2, y2); setChanged(); notifyObservers(); }
/** * Removes an entity from the map. * * @param entity the entity to remove */ public void removeEntity(MapEntity entity) { allEntities[entity.getLayer().getId()].remove(entity); setChanged(); notifyObservers(); }
/** * Checks that the map is valid, i.e. that it can be played without risk. * * @throws MapException if the map is not valid (e.g. no tileset is selected, or some entities are * not in a valid state). */ public void checkValidity() throws MapException { // check that a tileset is selected if (tilesetId.length() == 0) { throw new MapException("No tileset is selected"); } // check that all entities are valid for (MapEntities entities : allEntities) { for (MapEntity entity : entities) { if (!entity.isValid()) { throw new InvalidEntityException("The map contains an invalid entity.", entity); } } } }
/** * Brings the specified entities to the front, keeping their layer. The order of the specified * entities in the map is unchanged. * * @param entities the entities to move */ public void bringToFront(List<MapEntity> entities) { List<MapEntity> sortedEntities = getSortedEntities(entities); // bring to front each entity from sortedEntities ListIterator<MapEntity> iterator = sortedEntities.listIterator(0); while (iterator.hasNext()) { MapEntity entity = iterator.next(); Layer layer = entity.getLayer(); allEntities[layer.getId()].remove(entity); allEntities[layer.getId()].addLast(entity); } setChanged(); notifyObservers(); }
/** * Brings the specified entities to the back, keeping their layer. The order of the specified * entities in the map is unchanged. * * @param entities the entities to move */ public void bringToBack(List<MapEntity> entities) { List<MapEntity> sortedEntities = getSortedEntities(entities); // bring to back each entity from sortedEntities ListIterator<MapEntity> iterator = sortedEntities.listIterator(sortedEntities.size()); while (iterator.hasPrevious()) { MapEntity entity = iterator.previous(); Layer layer = entity.getLayer(); allEntities[layer.getId()].remove(entity); allEntities[layer.getId()].addFirst(entity); } setChanged(); notifyObservers(); }
/** * Changes the tileset of the map. * * @param tilesetId id of the new tileset, or an empty string to set no tileset * @return true if the tileset was loaded successfuly, false if some tiles could not be loaded in * this tileset * @throws MapException if this tileset could be applied */ public boolean setTileset(String tilesetId) throws ZSDXException { this.badTiles = false; // if the tileset is removed if (tilesetId.length() == 0 && this.tilesetId.length() != 0) { this.tilesetId = tilesetId; this.tileset = null; setChanged(); notifyObservers(); } // if the tileset is changed else if (!tilesetId.equals(this.tilesetId)) { this.tileset = new Tileset(tilesetId); for (Layer layer : Layer.values()) { LinkedList<MapEntity> entitiesToRemove = new LinkedList<MapEntity>(); for (MapEntity entity : allEntities[layer.getId()]) { try { entity.setTileset(tileset); } catch (NoSuchTilePatternException ex) { // the entity is not valid anymore, we should remove it from the map entitiesToRemove.add(entity); badTiles = true; } } for (MapEntity entity : entitiesToRemove) { allEntities[layer.getId()].remove(entity); } } this.tilesetId = tilesetId; setChanged(); notifyObservers(tileset); } return !badTiles; }
/** * Returns the entities located in a rectangle defined by two points. * * @param x1 x coordinate of the first point * @param y1 y coordinate of the first point * @param x2 x coordinate of the second point * @param y2 y coordinate of the second point */ public List<MapEntity> getEntitiesInRectangle(int x1, int y1, int x2, int y2) { List<MapEntity> entitiesInRectangle = new LinkedList<MapEntity>(); int x = Math.min(x1, x2); int width = Math.abs(x2 - x1); int y = Math.min(y1, y2); int height = Math.abs(y2 - y1); Rectangle rectangle = new Rectangle(x, y, width, height); for (Layer layer : Layer.values()) { for (MapEntity entity : allEntities[layer.getId()]) { if (rectangle.contains(entity.getPositionInMap())) { entitiesInRectangle.add(entity); } } } return entitiesInRectangle; }
/** * Changes the size of an entity on the map. * * @param entity an entity * @param width the new width * @param height the new height * @throws MapException if the entity is not resizable or the size specified is lower than or * equal to zero or the size specified is not divisible by 8 */ public void setEntitySize(MapEntity entity, int width, int height) throws MapException { entity.setSize(width, height); setChanged(); notifyObservers(); }
/** * Changes the position of an entity on the map, by specifying its rectangle. The entity is * resized so that it fits exactly in the rectangle. * * @param entity an entity * @param position a rectangle * @throws MapException if the entity is not resizable of the rectangle width or its height is * zero */ public void setEntityPosition(MapEntity entity, Rectangle position) throws MapException { entity.setPositionInMap(position); setChanged(); notifyObservers(); }
/** * Loads the map from its file. * * @throws ZSDXException if the file could not be read */ public void load() throws ZSDXException { int lineNumber = 0; try { // get the map name in the game resource database Resource mapResource = Project.getResource(ResourceType.MAP); setName(mapResource.getElementName(mapId)); File mapFile = Project.getMapFile(mapId); BufferedReader in = new BufferedReader(new FileReader(mapFile)); // read the map general info // syntax: width height world floor x y small_keys_variable tileset_id music_id String line = in.readLine(); if (line == null) { throw new ZSDXException("The map file is empty"); } lineNumber++; StringTokenizer tokenizer = new StringTokenizer(line); int width = Integer.parseInt(tokenizer.nextToken()); int height = Integer.parseInt(tokenizer.nextToken()); setSize(new Dimension(width, height)); setWorld(Integer.parseInt(tokenizer.nextToken())); setFloor(Integer.parseInt(tokenizer.nextToken())); int x = Integer.parseInt(tokenizer.nextToken()); int y = Integer.parseInt(tokenizer.nextToken()); setLocation(new Point(x, y)); setSmallKeysVariable(Integer.parseInt(tokenizer.nextToken())); setTileset(tokenizer.nextToken()); setMusic(tokenizer.nextToken()); // read the map entities line = in.readLine(); while (line != null) { lineNumber++; try { MapEntity entity = MapEntity.createFromString(this, line); addEntity(entity); } catch (NoSuchTilePatternException ex) { badTiles = true; } line = in.readLine(); } in.close(); history.setSaved(); } catch (NumberFormatException ex) { throw new ZSDXException("Line " + lineNumber + ": Integer expected"); } catch (IndexOutOfBoundsException ex) { throw new ZSDXException("Line " + lineNumber + ": Value expected"); } catch (ZSDXException ex) { throw new ZSDXException("Line " + lineNumber + ": " + ex.getMessage()); } catch (IOException ex) { throw new ZSDXException(ex.getMessage()); } setChanged(); notifyObservers(); }
/** * Saves the map into its file. * * @throws ZSDXException if the file could not be written for various reasons */ public void save() throws ZSDXException { // check that the map is valid checkValidity(); try { // open the map file File mapFile = Project.getMapFile(mapId); PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(mapFile))); // print the map general info // syntax: width height world floor x y small_keys_variable tileset_id music_id out.print(size.width); out.print('\t'); out.print(size.height); out.print('\t'); out.print(world); out.print('\t'); out.print(floor); out.print('\t'); out.print(location.x); out.print('\t'); out.print(location.y); out.print('\t'); out.print(smallKeysVariable); out.print('\t'); out.print(tilesetId); out.print('\t'); out.print(musicId); out.println(); for (Layer layer : Layer.values()) { MapEntities entities = allEntities[layer.getId()]; // print the entities for (MapEntity entity : entities) { out.print(entity.toString()); out.println(); } } out.close(); history.setSaved(); // also update the map name in the global resource list Resource mapResource = Project.getResource(ResourceType.MAP); mapResource.setElementName(mapId, name); Project.getResourceDatabase().save(); // upate the dungeon elements of this map if (isInDungeon()) { Dungeon.saveMapInfo(this); } // create a script for the map if necessary File scriptFile = Project.getMapScriptFile(mapId); if (!scriptFile.exists()) { scriptFile.createNewFile(); } } catch (IOException ex) { throw new MapException(ex.getMessage()); } }