/** * Sets the entities of the map. * * @param allEntities an array of 3 MapEntity sets: a set for each layer (this array is copied) */ public void setAllEntities(MapEntities[] allEntities) { for (Layer layer : Layer.values()) { this.allEntities[layer.getId()] = new MapEntities(allEntities[layer.getId()]); } setChanged(); notifyObservers(); }
/** * 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(); } }
@Override public boolean apply(final Layer la, final Area roi, final mpicbg.models.CoordinateTransform ict) throws Exception { double[] fp = null; mpicbg.models.CoordinateTransform chain = null; Area localroi = null; AffineTransform inverse = null; for (final Item item : al_items) { final long[] p_layer = item.p_layer; final double[][] p = item.p; for (int i = 0; i < item.n_points; i++) { if (p_layer[i] == la.getId()) { if (null == localroi) { inverse = this.at.createInverse(); localroi = roi.createTransformedArea(inverse); } if (localroi.contains(p[0][i], p[1][i])) { if (null == chain) { chain = M.wrap(this.at, ict, inverse); fp = new double[2]; } // Transform the point M.apply(chain, p, i, fp); } } } } if (null != chain) calculateBoundingBox(la); return true; }
public Layer getLayer(long id) { for (Layer layer : this.layers.values()) { if (layer.getId() == id) { return layer; } } return null; }
/** * 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; }
/** * Finds all entities of a type on the map. * * @param entityType a type of entity * @return the list of the entities of this kind on the map */ public List<MapEntity> getEntitiesOfType(EntityType entityType) { List<MapEntity> list = new LinkedList<MapEntity>(); for (Layer layer : Layer.values()) { list.addAll(allEntities[layer.getId()].getEntitiesOfType(entityType)); } return list; }
/** Initializes the object. */ private void initialize() { this.allEntities = new MapEntities[3]; for (Layer layer : Layer.values()) { this.allEntities[layer.getId()] = new MapEntities(); } this.entitySelection = new MapEntitySelection(this); this.history = new MapEditorHistory(); }
/** * Returns the total number of active entities of the map. * * @return the total number of active entities of the map. */ public int getNbDynamicEntities() { int nbDynamicEntities = 0; // count the dynamic entities of each layer for (Layer layer : Layer.values()) { nbDynamicEntities += allEntities[layer.getId()].getNbDynamicEntities(); } return nbDynamicEntities; }
/** * Returns an entity, specifying its type and its name. * * @param type the type of entity * @param name the name of the entity * @return the entity, or null if there is no entity with this name */ public MapEntity getEntityWithName(EntityType type, String name) { for (Layer layer : Layer.values()) { MapEntity entity = allEntities[layer.getId()].getEntityWithName(type, name); if (entity != null) { return entity; } } return null; }
@Override public boolean contains(final Layer layer, double x, double y) { final long lid = layer.getId(); final Point2D.Double po = inverseTransformPoint(x, y); x = po.x; y = po.y; for (final Item item : al_items) { if (-1 != item.find(lid, x, y, 1)) return true; } return false; }
/** * Returns the total number of entities of the map. * * @return the total number of entities of the map. */ public int getNbEntities() { int nbEntities = 0; // count the entities of each layer for (Layer layer : Layer.values()) { nbEntities += allEntities[layer.getId()].size(); } return nbEntities; }
/** * 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; }
// Comparable @Override public int compareTo(Layer layer) { if (priority < layer.priority) { return -1; } else if (priority > layer.priority) { return 1; } else if ((layer instanceof GroundCoverLayer) && (Math.abs(((GroundCoverLayer) layer).thickness) != Math.abs(thickness))) { return Math.abs(((GroundCoverLayer) layer).thickness) - Math.abs(thickness); } else { return getId().compareTo(layer.getId()); } }
/** * 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; }
/** Retain the data within the layer range, and through out all the rest. */ @Override public synchronized boolean crop(final List<Layer> range) { final HashSet<Long> lids = new HashSet<Long>(); for (final Layer l : range) { lids.add(l.getId()); } for (final Item item : al_items) { for (int i = 0; i < item.n_points; i++) { if (!lids.contains(item.p_layer[i])) { item.remove(i); i--; } } } calculateBoundingBox(null); return true; }
/** * 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(); }
@Override public synchronized Area getAreaAt(final Layer layer) { final Area a = new Area(); for (final Item item : al_items) { for (int i = 0; i < item.n_points; i++) { if (item.p_layer[i] != layer.getId()) continue; a.add( new Area( new Rectangle2D.Float( (float) (item.p[0][i] - item.radius), (float) (item.p[1][i] - item.radius), item.radius, item.radius))); } } a.transform(this.at); return a; }
public boolean removeIdentifiable(long id) { Collection<Scene> tmpScene = new ArrayList<Scene>(); tmpScene.addAll(this.scenes); for (Scene scene : tmpScene) { if (scene.getId() == id) { this.removeScene(scene); return true; } } List<Layer> tmpLayer = new ArrayList<Layer>(); tmpLayer.addAll(this.layers.values()); for (Layer layer : tmpLayer) { if (layer.getId() == id) { this.removeLayer(layer); return true; } } return false; }
/** * Returns the specified entities, sorted in the order of the map. The first entity is the lowest * one, the last entity is the highest one. * * @param entities the entities to sort * @return the same entities, sorted as they are in the map */ public List<MapEntity> getSortedEntities(List<MapEntity> entities) { List<MapEntity> sortedEntities = new LinkedList<MapEntity>(); // sort the entities so that they have the same order as in the map for (Layer layer : Layer.values()) { for (MapEntity entity : allEntities[layer.getId()]) { if (entities.contains(entity)) { sortedEntities.add(entity); } } } // now sortedEntities contains all entities of the list, // sorted in the same order as in the map return sortedEntities; }
/** * 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; }
/** * Returns the index of the added point only if: - there are no points, and thus this is the * first; - there is no point already for that layer; - the given layer is immediately adjacent * (outwards) to that of the first or the last points. * * <p>Otherwise returns -1 */ final int add(final double x, final double y, final Layer layer) { final long lid = layer.getId(); // trivial case if (0 == n_points) { p[0][0] = x; p[1][0] = y; p_layer[0] = lid; n_points = 1; return 0; } // check if there is already a point for the given layer for (int i = 0; i < n_points; i++) if (lid == p_layer[i]) { return -1; } final int il = layer_set.indexOf(layer); if (layer_set.indexOf(layer_set.getLayer(p_layer[n_points - 1])) == il - 1) { // check if new point is within radius of the found point if (p[0][n_points - 1] + radius >= x && p[0][n_points - 1] - radius <= x && p[1][n_points - 1] + radius >= y && p[1][n_points - 1] - radius <= y) { // ok } else { // can't add // Utils.log2(tag + " case append: can't add"); return -1; } // check size if (n_points >= p[0].length) enlargeArrays(); // append at the end p[0][n_points] = x; p[1][n_points] = y; p_layer[n_points] = lid; n_points++; return n_points - 1; } if (layer_set.indexOf(layer_set.getLayer(p_layer[0])) == il + 1) { // check if new point is within radius of the found point if (p[0][0] + radius >= x && p[0][0] - radius <= x && p[1][0] + radius >= y && p[1][0] - radius <= y) { // ok } else { // can't add // Utils.log2(tag + " case preppend: can't add"); return -1; } // check size if (n_points >= p[0].length) enlargeArrays(); // prepend // shift all points one position to the right for (int i = n_points - 1; i > -1; i--) { p[0][i + 1] = p[0][i]; p[1][i + 1] = p[1][i]; p_layer[i + 1] = p_layer[i]; } p[0][0] = x; p[1][0] = y; p_layer[0] = lid; n_points++; return 0; } // else invalid layer // Utils.log2(tag + " invalid layer"); return -1; }
@Override public void mousePressed( final MouseEvent me, final Layer la, int x_p, int y_p, final double mag) { final int tool = ProjectToolbar.getToolId(); if (ProjectToolbar.PEN != tool) return; final long lid = la.getId(); // isn't this.layer pointing to the current layer always? // transform the x_p, y_p to the local coordinates if (!this.at.isIdentity()) { final Point2D.Double p = inverseTransformPoint(x_p, y_p); x_p = (int) p.x; y_p = (int) p.y; } // find if the click is within radius of an existing point for the current layer for (final Item tmp : al_items) { index = tmp.find(lid, x_p, y_p, mag); if (-1 != index) { this.item = tmp; break; } } // final boolean is_zoom_invariant = "true".equals(project.getProperty("dissector_zoom")); // TODO: if zoom invariant, should check for nearest point. Or nearest point anyway, when // deleting // (but also for adding a new one?) if (me.isShiftDown() && Utils.isControlDown(me)) { if (-1 != index) { // delete item.remove(index); if (0 == item.n_points) al_items.remove(item); item = null; index = -1; Display.repaint(layer_set, this, 0); } // in any case: return; } if (-1 != index) return; // else try to add a point to a suitable item // Find an item in the previous or the next layer, // which falls within radius of the clicked point try { for (final Item tmp : al_items) { index = tmp.add(x_p, y_p, la); if (-1 != index) { this.item = tmp; return; } } // could not be added to an existing item, so creating a new item with a new point in it int max_tag = 0; for (final Item tmp : al_items) { if (tmp.tag > max_tag) max_tag = tmp.tag; } int radius = 8; // default if (al_items.size() > 0) radius = al_items.get(al_items.size() - 1).radius; this.item = new Item(max_tag + 1, radius, x_p, y_p, la); index = 0; al_items.add(this.item); } finally { if (null != item) { bbox = this.at.createTransformedShape(item.getBoundingBox()).getBounds(); Display.repaint(layer_set, bbox); } else Display.repaint(layer_set, this, 0); } }
@Override protected boolean layerRemoved(final Layer la) { super.layerRemoved(la); for (final Item item : al_items) item.layerRemoved(la.getId()); return true; }
/** * 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()); } }
/** * Returns the entities of the map on a given layer. * * @param layer the layer * @return the entities placed on that layer */ public MapEntities getEntities(Layer layer) { return allEntities[layer.getId()]; }