mirror of
https://github.com/AndorsTrailRelease/ATCS.git
synced 2025-10-27 18:44:03 +01:00
365 lines
9.6 KiB
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);
|
|
}
|
|
|
|
}
|