Compare commits

...

15 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
40 changed files with 1275 additions and 202 deletions

View File

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

View File

@@ -161,7 +161,7 @@ public class TileSet implements Iterable<Tile>
tilesPerRow = basicTileCutter.getTilesPerRow();
}
Image tileImage = cutter.getNextTile();
BufferedImage tileImage = cutter.getNextTile();
while (tileImage != null) {
Tile tile = new Tile();
tile.setImage(tileImage);
@@ -220,7 +220,7 @@ public class TileSet implements Iterable<Tile>
tileDimensions = new Rectangle(tileCutter.getTileDimensions());
int id = 0;
Image tileImage = tileCutter.getNextTile();
BufferedImage tileImage = tileCutter.getNextTile();
while (tileImage != null) {
Tile tile = getTile(id);
tile.setImage(tileImage);

View File

@@ -31,6 +31,7 @@ package tiled.io;
import java.awt.Color;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
@@ -223,9 +224,9 @@ public class TMXMapReader
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");
@@ -253,7 +254,7 @@ public class TMXMapReader
// size, somehow makes drawing of the tiles a lot
// faster on various systems (seen on Linux, Windows
// and MacOS X).
img = img.getScaledInstance(
img = (BufferedImage) img.getScaledInstance(
img.getWidth(null), img.getHeight(null),
Image.SCALE_FAST);
}
@@ -534,7 +535,7 @@ public class TMXMapReader
Node child = children.item(i);
if ("image".equalsIgnoreCase(child.getNodeName())) {
int id = getAttribute(child, "id", -1);
Image img = unmarshalImage(child, baseDir);
BufferedImage img = unmarshalImage(child, baseDir);
tile.setImage(img);
} else if ("animation".equalsIgnoreCase(child.getNodeName())) {
// TODO: fill this in once TMXMapWriter is complete

View File

@@ -64,7 +64,7 @@ public class BasicTileCutter implements TileCutter
this.image = image;
}
public Image getNextTile() {
public BufferedImage getNextTile() {
if (nextY + tileHeight + tileMargin <= image.getHeight()) {
BufferedImage tile =
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
* images are available
*/
public Image getNextTile();
public BufferedImage getNextTile();
/**
* 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 java.awt.*;
import java.awt.image.BufferedImageOp;
/**
* An interface defining methods to render a map.
@@ -50,5 +51,5 @@ public interface MapRenderer
* @param g the graphics context to paint to
* @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 java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
/**
* 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());
}
public void paintTileLayer(Graphics2D g, TileLayer layer) {
public void paintTileLayer(Graphics2D g, TileLayer layer, BufferedImageOp filter ) {
final Rectangle clip = g.getClipBounds();
final int tileWidth = map.getTileWidth();
final int tileHeight = map.getTileHeight();
@@ -74,15 +76,17 @@ public class OrthogonalRenderer implements MapRenderer
final Tile tile = layer.getTileAt(x, y);
if (tile == null)
continue;
final Image image = tile.getImage();
final BufferedImage image = tile.getImage();
if (image == null)
continue;
g.drawImage(
image,
filter,
x * tileWidth,
(y + 1) * tileHeight - image.getHeight(null),
null);
(y + 1) * tileHeight - image.getHeight(null));
}
}

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.1.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
java -Xmx512M -cp lib/AndorsTrainer_v0.1.2.jar:lib/ATCS_v0.4.1.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 "" "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.1.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.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
!define VERSION "0.4.1"
!define VERSION "0.4.7"
!define JAVA_BIN "java"
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 static final String APP_NAME = "Andor's Trail Content Studio";
public static final String APP_VERSION = "v0.4.1";
public static final String APP_VERSION = "v0.4.7";
public static boolean STARTED = false;
public static StudioFrame frame = null;

View File

@@ -2,13 +2,29 @@ package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
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.maps.TMXMapSet;
import com.gpl.rpg.atcontentstudio.model.maps.Worldmap;
@@ -21,6 +37,9 @@ public class GameSource implements ProjectTreeNode, Serializable {
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 TMXMapSet gameMaps;
public transient SpriteSheetSet gameSprites;
@@ -39,6 +58,8 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient Project parent = null;
public transient Map<String, List<String>> referencedSourceFiles = null;
public GameSource(File folder, Project parent) {
this.parent = parent;
this.baseFolder = folder;
@@ -59,6 +80,12 @@ public class GameSource implements ProjectTreeNode, Serializable {
}
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.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this);
@@ -70,6 +97,58 @@ public class GameSource implements ProjectTreeNode, Serializable {
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
public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements();

View File

@@ -73,10 +73,19 @@ public class Project implements ProjectTreeNode, Serializable {
public transient Workspace parent;
public Properties knownSpritesheetsProperties = null;
public static enum ResourceSet {
gameData,
debugData,
allFiles
}
public ResourceSet sourceSetToUse = ResourceSet.allFiles;
public Project(Workspace w, String name, File source) {
public Project(Workspace w, String name, File source, ResourceSet sourceSet) {
this.parent = w;
this.name = name;
this.sourceSetToUse = sourceSet;
//CREATE PROJECT
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();
baseContent.refreshTransients(this);
// l = new Date().getTime() - l;
@@ -477,6 +490,21 @@ public class Project implements ProjectTreeNode, Serializable {
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) {
if (item.getDataType() == GameSource.Type.created) {
return createdContent.gameData.items.getIndex(item);
@@ -522,6 +550,13 @@ public class Project implements ProjectTreeNode, Serializable {
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() {
return createdContent.gameData.npcs.size() + baseContent.gameData.npcs.size();
}
@@ -535,6 +570,21 @@ public class Project implements ProjectTreeNode, Serializable {
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) {
if (npc.getDataType() == GameSource.Type.created) {
return createdContent.gameData.npcs.getIndex(npc);
@@ -747,13 +797,13 @@ public class Project implements ProjectTreeNode, Serializable {
}
existingNode.getBacklinks().clear();
node.writable = true;
node.state = GameDataElement.State.created;
alteredContent.gameData.addElement(node);
node.link();
node.state = GameDataElement.State.created;
} else {
createdContent.gameData.addElement(node);
node.state = GameDataElement.State.created;
node.link();
node.state = GameDataElement.State.created;
}
fireElementAdded(node, getNodeIndex(node));
}
@@ -833,7 +883,7 @@ public class Project implements ProjectTreeNode, Serializable {
int index = -1;
while (--i >= 0) {
NPC npc = getNPC(i);
if (spawngroup_id.equals(npc.spawngroup_id)) {
if (spawngroup_id.equalsIgnoreCase(npc.spawngroup_id)) {
for (NPC present : result) {
if (present.id.equals(npc.id)) {
alreadyAdded = true;
@@ -851,7 +901,7 @@ public class Project implements ProjectTreeNode, Serializable {
}
if (result.isEmpty()) {
//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);
}
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() {
@Override
public void run() {
@@ -154,7 +154,7 @@ public class Workspace implements ProjectTreeNode, Serializable {
Notification.addError("A project named "+projectName+" already exists in this workspace.");
return;
}
Project p = new Project(activeWorkspace, projectName, gameSourceFolder);
Project p = new Project(activeWorkspace, projectName, gameSourceFolder, sourceSet);
activeWorkspace.projects.add(p);
activeWorkspace.projectsName.add(projectName);
activeWorkspace.projectsOpenByName.put(projectName, p.open);

View File

@@ -63,8 +63,8 @@ public class Dialogue extends JSONElement {
spawnAll,
removeSpawnArea,
deactivateSpawnArea,
activateMapChangeArea,
deactivateMapChangeArea
activateMapObjectGroup,
deactivateMapObjectGroup
}
}
@@ -171,7 +171,7 @@ public class Dialogue extends JSONElement {
requirement.parent = this;
if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType"));
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");
requirement.state = State.parsed;
reply.requirements.add(requirement);
@@ -242,8 +242,8 @@ public class Dialogue extends JSONElement {
for (Reward reward : rewards) {
if (reward.reward_obj_id != null) {
switch (reward.type) {
case activateMapChangeArea:
case deactivateMapChangeArea:
case activateMapObjectGroup:
case deactivateMapObjectGroup:
case spawnAll:
case removeSpawnArea:
case deactivateSpawnArea:

View File

@@ -154,7 +154,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
dataToSave.add(element.toJson());
}
}
if (dataToSave.isEmpty()) {
if (dataToSave.isEmpty() && jsonFile.exists()) {
if (jsonFile.delete()) {
Notification.addSuccess("File "+jsonFile.getAbsolutePath()+" deleted.");
} 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.Type;
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.SavedSlotCollection;
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_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 GameDataCategory<ActorCondition> actorConditions;
@@ -67,7 +79,87 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
v.add(quests);
//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()) {
if (f.getName().startsWith("actorconditions_")) {
ActorCondition.fromJson(f, actorConditions);
@@ -212,6 +304,16 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
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) {
if (quests == null) return null;
for (Quest gde : quests) {

View File

@@ -496,6 +496,8 @@ public class Item extends JSONElement {
itemJson.put("id", this.id);
if (this.icon_id != null) itemJson.put("iconID", this.icon_id);
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.base_market_cost != null) itemJson.put("baseMarketCost", this.base_market_cost);
if (this.category != null) {

View File

@@ -35,7 +35,7 @@ public class KeyArea extends MapObject {
oldSchoolRequirement = false;
}
requirement = new Requirement();
requirement.type = Requirement.RequirementType.valueOf(requireType);
if (requireType != null) requirement.type = Requirement.RequirementType.valueOf(requireType);
requirement.required_obj_id = requireId;
if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue);
requirement.state = GameDataElement.State.parsed;
@@ -77,7 +77,9 @@ public class KeyArea extends MapObject {
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.type != null) {
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) {

View File

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

View File

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

View File

@@ -38,6 +38,17 @@ public class TMXMap extends GameDataElement {
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 tiled.core.Map tmxMap = null;
@@ -46,6 +57,7 @@ public class TMXMap extends GameDataElement {
public ProjectTreeNode parent;
public Integer outside = null;
public ColorFilter colorFilter = null;
public boolean writable = false;
@@ -62,8 +74,11 @@ public class TMXMap extends GameDataElement {
usedSpritesheets = new HashSet<Spritesheet>();
try {
tmxMap = new TMXMapReader().readMap(tmxFile.getAbsolutePath(), this);
if (tmxMap.getProperties().get("outside") != null) {
outside = new Integer(((String) tmxMap.getProperties().get("outside")));
if (tmxMap.getProperties().get("outdoors") != null) {
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) {
Notification.addError("Impossible to load TMX map file "+tmxFile.getAbsolutePath());
@@ -97,8 +112,11 @@ public class TMXMap extends GameDataElement {
try {
clone.usedSpritesheets = new HashSet<Spritesheet>();
clone.tmxMap = new TMXMapReader().readMap(new StringReader(this.toXml()), clone);
if (clone.tmxMap.getProperties().get("outside") != null) {
clone.outside = new Integer(((String) clone.tmxMap.getProperties().get("outside")));
if (clone.tmxMap.getProperties().get("outdoors") != null) {
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()) {
if (layer instanceof tiled.core.ObjectGroup) {
@@ -210,6 +228,17 @@ public class TMXMap extends GameDataElement {
}
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) {
group.pushBackToTiledProperties();
if (!tmxMap.containsLayer(group.tmxGroup)) {

View File

@@ -10,11 +10,14 @@ import java.util.List;
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.Type;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
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_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 List<TMXMap> tmxMaps;
@@ -29,7 +37,9 @@ public class TMXMapSet implements ProjectTreeNode {
public TMXMapSet(GameSource 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) {
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
if (!this.mapFolder.exists()) {
@@ -38,7 +48,22 @@ public class TMXMapSet implements ProjectTreeNode {
}
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()) {
if (f.getName().endsWith(".tmx") || f.getName().endsWith(".TMX")) {
TMXMap map = new TMXMap(this, f);

View File

@@ -90,7 +90,9 @@ public class WorldmapSegment extends GameDataElement {
return;
}
for (String mapName : mapLocations.keySet()) {
getProject().getMap(mapName).addBacklink(this);
if (getProject().getMap(mapName) != null) {
getProject().getMap(mapName).addBacklink(this);
}
}
}

View File

@@ -36,7 +36,7 @@ public class AboutEditor extends Editor {
"<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/>" +
"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/>" +
"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/>" +

View File

@@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
@@ -29,6 +30,7 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSpinner.NumberEditor;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.SpinnerNumberModel;
@@ -147,6 +149,51 @@ public abstract class Editor extends JPanel implements ProjectElementListener {
});
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) {
// 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.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
@@ -293,6 +294,7 @@ public class JSONCreationWizard extends JDialog {
creation.id = idField.getText();
JSONCreationWizard.this.setVisible(false);
JSONCreationWizard.this.dispose();
creation.state = State.created;
proj.createElement(creation);
notifyCreated();
ATContentStudio.frame.selectInTree(creation);

View File

@@ -1,5 +1,6 @@
package com.gpl.rpg.atcontentstudio.ui;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
@@ -8,18 +9,26 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
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.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
@@ -30,7 +39,8 @@ public class ProjectCreationWizard extends JDialog {
private static final long serialVersionUID = -2854969975146867119L;
final JTextField projectNameField;
final JComboBox atSourceSelectionCombo;
final JComboBox<String> atSourceSelectionCombo;
final JComboBox<Project.ResourceSet> resourceSetToUse;
final JButton browse;
final JButton okButton;
@@ -42,7 +52,62 @@ public class ProjectCreationWizard extends JDialog {
super(ATContentStudio.frame);
setTitle("Create project");
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...");
okButton = new JButton("Ok");
cancelButton = new JButton("Cancel");
@@ -103,7 +168,7 @@ public class ProjectCreationWizard extends JDialog {
if (!Workspace.activeWorkspace.knownMapSourcesFolders.contains(atSourceFolder)) {
Workspace.activeWorkspace.knownMapSourcesFolders.add(atSourceFolder);
}
Workspace.createProject(projectNameField.getText(), atSourceFolder);
Workspace.createProject(projectNameField.getText(), atSourceFolder, (Project.ResourceSet)resourceSetToUse.getSelectedItem());
ProjectCreationWizard.this.dispose();
}
});
@@ -154,6 +219,17 @@ public class ProjectCreationWizard extends JDialog {
c.weightx = 20;
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();
buttonPane.setLayout(new GridBagLayout());
GridBagConstraints c2 = new GridBagConstraints();

View File

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

View File

@@ -23,6 +23,7 @@ import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
@@ -79,7 +80,7 @@ public class DialogueEditor extends JSONElementEditor {
private static final int SHOP_INDEX = 5;
private JTextField idField;
private JTextField messageField;
private JTextArea messageField;
private MyComboBox switchToNpcBox;
private RewardsListModel rewardsListModel;
@@ -127,7 +128,7 @@ public class DialogueEditor extends JSONElementEditor {
createButtonPane(pane, dialogue.getProject(), dialogue, Dialogue.class, dialogue.getImage(), null, 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);
CollapsiblePanel rewards = new CollapsiblePanel("Reaching this phrase gives the following rewards: ");
@@ -320,8 +321,13 @@ public class DialogueEditor extends JSONElementEditor {
}
if (reward.type != null) {
switch (reward.type) {
case activateMapChangeArea:
case deactivateMapChangeArea:
case activateMapObjectGroup:
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 removeSpawnArea:
case spawnAll:
@@ -717,63 +723,72 @@ public class DialogueEditor extends JSONElementEditor {
JLabel label = ((JLabel)c);
Dialogue.Reward reward = (Dialogue.Reward)value;
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 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");
}
decorateRewardJLabel(label, reward);
}
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 {
@@ -981,19 +996,23 @@ public class DialogueEditor extends JSONElementEditor {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) {
((JLabel)c).setText(((Requirement)value).getDesc());
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.");
}
decorateRequirementJLabel((JLabel)c, (Requirement)value);
}
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 {
@Override
public void valueChanged(JComponent source, Object value) {
@@ -1019,6 +1038,10 @@ public class DialogueEditor extends JSONElementEditor {
} else if (source == rewardTypeCombo) {
if (selectedReward.type != value) {
selectedReward.type = (Dialogue.Reward.RewardType) value;
if (selectedReward.map != null) {
selectedReward.map.removeBacklink(dialogue);
}
selectedReward.map = null;
selectedReward.map_name = null;
selectedReward.reward_obj = null;
selectedReward.reward_obj_id = null;

View File

@@ -1,24 +1,32 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import org.fife.ui.rtextarea.ColorBackgroundPainterStrategy;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
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).setMaxWidth(130);
stagesTable.setCellSelectionEnabled(true);
stagesTable.getColumnModel().getColumn(1).setCellRenderer(new MultilineCellRenderer());
stagesPane.add(new JScrollPane(stagesTable), BorderLayout.CENTER);
if (quest.writable) {
JPanel buttonPane = new JPanel();
@@ -330,6 +339,48 @@ public class QuestEditor extends JSONElementEditor {
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;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
@@ -9,6 +13,12 @@ import java.util.HashMap;
import java.util.Iterator;
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.Visualization;
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.gamedata.Dialogue;
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.gamedataeditors.DialogueEditor;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor.TMXReplacementViewer;
import com.jidesoft.swing.JideBoxLayout;
public class DialogueGraphView extends Display {
@@ -147,6 +161,7 @@ public class DialogueGraphView extends Display {
setSize(500,500);
pan(250, 250);
setHighQuality(true);
addControlListener(new TooltipControl());
addControlListener(new DoubleClickControl());
addControlListener(new WheelZoomControl());
addControlListener(new ZoomControl());
@@ -434,6 +449,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;
}
}

View File

@@ -3,6 +3,7 @@ package com.gpl.rpg.atcontentstudio.ui.map;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -16,9 +17,10 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImageOp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
@@ -42,12 +44,14 @@ import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolTip;
import javax.swing.JTree;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
import javax.swing.ToolTipManager;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
@@ -98,6 +102,7 @@ import com.gpl.rpg.atcontentstudio.ui.Editor;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox;
import com.gpl.rpg.atcontentstudio.ui.ScrollablePanel;
import com.gpl.rpg.atcontentstudio.ui.tools.MatrixComposite;
import com.jidesoft.swing.JideBoxLayout;
import com.jidesoft.swing.JideTabbedPane;
@@ -112,6 +117,7 @@ public class TMXMapEditor extends Editor {
private RSyntaxTextArea editorPane;
private IntegerBasedCheckBox outsideBox;
private JComboBox colorFilterBox;
private LayerListModel layerListModel;
private JList layerList;
private tiled.core.MapLayer selectedLayer;
@@ -121,6 +127,7 @@ public class TMXMapEditor extends Editor {
private JPanel layerDetailsPane;
private BooleanBasedCheckBox layerVisibleBox;
private BooleanBasedCheckBox activeLayerBox;
private JTextField layerNameField;
private MapObjectsListModel groupObjectsListModel;
private JList groupObjectsList;
@@ -143,6 +150,8 @@ public class TMXMapEditor extends Editor {
private JComboBox targetAreaCombo;
private JComboBox evaluateTriggerBox;
private JSpinner quantityField;
private JCheckBox activeForNewGame;
private JTextField spawngroupField;
private JList npcList;
private SpawnGroupNpcListModel npcListModel;
@@ -200,6 +209,7 @@ public class TMXMapEditor extends Editor {
addLabelField(pane, "TMX File: ", ((TMXMap)target).tmxFile.getAbsolutePath());
createButtonPane(pane, map.getProject(), map, listener);
outsideBox = addIntegerBasedCheckBox(pane, "Map is outdoors", map.outside, map.writable, listener);
colorFilterBox = addEnumValueBox(pane, "Color Filter", TMXMap.ColorFilter.values(), map.colorFilter, map.writable, listener);
JSplitPane layersViewSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
layerListModel = new LayerListModel(map);
@@ -303,6 +313,7 @@ public class TMXMapEditor extends Editor {
break;
}
}
activeForNewGame = addBooleanBasedCheckBox(groupDetailPane, "Active for new game", objGroup.active, map.writable, listener);
groupObjectsListModel = new MapObjectsListModel(objGroup);
groupObjectsList = new JList(groupObjectsListModel);
groupObjectsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
@@ -535,15 +546,17 @@ public class TMXMapEditor extends Editor {
} else if (selected instanceof RestArea) {
pane.add(new JLabel("Rest areas have no parameters"), JideBoxLayout.FIX);
areaField = addTextField(pane, "Area ID: ", ((RestArea)selected).name, ((TMXMap)target).writable, listener);
} else if (selected instanceof ScriptArea) {
evaluateTriggerBox = addEnumValueBox(pane, "Evaluate on every: ", ScriptArea.EvaluationTrigger.values(), ((ScriptArea)selected).trigger_type, ((TMXMap)target).writable, listener);
dialogueBox = addDialogueBox(pane, ((TMXMap)target).getProject(), "Script: ", ((ScriptArea)selected).dialogue, ((TMXMap)target).writable, listener);
} else if (selected instanceof SignArea) {
dialogueBox = addDialogueBox(pane, ((TMXMap)target).getProject(), "Message: ", ((SignArea)selected).dialogue, ((TMXMap)target).writable, listener);
} else if (selected instanceof SpawnArea) {
areaField = addTextField(pane, "Spawn group ID: ", ((SpawnArea)selected).name, ((TMXMap)target).writable, listener);
areaField = addTextField(pane, "Spawn area ID: ", ((SpawnArea)selected).name, ((TMXMap)target).writable, listener);
spawngroupField = addTextField(pane, "Spawn group ID: ", ((SpawnArea)selected).spawngroup_id, ((TMXMap)target).writable, listener);
quantityField = addIntegerField(pane, "Number of spawned NPCs: ", ((SpawnArea)selected).quantity, false, ((TMXMap)target).writable, listener);
activeForNewGame = addBooleanBasedCheckBox(pane, "Active in a new game: ", ((SpawnArea)selected).active, ((TMXMap)target).writable, listener);
npcListModel = new SpawnGroupNpcListModel((SpawnArea) selected);
npcList = new JList(npcListModel);
npcList.setCellRenderer(new GDERenderer(true, ((TMXMap)target).writable));
@@ -687,7 +700,7 @@ public class TMXMapEditor extends Editor {
replacementSimulator.setLayout(new JideBoxLayout(replacementSimulator, JideBoxLayout.PAGE_AXIS));
final JCheckBox walkableVisibleBox = new JCheckBox("Show \""+TMXMap.WALKABLE_LAYER_NAME+"\" layer.");
JPanel areasActivationPane = new JPanel();
areasActivationPane.setLayout(new JideBoxLayout(areasActivationPane, JideBoxLayout.LINE_AXIS));
areasActivationPane.setLayout(new JideBoxLayout(areasActivationPane, JideBoxLayout.PAGE_AXIS));
TreeModel areasTreeModel = new ReplaceAreasActivationTreeModel();
final JTree areasTree = new JTree(areasTreeModel);
areasTree.setEditable(false);
@@ -697,10 +710,14 @@ public class TMXMapEditor extends Editor {
final JToggleButton activate = new JToggleButton("Activate ReplaceArea(s)");
areasActivationPane.add(activate, JideBoxLayout.VARY);
final TMXReplacementViewer viewer = new TMXReplacementViewer((TMXMap)target);
JPanel activateAndViewPane = new JPanel();
activateAndViewPane.setLayout(new JideBoxLayout(activateAndViewPane, JideBoxLayout.LINE_AXIS));
activateAndViewPane.add(areasActivationPane, JideBoxLayout.FIX);
activateAndViewPane.add(viewer, JideBoxLayout.VARY);
replacementSimulator.add(walkableVisibleBox, JideBoxLayout.FIX);
replacementSimulator.add(areasActivationPane, JideBoxLayout.FIX);
replacementSimulator.add(viewer, JideBoxLayout.VARY);
replacementSimulator.add(activateAndViewPane, JideBoxLayout.VARY);
walkableVisibleBox.setSelected(true);
walkableVisibleBox.addActionListener(new ActionListener() {
@@ -739,11 +756,14 @@ public class TMXMapEditor extends Editor {
areasTree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
ReplaceArea oldHighlight = viewer.highlighted;
viewer.highlighted = null;
if (areasTree.getSelectionPaths() == null) return;
for (TreePath paths : areasTree.getSelectionPaths()) {
Object target = paths.getLastPathComponent();
if (target instanceof ReplaceArea) {
activate.setSelected(viewer.activeReplacements.get((ReplaceArea) target));
viewer.highlighted = (ReplaceArea)target;
} else if (target instanceof MapObjectGroup) {
for (MapObject obj : ((MapObjectGroup)target).mapObjects) {
activate.setSelected(true);
@@ -754,7 +774,10 @@ public class TMXMapEditor extends Editor {
}
}
}
}
if (oldHighlight != viewer.highlighted) {
viewer.revalidate();
viewer.repaint();
}
}
});
@@ -1223,12 +1246,51 @@ public class TMXMapEditor extends Editor {
}
private static final BufferedImageOp colorFilterBlack20 = null;
private static final BufferedImageOp colorFilterBlack40 = null;
private static final BufferedImageOp colorFilterBlack60 = null;
private static final BufferedImageOp colorFilterBlack80 = null;
private static final BufferedImageOp colorFilterInvert = null;
private static final BufferedImageOp colorFilterBW = null;
// private static final BufferedImageOp colorFilterBlack20 = createGrayScaleColorFilter(0.8f);
// private static final BufferedImageOp colorFilterBlack40 = createGrayScaleColorFilter(0.6f);
// private static final BufferedImageOp colorFilterBlack60 = createGrayScaleColorFilter(0.4f);
// private static final BufferedImageOp colorFilterBlack80 = createGrayScaleColorFilter(0.2f);
// private static final BufferedImageOp colorFilterInvert = createInvertColorFilter();
// private static final BufferedImageOp colorFilterBW = createBWColorFilter();
//
// private static BufferedImageOp createGrayScaleColorFilter(float f) {
// byte[] gs = new byte[256];
// for (int i=0; i < 256; i++) {
// gs[i] = (byte)( i * f);
// }
// return new LookupOp(new ByteLookupTable(0, gs), null);
// }
//
// private static BufferedImageOp createInvertColorFilter() {
// byte[] invert = new byte[256];
// for (int i=0; i < 256; i++) {
// invert[i] = (byte) (255 - i);
// }
// return new LookupOp(new ByteLookupTable(0, invert), null);
// }
//
//
// private static BufferedImageOp createBWColorFilter() {
// return new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
// }
public class TMXViewer extends JPanel implements Scrollable {
private static final long serialVersionUID = 2845032142029325865L;
public tiled.core.MapObject highlighted = null;
private MapRenderer renderer;
private FieldUpdateListener listener;
private TMXMap map;
public boolean resizing = false;
public boolean moving = false;
@@ -1238,7 +1300,8 @@ public class TMXMapEditor extends Editor {
return new Rectangle(selectedMapObject.x + selectedMapObject.w - 16, selectedMapObject.y + selectedMapObject.h - 16, 16, 16);
}
public Rectangle getMoveHitArea() {
public Rectangle getMoveHitArea() {
//16x16 px square in the upper left corner of area
return new Rectangle(selectedMapObject.x, selectedMapObject.y, 16, 16);
}
@@ -1248,22 +1311,10 @@ public class TMXMapEditor extends Editor {
return new Rectangle(obj.x, obj.y, 16, 16);
}
public Point getClosestTileCorner(Point p) {
return new Point(getClosestMultiple(p.x, 32), getClosestMultiple(p.y, 32));
}
public int getClosestMultiple(int num, int ref) {
int rest = num % ref;
int result = num - rest;
if (rest >= ref / 2) {
result += ref;
}
return result;
}
public TMXViewer(final TMXMap map, FieldUpdateListener listener) {
this.listener = listener;
renderer = createRenderer(map.tmxMap);
this.map = map;
setPreferredSize(renderer.getMapSize());
setOpaque(true);
@@ -1377,20 +1428,150 @@ public class TMXMapEditor extends Editor {
public void paintComponent(Graphics g) {
final Graphics2D g2d = (Graphics2D) g.create();
final Rectangle clip = g2d.getClipBounds();
BufferedImageOp filter = null;
if (map.colorFilter != null) {
switch(map.colorFilter) {
case black20:
filter=colorFilterBlack20;
break;
case black40:
filter=colorFilterBlack40;
break;
case black60:
filter=colorFilterBlack60;
break;
case black80:
filter=colorFilterBlack80;
break;
case bw:
filter=colorFilterBW;
break;
case invert:
filter=colorFilterInvert;
break;
default:
break;
}
}
// Draw a gray background
g2d.setPaint(new Color(100, 100, 100));
g2d.fill(clip);
// Draw each tile map layer
boolean paintSelected = false;
for (tiled.core.MapLayer layer : ((TMXMap)target).tmxMap) {
if (layer instanceof tiled.core.TileLayer && layer.isVisible()) {
renderer.paintTileLayer(g2d, (tiled.core.TileLayer) layer);
} else if (layer instanceof tiled.core.ObjectGroup && layer.isVisible()) {
renderer.paintTileLayer(g2d, (tiled.core.TileLayer) layer, filter);
}
}
if (map.colorFilter != null) {
Composite oldComp = g2d.getComposite();
MatrixComposite newComp = null;
float f=0.0f;
switch(map.colorFilter) {
case black20:
f=0.8f;
newComp = new MatrixComposite(new float[]{
f, 0.00f, 0.00f, 0.0f, 0.0f,
0.00f, f, 0.00f, 0.0f, 0.0f,
0.00f, 0.00f, f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case black40:
f=0.6f;
newComp = new MatrixComposite(new float[]{
f, 0.00f, 0.00f, 0.0f, 0.0f,
0.00f, f, 0.00f, 0.0f, 0.0f,
0.00f, 0.00f, f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case black60:
f=0.4f;
newComp = new MatrixComposite(new float[]{
f, 0.00f, 0.00f, 0.0f, 0.0f,
0.00f, f, 0.00f, 0.0f, 0.0f,
0.00f, 0.00f, f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case black80:
f=0.2f;
newComp = new MatrixComposite(new float[]{
f, 0.00f, 0.00f, 0.0f, 0.0f,
0.00f, f, 0.00f, 0.0f, 0.0f,
0.00f, 0.00f, f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case bw:
newComp = new MatrixComposite(new float[]{
0.33f, 0.59f, 0.11f, 0.0f, 0.0f,
0.33f, 0.59f, 0.11f, 0.0f, 0.0f,
0.33f, 0.59f, 0.11f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case invert:
newComp = new MatrixComposite(new float[]{
-1.00f, 0.00f, 0.00f, 0.0f, 255.0f,
0.00f, -1.00f, 0.00f, 0.0f, 255.0f,
0.00f, 0.00f, -1.00f, 0.0f, 255.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case redtint:
newComp = new MatrixComposite(new float[]{
1.20f, 0.20f, 0.20f, 0.0f, 25.0f,
0.00f, 0.80f, 0.00f, 0.0f, 0.0f,
0.00f, 0.00f, 0.80f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case greentint:
newComp = new MatrixComposite(new float[]{
0.85f, 0.00f, 0.00f, 0.0f, 0.0f,
0.15f, 1.15f, 0.15f, 0.0f, 15.0f,
0.00f, 0.00f, 0.85f, 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
case bluetint:
newComp = new MatrixComposite(new float[]{
0.70f, 0.00f, 0.00f, 0.0f, 0.0f,
0.00f, 0.70f, 0.00f, 0.0f, 0.0f,
0.30f, 0.30f, 1.30f, 0.0f, 40.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f
});
break;
default:
break;
}
if (newComp != null) {
g2d.setComposite(newComp);
g2d.setPaint(new Color(1.0f, 1.0f, 1.0f, 1.0f));
g2d.fill(clip);
g2d.setComposite(oldComp);
}
}
// Draw each map object layer
boolean paintSelected = false;
for (tiled.core.MapLayer layer : ((TMXMap)target).tmxMap) {
if (layer instanceof tiled.core.ObjectGroup && layer.isVisible()) {
paintSelected |= paintObjectGroup(g2d, (tiled.core.ObjectGroup) layer);
}
}
if (paintSelected) {
//TODO make this less ugly..... visually speaking.
g2d.setColor(new Color(190, 20, 20));
@@ -1420,27 +1601,7 @@ public class TMXMapEditor extends Editor {
return paintSelected;
}
private void drawObject(MapObject object, Graphics2D g2d, Color color) {
g2d.setPaint(color);
g2d.drawRect(object.x+1, object.y+1, object.w-3, object.h-3);
g2d.drawRect(object.x+2, object.y+2, object.w-5, object.h-5);
g2d.setPaint(color.darker().darker());
g2d.drawLine(object.x, object.y + object.h - 1, object.x + object.w - 1, object.y + object.h - 1);
g2d.drawLine(object.x + object.w - 1, object.y, object.x + object.w - 1, object.y + object.h - 1);
g2d.drawLine(object.x + 3, object.y + 3, object.x + object.w - 4, object.y + 3);
g2d.drawLine(object.x + 3, object.y + 3, object.x + 3, object.y + object.h - 4);
g2d.setPaint(color.brighter().brighter().brighter());
g2d.drawLine(object.x, object.y, object.x + object.w - 1, object.y);
g2d.drawLine(object.x, object.y, object.x, object.y + object.h - 1);
g2d.drawLine(object.x + 3, object.y + object.h - 4, object.x + object.w - 4, object.y + object.h - 4);
g2d.drawLine(object.x + object.w - 4, object.y + 3, object.x + object.w - 4, object.y + object.h - 4);
Image img = object.getIcon();
g2d.setColor(new Color(255, 255, 255, 120));
g2d.fillRect(object.x + 2, object.y + 2, img.getWidth(null), img.getHeight(null));
g2d.drawImage(object.getIcon(), object.x + 2, object.y + 2, null);
}
private MapRenderer createRenderer(tiled.core.Map map) {
private MapRenderer createRenderer(tiled.core.Map map) {
switch (map.getOrientation()) {
case tiled.core.Map.ORIENTATION_ORTHOGONAL:
return new OrthogonalRenderer(map);
@@ -1699,6 +1860,11 @@ public class TMXMapEditor extends Editor {
modified = false;
tmxViewer.revalidate();
tmxViewer.repaint();
} else if (source == activeForNewGame) {
if (selectedLayer instanceof tiled.core.ObjectGroup) {
map.getGroup((tiled.core.ObjectGroup) selectedLayer).active = activeForNewGame.isSelected();
}
modified = true;
} else if (source == layerList) {
modified = false;
tmxViewer.revalidate();
@@ -1708,6 +1874,9 @@ public class TMXMapEditor extends Editor {
tmxViewer.revalidate();
tmxViewer.repaint();
} else if (source == areaField) {
selectedMapObject.name = (String) value;
groupObjectsListModel.objectChanged(selectedMapObject);
} else if (source == spawngroupField) {
if (selectedMapObject instanceof SpawnArea) {
SpawnArea area = (SpawnArea)selectedMapObject;
if (area.spawnGroup != null && !area.spawnGroup.isEmpty()) {
@@ -1715,7 +1884,7 @@ public class TMXMapEditor extends Editor {
npc.removeBacklink(map);
}
}
area.name = (String) value;
area.spawngroup_id = (String) value;
selectedMapObject.link();
npcList.setModel(new SpawnGroupNpcListModel(area));
groupObjectsListModel.objectChanged(area);
@@ -1723,10 +1892,6 @@ public class TMXMapEditor extends Editor {
npcList.repaint();
tmxViewer.revalidate();
tmxViewer.repaint();
} else if (selectedMapObject instanceof MapChange) {
MapChange area = (MapChange) selectedMapObject;
area.name = (String) value;
groupObjectsListModel.objectChanged(area);
}
} else if (source == targetAreaCombo) {
if (selectedMapObject instanceof MapChange) {
@@ -1735,6 +1900,10 @@ public class TMXMapEditor extends Editor {
}
} else if (source == outsideBox) {
map.outside = (Integer)value;
} else if (source == colorFilterBox) {
map.colorFilter = (TMXMap.ColorFilter) value;
tmxViewer.revalidate();
tmxViewer.repaint();
} else if (source == droplistBox) {
if (selectedMapObject instanceof ContainerArea) {
ContainerArea area = (ContainerArea)selectedMapObject;
@@ -1820,6 +1989,11 @@ public class TMXMapEditor extends Editor {
SpawnArea area = (SpawnArea) selectedMapObject;
area.quantity = (Integer) value;
}
} else if (source == activeForNewGame) {
if (selectedMapObject instanceof SpawnArea) {
SpawnArea area = (SpawnArea) selectedMapObject;
area.active = (Boolean) value;
}
} else if (source == requirementTypeCombo) {
if (selectedMapObject instanceof KeyArea) {
KeyArea area = (KeyArea) selectedMapObject;
@@ -1933,6 +2107,8 @@ public class TMXMapEditor extends Editor {
private Map<String, List<ReplaceArea>> replacementsForLayer = new LinkedHashMap<String, List<ReplaceArea>>();
public Map<ReplaceArea, Boolean> activeReplacements = new LinkedHashMap<ReplaceArea, Boolean>();
private boolean tooltipActivated = true;
public TMXReplacementViewer(final TMXMap map) {
this.map = map;
renderer = createRenderer(map.tmxMap);
@@ -1941,6 +2117,30 @@ public class TMXMapEditor extends Editor {
setPreferredSize(renderer.getMapSize());
setOpaque(true);
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
tooltippedTile.setLocation(e.getX() / 32, e.getY() / 32);
if (!((TMXMap)target).tmxMap.contains(tooltippedTile.x, tooltippedTile.y)) {
if (tooltipActivated) {
//Hides the tooltip...
ToolTipManager.sharedInstance().setEnabled(false);
ToolTipManager.sharedInstance().unregisterComponent(TMXReplacementViewer.this);
tooltipActivated = false;
}
} else {
if (!tooltipActivated) {
ToolTipManager.sharedInstance().registerComponent(TMXReplacementViewer.this);
ToolTipManager.sharedInstance().setEnabled(true);
tooltipActivated = true;
}
}
}
});
ToolTipManager.sharedInstance().registerComponent(this);
setToolTipText("");
}
@@ -2029,6 +2229,34 @@ public class TMXMapEditor extends Editor {
final Graphics2D g2d = (Graphics2D) g.create();
final Rectangle clip = g2d.getClipBounds();
BufferedImageOp filter = null;
if (map.colorFilter != null) {
switch(map.colorFilter) {
case black20:
filter=colorFilterBlack20;
break;
case black40:
filter=colorFilterBlack40;
break;
case black60:
filter=colorFilterBlack60;
break;
case black80:
filter=colorFilterBlack80;
break;
case bw:
filter=colorFilterBW;
break;
case invert:
filter=colorFilterInvert;
break;
default:
break;
}
}
// Draw a gray background
g2d.setPaint(new Color(100, 100, 100));
g2d.fill(clip);
@@ -2036,19 +2264,19 @@ public class TMXMapEditor extends Editor {
// Draw each tile map layer
if (ground != null) {
renderer.paintTileLayer(g2d, ground);
renderer.paintTileLayer(g2d, ground, filter);
}
if (objects != null) {
renderer.paintTileLayer(g2d, objects);
renderer.paintTileLayer(g2d, objects, filter);
}
if (above != null) {
renderer.paintTileLayer(g2d, above);
renderer.paintTileLayer(g2d, above, filter);
}
if (walkable != null && showWalkable) {
renderer.paintTileLayer(g2d, walkable);
renderer.paintTileLayer(g2d, walkable, filter);
}
if (highlighted != null) {
@@ -2058,26 +2286,7 @@ public class TMXMapEditor extends Editor {
g2d.dispose();
}
private void drawObject(MapObject object, Graphics2D g2d, Color color) {
g2d.setPaint(color);
g2d.drawRect(object.x+1, object.y+1, object.w-3, object.h-3);
g2d.drawRect(object.x+2, object.y+2, object.w-5, object.h-5);
g2d.setPaint(color.darker().darker());
g2d.drawLine(object.x, object.y + object.h - 1, object.x + object.w - 1, object.y + object.h - 1);
g2d.drawLine(object.x + object.w - 1, object.y, object.x + object.w - 1, object.y + object.h - 1);
g2d.drawLine(object.x + 3, object.y + 3, object.x + object.w - 4, object.y + 3);
g2d.drawLine(object.x + 3, object.y + 3, object.x + 3, object.y + object.h - 4);
g2d.setPaint(color.brighter().brighter().brighter());
g2d.drawLine(object.x, object.y, object.x + object.w - 1, object.y);
g2d.drawLine(object.x, object.y, object.x, object.y + object.h - 1);
g2d.drawLine(object.x + 3, object.y + object.h - 4, object.x + object.w - 4, object.y + object.h - 4);
g2d.drawLine(object.x + object.w - 4, object.y + 3, object.x + object.w - 4, object.y + object.h - 4);
Image img = object.getIcon();
g2d.setColor(new Color(255, 255, 255, 120));
g2d.fillRect(object.x + 2, object.y + 2, img.getWidth(null), img.getHeight(null));
g2d.drawImage(object.getIcon(), object.x + 2, object.y + 2, null);
}
private OrthogonalRenderer createRenderer(tiled.core.Map map) {
return new OrthogonalRenderer(map);
@@ -2113,9 +2322,124 @@ public class TMXMapEditor extends Editor {
public boolean getScrollableTracksViewportHeight() {
return false;
}
JLabel noTileGround = new JLabel(new ImageIcon(DefaultIcons.getNullifyImage().getScaledInstance(32, 32, Image.SCALE_DEFAULT)));
JLabel noTileObjects = new JLabel(new ImageIcon(DefaultIcons.getNullifyImage().getScaledInstance(32, 32, Image.SCALE_DEFAULT)));
JLabel noTileAbove = new JLabel(new ImageIcon(DefaultIcons.getNullifyImage().getScaledInstance(32, 32, Image.SCALE_DEFAULT)));
{
noTileGround.setPreferredSize(new Dimension(32, 32));
noTileObjects.setPreferredSize(new Dimension(32, 32));
noTileAbove.setPreferredSize(new Dimension(32, 32));
}
Point tooltippedTile = new Point();
JToolTip tt = null;
Point lastTTTile = null;
@Override
public JToolTip createToolTip() {
if (tooltippedTile.equals(lastTTTile)) {
return tt;
}
if (!((TMXMap)target).tmxMap.contains(tooltippedTile.x, tooltippedTile.y)) {
return super.createToolTip();
}
tt = super.createToolTip();
lastTTTile = new Point(tooltippedTile);
tt.setLayout(new BorderLayout());
JPanel content = new JPanel();
content.setLayout(new JideBoxLayout(content, JideBoxLayout.PAGE_AXIS));
if (tooltippedTile != null) {
Image tile;
JLabel label;
if (above != null && above.getTileAt(tooltippedTile.x, tooltippedTile.y) != null) {
tile = above.getTileAt(tooltippedTile.x, tooltippedTile.y).getImage();
} else {
tile = null;
}
if (tile != null) {
label = new JLabel(new ImageIcon(tile));
label.setPreferredSize(new Dimension(32,32));
content.add(label, JideBoxLayout.FIX);
} else {
content.add(noTileAbove, JideBoxLayout.FIX);
}
if (objects != null && objects.getTileAt(tooltippedTile.x, tooltippedTile.y) != null) {
tile = objects.getTileAt(tooltippedTile.x, tooltippedTile.y).getImage();
} else {
tile = null;
}
if (tile != null) {
label = new JLabel(new ImageIcon(tile));
label.setPreferredSize(new Dimension(32,32));
content.add(label, JideBoxLayout.FIX);
} else {
content.add(noTileObjects, JideBoxLayout.FIX);
}
if (ground != null && ground.getTileAt(tooltippedTile.x, tooltippedTile.y) != null) {
tile = ground.getTileAt(tooltippedTile.x, tooltippedTile.y).getImage();
} else {
tile = null;
}
if (tile != null) {
label = new JLabel(new ImageIcon(tile));
label.setPreferredSize(new Dimension(32,32));
content.add(label, JideBoxLayout.FIX);
} else {
content.add(noTileGround, JideBoxLayout.FIX);
}
content.add(new JLabel(tooltippedTile.x+", "+tooltippedTile.y), JideBoxLayout.FIX);
}
tt.add(content, BorderLayout.CENTER);
tt.setPreferredSize(tt.getLayout().preferredLayoutSize(tt));
return tt;
}
@Override
public Point getToolTipLocation(MouseEvent event) {
return event.getPoint();//new Point(event.getX() - (event.getX() % 32), event.getY() - (event.getY() % 32));
}
}
public Point getClosestTileCorner(Point p) {
return new Point(getClosestMultiple(p.x, 32), getClosestMultiple(p.y, 32));
}
public int getClosestMultiple(int num, int ref) {
int rest = num % ref;
int result = num - rest;
if (rest >= ref / 2) {
result += ref;
}
return result;
}
private void drawObject(MapObject object, Graphics2D g2d, Color color) {
g2d.setPaint(color);
g2d.drawRect(object.x+1, object.y+1, object.w-3, object.h-3);
g2d.drawRect(object.x+2, object.y+2, object.w-5, object.h-5);
g2d.setPaint(color.darker().darker());
g2d.drawLine(object.x, object.y + object.h - 1, object.x + object.w - 1, object.y + object.h - 1);
g2d.drawLine(object.x + object.w - 1, object.y, object.x + object.w - 1, object.y + object.h - 1);
g2d.drawLine(object.x + 3, object.y + 3, object.x + object.w - 4, object.y + 3);
g2d.drawLine(object.x + 3, object.y + 3, object.x + 3, object.y + object.h - 4);
g2d.setPaint(color.brighter().brighter().brighter());
g2d.drawLine(object.x, object.y, object.x + object.w - 1, object.y);
g2d.drawLine(object.x, object.y, object.x, object.y + object.h - 1);
g2d.drawLine(object.x + 3, object.y + object.h - 4, object.x + object.w - 4, object.y + object.h - 4);
g2d.drawLine(object.x + object.w - 4, object.y + 3, object.x + object.w - 4, object.y + object.h - 4);
Image img = object.getIcon();
g2d.setColor(new Color(255, 255, 255, 120));
g2d.fillRect(object.x + 2, object.y + 2, img.getWidth(null), img.getHeight(null));
g2d.drawImage(object.getIcon(), object.x + 2, object.y + 2, null);
}
}

View File

@@ -102,6 +102,10 @@ public class WorldMapEditor extends Editor {
return pane;
}
public void updateXmlViewText(String text) {
editorPane.setText(text);
}
private JPanel buildSegmentTab(final WorldmapSegment worldmap) {
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) {
if (layer instanceof tiled.core.TileLayer && layer.isVisible()) {
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()) {
// paintObjectGroup(g2, map, (tiled.core.ObjectGroup) layer);
}

View File

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

View File

@@ -18,7 +18,7 @@ public class ItemsTableView extends ElementTableView {
private static final long serialVersionUID = 1474255176349837609L;
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 {
@@ -32,7 +32,7 @@ public class ItemsTableView extends ElementTableView {
@Override
public int getRowCount() {
// return proj.getItemCount() + 1;
return proj.getItemCount();
return proj.getItemCountIncludingAltered();
}
@Override
@@ -130,7 +130,7 @@ public class ItemsTableView extends ElementTableView {
// return getColumnName(columnIndex);
// }
// 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 canEquip = item.category != null && item.category.action_type == ItemCategory.ActionType.equip;
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;
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 {
@@ -30,7 +30,7 @@ public class NPCsTableView extends ElementTableView {
@Override
public int getRowCount() {
return proj.getNPCCount();
return proj.getNPCCountIncludingAltered();
}
@Override
@@ -109,7 +109,7 @@ public class NPCsTableView extends ElementTableView {
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
NPC npc = proj.getNPC(rowIndex);
NPC npc = proj.getNPCIncludingAltered(rowIndex);
switch (columnIndex) {
case 0: return new ImageIcon(npc.getIcon()); // Icon
case 1: return npc.id; //ID