Compare commits

...

20 Commits

Author SHA1 Message Date
Zukero
1a70f87897 v0.4.7 ! 2016-08-10 18:03:11 +02:00
Zukero
c07fb4ddf3 Implemented all colorfilters in TMXMapEditor, thanks to the new
MatrixComposite that really emulates the ColorMatrixColorFilter of
Android ! Hi-fidelity filter emulation !
2016-08-10 16:20:48 +02:00
Zukero
1458fb0aaa Bug fix for the map's "outside" property that wasn't handled properly.
Added support for the new "colorfilter" map property. Due to Java2D
having no correct color filter support, only the "blackXX" values can be
previwed. "bw" and "invert" cannot, the performance cost was simply way
too high.
2016-08-08 16:31:38 +02:00
Zukero
57b8209b26 v0.4.6 ! Oh so many bugfixes... 2016-07-21 16:39:55 +02:00
Zukero
a7224755ff Fixed NPE in KeyArea creation. Rest areas can be renamed. 2016-07-19 18:49:42 +02:00
Zukero
e97168c62e v0.4.5 complete with packaging. 2016-07-19 17:57:02 +02:00
Zukero
1e8dd405c3 Addedchanges to match new datamodel in AT. Notably, ability to disable a
Map Object Group in a new game in a map, and the associated rewards
((de)activateMapObjectGroup) in dialogues that replace
(de)activateMapChangeArea.
2016-07-19 17:37:54 +02:00
Zukero
830e9de56b v0.4.5 to cope with changes to spawnareas definition in game code.
replaced gcode references by github repo.
2016-07-18 18:55:16 +02:00
Zukero
2a06002b51 Updated packaging for v0.4.4 2016-01-05 14:22:18 +01:00
Zukero
84b1b6a7eb v0.4.4 !
- Projects can now use either loadresources.xml or
loadresources_debug.xml, or none (as before). This must be selected at
project creation and cannot be changed.
- NPC and Items comparators now include both the source and altered
version of elements present in both.
- Spritesheets view should now be better laid out, as insets were not
taken into account, thus cropping a few pixels right and down.
2016-01-05 14:15:23 +01:00
Zukero
f924c481f8 v0.4.3 ! Only a bugfix on JSON import. 2016-01-01 22:59:20 +01:00
Zukero
ed004f5cfc v0.4.2 ! 2015-10-30 14:09:28 +01:00
Zukero
12ca21b9e4 Added "active" setting for SpawnAreas. Added cool tooltip to
DialogueGraphView
2015-10-30 14:02:38 +01:00
Zukero
f5c454807c Small bug fixes (started ignoring case for Spawn Group lookup, like in
the game; avoid NPE in Dialogue parser).
2015-10-30 12:50:03 +01:00
Zukero
6118fc39d8 Changed (enhanced ?) UI for Map replacement activation in simulator.
Added cool tooltip on the Map replacement simulator showing tiles used
for Ground, Objects and Above layers, as well as coordinates, taking the
active replacements into account.
2015-10-28 16:47:42 +01:00
Zukero
7d5a5008bd v0.4.1 packaging done. 2015-10-27 17:24:30 +01:00
Zukero
56b7ab4b92 v0.4.1 ! Now with ReplaceArea support and simulation tool ! 2015-10-27 17:14:15 +01:00
Zukero
0776bc4109 Added replace areas support in model (to preserve contents on map
saving)
2015-08-12 17:59:28 +02:00
Zukero
c870be2d1f Fixed missing attributes in TMX file loading and writing (sizes in
tilesets).
Added a fancy logo in the workspace selector... could look better
though.
2015-08-12 15:14:30 +02:00
Zukero
1c90d47bdf Update eclipse project's classpath. 2015-08-11 17:38:15 +02:00
46 changed files with 2199 additions and 194 deletions

View File

@@ -10,7 +10,7 @@
<classpathentry kind="lib" path="lib/prefuse.jar"/> <classpathentry kind="lib" path="lib/prefuse.jar"/>
<classpathentry kind="lib" path="lib/rsyntaxtextarea.jar"/> <classpathentry kind="lib" path="lib/rsyntaxtextarea.jar"/>
<classpathentry kind="lib" path="lib/ui.jar"/> <classpathentry kind="lib" path="lib/ui.jar"/>
<classpathentry kind="lib" path="lib/AndorsTrainer_v0.1.1.jar"/>
<classpathentry kind="lib" path="lib/bsh-2.0b4.jar"/> <classpathentry kind="lib" path="lib/bsh-2.0b4.jar"/>
<classpathentry kind="lib" path="lib/AndorsTrainer_v0.1.2.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@@ -29,6 +29,7 @@
package tiled.core; package tiled.core;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Properties; import java.util.Properties;
/** /**
@@ -36,7 +37,7 @@ import java.util.Properties;
*/ */
public class Tile public class Tile
{ {
private Image image; private BufferedImage image;
private int id = -1; private int id = -1;
private Properties properties; private Properties properties;
private TileSet tileset; private TileSet tileset;
@@ -76,7 +77,7 @@ public class Tile
* *
* @param i the new image of the tile * @param i the new image of the tile
*/ */
public void setImage(Image i) { public void setImage(BufferedImage i) {
image = i; image = i;
} }
@@ -133,7 +134,7 @@ public class Tile
* *
* @return Image * @return Image
*/ */
public Image getImage() { public BufferedImage getImage() {
if (tileset != null && tileset.sheet != null) return tileset.sheet.getImage(getId()); if (tileset != null && tileset.sheet != null) return tileset.sheet.getImage(getId());
return image; return image;
} }

View File

@@ -74,6 +74,7 @@ public class TileSet implements Iterable<Tile>
private Color transparentColor; private Color transparentColor;
private Image tileSetImage; private Image tileSetImage;
public Spritesheet sheet = null; public Spritesheet sheet = null;
public Rectangle sheetDimensions;
/** /**
* Default constructor * Default constructor
@@ -120,8 +121,10 @@ public class TileSet implements Iterable<Tile>
importTileBitmap(buffered, cutter); importTileBitmap(buffered, cutter);
} }
public void loadFromProject(String name, TMXMap tmxMap) { public void loadFromProject(String name, TMXMap tmxMap, int tileWidth, int tileHeight) {
sheet = tmxMap.getProject().getSpritesheet(name); sheet = tmxMap.getProject().getSpritesheet(name);
tileDimensions.width = tileWidth;
tileDimensions.height = tileHeight;
int i = 0; int i = 0;
Image tileImage = sheet.getImage(i); Image tileImage = sheet.getImage(i);
while (tileImage != null) { while (tileImage != null) {
@@ -158,7 +161,7 @@ public class TileSet implements Iterable<Tile>
tilesPerRow = basicTileCutter.getTilesPerRow(); tilesPerRow = basicTileCutter.getTilesPerRow();
} }
Image tileImage = cutter.getNextTile(); BufferedImage tileImage = cutter.getNextTile();
while (tileImage != null) { while (tileImage != null) {
Tile tile = new Tile(); Tile tile = new Tile();
tile.setImage(tileImage); tile.setImage(tileImage);
@@ -217,7 +220,7 @@ public class TileSet implements Iterable<Tile>
tileDimensions = new Rectangle(tileCutter.getTileDimensions()); tileDimensions = new Rectangle(tileCutter.getTileDimensions());
int id = 0; int id = 0;
Image tileImage = tileCutter.getNextTile(); BufferedImage tileImage = tileCutter.getNextTile();
while (tileImage != null) { while (tileImage != null) {
Tile tile = getTile(id); Tile tile = getTile(id);
tile.setImage(tileImage); tile.setImage(tileImage);

View File

@@ -30,6 +30,8 @@ package tiled.io;
import java.awt.Color; import java.awt.Color;
import java.awt.Image; import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -222,9 +224,9 @@ public class TMXMapReader
return o; return o;
} }
private Image unmarshalImage(Node t, String baseDir) throws IOException private BufferedImage unmarshalImage(Node t, String baseDir) throws IOException
{ {
Image img = null; BufferedImage img = null;
String source = getAttributeValue(t, "source"); String source = getAttributeValue(t, "source");
@@ -252,7 +254,7 @@ public class TMXMapReader
// size, somehow makes drawing of the tiles a lot // size, somehow makes drawing of the tiles a lot
// faster on various systems (seen on Linux, Windows // faster on various systems (seen on Linux, Windows
// and MacOS X). // and MacOS X).
img = img.getScaledInstance( img = (BufferedImage) img.getScaledInstance(
img.getWidth(null), img.getHeight(null), img.getWidth(null), img.getHeight(null),
Image.SCALE_FAST); Image.SCALE_FAST);
} }
@@ -382,7 +384,10 @@ public class TMXMapReader
// case. // case.
if (tmxMap.getProject().getSpritesheet(name) != null) { if (tmxMap.getProject().getSpritesheet(name) != null) {
set.loadFromProject(name, tmxMap); set.loadFromProject(name, tmxMap, tileWidth, tileHeight);
set.sheetDimensions = new Rectangle();
set.sheetDimensions.width = getAttribute(child, "width", 0);
set.sheetDimensions.height = getAttribute(child, "height", 0);
} else { } else {
@@ -530,7 +535,7 @@ public class TMXMapReader
Node child = children.item(i); Node child = children.item(i);
if ("image".equalsIgnoreCase(child.getNodeName())) { if ("image".equalsIgnoreCase(child.getNodeName())) {
int id = getAttribute(child, "id", -1); int id = getAttribute(child, "id", -1);
Image img = unmarshalImage(child, baseDir); BufferedImage img = unmarshalImage(child, baseDir);
tile.setImage(img); tile.setImage(img);
} else if ("animation".equalsIgnoreCase(child.getNodeName())) { } else if ("animation".equalsIgnoreCase(child.getNodeName())) {
// TODO: fill this in once TMXMapWriter is complete // TODO: fill this in once TMXMapWriter is complete

View File

@@ -257,6 +257,10 @@ public class TMXMapWriter
if (tileBitmapFile != null) { if (tileBitmapFile != null) {
w.startElement("image"); w.startElement("image");
w.writeAttribute("source", getRelativePath(wp, tileBitmapFile)); w.writeAttribute("source", getRelativePath(wp, tileBitmapFile));
if (set.sheetDimensions != null) {
w.writeAttribute("width", set.sheetDimensions.width);
w.writeAttribute("height", set.sheetDimensions.height);
}
Color trans = set.getTransparentColor(); Color trans = set.getTransparentColor();
if (trans != null) { if (trans != null) {

View File

@@ -64,7 +64,7 @@ public class BasicTileCutter implements TileCutter
this.image = image; this.image = image;
} }
public Image getNextTile() { public BufferedImage getNextTile() {
if (nextY + tileHeight + tileMargin <= image.getHeight()) { if (nextY + tileHeight + tileMargin <= image.getHeight()) {
BufferedImage tile = BufferedImage tile =
image.getSubimage(nextX, nextY, tileWidth, tileHeight); image.getSubimage(nextX, nextY, tileWidth, tileHeight);

View File

@@ -48,7 +48,7 @@ public interface TileCutter
* @return the next tile image, or <code>null</code> when no more tile * @return the next tile image, or <code>null</code> when no more tile
* images are available * images are available
*/ */
public Image getNextTile(); public BufferedImage getNextTile();
/** /**
* Resets the tile cutter so that the next call to <code>getNextTile</code> * Resets the tile cutter so that the next call to <code>getNextTile</code>

View File

@@ -30,6 +30,7 @@ package tiled.view;
import tiled.core.TileLayer; import tiled.core.TileLayer;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImageOp;
/** /**
* An interface defining methods to render a map. * An interface defining methods to render a map.
@@ -50,5 +51,5 @@ public interface MapRenderer
* @param g the graphics context to paint to * @param g the graphics context to paint to
* @param layer the layer to paint * @param layer the layer to paint
*/ */
public void paintTileLayer(Graphics2D g, TileLayer layer); public void paintTileLayer(Graphics2D g, TileLayer layer, BufferedImageOp filter);
} }

View File

@@ -32,6 +32,8 @@ import tiled.core.Tile;
import tiled.core.TileLayer; import tiled.core.TileLayer;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
/** /**
* The orthogonal map renderer. This is the most basic map renderer, dealing * The orthogonal map renderer. This is the most basic map renderer, dealing
@@ -51,7 +53,7 @@ public class OrthogonalRenderer implements MapRenderer
map.getHeight() * map.getTileHeight()); map.getHeight() * map.getTileHeight());
} }
public void paintTileLayer(Graphics2D g, TileLayer layer) { public void paintTileLayer(Graphics2D g, TileLayer layer, BufferedImageOp filter ) {
final Rectangle clip = g.getClipBounds(); final Rectangle clip = g.getClipBounds();
final int tileWidth = map.getTileWidth(); final int tileWidth = map.getTileWidth();
final int tileHeight = map.getTileHeight(); final int tileHeight = map.getTileHeight();
@@ -74,15 +76,17 @@ public class OrthogonalRenderer implements MapRenderer
final Tile tile = layer.getTileAt(x, y); final Tile tile = layer.getTileAt(x, y);
if (tile == null) if (tile == null)
continue; continue;
final Image image = tile.getImage(); final BufferedImage image = tile.getImage();
if (image == null) if (image == null)
continue; continue;
g.drawImage( g.drawImage(
image, image,
filter,
x * tileWidth, x * tileWidth,
(y + 1) * tileHeight - image.getHeight(null), (y + 1) * tileHeight - image.getHeight(null));
null);
} }
} }
@@ -90,4 +94,5 @@ public class OrthogonalRenderer implements MapRenderer
g.translate(-bounds.x * tileWidth, -bounds.y * tileHeight); g.translate(-bounds.x * tileWidth, -bounds.y * tileHeight);
} }
} }

View File

@@ -1 +1 @@
start "" "javaw.exe" -Xmx512M -cp "lib\jide-oss.jar;lib\ui.jar;lib\junit-4.10.jar;lib\json_simple-1.1.jar;lib\rsyntaxtextarea.jar;lib\prefuse.jar;lib\ATCS_v0.4.0.jar;lib\AndorsTrainer_v0.1.2.jar;lib\bsh-2.0b4.jar" com.gpl.rpg.atcontentstudio.ATContentStudio start "" "javaw.exe" -Xmx512M -cp "lib\ATCS_v0.4.7.jar;lib\jide-oss.jar;lib\ui.jar;lib\junit-4.10.jar;lib\json_simple-1.1.jar;lib\rsyntaxtextarea.jar;lib\prefuse.jar;lib\AndorsTrainer_v0.1.2.jar;lib\bsh-2.0b4.jar" com.gpl.rpg.atcontentstudio.ATContentStudio

View File

@@ -1,2 +1,2 @@
#!/bin/bash #!/bin/bash
java -Xmx512M -cp lib/AndorsTrainer_v0.1.2.jar:lib/ATCS_v0.4.0.jar:lib/prefuse.jar:lib/json_simple-1.1.jar:lib/jide-oss.jar:lib/ui.jar:lib/junit-4.10.jar:lib/rsyntaxtextarea.jar:lib/bsh-2.0b4.jar com.gpl.rpg.atcontentstudio.ATContentStudio java -Xmx512M -cp lib/AndorsTrainer_v0.1.2.jar:lib/ATCS_v0.4.7.jar:lib/prefuse.jar:lib/json_simple-1.1.jar:lib/jide-oss.jar:lib/ui.jar:lib/junit-4.10.jar:lib/rsyntaxtextarea.jar:lib/bsh-2.0b4.jar com.gpl.rpg.atcontentstudio.ATContentStudio

View File

@@ -1 +1 @@
start "" "D:\Programs\jdk1.6.0_24\\bin\javaw.exe" -Xmx512M -cp "lib\jide-oss.jar;lib\ui.jar;lib\junit-4.10.jar;lib\json_simple-1.1.jar;lib\rsyntaxtextarea.jar;lib\ATCS_v0.0.4.jar;lib\AndorsTrainer_V0.1.2.jar" com.gpl.rpg.atcontentstudio.ATContentStudio start "" "javaw.exe" -Xmx512M -cp "lib\ATCS_v0.4.6.jar;lib\jide-oss.jar;lib\ui.jar;lib\junit-4.10.jar;lib\json_simple-1.1.jar;lib\rsyntaxtextarea.jar;lib\prefuse.jar;lib\AndorsTrainer_v0.1.2.jar;lib\bsh-2.0b4.jar" com.gpl.rpg.atcontentstudio.ATContentStudio

View File

@@ -1,6 +1,6 @@
!include MUI2.nsh !include MUI2.nsh
!define VERSION "0.4.0" !define VERSION "0.4.7"
!define JAVA_BIN "java" !define JAVA_BIN "java"
Name "Andor's Trail Content Studio v${VERSION}" Name "Andor's Trail Content Studio v${VERSION}"

View File

@@ -18,7 +18,7 @@ import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector;
public class ATContentStudio { public class ATContentStudio {
public static final String APP_NAME = "Andor's Trail Content Studio"; public static final String APP_NAME = "Andor's Trail Content Studio";
public static final String APP_VERSION = "v0.4.0"; public static final String APP_VERSION = "v0.4.7";
public static boolean STARTED = false; public static boolean STARTED = false;
public static StudioFrame frame = null; public static StudioFrame frame = null;

View File

@@ -2,13 +2,29 @@ package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
import com.gpl.rpg.atcontentstudio.model.maps.Worldmap; import com.gpl.rpg.atcontentstudio.model.maps.Worldmap;
@@ -21,6 +37,9 @@ public class GameSource implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = -1512979360971918158L; private static final long serialVersionUID = -1512979360971918158L;
public static final String DEFAULT_REL_PATH_FOR_GAME_RESOURCE = "res"+File.separator+"values"+File.separator+"loadresources.xml";
public static final String DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE = "res"+File.separator+"values"+File.separator+"loadresources_debug.xml";
public transient GameDataSet gameData; public transient GameDataSet gameData;
public transient TMXMapSet gameMaps; public transient TMXMapSet gameMaps;
public transient SpriteSheetSet gameSprites; public transient SpriteSheetSet gameSprites;
@@ -39,6 +58,8 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient Project parent = null; public transient Project parent = null;
public transient Map<String, List<String>> referencedSourceFiles = null;
public GameSource(File folder, Project parent) { public GameSource(File folder, Project parent) {
this.parent = parent; this.parent = parent;
this.baseFolder = folder; this.baseFolder = folder;
@@ -59,6 +80,12 @@ public class GameSource implements ProjectTreeNode, Serializable {
} }
public void initData() { public void initData() {
if (type == Type.source) {
if (parent.sourceSetToUse == ResourceSet.gameData || parent.sourceSetToUse == ResourceSet.debugData) {
referencedSourceFiles = new LinkedHashMap<String, List<String>>();
readResourceList();
}
}
this.gameData = new GameDataSet(this); this.gameData = new GameDataSet(this);
this.gameMaps = new TMXMapSet(this); this.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this); this.gameSprites = new SpriteSheetSet(this);
@@ -70,6 +97,58 @@ public class GameSource implements ProjectTreeNode, Serializable {
v.add(worldmap); v.add(worldmap);
} }
public void readResourceList() {
File xmlFile = null;
if (parent.sourceSetToUse == ResourceSet.gameData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_GAME_RESOURCE);
} else if (parent.sourceSetToUse == ResourceSet.debugData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE);
} else {
return;
}
if (!xmlFile.exists()) return;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc;
try {
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(xmlFile));
// insrc.setSystemId("http://worldmap/");
insrc.setEncoding("UTF-8");
doc = builder.parse(insrc);
Element root = (Element) doc.getElementsByTagName("resources").item(0);
if (root != null) {
NodeList arraysList = root.getElementsByTagName("array");
if (arraysList != null) {
for (int i = 0; i < arraysList.getLength(); i++) {
Element arrayNode = (Element) arraysList.item(i);
String name = arrayNode.getAttribute("name");
List<String> arrayContents = new LinkedList<String>();
NodeList arrayItems = arrayNode.getElementsByTagName("item");
if (arrayItems != null) {
for (int j = 0; j < arrayItems.getLength(); j++) {
arrayContents.add(((Element)arrayItems.item(j)).getTextContent());
}
referencedSourceFiles.put(name, arrayContents);
}
}
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override @Override
public Enumeration<ProjectTreeNode> children() { public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements(); return v.getNonEmptyElements();

View File

@@ -74,9 +74,18 @@ public class Project implements ProjectTreeNode, Serializable {
public Properties knownSpritesheetsProperties = null; public Properties knownSpritesheetsProperties = null;
public Project(Workspace w, String name, File source) { public static enum ResourceSet {
gameData,
debugData,
allFiles
}
public ResourceSet sourceSetToUse = ResourceSet.allFiles;
public Project(Workspace w, String name, File source, ResourceSet sourceSet) {
this.parent = w; this.parent = w;
this.name = name; this.name = name;
this.sourceSetToUse = sourceSet;
//CREATE PROJECT //CREATE PROJECT
baseFolder = new File(w.baseFolder, name+File.separator); baseFolder = new File(w.baseFolder, name+File.separator);
@@ -220,6 +229,10 @@ public class Project implements ProjectTreeNode, Serializable {
} }
} }
if (sourceSetToUse == null) {
sourceSetToUse = ResourceSet.allFiles;
}
// long l = new Date().getTime(); // long l = new Date().getTime();
baseContent.refreshTransients(this); baseContent.refreshTransients(this);
// l = new Date().getTime() - l; // l = new Date().getTime() - l;
@@ -477,6 +490,21 @@ public class Project implements ProjectTreeNode, Serializable {
return null; return null;
} }
public int getItemCountIncludingAltered() {
return createdContent.gameData.items.size() + alteredContent.gameData.items.size() + baseContent.gameData.items.size();
}
public Item getItemIncludingAltered(int index) {
if (index < createdContent.gameData.items.size()) {
return createdContent.gameData.items.get(index);
} else if (index < createdContent.gameData.items.size() + alteredContent.gameData.items.size()){
return alteredContent.gameData.items.get(index - createdContent.gameData.items.size());
} else if (index < getItemCountIncludingAltered()) {
return baseContent.gameData.items.get(index - (createdContent.gameData.items.size() + alteredContent.gameData.items.size()));
}
return null;
}
public int getItemIndex(Item item) { public int getItemIndex(Item item) {
if (item.getDataType() == GameSource.Type.created) { if (item.getDataType() == GameSource.Type.created) {
return createdContent.gameData.items.getIndex(item); return createdContent.gameData.items.getIndex(item);
@@ -522,6 +550,13 @@ public class Project implements ProjectTreeNode, Serializable {
return gde; return gde;
} }
public NPC getNPCIgnoreCase(String id) {
NPC gde = createdContent.gameData.getNPCIgnoreCase(id);
if (gde == null) gde = alteredContent.gameData.getNPCIgnoreCase(id);
if (gde == null) gde = baseContent.gameData.getNPCIgnoreCase(id);
return gde;
}
public int getNPCCount() { public int getNPCCount() {
return createdContent.gameData.npcs.size() + baseContent.gameData.npcs.size(); return createdContent.gameData.npcs.size() + baseContent.gameData.npcs.size();
} }
@@ -535,6 +570,21 @@ public class Project implements ProjectTreeNode, Serializable {
return null; return null;
} }
public int getNPCCountIncludingAltered() {
return createdContent.gameData.npcs.size() + alteredContent.gameData.npcs.size() + baseContent.gameData.npcs.size();
}
public NPC getNPCIncludingAltered(int index) {
if (index < createdContent.gameData.npcs.size()) {
return createdContent.gameData.npcs.get(index);
} else if (index < createdContent.gameData.npcs.size() + alteredContent.gameData.npcs.size()){
return alteredContent.gameData.npcs.get(index - createdContent.gameData.npcs.size());
} else if (index < getNPCCountIncludingAltered()) {
return baseContent.gameData.npcs.get(index - (createdContent.gameData.npcs.size() + alteredContent.gameData.npcs.size()));
}
return null;
}
public int getNPCIndex(NPC npc) { public int getNPCIndex(NPC npc) {
if (npc.getDataType() == GameSource.Type.created) { if (npc.getDataType() == GameSource.Type.created) {
return createdContent.gameData.npcs.getIndex(npc); return createdContent.gameData.npcs.getIndex(npc);
@@ -747,13 +797,13 @@ public class Project implements ProjectTreeNode, Serializable {
} }
existingNode.getBacklinks().clear(); existingNode.getBacklinks().clear();
node.writable = true; node.writable = true;
node.state = GameDataElement.State.created;
alteredContent.gameData.addElement(node); alteredContent.gameData.addElement(node);
node.link(); node.link();
node.state = GameDataElement.State.created;
} else { } else {
createdContent.gameData.addElement(node); createdContent.gameData.addElement(node);
node.state = GameDataElement.State.created;
node.link(); node.link();
node.state = GameDataElement.State.created;
} }
fireElementAdded(node, getNodeIndex(node)); fireElementAdded(node, getNodeIndex(node));
} }
@@ -833,7 +883,7 @@ public class Project implements ProjectTreeNode, Serializable {
int index = -1; int index = -1;
while (--i >= 0) { while (--i >= 0) {
NPC npc = getNPC(i); NPC npc = getNPC(i);
if (spawngroup_id.equals(npc.spawngroup_id)) { if (spawngroup_id.equalsIgnoreCase(npc.spawngroup_id)) {
for (NPC present : result) { for (NPC present : result) {
if (present.id.equals(npc.id)) { if (present.id.equals(npc.id)) {
alreadyAdded = true; alreadyAdded = true;
@@ -851,7 +901,7 @@ public class Project implements ProjectTreeNode, Serializable {
} }
if (result.isEmpty()) { if (result.isEmpty()) {
//Fallback case. A single NPC does not declare a spawn group, but is referred by its ID in maps' spawn areas. //Fallback case. A single NPC does not declare a spawn group, but is referred by its ID in maps' spawn areas.
NPC npc = getNPC(spawngroup_id); NPC npc = getNPCIgnoreCase(spawngroup_id);
if (npc != null) result.add(npc); if (npc != null) result.add(npc);
} }
return result; return result;

View File

@@ -146,7 +146,7 @@ public class Workspace implements ProjectTreeNode, Serializable {
} }
public static void createProject(final String projectName, final File gameSourceFolder) { public static void createProject(final String projectName, final File gameSourceFolder, final Project.ResourceSet sourceSet) {
WorkerDialog.showTaskMessage("Creating project "+projectName+"...", ATContentStudio.frame, new Runnable() { WorkerDialog.showTaskMessage("Creating project "+projectName+"...", ATContentStudio.frame, new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -154,7 +154,7 @@ public class Workspace implements ProjectTreeNode, Serializable {
Notification.addError("A project named "+projectName+" already exists in this workspace."); Notification.addError("A project named "+projectName+" already exists in this workspace.");
return; return;
} }
Project p = new Project(activeWorkspace, projectName, gameSourceFolder); Project p = new Project(activeWorkspace, projectName, gameSourceFolder, sourceSet);
activeWorkspace.projects.add(p); activeWorkspace.projects.add(p);
activeWorkspace.projectsName.add(projectName); activeWorkspace.projectsName.add(projectName);
activeWorkspace.projectsOpenByName.put(projectName, p.open); activeWorkspace.projectsOpenByName.put(projectName, p.open);

View File

@@ -63,8 +63,8 @@ public class Dialogue extends JSONElement {
spawnAll, spawnAll,
removeSpawnArea, removeSpawnArea,
deactivateSpawnArea, deactivateSpawnArea,
activateMapChangeArea, activateMapObjectGroup,
deactivateMapChangeArea deactivateMapObjectGroup
} }
} }
@@ -171,7 +171,7 @@ public class Dialogue extends JSONElement {
requirement.parent = this; requirement.parent = this;
if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType")); if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType"));
requirement.required_obj_id = (String) requirementJson.get("requireID"); requirement.required_obj_id = (String) requirementJson.get("requireID");
requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString())); if (requirementJson.get("value") != null) requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString()));
if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate"); if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate");
requirement.state = State.parsed; requirement.state = State.parsed;
reply.requirements.add(requirement); reply.requirements.add(requirement);
@@ -242,8 +242,8 @@ public class Dialogue extends JSONElement {
for (Reward reward : rewards) { for (Reward reward : rewards) {
if (reward.reward_obj_id != null) { if (reward.reward_obj_id != null) {
switch (reward.type) { switch (reward.type) {
case activateMapChangeArea: case activateMapObjectGroup:
case deactivateMapChangeArea: case deactivateMapObjectGroup:
case spawnAll: case spawnAll:
case removeSpawnArea: case removeSpawnArea:
case deactivateSpawnArea: case deactivateSpawnArea:

View File

@@ -154,7 +154,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
dataToSave.add(element.toJson()); dataToSave.add(element.toJson());
} }
} }
if (dataToSave.isEmpty()) { if (dataToSave.isEmpty() && jsonFile.exists()) {
if (jsonFile.delete()) { if (jsonFile.delete()) {
Notification.addSuccess("File "+jsonFile.getAbsolutePath()+" deleted."); Notification.addSuccess("File "+jsonFile.getAbsolutePath()+" deleted.");
} else { } else {

View File

@@ -13,6 +13,7 @@ import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SavedSlotCollection; import com.gpl.rpg.atcontentstudio.model.SavedSlotCollection;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
@@ -25,6 +26,17 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res"+File.separator+"raw"+File.separator; public static final String DEFAULT_REL_PATH_IN_SOURCE = "res"+File.separator+"raw"+File.separator;
public static final String DEFAULT_REL_PATH_IN_PROJECT = "json"+File.separator; public static final String DEFAULT_REL_PATH_IN_PROJECT = "json"+File.separator;
public static final String GAME_AC_ARRAY_NAME = "loadresource_actorconditions";
public static final String GAME_DIALOGUES_ARRAY_NAME = "loadresource_conversationlists";
public static final String GAME_DROPLISTS_ARRAY_NAME = "loadresource_droplists";
public static final String GAME_ITEMS_ARRAY_NAME = "loadresource_items";
public static final String GAME_ITEMCAT_ARRAY_NAME = "loadresource_itemcategories";
public static final String GAME_NPC_ARRAY_NAME = "loadresource_monsters";
public static final String GAME_QUESTS_ARRAY_NAME = "loadresource_quests";
public static final String DEBUG_SUFFIX = "_debug";
public static final String RESOURCE_PREFIX = "@raw/";
public static final String FILENAME_SUFFIX = ".json";
public File baseFolder; public File baseFolder;
public GameDataCategory<ActorCondition> actorConditions; public GameDataCategory<ActorCondition> actorConditions;
@@ -67,7 +79,87 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
v.add(quests); v.add(quests);
//Start parsing to populate categories' content. //Start parsing to populate categories' content.
if (parent.type != GameSource.Type.referenced) { if (parent.type == GameSource.Type.source && (parent.parent.sourceSetToUse == ResourceSet.debugData || parent.parent.sourceSetToUse == ResourceSet.gameData)) {
String suffix = (parent.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : "";
if (parent.referencedSourceFiles.get(GAME_AC_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_AC_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
ActorCondition.fromJson(f, actorConditions);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_DIALOGUES_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_DIALOGUES_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Dialogue.fromJson(f, dialogues);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_DROPLISTS_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_DROPLISTS_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Droplist.fromJson(f, droplists);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_ITEMS_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_ITEMS_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Item.fromJson(f, items);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_ITEMCAT_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_ITEMCAT_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
ItemCategory.fromJson(f, itemCategories);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_NPC_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_NPC_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
NPC.fromJson(f, npcs);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_QUESTS_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_QUESTS_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Quest.fromJson(f, quests);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
} else if (parent.type != GameSource.Type.referenced) {
for (File f : baseFolder.listFiles()) { for (File f : baseFolder.listFiles()) {
if (f.getName().startsWith("actorconditions_")) { if (f.getName().startsWith("actorconditions_")) {
ActorCondition.fromJson(f, actorConditions); ActorCondition.fromJson(f, actorConditions);
@@ -212,6 +304,16 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
return null; return null;
} }
public NPC getNPCIgnoreCase(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equalsIgnoreCase(gde.id)){
return gde;
}
}
return null;
}
public Quest getQuest(String id) { public Quest getQuest(String id) {
if (quests == null) return null; if (quests == null) return null;
for (Quest gde : quests) { for (Quest gde : quests) {

View File

@@ -496,6 +496,8 @@ public class Item extends JSONElement {
itemJson.put("id", this.id); itemJson.put("id", this.id);
if (this.icon_id != null) itemJson.put("iconID", this.icon_id); if (this.icon_id != null) itemJson.put("iconID", this.icon_id);
if (this.name != null) itemJson.put("name", this.name); if (this.name != null) itemJson.put("name", this.name);
if(this.display_type != null) itemJson.put("displaytype", this.display_type.toString());
if (this.has_manual_price != null) itemJson.put("hasManualPrice", this.has_manual_price); if (this.has_manual_price != null) itemJson.put("hasManualPrice", this.has_manual_price);
if (this.base_market_cost != null) itemJson.put("baseMarketCost", this.base_market_cost); if (this.base_market_cost != null) itemJson.put("baseMarketCost", this.base_market_cost);
if (this.category != null) { if (this.category != null) {

View File

@@ -12,6 +12,7 @@ public class KeyArea extends MapObject {
public String dialogue_id = null; public String dialogue_id = null;
public Dialogue dialogue = null; public Dialogue dialogue = null;
public Requirement requirement = null; public Requirement requirement = null;
public boolean oldSchoolRequirement = true;
public KeyArea(tiled.core.MapObject obj) { public KeyArea(tiled.core.MapObject obj) {
dialogue_id = obj.getProperties().getProperty("phrase"); dialogue_id = obj.getProperties().getProperty("phrase");
@@ -29,9 +30,12 @@ public class KeyArea extends MapObject {
requireType = fields[0]; requireType = fields[0];
requireId = fields[1]; requireId = fields[1];
} }
oldSchoolRequirement = true;
} else {
oldSchoolRequirement = false;
} }
requirement = new Requirement(); requirement = new Requirement();
requirement.type = Requirement.RequirementType.valueOf(requireType); if (requireType != null) requirement.type = Requirement.RequirementType.valueOf(requireType);
requirement.required_obj_id = requireId; requirement.required_obj_id = requireId;
if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue); if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue);
requirement.state = GameDataElement.State.parsed; requirement.state = GameDataElement.State.parsed;
@@ -59,6 +63,7 @@ public class KeyArea extends MapObject {
dialogue = (Dialogue) newOne; dialogue = (Dialogue) newOne;
newOne.addBacklink(parentMap); newOne.addBacklink(parentMap);
} }
requirement.elementChanged(oldOne, newOne);
} }
@Override @Override
@@ -69,16 +74,36 @@ public class KeyArea extends MapObject {
tmxObject.getProperties().setProperty("phrase", dialogue_id); tmxObject.getProperties().setProperty("phrase", dialogue_id);
} }
if (requirement != null) { if (requirement != null) {
tmxObject.getProperties().setProperty("requireType", requirement.type.toString()); if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
if (requirement.required_obj != null) { tmxObject.setName(requirement.required_obj_id+":"+Integer.toString(requirement.required_value));
tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id); } else {
} else if (requirement.required_obj_id != null) { if (requirement.type != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id); tmxObject.getProperties().setProperty("requireType", requirement.type.toString());
} }
if (requirement.required_value != null) { if (requirement.required_obj != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString()); tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id);
} else if (requirement.required_obj_id != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id);
}
if (requirement.required_value != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString());
}
} }
} }
} }
public void updateNameFromRequirementChange() {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
name = requirement.required_obj_id+":"+Integer.toString(requirement.required_value);
} else if (oldSchoolRequirement) {
int i = 0;
String futureName = requirement.type.toString() + "#" + Integer.toString(i);
while (parentMap.getMapObject(futureName) != null) {
i++;
futureName = requirement.type.toString() + "#" + Integer.toString(i);
}
this.name = futureName;
}
}
} }

View File

@@ -94,6 +94,7 @@ public abstract class MapObject {
public abstract void savePropertiesInTmxObject(tiled.core.MapObject tmxObject); public abstract void savePropertiesInTmxObject(tiled.core.MapObject tmxObject);
public static MapObject newMapchange(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newMapchange(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Mapchange");
MapObject result = new MapChange(obj); MapObject result = new MapChange(obj);
result.type = Types.mapchange; result.type = Types.mapchange;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -101,6 +102,7 @@ public abstract class MapObject {
} }
public static MapObject newSpawnArea(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newSpawnArea(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Spawnarea");
MapObject result = new SpawnArea(obj); MapObject result = new SpawnArea(obj);
result.type = Types.spawn; result.type = Types.spawn;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -108,6 +110,7 @@ public abstract class MapObject {
} }
public static MapObject newRest(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newRest(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Rest");
MapObject result = new RestArea(obj); MapObject result = new RestArea(obj);
result.type = Types.rest; result.type = Types.rest;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -115,6 +118,7 @@ public abstract class MapObject {
} }
public static MapObject newKey(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newKey(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Key");
MapObject result = new KeyArea(obj); MapObject result = new KeyArea(obj);
result.type = Types.key; result.type = Types.key;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -122,6 +126,7 @@ public abstract class MapObject {
} }
public static MapObject newReplace(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newReplace(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Replace");
MapObject result = new ReplaceArea(obj); MapObject result = new ReplaceArea(obj);
result.type = Types.replace; result.type = Types.replace;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -129,6 +134,7 @@ public abstract class MapObject {
} }
public static MapObject newScript(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newScript(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Script");
MapObject result = new ScriptArea(obj); MapObject result = new ScriptArea(obj);
result.type = Types.script; result.type = Types.script;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -136,6 +142,7 @@ public abstract class MapObject {
} }
public static MapObject newContainer(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newContainer(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Container");
MapObject result = new ContainerArea(obj); MapObject result = new ContainerArea(obj);
result.type = Types.container; result.type = Types.container;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);
@@ -143,6 +150,7 @@ public abstract class MapObject {
} }
public static MapObject newSign(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newSign(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Sign");
MapObject result = new SignArea(obj); MapObject result = new SignArea(obj);
result.type = Types.sign; result.type = Types.sign;
initObj(result, obj, parentMap); initObj(result, obj, parentMap);

View File

@@ -13,12 +13,18 @@ public class MapObjectGroup {
public String name; public String name;
public boolean visible; public boolean visible;
public List<MapObject> mapObjects = new ArrayList<MapObject>(); public List<MapObject> mapObjects = new ArrayList<MapObject>();
public Boolean active;
public MapObjectGroup(tiled.core.ObjectGroup layer, TMXMap map) { public MapObjectGroup(tiled.core.ObjectGroup layer, TMXMap map) {
this.tmxGroup = layer; this.tmxGroup = layer;
this.name = layer.getName(); this.name = layer.getName();
this.visible = layer.isVisible(); this.visible = layer.isVisible();
this.parentMap = map; this.parentMap = map;
if (layer.getProperties().get("active") != null) {
active = new Boolean(((String) layer.getProperties().get("active")));
} else {
active = true;
}
for (tiled.core.MapObject obj : layer.getObjectsList()) { for (tiled.core.MapObject obj : layer.getObjectsList()) {
mapObjects.add(MapObject.buildObject(obj, map)); mapObjects.add(MapObject.buildObject(obj, map));
} }
@@ -44,6 +50,9 @@ public class MapObjectGroup {
} }
tmxGroup.setVisible(visible); tmxGroup.setVisible(visible);
tmxGroup.setName(name); tmxGroup.setName(name);
if (!active) {
tmxGroup.getProperties().put("active", Boolean.toString(active));
}
for (MapObject object : mapObjects) { for (MapObject object : mapObjects) {
tmxGroup.addObject(object.toTmxObject()); tmxGroup.addObject(object.toTmxObject());
} }

View File

@@ -1,21 +1,62 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image; import java.awt.Image;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class ReplaceArea extends MapObject { public class ReplaceArea extends MapObject {
public Requirement requirement = null;
public boolean oldSchoolRequirement = true;
public List<ReplaceArea.Replacement> replacements = null;
public ReplaceArea(tiled.core.MapObject obj) { public ReplaceArea(tiled.core.MapObject obj) {
// TODO Auto-generated constructor stub // String requireType = obj.getProperties().getProperty("requireType");
String requireId = obj.getProperties().getProperty("requireId");
String requireValue = obj.getProperties().getProperty("requireValue");
if (requireId == null) {
String[] fields = obj.getName().split(":");
if (fields.length == 2) {
// requireType = Requirement.RequirementType.questProgress.toString();
requireValue = fields[1];
requireId = fields[0];
} /*else if (fields.length == 3) {
requireValue = fields[2];
requireType = fields[0];
requireId = fields[1];
}*/
oldSchoolRequirement = true;
} else {
oldSchoolRequirement = false;
}
requirement = new Requirement();
//Replace areas only support questProgress requirements ATM
//requirement.type = Requirement.RequirementType.valueOf(requireType);
requirement.type = Requirement.RequirementType.questProgress;
requirement.required_obj_id = requireId;
if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue);
requirement.state = GameDataElement.State.parsed;
for (Object s : obj.getProperties().keySet()) {
if (replacements == null) replacements = new LinkedList<ReplaceArea.Replacement>();
replacements.add(new Replacement(s.toString(), obj.getProperties().getProperty(s.toString())));
}
} }
@Override @Override
public void link() { public void link() {
// TODO Auto-generated method stub requirement.parent = parentMap;
requirement.link();
} }
@Override @Override
@@ -25,14 +66,79 @@ public class ReplaceArea extends MapObject {
@Override @Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
// TODO Auto-generated method stub requirement.elementChanged(oldOne, newOne);
}
public ReplaceArea.Replacement addReplacement(String source, String target) {
Replacement repl = new Replacement(source, target);
addReplacement(repl);
return repl;
}
public void addReplacement(ReplaceArea.Replacement repl) {
if (replacements == null) replacements = new LinkedList<ReplaceArea.Replacement>();
replacements.add(repl);
}
// public void removeReplacement(String source, String target) {
// replacedLayers.remove(source);
// }
public void removeReplacement(Replacement repl) {
replacements.remove(repl);
} }
@Override @Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) { public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
// TODO Auto-generated method stub if (replacements != null) {
for(Replacement r : replacements)
tmxObject.getProperties().setProperty(r.sourceLayer, r.targetLayer);
}
if (requirement != null) {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
tmxObject.setName(requirement.required_obj_id+":"+Integer.toString(requirement.required_value));
} else {
tmxObject.getProperties().setProperty("requireType", requirement.type.toString());
if (requirement.required_obj != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id);
} else if (requirement.required_obj_id != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id);
}
if (requirement.required_value != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString());
}
}
}
} }
//Don't use yet !
public void updateNameFromRequirementChange() {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
name = requirement.required_obj_id+":"+Integer.toString(requirement.required_value);
} else if (oldSchoolRequirement) {
int i = 0;
String futureName = requirement.type.toString() + "#" + Integer.toString(i);
while (parentMap.getMapObject(futureName) != null) {
i++;
futureName = requirement.type.toString() + "#" + Integer.toString(i);
}
this.name = futureName;
}
}
public class Replacement {
public String sourceLayer, targetLayer;
public Replacement(String source, String target) {
this.sourceLayer = source;
this.targetLayer = target;
}
}
public boolean hasReplacementFor(String name) {
if (name == null) return false;
for (Replacement repl : replacements) {
if (name.equalsIgnoreCase(repl.sourceLayer)) return true;
}
return false;
}
} }

View File

@@ -12,6 +12,8 @@ public class SpawnArea extends MapObject {
public int quantity = 1; public int quantity = 1;
public int spawnchance = 10; public int spawnchance = 10;
public boolean active = true;
public String spawngroup_id;
public List<NPC> spawnGroup = new ArrayList<NPC>(); public List<NPC> spawnGroup = new ArrayList<NPC>();
public SpawnArea(tiled.core.MapObject obj) { public SpawnArea(tiled.core.MapObject obj) {
@@ -21,12 +23,20 @@ public class SpawnArea extends MapObject {
if (obj.getProperties().getProperty("spawnchance") != null) { if (obj.getProperties().getProperty("spawnchance") != null) {
this.spawnchance = Integer.parseInt(obj.getProperties().getProperty("spawnchance")); this.spawnchance = Integer.parseInt(obj.getProperties().getProperty("spawnchance"));
} }
if (obj.getProperties().getProperty("active") != null) {
this.active = Boolean.parseBoolean(obj.getProperties().getProperty("active"));
}
if (obj.getProperties().getProperty("spawngroup") != null) {
this.spawngroup_id = obj.getProperties().getProperty("spawngroup");
} else if (obj.getName() != null ){
this.spawngroup_id = obj.getName();
}
} }
@Override @Override
public void link() { public void link() {
if (name != null) { if (spawngroup_id != null) {
spawnGroup = parentMap.getProject().getSpawnGroup(name); spawnGroup = parentMap.getProject().getSpawnGroup(spawngroup_id);
} else { } else {
spawnGroup = new ArrayList<NPC>(); spawnGroup = new ArrayList<NPC>();
} }
@@ -61,12 +71,18 @@ public class SpawnArea extends MapObject {
@Override @Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) { public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (spawngroup_id != null) {
tmxObject.getProperties().setProperty("spawngroup", spawngroup_id);
}
if (quantity != 1) { if (quantity != 1) {
tmxObject.getProperties().setProperty("quantity", Integer.toString(quantity)); tmxObject.getProperties().setProperty("quantity", Integer.toString(quantity));
} }
if (spawnchance != 10) { if (spawnchance != 10) {
tmxObject.getProperties().setProperty("spawnchance", Integer.toString(spawnchance)); tmxObject.getProperties().setProperty("spawnchance", Integer.toString(spawnchance));
} }
if (!this.active) {
tmxObject.getProperties().setProperty("active", Boolean.toString(active));
}
} }
} }

View File

@@ -33,6 +33,23 @@ public class TMXMap extends GameDataElement {
private static final long serialVersionUID = 1609502879500898837L; 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 enum ColorFilter {
black20,
black40,
black60,
black80,
invert,
bw,
redtint,
greentint,
bluetint
}
public File tmxFile = null; public File tmxFile = null;
public tiled.core.Map tmxMap = null; public tiled.core.Map tmxMap = null;
public Set<Spritesheet> usedSpritesheets = null; public Set<Spritesheet> usedSpritesheets = null;
@@ -40,6 +57,7 @@ public class TMXMap extends GameDataElement {
public ProjectTreeNode parent; public ProjectTreeNode parent;
public Integer outside = null; public Integer outside = null;
public ColorFilter colorFilter = null;
public boolean writable = false; public boolean writable = false;
@@ -56,8 +74,11 @@ public class TMXMap extends GameDataElement {
usedSpritesheets = new HashSet<Spritesheet>(); usedSpritesheets = new HashSet<Spritesheet>();
try { try {
tmxMap = new TMXMapReader().readMap(tmxFile.getAbsolutePath(), this); tmxMap = new TMXMapReader().readMap(tmxFile.getAbsolutePath(), this);
if (tmxMap.getProperties().get("outside") != null) { if (tmxMap.getProperties().get("outdoors") != null) {
outside = new Integer(((String) tmxMap.getProperties().get("outside"))); outside = new Integer(((String) tmxMap.getProperties().get("outdoors")));
}
if (tmxMap.getProperties().get("colorfilter") != null) {
colorFilter = ColorFilter.valueOf(((String) tmxMap.getProperties().get("colorfilter")));
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Notification.addError("Impossible to load TMX map file "+tmxFile.getAbsolutePath()); Notification.addError("Impossible to load TMX map file "+tmxFile.getAbsolutePath());
@@ -91,8 +112,11 @@ public class TMXMap extends GameDataElement {
try { try {
clone.usedSpritesheets = new HashSet<Spritesheet>(); clone.usedSpritesheets = new HashSet<Spritesheet>();
clone.tmxMap = new TMXMapReader().readMap(new StringReader(this.toXml()), clone); clone.tmxMap = new TMXMapReader().readMap(new StringReader(this.toXml()), clone);
if (clone.tmxMap.getProperties().get("outside") != null) { if (clone.tmxMap.getProperties().get("outdoors") != null) {
clone.outside = new Integer(((String) clone.tmxMap.getProperties().get("outside"))); clone.outside = new Integer(((String) clone.tmxMap.getProperties().get("outdoors")));
}
if (clone.tmxMap.getProperties().get("colorfilter") != null) {
clone.colorFilter = ColorFilter.valueOf(((String) tmxMap.getProperties().get("colorfilter")));
} }
for (tiled.core.MapLayer layer : clone.tmxMap.getLayers()) { for (tiled.core.MapLayer layer : clone.tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) { if (layer instanceof tiled.core.ObjectGroup) {
@@ -204,6 +228,17 @@ public class TMXMap extends GameDataElement {
} }
public String toXml() { public String toXml() {
if (outside != null && outside == 1) {
tmxMap.getProperties().put("outdoors", Integer.toString(outside));
} else {
tmxMap.getProperties().remove("outdoors");
}
if (colorFilter != null) {
tmxMap.getProperties().put("colorfilter", colorFilter.toString());
} else {
tmxMap.getProperties().remove("colorfilter");
}
for (MapObjectGroup group : groups) { for (MapObjectGroup group : groups) {
group.pushBackToTiledProperties(); group.pushBackToTiledProperties();
if (!tmxMap.containsLayer(group.tmxGroup)) { if (!tmxMap.containsLayer(group.tmxGroup)) {
@@ -335,4 +370,24 @@ public class TMXMap extends GameDataElement {
return result; 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);
}
} }

View File

@@ -10,11 +10,14 @@ import java.util.List;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class TMXMapSet implements ProjectTreeNode { public class TMXMapSet implements ProjectTreeNode {
@@ -22,6 +25,11 @@ public class TMXMapSet implements ProjectTreeNode {
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res/xml/"; public static final String DEFAULT_REL_PATH_IN_SOURCE = "res/xml/";
public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps/"; public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps/";
public static final String GAME_MAPS_ARRAY_NAME = "loadresource_maps";
public static final String DEBUG_SUFFIX = "_debug";
public static final String RESOURCE_PREFIX = "@xml/";
public static final String FILENAME_SUFFIX = ".tmx";
public File mapFolder = null; public File mapFolder = null;
public List<TMXMap> tmxMaps; public List<TMXMap> tmxMaps;
@@ -29,7 +37,9 @@ public class TMXMapSet implements ProjectTreeNode {
public TMXMapSet(GameSource source) { public TMXMapSet(GameSource source) {
this.parent = source; this.parent = source;
if (source.type == GameSource.Type.source) this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE); if (source.type == GameSource.Type.source) {
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
}
else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) { else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT); this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
if (!this.mapFolder.exists()) { if (!this.mapFolder.exists()) {
@@ -38,7 +48,22 @@ public class TMXMapSet implements ProjectTreeNode {
} }
this.tmxMaps = new ArrayList<TMXMap>(); this.tmxMaps = new ArrayList<TMXMap>();
if (this.mapFolder != null) { if (source.type == GameSource.Type.source && (source.parent.sourceSetToUse == ResourceSet.debugData || source.parent.sourceSetToUse == ResourceSet.gameData)) {
String suffix = (source.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : "";
if (source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME+suffix) != null) {
for (String resource : source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME+suffix)) {
File f = new File(mapFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
TMXMap map = new TMXMap(this, f);
tmxMaps.add(map);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
} else if (this.mapFolder != null) {
for (File f : this.mapFolder.listFiles()) { for (File f : this.mapFolder.listFiles()) {
if (f.getName().endsWith(".tmx") || f.getName().endsWith(".TMX")) { if (f.getName().endsWith(".tmx") || f.getName().endsWith(".TMX")) {
TMXMap map = new TMXMap(this, f); TMXMap map = new TMXMap(this, f);

View File

@@ -11,6 +11,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -52,7 +53,7 @@ public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeN
public File worldmapFile; public File worldmapFile;
public GameSource parent; public GameSource parent;
public Map<String, Map<String, Point>> segments = new HashMap<String, Map<String,Point>>(); public Map<String, Map<String, Point>> segments = new LinkedHashMap<String, Map<String,Point>>();
public Worldmap(GameSource gameSource) { public Worldmap(GameSource gameSource) {
this.parent = gameSource; this.parent = gameSource;
@@ -261,6 +262,7 @@ public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeN
Source input = new DOMSource(doc); Source input = new DOMSource(doc);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output); transformer.transform(input, output);
} catch (TransformerConfigurationException e) { } catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block

View File

@@ -2,12 +2,26 @@ package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image; import java.awt.Image;
import java.awt.Point; import java.awt.Point;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.StringWriter;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@@ -76,7 +90,9 @@ public class WorldmapSegment extends GameDataElement {
return; return;
} }
for (String mapName : mapLocations.keySet()) { for (String mapName : mapLocations.keySet()) {
getProject().getMap(mapName).addBacklink(this); if (getProject().getMap(mapName) != null) {
getProject().getMap(mapName).addBacklink(this);
}
} }
} }
@@ -103,6 +119,32 @@ public class WorldmapSegment extends GameDataElement {
((Worldmap)parent).save(); ((Worldmap)parent).save();
} }
public String toXml() {
Document doc;
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
doc.setXmlVersion("1.0");
Element root = doc.createElement("worldmap");
doc.appendChild(root);
root.appendChild(this.toXmlElement(doc));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result output = new StreamResult(baos);
Source input = new DOMSource(doc);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output);
return baos.toString();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
public Element toXmlElement(Document doc) { public Element toXmlElement(Document doc) {
Element element = doc.createElement("segment"); Element element = doc.createElement("segment");
element.setAttribute("id", id); element.setAttribute("id", id);

View File

@@ -36,7 +36,7 @@ public class AboutEditor extends Editor {
"<br/>" + "<br/>" +
"Play <a href=\"https://play.google.com/store/apps/details?id=com.gpl.rpg.AndorsTrail\">Andor's Trail</a> for free on your Android device.<br/>" + "Play <a href=\"https://play.google.com/store/apps/details?id=com.gpl.rpg.AndorsTrail\">Andor's Trail</a> for free on your Android device.<br/>" +
"Visit <a href=\"http://andorstrail.com/\">the official forum</a> to give or receive help.<br/>" + "Visit <a href=\"http://andorstrail.com/\">the official forum</a> to give or receive help.<br/>" +
"Open the project's <a href=\"https://code.google.com/p/andors-trail/\">Google Code page</a> to check out the game's source code.<br/>" + "Open the project's <a href=\"https://github.com/Zukero/andors-trail/\">GitHub project page</a> to check out the game's source code.<br/>" +
"<br/>" + "<br/>" +
"For content creation help, make sure to use the following resources:<br/>" + "For content creation help, make sure to use the following resources:<br/>" +
"<a href=\"http://andorstrail.com/viewtopic.php?f=6&t=4560\">The contribution guide on the forums</a><br/>" + "<a href=\"http://andorstrail.com/viewtopic.php?f=6&t=4560\">The contribution guide on the forums</a><br/>" +

View File

@@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import javax.swing.AbstractListModel; import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel; import javax.swing.ComboBoxModel;
@@ -29,6 +30,7 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JSpinner.NumberEditor; import javax.swing.JSpinner.NumberEditor;
import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel; import javax.swing.ListModel;
import javax.swing.SpinnerNumberModel; import javax.swing.SpinnerNumberModel;
@@ -148,6 +150,51 @@ public abstract class Editor extends JPanel implements ProjectElementListener {
return tfField; return tfField;
} }
public static JTextArea addTextArea(JPanel pane, String label, String initialValue, boolean editable, final FieldUpdateListener listener) {
String text= initialValue == null ? "" : initialValue.replaceAll("\\n", "\n");
JPanel tfPane = new JPanel();
tfPane.setLayout(new JideBoxLayout(tfPane, JideBoxLayout.LINE_AXIS, 6));
JLabel tfLabel = new JLabel(label);
tfPane.add(tfLabel, JideBoxLayout.FIX);
final JTextArea tfArea = new JTextArea(text);
tfArea.setEditable(editable);
tfPane.add(new JScrollPane(tfArea), JideBoxLayout.VARY);
JButton nullify = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
tfPane.add(nullify, JideBoxLayout.FIX);
nullify.setEnabled(editable);
pane.add(tfPane, JideBoxLayout.FIX);
nullify.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tfArea.setText("");
listener.valueChanged(tfArea, null);
}
});
tfArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
listener.valueChanged(tfArea, tfArea.getText().replaceAll("\n", Matcher.quoteReplacement("\n")));
}
@Override
public void insertUpdate(DocumentEvent e) {
listener.valueChanged(tfArea, tfArea.getText().replaceAll("\n", Matcher.quoteReplacement("\n")));
}
@Override
public void changedUpdate(DocumentEvent e) {
listener.valueChanged(tfArea, tfArea.getText().replaceAll("\n", Matcher.quoteReplacement("\n")));
}
});
// tfArea.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// listener.valueChanged(tfArea, tfArea.getText().replaceAll("\n", "\\n"));
// }
// });
return tfArea;
}
// public static JSpinner addIntegerField(JPanel pane, String label, Integer initialValue, boolean allowNegatives, boolean editable) { // public static JSpinner addIntegerField(JPanel pane, String label, Integer initialValue, boolean allowNegatives, boolean editable) {
// return addIntegerField(pane, label, initialValue, allowNegatives, editable, nullListener); // return addIntegerField(pane, label, initialValue, allowNegatives, editable, nullListener);
// } // }

View File

@@ -27,6 +27,7 @@ import javax.swing.event.ListDataListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition; import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
@@ -293,6 +294,7 @@ public class JSONCreationWizard extends JDialog {
creation.id = idField.getText(); creation.id = idField.getText();
JSONCreationWizard.this.setVisible(false); JSONCreationWizard.this.setVisible(false);
JSONCreationWizard.this.dispose(); JSONCreationWizard.this.dispose();
creation.state = State.created;
proj.createElement(creation); proj.createElement(creation);
notifyCreated(); notifyCreated();
ATContentStudio.frame.selectInTree(creation); ATContentStudio.frame.selectInTree(creation);

View File

@@ -1,5 +1,6 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
@@ -8,18 +9,26 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.Workspace; import com.gpl.rpg.atcontentstudio.model.Workspace;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
@@ -30,7 +39,8 @@ public class ProjectCreationWizard extends JDialog {
private static final long serialVersionUID = -2854969975146867119L; private static final long serialVersionUID = -2854969975146867119L;
final JTextField projectNameField; final JTextField projectNameField;
final JComboBox atSourceSelectionCombo; final JComboBox<String> atSourceSelectionCombo;
final JComboBox<Project.ResourceSet> resourceSetToUse;
final JButton browse; final JButton browse;
final JButton okButton; final JButton okButton;
@@ -42,7 +52,62 @@ public class ProjectCreationWizard extends JDialog {
super(ATContentStudio.frame); super(ATContentStudio.frame);
setTitle("Create project"); setTitle("Create project");
projectNameField = new JTextField(); projectNameField = new JTextField();
atSourceSelectionCombo = new JComboBox(); atSourceSelectionCombo = new JComboBox<String>();
resourceSetToUse = new JComboBox<Project.ResourceSet>(new ComboBoxModel<Project.ResourceSet>() {
Project.ResourceSet selected = Project.ResourceSet.allFiles;
@Override
public int getSize() {
return Project.ResourceSet.values().length;
}
@Override
public ResourceSet getElementAt(int index) {
return Project.ResourceSet.values()[index];
}
List<ListDataListener> listeners = new LinkedList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
@Override
public void setSelectedItem(Object anItem) {
selected = (ResourceSet) anItem;
}
@Override
public Object getSelectedItem() {
return selected;
}
});
resourceSetToUse.setRenderer(new ListCellRenderer<Project.ResourceSet>() {
@Override
public Component getListCellRendererComponent(
JList<? extends ResourceSet> list, ResourceSet value,
int index, boolean isSelected, boolean cellHasFocus) {
switch (value) {
case allFiles:
return new JLabel("All available files");
case debugData:
return new JLabel("Debug data");
case gameData:
return new JLabel("Real game data");
default:
return new JLabel();
}
}
});
browse = new JButton("Browse..."); browse = new JButton("Browse...");
okButton = new JButton("Ok"); okButton = new JButton("Ok");
cancelButton = new JButton("Cancel"); cancelButton = new JButton("Cancel");
@@ -103,7 +168,7 @@ public class ProjectCreationWizard extends JDialog {
if (!Workspace.activeWorkspace.knownMapSourcesFolders.contains(atSourceFolder)) { if (!Workspace.activeWorkspace.knownMapSourcesFolders.contains(atSourceFolder)) {
Workspace.activeWorkspace.knownMapSourcesFolders.add(atSourceFolder); Workspace.activeWorkspace.knownMapSourcesFolders.add(atSourceFolder);
} }
Workspace.createProject(projectNameField.getText(), atSourceFolder); Workspace.createProject(projectNameField.getText(), atSourceFolder, (Project.ResourceSet)resourceSetToUse.getSelectedItem());
ProjectCreationWizard.this.dispose(); ProjectCreationWizard.this.dispose();
} }
}); });
@@ -154,6 +219,17 @@ public class ProjectCreationWizard extends JDialog {
c.weightx = 20; c.weightx = 20;
panel.add(browse, c); panel.add(browse, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("Resource set: "), c);
c.gridx++;
c.weightx = 80;
c.gridwidth = 2;
panel.add(resourceSetToUse, c);
JPanel buttonPane = new JPanel(); JPanel buttonPane = new JPanel();
buttonPane.setLayout(new GridBagLayout()); buttonPane.setLayout(new GridBagLayout());
GridBagConstraints c2 = new GridBagConstraints(); GridBagConstraints c2 = new GridBagConstraints();

View File

@@ -370,7 +370,7 @@ public class WorkspaceActions {
} }
@Override @Override
public void putValue(String key, Object value) { public synchronized void putValue(String key, Object value) {
PropertyChangeEvent event = new PropertyChangeEvent(this, key, values.get(key), value); PropertyChangeEvent event = new PropertyChangeEvent(this, key, values.get(key), value);
values.put(key, value); values.put(key, value);
for (PropertyChangeListener l : listeners) { for (PropertyChangeListener l : listeners) {
@@ -379,7 +379,7 @@ public class WorkspaceActions {
} }
@Override @Override
public void setEnabled(boolean b) { public synchronized void setEnabled(boolean b) {
PropertyChangeEvent event = new PropertyChangeEvent(this, "enabled", isEnabled(), b); PropertyChangeEvent event = new PropertyChangeEvent(this, "enabled", isEnabled(), b);
enabled = b; enabled = b;
for (PropertyChangeListener l : listeners) { for (PropertyChangeListener l : listeners) {
@@ -395,12 +395,12 @@ public class WorkspaceActions {
private Set<PropertyChangeListener> listeners = new HashSet<PropertyChangeListener>(); private Set<PropertyChangeListener> listeners = new HashSet<PropertyChangeListener>();
@Override @Override
public void addPropertyChangeListener(PropertyChangeListener listener) { public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
listeners.add(listener); listeners.add(listener);
} }
@Override @Override
public void removePropertyChangeListener(PropertyChangeListener listener) { public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
listeners.remove(listener); listeners.remove(listener);
} }

View File

@@ -6,9 +6,12 @@ import java.awt.GridBagLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
@@ -108,9 +111,15 @@ public class WorkspaceSelector extends JFrame {
//Layout, labels and dialog behavior. //Layout, labels and dialog behavior.
setTitle("Select your workspace"); setTitle("Select your workspace");
JLabel logoLabel = new JLabel();
try {
logoLabel = new JLabel(new ImageIcon(ImageIO.read(WorkspaceSelector.class.getResource("/com/gpl/rpg/atcontentstudio/img/atcs_logo_banner.png"))), JLabel.CENTER);
} catch (IOException e1) {}
JPanel dialogPane = new JPanel(); JPanel dialogPane = new JPanel();
dialogPane.setLayout(new BorderLayout()); dialogPane.setLayout(new BorderLayout());
dialogPane.add(logoLabel, BorderLayout.NORTH);
dialogPane.add(new JLabel("Workspace : "), BorderLayout.WEST); dialogPane.add(new JLabel("Workspace : "), BorderLayout.WEST);
dialogPane.add(combo, BorderLayout.CENTER); dialogPane.add(combo, BorderLayout.CENTER);
dialogPane.add(browse, BorderLayout.EAST); dialogPane.add(browse, BorderLayout.EAST);

View File

@@ -23,6 +23,7 @@ import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel; import javax.swing.ListModel;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
@@ -79,7 +80,7 @@ public class DialogueEditor extends JSONElementEditor {
private static final int SHOP_INDEX = 5; private static final int SHOP_INDEX = 5;
private JTextField idField; private JTextField idField;
private JTextField messageField; private JTextArea messageField;
private MyComboBox switchToNpcBox; private MyComboBox switchToNpcBox;
private RewardsListModel rewardsListModel; private RewardsListModel rewardsListModel;
@@ -127,7 +128,7 @@ public class DialogueEditor extends JSONElementEditor {
createButtonPane(pane, dialogue.getProject(), dialogue, Dialogue.class, dialogue.getImage(), null, listener); createButtonPane(pane, dialogue.getProject(), dialogue, Dialogue.class, dialogue.getImage(), null, listener);
idField = addTextField(pane, "Internal ID: ", dialogue.id, dialogue.writable, listener); idField = addTextField(pane, "Internal ID: ", dialogue.id, dialogue.writable, listener);
messageField = addTextField(pane, "Message: ", dialogue.message, dialogue.writable, listener); messageField = addTextArea(pane, "Message: ", dialogue.message, dialogue.writable, listener);
switchToNpcBox = addNPCBox(pane, dialogue.getProject(), "Switch active NPC to: ", dialogue.switch_to_npc, dialogue.writable, listener); switchToNpcBox = addNPCBox(pane, dialogue.getProject(), "Switch active NPC to: ", dialogue.switch_to_npc, dialogue.writable, listener);
CollapsiblePanel rewards = new CollapsiblePanel("Reaching this phrase gives the following rewards: "); CollapsiblePanel rewards = new CollapsiblePanel("Reaching this phrase gives the following rewards: ");
@@ -320,8 +321,13 @@ public class DialogueEditor extends JSONElementEditor {
} }
if (reward.type != null) { if (reward.type != null) {
switch (reward.type) { switch (reward.type) {
case activateMapChangeArea: case activateMapObjectGroup:
case deactivateMapChangeArea: case deactivateMapObjectGroup:
rewardMap = addMapBox(pane, ((Dialogue)target).getProject(), "Map Name: ", reward.map, writable, listener);
rewardObjId = addTextField(pane, "Group ID: ", reward.reward_obj_id, writable, listener);
rewardObj = null;
rewardValue = null;
break;
case deactivateSpawnArea: case deactivateSpawnArea:
case removeSpawnArea: case removeSpawnArea:
case spawnAll: case spawnAll:
@@ -717,63 +723,72 @@ public class DialogueEditor extends JSONElementEditor {
JLabel label = ((JLabel)c); JLabel label = ((JLabel)c);
Dialogue.Reward reward = (Dialogue.Reward)value; Dialogue.Reward reward = (Dialogue.Reward)value;
if (reward.type != null) { decorateRewardJLabel(label, reward);
String rewardObjDesc = null;
if( reward.reward_obj != null) {
rewardObjDesc = reward.reward_obj.getDesc();
} else if (reward.reward_obj_id != null) {
rewardObjDesc = reward.reward_obj_id;
}
switch (reward.type) {
case activateMapChangeArea:
label.setText("Activate mapchange area "+rewardObjDesc+" on map "+reward.map_name);
break;
case actorCondition:
label.setText("Give actor condition "+rewardObjDesc+" for "+reward.reward_value+" turns");
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case alignmentChange:
label.setText("Change alignment for faction "+rewardObjDesc+" : "+reward.reward_value);
break;
case createTimer:
label.setText("Create timer "+rewardObjDesc);
break;
case deactivateMapChangeArea:
label.setText("Deactivate mapchange area "+rewardObjDesc+" on map "+reward.map_name);
break;
case deactivateSpawnArea:
label.setText("Deactivate spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
break;
case dropList:
label.setText("Give contents of droplist "+rewardObjDesc);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case giveItem:
label.setText("Give "+reward.reward_value+" "+rewardObjDesc);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case questProgress:
label.setText("Give quest progress "+rewardObjDesc+":"+reward.reward_value);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case removeSpawnArea:
label.setText("Remove all monsters in spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
break;
case skillIncrease:
label.setText("Increase skill "+rewardObjDesc+" level");
break;
case spawnAll:
label.setText("Respawn all monsters in spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
break;
}
} else {
label.setText("New, undefined reward");
}
} }
return c; return c;
} }
} }
public static void decorateRewardJLabel(JLabel label, Dialogue.Reward reward) {
if (reward.type != null) {
String rewardObjDesc = null;
if( reward.reward_obj != null) {
rewardObjDesc = reward.reward_obj.getDesc();
} else if (reward.reward_obj_id != null) {
rewardObjDesc = reward.reward_obj_id;
}
switch (reward.type) {
case activateMapObjectGroup:
label.setText("Activate map object group "+rewardObjDesc+" on map "+reward.map_name);
label.setIcon(new ImageIcon(DefaultIcons.getObjectLayerIcon()));
break;
case actorCondition:
label.setText("Give actor condition "+rewardObjDesc+" for "+reward.reward_value+" turns");
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case alignmentChange:
label.setText("Change alignment for faction "+rewardObjDesc+" : "+reward.reward_value);
break;
case createTimer:
label.setText("Create timer "+rewardObjDesc);
break;
case deactivateMapObjectGroup:
label.setText("Deactivate map object group "+rewardObjDesc+" on map "+reward.map_name);
label.setIcon(new ImageIcon(DefaultIcons.getObjectLayerIcon()));
break;
case deactivateSpawnArea:
label.setText("Deactivate spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
label.setIcon(new ImageIcon(DefaultIcons.getNPCIcon()));
break;
case dropList:
label.setText("Give contents of droplist "+rewardObjDesc);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case giveItem:
label.setText("Give "+reward.reward_value+" "+rewardObjDesc);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case questProgress:
label.setText("Give quest progress "+rewardObjDesc+":"+reward.reward_value);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case removeSpawnArea:
label.setText("Remove all monsters in spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
label.setIcon(new ImageIcon(DefaultIcons.getNPCIcon()));
break;
case skillIncrease:
label.setText("Increase skill "+rewardObjDesc+" level");
break;
case spawnAll:
label.setText("Respawn all monsters in spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
label.setIcon(new ImageIcon(DefaultIcons.getNPCIcon()));
break;
}
} else {
label.setText("New, undefined reward");
}
}
public static class RepliesListModel implements ListModel { public static class RepliesListModel implements ListModel {
@@ -981,19 +996,23 @@ public class DialogueEditor extends JSONElementEditor {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
((JLabel)c).setText(((Requirement)value).getDesc()); decorateRequirementJLabel((JLabel)c, (Requirement)value);
if (((Requirement)value).required_obj != null) {
if (((Requirement)value).required_obj.getIcon() != null) {
((JLabel)c).setIcon(new ImageIcon(((Requirement)value).required_obj.getIcon()));
}
} if (((Requirement)value).type == null) {
((JLabel)c).setText("New, undefined requirement.");
}
} }
return c; return c;
} }
} }
public static void decorateRequirementJLabel(JLabel label, Requirement req) {
label.setText(req.getDesc());
if (req.required_obj != null) {
if (req.required_obj.getIcon() != null) {
label.setIcon(new ImageIcon(req.required_obj.getIcon()));
}
} if (req.type == null) {
label.setText("New, undefined requirement.");
}
}
public class DialogueFieldUpdater implements FieldUpdateListener { public class DialogueFieldUpdater implements FieldUpdateListener {
@Override @Override
public void valueChanged(JComponent source, Object value) { public void valueChanged(JComponent source, Object value) {
@@ -1019,6 +1038,10 @@ public class DialogueEditor extends JSONElementEditor {
} else if (source == rewardTypeCombo) { } else if (source == rewardTypeCombo) {
if (selectedReward.type != value) { if (selectedReward.type != value) {
selectedReward.type = (Dialogue.Reward.RewardType) value; selectedReward.type = (Dialogue.Reward.RewardType) value;
if (selectedReward.map != null) {
selectedReward.map.removeBacklink(dialogue);
}
selectedReward.map = null;
selectedReward.map_name = null; selectedReward.map_name = null;
selectedReward.reward_obj = null; selectedReward.reward_obj = null;
selectedReward.reward_obj_id = null; selectedReward.reward_obj_id = null;

View File

@@ -1,24 +1,32 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors; package com.gpl.rpg.atcontentstudio.ui.gamedataeditors;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener; import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel; import javax.swing.table.TableModel;
import org.fife.ui.rtextarea.ColorBackgroundPainterStrategy;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
@@ -79,6 +87,7 @@ public class QuestEditor extends JSONElementEditor {
stagesTable.getColumnModel().getColumn(3).setMinWidth(130); stagesTable.getColumnModel().getColumn(3).setMinWidth(130);
stagesTable.getColumnModel().getColumn(3).setMaxWidth(130); stagesTable.getColumnModel().getColumn(3).setMaxWidth(130);
stagesTable.setCellSelectionEnabled(true); stagesTable.setCellSelectionEnabled(true);
stagesTable.getColumnModel().getColumn(1).setCellRenderer(new MultilineCellRenderer());
stagesPane.add(new JScrollPane(stagesTable), BorderLayout.CENTER); stagesPane.add(new JScrollPane(stagesTable), BorderLayout.CENTER);
if (quest.writable) { if (quest.writable) {
JPanel buttonPane = new JPanel(); JPanel buttonPane = new JPanel();
@@ -330,6 +339,48 @@ public class QuestEditor extends JSONElementEditor {
updateJsonViewText(quest.toJsonString()); updateJsonViewText(quest.toJsonString());
} }
}
public class MultilineCellRenderer extends JTextArea implements TableCellRenderer {
private static final long serialVersionUID = 6539816623608859506L;
public MultilineCellRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
//setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if (isSelected) {
setForeground(stagesTable.getSelectionForeground());
setBackground(stagesTable.getSelectionBackground());
} else {
setForeground(stagesTable.getForeground());
setBackground(stagesTable.getBackground());
}
setFont(stagesTable.getFont());
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
if (stagesTable.isCellEditable(row, column)) {
setForeground(UIManager.getColor("Table.focusCellForeground"));
setBackground(UIManager.getColor("Table.focusCellBackground"));
}
} else {
setBorder(BorderFactory.createLineBorder(getBackground(), 1));
}
setText((value == null ? "" : value.toString()));
int fh = getFontMetrics(getFont()).getHeight();
// int tl = getText().length();
setSize(stagesTable.getWidth(), fh);
stagesTable.setRowHeight(row, getPreferredSize().height);
return this;
}
} }

View File

@@ -1,7 +1,11 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree; package com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image; import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
@@ -9,6 +13,12 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolTip;
import javax.swing.ToolTipManager;
import prefuse.Display; import prefuse.Display;
import prefuse.Visualization; import prefuse.Visualization;
import prefuse.action.ActionList; import prefuse.action.ActionList;
@@ -42,7 +52,11 @@ import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue; import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC; import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.DialogueEditor;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor.TMXReplacementViewer;
import com.jidesoft.swing.JideBoxLayout;
public class DialogueGraphView extends Display { public class DialogueGraphView extends Display {
@@ -147,6 +161,7 @@ public class DialogueGraphView extends Display {
setSize(500,500); setSize(500,500);
pan(250, 250); pan(250, 250);
setHighQuality(true); setHighQuality(true);
addControlListener(new TooltipControl());
addControlListener(new DoubleClickControl()); addControlListener(new DoubleClickControl());
addControlListener(new WheelZoomControl()); addControlListener(new WheelZoomControl());
addControlListener(new ZoomControl()); addControlListener(new ZoomControl());
@@ -435,6 +450,90 @@ public class DialogueGraphView extends Display {
} }
} }
class TooltipControl extends ControlAdapter {
@Override
public void itemEntered(VisualItem item, MouseEvent e) {
if (item.get(TARGET) != null) {
tooltippedItem = item;
if (!tooltipActivated) {
setToolTipText("");
ToolTipManager.sharedInstance().registerComponent(DialogueGraphView.this);
ToolTipManager.sharedInstance().setEnabled(true);
tooltipActivated = true;
}
}
}
@Override
public void itemExited(VisualItem item, MouseEvent e) {
//Hides the tooltip...
ToolTipManager.sharedInstance().setEnabled(false);
ToolTipManager.sharedInstance().unregisterComponent(DialogueGraphView.this);
tooltipActivated = false;
}
}
JToolTip tt = null;
private VisualItem tooltippedItem = null;
private VisualItem lastTTItem = null;
private boolean tooltipActivated = false;
@Override
public Point getToolTipLocation(MouseEvent event) {
return new Point(event.getX() + 5, event.getY() + 5);
}
@Override
public JToolTip createToolTip() {
if (tt == null) tt = super.createToolTip();
if (tooltippedItem == lastTTItem) {
return tt;
}
tt = super.createToolTip();
lastTTItem = tooltippedItem;
tt.setLayout(new BorderLayout());
JPanel content = new JPanel();
content.setLayout(new JideBoxLayout(content, JideBoxLayout.PAGE_AXIS));
JLabel label;
if (tooltippedItem != null) {
Object target = tooltippedItem.get(TARGET);
if (target != null) {
if (target instanceof Dialogue) {
Dialogue d = (Dialogue) target;
label = new JLabel(new ImageIcon(DefaultIcons.getDialogueIcon()));
label.setText(d.id);
content.add(label, JideBoxLayout.FIX);
if (tooltippedItem.get(REPLY) == null) {
if (d.rewards != null && !d.rewards.isEmpty()) {
for (Dialogue.Reward r : d.rewards) {
label = new JLabel();
DialogueEditor.decorateRewardJLabel(label, r);
content.add(label, JideBoxLayout.FIX);
}
}
} else {
Object replObj = tooltippedItem.get(REPLY);
if (replObj instanceof Dialogue.Reply) {
Dialogue.Reply r = (Dialogue.Reply) replObj;
if (r.requirements != null && !r.requirements.isEmpty()) {
for (Requirement req : r.requirements) {
label = new JLabel();
DialogueEditor.decorateRequirementJLabel(label, req);
content.add(label, JideBoxLayout.FIX);
}
}
}
}
}
}
}
tt.add(content, BorderLayout.CENTER);
tt.setPreferredSize(tt.getLayout().preferredLayoutSize(tt));
return tt;
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,9 @@ import javax.swing.JViewport;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
@@ -46,6 +49,9 @@ public class WorldMapEditor extends Editor {
private static final long serialVersionUID = -8358238912588729094L; private static final long serialVersionUID = -8358238912588729094L;
private RSyntaxTextArea editorPane;
public EditMode editMode = EditMode.moveViewSelect; public EditMode editMode = EditMode.moveViewSelect;
public enum EditMode { public enum EditMode {
@@ -72,6 +78,10 @@ public class WorldMapEditor extends Editor {
add(editorTabsHolder, BorderLayout.CENTER); add(editorTabsHolder, BorderLayout.CENTER);
editorTabsHolder.add("Map", buildSegmentTab(worldmap)); editorTabsHolder.add("Map", buildSegmentTab(worldmap));
JScrollPane xmlScroller = new JScrollPane(getXmlEditorPane(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
xmlScroller.getVerticalScrollBar().setUnitIncrement(16);
editorTabsHolder.add("XML", xmlScroller);
} }
@Override @Override
@@ -80,6 +90,22 @@ public class WorldMapEditor extends Editor {
} }
public JPanel getXmlEditorPane() {
JPanel pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
editorPane = new RSyntaxTextArea();
editorPane.setText(((WorldmapSegment)target).toXml());
editorPane.setEditable(false);
editorPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
pane.add(editorPane, JideBoxLayout.VARY);
return pane;
}
public void updateXmlViewText(String text) {
editorPane.setText(text);
}
private JPanel buildSegmentTab(final WorldmapSegment worldmap) { private JPanel buildSegmentTab(final WorldmapSegment worldmap) {
JPanel pane = new JPanel(); JPanel pane = new JPanel();

View File

@@ -81,7 +81,7 @@ public class WorldMapView extends JComponent implements Scrollable {
for (tiled.core.MapLayer layer : ((TMXMap)map).tmxMap) { for (tiled.core.MapLayer layer : ((TMXMap)map).tmxMap) {
if (layer instanceof tiled.core.TileLayer && layer.isVisible()) { if (layer instanceof tiled.core.TileLayer && layer.isVisible()) {
if (layer.getName().equalsIgnoreCase("walkable")) continue; if (layer.getName().equalsIgnoreCase("walkable")) continue;
renderer.paintTileLayer(g2, (tiled.core.TileLayer) layer); renderer.paintTileLayer(g2, (tiled.core.TileLayer) layer, null);
} else if (layer instanceof tiled.core.ObjectGroup && layer.isVisible()) { } else if (layer instanceof tiled.core.ObjectGroup && layer.isVisible()) {
// paintObjectGroup(g2, map, (tiled.core.ObjectGroup) layer); // paintObjectGroup(g2, map, (tiled.core.ObjectGroup) layer);
} }

View File

@@ -151,10 +151,10 @@ public class SpritesheetEditor extends Editor {
TableColumn col; TableColumn col;
while (columns.hasMoreElements()) { while (columns.hasMoreElements()) {
col = columns.nextElement(); col = columns.nextElement();
col.setMinWidth(sheet.spriteWidth + 1); col.setMinWidth(sheet.spriteWidth + 4);
col.setMaxWidth(sheet.spriteWidth + 1); col.setMaxWidth(sheet.spriteWidth + 4);
} }
spritesTable.setRowHeight(sheet.spriteHeight + 1); spritesTable.setRowHeight(sheet.spriteHeight + 4);
pane.add(new JScrollPane(spritesTable), BorderLayout.CENTER); pane.add(new JScrollPane(spritesTable), BorderLayout.CENTER);
} }
} }

View File

@@ -18,7 +18,7 @@ public class ItemsTableView extends ElementTableView {
private static final long serialVersionUID = 1474255176349837609L; private static final long serialVersionUID = 1474255176349837609L;
public ItemsTableView(Project proj) { public ItemsTableView(Project proj) {
super(new ItemsTableModel(proj), "Compare "+proj.getItemCount()+" items.", new ImageIcon(DefaultIcons.getItemIcon())); super(new ItemsTableModel(proj), "Compare "+proj.getItemCountIncludingAltered()+" items.", new ImageIcon(DefaultIcons.getItemIcon()));
} }
private static class ItemsTableModel implements TableModel { private static class ItemsTableModel implements TableModel {
@@ -32,7 +32,7 @@ public class ItemsTableView extends ElementTableView {
@Override @Override
public int getRowCount() { public int getRowCount() {
// return proj.getItemCount() + 1; // return proj.getItemCount() + 1;
return proj.getItemCount(); return proj.getItemCountIncludingAltered();
} }
@Override @Override
@@ -130,7 +130,7 @@ public class ItemsTableView extends ElementTableView {
// return getColumnName(columnIndex); // return getColumnName(columnIndex);
// } // }
// Item item = proj.getItem(rowIndex - 1); // Item item = proj.getItem(rowIndex - 1);
Item item = proj.getItem(rowIndex); Item item = proj.getItemIncludingAltered(rowIndex);
boolean canUse = item.category != null && item.category.action_type == ItemCategory.ActionType.use; boolean canUse = item.category != null && item.category.action_type == ItemCategory.ActionType.use;
boolean canEquip = item.category != null && item.category.action_type == ItemCategory.ActionType.equip; boolean canEquip = item.category != null && item.category.action_type == ItemCategory.ActionType.equip;
switch (columnIndex) { switch (columnIndex) {

View File

@@ -0,0 +1,124 @@
package com.gpl.rpg.atcontentstudio.ui.tools;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.RenderingHints;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
/**
* This Composite emulates the behaviour of Android's ColorMatrixColorFilter,
* except that you have to use this one a posteriori instead of a filtering paint.
*
* It applies a ColorMatrix to the destination pixels, regardless of potential "source" pixels.
* Once created and activated through Graphics2D.setComposite(), just paint anything over the pixels you want "filtered".
*
* Works on a per-pixel basis, no sampling of surrounding pixels, or anything.
*
* @author pochat
*
*/
public class MatrixComposite implements Composite {
final float[] matrix = new float[20];
/**
* Dismisses the source pixels. Just paint it black, or white, it only affects the dest RGB with the following formulae.
*
* R' = a*R + b*G + c*B + d*A + e;
* G' = f*R + g*G + h*B + i*A + j;
* B' = k*R + l*G + m*B + n*A + o;
* A' = p*R + q*G + r*B + s*A + t;
*
* @param matrix a flat float[20] array, giving the a..t values;
*/
public MatrixComposite(float[] matrix) {
if (matrix.length != this.matrix.length) {
throw new Error("MatrixComposite matrix must be of length "+this.matrix.length);
}
System.arraycopy(matrix, 0, this.matrix, 0, this.matrix.length);
}
@Override
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel, RenderingHints hints) {
return new MatrixCompositeContext(this);
}
class MatrixCompositeContext implements CompositeContext {
MatrixComposite composite;
public MatrixCompositeContext(MatrixComposite composite) {
this.composite = composite;
}
@Override
public void dispose() {
}
@Override
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
throw new IllegalStateException(
"Source and destination must store pixels as INT.");
}
int width = Math.min(src.getWidth(), dstIn.getWidth());
int height = Math.min(src.getHeight(), dstIn.getHeight());
float alpha = 1.0f;
int[] srcPixel = new int[4];
int[] dstPixel = new int[4];
int[] srcPixels = new int[width];
int[] dstPixels = new int[width];
for (int y = 0; y < height; y++) {
src.getDataElements(0, y, width, 1, srcPixels);
dstIn.getDataElements(0, y, width, 1, dstPixels);
for (int x = 0; x < width; x++) {
// pixels are stored as INT_ARGB
// our arrays are [R, G, B, A]
int pixel = srcPixels[x];
srcPixel[0] = (pixel >> 16) & 0xFF;
srcPixel[1] = (pixel >> 8) & 0xFF;
srcPixel[2] = (pixel ) & 0xFF;
srcPixel[3] = (pixel >> 24) & 0xFF;
pixel = dstPixels[x];
dstPixel[0] = (pixel >> 16) & 0xFF;
dstPixel[1] = (pixel >> 8) & 0xFF;
dstPixel[2] = (pixel ) & 0xFF;
dstPixel[3] = (pixel >> 24) & 0xFF;
int[] result = applyMatrix(matrix, dstPixel);
// mixes the result with the opacity
dstPixels[x] = ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 |
((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 |
((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) << 8 |
(int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF;
}
dstOut.setDataElements(0, y, width, 1, dstPixels);
}
}
private int[] applyMatrix(float[] matrix, int[] dstPixel) {
int[] result = new int[4];
result[0] = Math.max(0, Math.min(255, (int) (matrix[ 0] * dstPixel[0] + matrix[ 1] * dstPixel[1] + matrix[ 2] * dstPixel[2] + matrix[ 3] * dstPixel[3] + matrix[ 4]) ));
result[1] = Math.max(0, Math.min(255, (int) (matrix[ 5] * dstPixel[0] + matrix[ 6] * dstPixel[1] + matrix[ 7] * dstPixel[2] + matrix[ 8] * dstPixel[3] + matrix[ 9]) ));
result[2] = Math.max(0, Math.min(255, (int) (matrix[10] * dstPixel[0] + matrix[11] * dstPixel[1] + matrix[12] * dstPixel[2] + matrix[13] * dstPixel[3] + matrix[14]) ));
result[3] = Math.max(0, Math.min(255, (int) (matrix[15] * dstPixel[0] + matrix[16] * dstPixel[1] + matrix[17] * dstPixel[2] + matrix[18] * dstPixel[3] + matrix[19]) ));
return result;
}
}
}

View File

@@ -17,7 +17,7 @@ public class NPCsTableView extends ElementTableView {
private static final long serialVersionUID = -4196852140899079621L; private static final long serialVersionUID = -4196852140899079621L;
public NPCsTableView(Project proj) { public NPCsTableView(Project proj) {
super(new NPCsTableModel(proj), "Compare "+proj.getNPCCount()+" NPCs.", new ImageIcon(DefaultIcons.getNPCIcon())); super(new NPCsTableModel(proj), "Compare "+proj.getNPCCountIncludingAltered()+" NPCs.", new ImageIcon(DefaultIcons.getNPCIcon()));
} }
private static class NPCsTableModel implements TableModel { private static class NPCsTableModel implements TableModel {
@@ -30,7 +30,7 @@ public class NPCsTableView extends ElementTableView {
@Override @Override
public int getRowCount() { public int getRowCount() {
return proj.getNPCCount(); return proj.getNPCCountIncludingAltered();
} }
@Override @Override
@@ -109,7 +109,7 @@ public class NPCsTableView extends ElementTableView {
@Override @Override
public Object getValueAt(int rowIndex, int columnIndex) { public Object getValueAt(int rowIndex, int columnIndex) {
NPC npc = proj.getNPC(rowIndex); NPC npc = proj.getNPCIncludingAltered(rowIndex);
switch (columnIndex) { switch (columnIndex) {
case 0: return new ImageIcon(npc.getIcon()); // Icon case 0: return new ImageIcon(npc.getIcon()); // Icon
case 1: return npc.id; //ID case 1: return npc.id; //ID