Compare commits

...

7 Commits

Author SHA1 Message Date
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
21 changed files with 708 additions and 147 deletions

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.4.jar;lib\jide-oss.jar;lib\ui.jar;lib\junit-4.10.jar;lib\json_simple-1.1.jar;lib\rsyntaxtextarea.jar;lib\prefuse.jar;lib\AndorsTrainer_v0.1.2.jar;lib\bsh-2.0b4.jar" com.gpl.rpg.atcontentstudio.ATContentStudio

View File

@@ -1,2 +1,2 @@
#!/bin/bash #!/bin/bash
java -Xmx512M -cp lib/AndorsTrainer_v0.1.2.jar:lib/ATCS_v0.4.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.4.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\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.3.jar;lib\AndorsTrainer_v0.1.2.jar;lib\bsh-2.0b4.jar" com.gpl.rpg.atcontentstudio.ATContentStudio

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -171,7 +171,7 @@ public class Dialogue extends JSONElement {
requirement.parent = this; requirement.parent = this;
if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType")); if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType"));
requirement.required_obj_id = (String) requirementJson.get("requireID"); requirement.required_obj_id = (String) requirementJson.get("requireID");
requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString())); if (requirementJson.get("value") != null) requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString()));
if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate"); if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate");
requirement.state = State.parsed; requirement.state = State.parsed;
reply.requirements.add(requirement); reply.requirements.add(requirement);

View File

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

View File

@@ -12,6 +12,7 @@ public class SpawnArea extends MapObject {
public int quantity = 1; public int quantity = 1;
public int spawnchance = 10; public int spawnchance = 10;
public boolean active = true;
public List<NPC> spawnGroup = new ArrayList<NPC>(); public List<NPC> spawnGroup = new ArrayList<NPC>();
public SpawnArea(tiled.core.MapObject obj) { public SpawnArea(tiled.core.MapObject obj) {
@@ -21,6 +22,9 @@ public class SpawnArea extends MapObject {
if (obj.getProperties().getProperty("spawnchance") != null) { if (obj.getProperties().getProperty("spawnchance") != null) {
this.spawnchance = Integer.parseInt(obj.getProperties().getProperty("spawnchance")); this.spawnchance = Integer.parseInt(obj.getProperties().getProperty("spawnchance"));
} }
if (obj.getProperties().getProperty("active") != null) {
this.active = Boolean.parseBoolean(obj.getProperties().getProperty("active"));
}
} }
@Override @Override
@@ -67,6 +71,9 @@ public class SpawnArea extends MapObject {
if (spawnchance != 10) { if (spawnchance != 10) {
tmxObject.getProperties().setProperty("spawnchance", Integer.toString(spawnchance)); tmxObject.getProperties().setProperty("spawnchance", Integer.toString(spawnchance));
} }
if (!this.active) {
tmxObject.getProperties().setProperty("active", Boolean.toString(active));
}
} }
} }

View File

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

View File

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

View File

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

View File

@@ -717,63 +717,67 @@ public class DialogueEditor extends JSONElementEditor {
JLabel label = ((JLabel)c); JLabel label = ((JLabel)c);
Dialogue.Reward reward = (Dialogue.Reward)value; Dialogue.Reward reward = (Dialogue.Reward)value;
if (reward.type != null) { decorateRewardJLabel(label, reward);
String rewardObjDesc = null;
if( reward.reward_obj != null) {
rewardObjDesc = reward.reward_obj.getDesc();
} else if (reward.reward_obj_id != null) {
rewardObjDesc = reward.reward_obj_id;
}
switch (reward.type) {
case activateMapChangeArea:
label.setText("Activate mapchange area "+rewardObjDesc+" on map "+reward.map_name);
break;
case actorCondition:
label.setText("Give actor condition "+rewardObjDesc+" for "+reward.reward_value+" turns");
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case alignmentChange:
label.setText("Change alignment for faction "+rewardObjDesc+" : "+reward.reward_value);
break;
case createTimer:
label.setText("Create timer "+rewardObjDesc);
break;
case deactivateMapChangeArea:
label.setText("Deactivate mapchange area "+rewardObjDesc+" on map "+reward.map_name);
break;
case deactivateSpawnArea:
label.setText("Deactivate spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
break;
case dropList:
label.setText("Give contents of droplist "+rewardObjDesc);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case giveItem:
label.setText("Give "+reward.reward_value+" "+rewardObjDesc);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case questProgress:
label.setText("Give quest progress "+rewardObjDesc+":"+reward.reward_value);
if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon()));
break;
case removeSpawnArea:
label.setText("Remove all monsters in spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
break;
case skillIncrease:
label.setText("Increase skill "+rewardObjDesc+" level");
break;
case spawnAll:
label.setText("Respawn all monsters in spawnarea area "+rewardObjDesc+" on map "+reward.map_name);
break;
}
} else {
label.setText("New, undefined reward");
}
} }
return c; return c;
} }
} }
public static void decorateRewardJLabel(JLabel label, Dialogue.Reward reward) {
if (reward.type != null) {
String rewardObjDesc = null;
if( reward.reward_obj != null) {
rewardObjDesc = reward.reward_obj.getDesc();
} else if (reward.reward_obj_id != null) {
rewardObjDesc = reward.reward_obj_id;
}
switch (reward.type) {
case 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");
}
}
public static class RepliesListModel implements ListModel { public static class RepliesListModel implements ListModel {
@@ -981,19 +985,23 @@ public class DialogueEditor extends JSONElementEditor {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
((JLabel)c).setText(((Requirement)value).getDesc()); decorateRequirementJLabel((JLabel)c, (Requirement)value);
if (((Requirement)value).required_obj != null) {
if (((Requirement)value).required_obj.getIcon() != null) {
((JLabel)c).setIcon(new ImageIcon(((Requirement)value).required_obj.getIcon()));
}
} if (((Requirement)value).type == null) {
((JLabel)c).setText("New, undefined requirement.");
}
} }
return c; return c;
} }
} }
public static void decorateRequirementJLabel(JLabel label, Requirement req) {
label.setText(req.getDesc());
if (req.required_obj != null) {
if (req.required_obj.getIcon() != null) {
label.setIcon(new ImageIcon(req.required_obj.getIcon()));
}
} if (req.type == null) {
label.setText("New, undefined requirement.");
}
}
public class DialogueFieldUpdater implements FieldUpdateListener { public class DialogueFieldUpdater implements FieldUpdateListener {
@Override @Override
public void valueChanged(JComponent source, Object value) { public void valueChanged(JComponent source, Object value) {

View File

@@ -1,7 +1,11 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree; package com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image; import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
@@ -9,6 +13,12 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolTip;
import javax.swing.ToolTipManager;
import prefuse.Display; import prefuse.Display;
import prefuse.Visualization; import prefuse.Visualization;
import prefuse.action.ActionList; import prefuse.action.ActionList;
@@ -42,7 +52,11 @@ import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue; import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC; import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.DialogueEditor;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor.TMXReplacementViewer;
import com.jidesoft.swing.JideBoxLayout;
public class DialogueGraphView extends Display { public class DialogueGraphView extends Display {
@@ -147,6 +161,7 @@ public class DialogueGraphView extends Display {
setSize(500,500); setSize(500,500);
pan(250, 250); pan(250, 250);
setHighQuality(true); setHighQuality(true);
addControlListener(new TooltipControl());
addControlListener(new DoubleClickControl()); addControlListener(new DoubleClickControl());
addControlListener(new WheelZoomControl()); addControlListener(new WheelZoomControl());
addControlListener(new ZoomControl()); addControlListener(new ZoomControl());
@@ -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

@@ -16,6 +16,7 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -42,12 +43,14 @@ import javax.swing.JSpinner;
import javax.swing.JSplitPane; import javax.swing.JSplitPane;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.JToggleButton; import javax.swing.JToggleButton;
import javax.swing.JToolTip;
import javax.swing.JTree; import javax.swing.JTree;
import javax.swing.ListModel; import javax.swing.ListModel;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable; import javax.swing.Scrollable;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.ToolTipManager;
import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener; import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
@@ -143,6 +146,7 @@ public class TMXMapEditor extends Editor {
private JComboBox targetAreaCombo; private JComboBox targetAreaCombo;
private JComboBox evaluateTriggerBox; private JComboBox evaluateTriggerBox;
private JSpinner quantityField; private JSpinner quantityField;
private JCheckBox activeForNewGame;
private JList npcList; private JList npcList;
private SpawnGroupNpcListModel npcListModel; private SpawnGroupNpcListModel npcListModel;
@@ -544,6 +548,7 @@ public class TMXMapEditor extends Editor {
} else if (selected instanceof SpawnArea) { } else if (selected instanceof SpawnArea) {
areaField = addTextField(pane, "Spawn group ID: ", ((SpawnArea)selected).name, ((TMXMap)target).writable, listener); areaField = addTextField(pane, "Spawn group ID: ", ((SpawnArea)selected).name, ((TMXMap)target).writable, listener);
quantityField = addIntegerField(pane, "Number of spawned NPCs: ", ((SpawnArea)selected).quantity, false, ((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); npcListModel = new SpawnGroupNpcListModel((SpawnArea) selected);
npcList = new JList(npcListModel); npcList = new JList(npcListModel);
npcList.setCellRenderer(new GDERenderer(true, ((TMXMap)target).writable)); npcList.setCellRenderer(new GDERenderer(true, ((TMXMap)target).writable));
@@ -687,7 +692,7 @@ public class TMXMapEditor extends Editor {
replacementSimulator.setLayout(new JideBoxLayout(replacementSimulator, JideBoxLayout.PAGE_AXIS)); replacementSimulator.setLayout(new JideBoxLayout(replacementSimulator, JideBoxLayout.PAGE_AXIS));
final JCheckBox walkableVisibleBox = new JCheckBox("Show \""+TMXMap.WALKABLE_LAYER_NAME+"\" layer."); final JCheckBox walkableVisibleBox = new JCheckBox("Show \""+TMXMap.WALKABLE_LAYER_NAME+"\" layer.");
JPanel areasActivationPane = new JPanel(); JPanel areasActivationPane = new JPanel();
areasActivationPane.setLayout(new JideBoxLayout(areasActivationPane, JideBoxLayout.LINE_AXIS)); areasActivationPane.setLayout(new JideBoxLayout(areasActivationPane, JideBoxLayout.PAGE_AXIS));
TreeModel areasTreeModel = new ReplaceAreasActivationTreeModel(); TreeModel areasTreeModel = new ReplaceAreasActivationTreeModel();
final JTree areasTree = new JTree(areasTreeModel); final JTree areasTree = new JTree(areasTreeModel);
areasTree.setEditable(false); areasTree.setEditable(false);
@@ -697,10 +702,14 @@ public class TMXMapEditor extends Editor {
final JToggleButton activate = new JToggleButton("Activate ReplaceArea(s)"); final JToggleButton activate = new JToggleButton("Activate ReplaceArea(s)");
areasActivationPane.add(activate, JideBoxLayout.VARY); areasActivationPane.add(activate, JideBoxLayout.VARY);
final TMXReplacementViewer viewer = new TMXReplacementViewer((TMXMap)target); 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(walkableVisibleBox, JideBoxLayout.FIX);
replacementSimulator.add(areasActivationPane, JideBoxLayout.FIX); replacementSimulator.add(activateAndViewPane, JideBoxLayout.VARY);
replacementSimulator.add(viewer, JideBoxLayout.VARY);
walkableVisibleBox.setSelected(true); walkableVisibleBox.setSelected(true);
walkableVisibleBox.addActionListener(new ActionListener() { walkableVisibleBox.addActionListener(new ActionListener() {
@@ -739,11 +748,14 @@ public class TMXMapEditor extends Editor {
areasTree.addTreeSelectionListener(new TreeSelectionListener() { areasTree.addTreeSelectionListener(new TreeSelectionListener() {
@Override @Override
public void valueChanged(TreeSelectionEvent e) { public void valueChanged(TreeSelectionEvent e) {
ReplaceArea oldHighlight = viewer.highlighted;
viewer.highlighted = null;
if (areasTree.getSelectionPaths() == null) return; if (areasTree.getSelectionPaths() == null) return;
for (TreePath paths : areasTree.getSelectionPaths()) { for (TreePath paths : areasTree.getSelectionPaths()) {
Object target = paths.getLastPathComponent(); Object target = paths.getLastPathComponent();
if (target instanceof ReplaceArea) { if (target instanceof ReplaceArea) {
activate.setSelected(viewer.activeReplacements.get((ReplaceArea) target)); activate.setSelected(viewer.activeReplacements.get((ReplaceArea) target));
viewer.highlighted = (ReplaceArea)target;
} else if (target instanceof MapObjectGroup) { } else if (target instanceof MapObjectGroup) {
for (MapObject obj : ((MapObjectGroup)target).mapObjects) { for (MapObject obj : ((MapObjectGroup)target).mapObjects) {
activate.setSelected(true); activate.setSelected(true);
@@ -754,7 +766,10 @@ public class TMXMapEditor extends Editor {
} }
} }
} }
}
if (oldHighlight != viewer.highlighted) {
viewer.revalidate();
viewer.repaint();
} }
} }
}); });
@@ -1248,19 +1263,6 @@ public class TMXMapEditor extends Editor {
return new Rectangle(obj.x, obj.y, 16, 16); 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) { public TMXViewer(final TMXMap map, FieldUpdateListener listener) {
this.listener = listener; this.listener = listener;
renderer = createRenderer(map.tmxMap); renderer = createRenderer(map.tmxMap);
@@ -1420,27 +1422,7 @@ public class TMXMapEditor extends Editor {
return paintSelected; return paintSelected;
} }
private void drawObject(MapObject object, Graphics2D g2d, Color color) { private MapRenderer createRenderer(tiled.core.Map map) {
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) {
switch (map.getOrientation()) { switch (map.getOrientation()) {
case tiled.core.Map.ORIENTATION_ORTHOGONAL: case tiled.core.Map.ORIENTATION_ORTHOGONAL:
return new OrthogonalRenderer(map); return new OrthogonalRenderer(map);
@@ -1820,6 +1802,11 @@ public class TMXMapEditor extends Editor {
SpawnArea area = (SpawnArea) selectedMapObject; SpawnArea area = (SpawnArea) selectedMapObject;
area.quantity = (Integer) value; area.quantity = (Integer) value;
} }
} else if (source == activeForNewGame) {
if (selectedMapObject instanceof SpawnArea) {
SpawnArea area = (SpawnArea) selectedMapObject;
area.active = (Boolean) value;
}
} else if (source == requirementTypeCombo) { } else if (source == requirementTypeCombo) {
if (selectedMapObject instanceof KeyArea) { if (selectedMapObject instanceof KeyArea) {
KeyArea area = (KeyArea) selectedMapObject; KeyArea area = (KeyArea) selectedMapObject;
@@ -1933,6 +1920,8 @@ public class TMXMapEditor extends Editor {
private Map<String, List<ReplaceArea>> replacementsForLayer = new LinkedHashMap<String, List<ReplaceArea>>(); private Map<String, List<ReplaceArea>> replacementsForLayer = new LinkedHashMap<String, List<ReplaceArea>>();
public Map<ReplaceArea, Boolean> activeReplacements = new LinkedHashMap<ReplaceArea, Boolean>(); public Map<ReplaceArea, Boolean> activeReplacements = new LinkedHashMap<ReplaceArea, Boolean>();
private boolean tooltipActivated = true;
public TMXReplacementViewer(final TMXMap map) { public TMXReplacementViewer(final TMXMap map) {
this.map = map; this.map = map;
renderer = createRenderer(map.tmxMap); renderer = createRenderer(map.tmxMap);
@@ -1941,6 +1930,30 @@ public class TMXMapEditor extends Editor {
setPreferredSize(renderer.getMapSize()); setPreferredSize(renderer.getMapSize());
setOpaque(true); 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("");
} }
@@ -2058,26 +2071,7 @@ public class TMXMapEditor extends Editor {
g2d.dispose(); 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) { private OrthogonalRenderer createRenderer(tiled.core.Map map) {
return new OrthogonalRenderer(map); return new OrthogonalRenderer(map);
@@ -2113,9 +2107,124 @@ public class TMXMapEditor extends Editor {
public boolean getScrollableTracksViewportHeight() { public boolean getScrollableTracksViewportHeight() {
return false; 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; return pane;
} }
public void updateXmlViewText(String text) {
editorPane.setText(text);
}
private JPanel buildSegmentTab(final WorldmapSegment worldmap) { private JPanel buildSegmentTab(final WorldmapSegment worldmap) {
JPanel pane = new JPanel(); JPanel pane = new JPanel();

View File

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

View File

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

View File

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