Files
archived-ATCS/src/com/gpl/rpg/atcontentstudio/model/maps/TMXMap.java

365 lines
9.6 KiB
Java

package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.tree.TreeNode;
import tiled.io.TMXMapReader;
import tiled.io.TMXMapWriter;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class TMXMap extends GameDataElement {
private static final long serialVersionUID = 1609502879500898837L;
public static final String GROUND_LAYER_NAME = "Ground";
public static final String OBJECTS_LAYER_NAME = "Objects";
public static final String ABOVE_LAYER_NAME = "Above";
public static final String WALKABLE_LAYER_NAME = "Walkable";
public File tmxFile = null;
public tiled.core.Map tmxMap = null;
public Set<Spritesheet> usedSpritesheets = null;
public List<MapObjectGroup> groups = null;
public ProjectTreeNode parent;
public Integer outside = null;
public boolean writable = false;
public TMXMap(TMXMapSet parent, File f) {
this.parent = parent;
this.tmxFile = f;
String name = f.getName();
id = name.substring(0, name.length() - 4);
}
public void parse() {
if (this.state == GameDataElement.State.init) {
if (tmxMap != null) return;
usedSpritesheets = new HashSet<Spritesheet>();
try {
tmxMap = new TMXMapReader().readMap(tmxFile.getAbsolutePath(), this);
if (tmxMap.getProperties().get("outside") != null) {
outside = new Integer(((String) tmxMap.getProperties().get("outside")));
}
} catch (FileNotFoundException e) {
Notification.addError("Impossible to load TMX map file "+tmxFile.getAbsolutePath());
} catch (Exception e) {
Notification.addError("Error while loading TMX map file "+tmxFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
}
for (tiled.core.MapLayer layer : tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) {
if (groups == null) {
groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
groups.add(group);
}
}
for (Spritesheet s : usedSpritesheets) {
s.addBacklink(this);
}
state = State.parsed;
}
}
public void create() {
if (tmxMap != null) return;
tmxMap = new tiled.core.Map(30, 30);
}
public TMXMap clone() {
TMXMap clone = new TMXMap((TMXMapSet) this.parent, this.tmxFile);
try {
clone.usedSpritesheets = new HashSet<Spritesheet>();
clone.tmxMap = new TMXMapReader().readMap(new StringReader(this.toXml()), clone);
if (clone.tmxMap.getProperties().get("outside") != null) {
clone.outside = new Integer(((String) clone.tmxMap.getProperties().get("outside")));
}
for (tiled.core.MapLayer layer : clone.tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) {
if (clone.groups == null) {
clone.groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
clone.groups.add(group);
}
}
for (Spritesheet s : usedSpritesheets) {
s.addBacklink(clone);
}
} catch (Exception e) {
Notification.addError("Error while cloning map "+this.id+" : "+e.getMessage());
e.printStackTrace();
}
return clone;
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public TreeNode getChildAt(int arg0) {
return null;
}
@Override
public int getChildCount() {
return 0;
}
@Override
public int getIndex(TreeNode arg0) {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (this.state == State.modified ? "*" : "")+id;
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return DefaultIcons.getTiledIconIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getTiledIconIcon();
}
@Override
public Image getClosedIcon() {return null;}
@Override
public Image getOpenIcon() {return null;}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
public String toXml() {
for (MapObjectGroup group : groups) {
group.pushBackToTiledProperties();
if (!tmxMap.containsLayer(group.tmxGroup)) {
tmxMap.addLayer(group.tmxGroup);
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
TMXMapWriter writer = new TMXMapWriter();
writer.settings.layerCompressionMethod = TMXMapWriter.Settings.LAYER_COMPRESSION_METHOD_ZLIB;
if (getDataType() == GameSource.Type.source) {
writer.writeMap(tmxMap, baos, tmxFile.getAbsolutePath());
} else {
writer.writeMap(tmxMap, baos, getProject().baseContent.gameMaps.mapFolder.getAbsolutePath()+File.separator+"placeholder.tmx");
}
} catch (Exception e) {
Notification.addError("Error while converting map "+getDesc()+" to XML: "+e.getMessage());
e.printStackTrace();
}
return baos.toString();
}
@Override
public boolean isEmpty() {
return false;
}
public void save() {
if (writable) {
try {
FileWriter w = new FileWriter(tmxFile);
w.write(toXml());
w.close();
this.state = State.saved;
Notification.addSuccess("TMX file "+tmxFile.getAbsolutePath()+" saved.");
} catch (IOException e) {
Notification.addError("Error while writing TMX file "+tmxFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
}
}
}
@Override
public List<SaveEvent> attemptSave() {
//TODO check cases where map should be moved from altered/created to created/altered....
save();
return null;
}
public void delete() {
if (writable) {
if (tmxFile.exists()) {
if (tmxFile.delete()) {
Notification.addSuccess("TMX file "+tmxFile.getAbsolutePath()+" deleted.");
} else {
Notification.addError("Error while deleting TMX file "+tmxFile.getAbsolutePath());
}
}
((TMXMapSet)parent).tmxMaps.remove(this);
//TODO clear blacklinks ?
}
}
@Override
public void link() {
if (this.state == GameDataElement.State.init) {
parse();
}
if (this.state == GameDataElement.State.parsed || this.state == GameDataElement.State.created) {
for (MapObjectGroup group : groups) {
group.link();
}
}
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
for (MapObjectGroup group : groups) {
group.elementChanged(oldOne, newOne);
}
}
@Override
public String getProjectFilename() {
return tmxFile.getName();
}
public void addLayer(tiled.core.MapLayer layer) {
tmxMap.addLayer(layer);
if (layer instanceof tiled.core.ObjectGroup) {
groups.add(new MapObjectGroup((tiled.core.ObjectGroup) layer, this));
}
}
public void removeLayer(tiled.core.MapLayer layer) {
tmxMap.removeLayer(tmxMap.getLayerIndex(layer));
if (layer instanceof tiled.core.ObjectGroup) {
MapObjectGroup toRemove = null;
for (MapObjectGroup group : groups) {
if (group.tmxGroup == layer) {
toRemove = group;
}
}
if (toRemove != null) {
groups.remove(toRemove);
}
}
}
public MapObjectGroup getGroup(tiled.core.ObjectGroup selectedLayer) {
for (MapObjectGroup group : groups) {
if (group.tmxGroup == selectedLayer) {
return group;
}
}
return null;
}
public List<String> getMapchangesNames() {
List<String> result = new ArrayList<String>();
result.add(null);
for (MapObjectGroup group : groups) {
for (MapObject obj : group.mapObjects) {
if (obj.type == MapObject.Types.mapchange) {
result.add(obj.name);
}
}
}
return result;
}
public MapObject getMapObject(String name) {
MapObject result = null;
for (MapObjectGroup group : groups) {
for (MapObject obj : group.mapObjects) {
if (obj.name.equals(name)) {
result = obj;
break;
}
}
}
return result;
}
public static boolean isPaintedLayerName(String name) {
return GROUND_LAYER_NAME.equalsIgnoreCase(name) ||
OBJECTS_LAYER_NAME.equalsIgnoreCase(name) ||
ABOVE_LAYER_NAME.equalsIgnoreCase(name) ||
WALKABLE_LAYER_NAME.equalsIgnoreCase(name);
}
}