Compare commits

...

7 Commits

Author SHA1 Message Date
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
26 changed files with 414 additions and 51 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.3.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,2 +1,2 @@
#!/bin/bash
java -Xmx512M -cp lib/AndorsTrainer_v0.1.2.jar:lib/ATCS_v0.4.3.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.6.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.3.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.3"
!define VERSION "0.4.6"
!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.3";
public static final String APP_VERSION = "v0.4.6";
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);
@@ -542,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);

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
}
}
@@ -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);

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

@@ -13,6 +13,7 @@ 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) {
@@ -25,12 +26,17 @@ public class SpawnArea extends MapObject {
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>();
}
@@ -65,6 +71,9 @@ 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));
}

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

@@ -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

@@ -320,8 +320,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:
@@ -732,8 +737,9 @@ public class DialogueEditor extends JSONElementEditor {
rewardObjDesc = reward.reward_obj_id;
}
switch (reward.type) {
case activateMapChangeArea:
label.setText("Activate mapchange area "+rewardObjDesc+" on map "+reward.map_name);
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");
@@ -745,11 +751,13 @@ public class DialogueEditor extends JSONElementEditor {
case createTimer:
label.setText("Create timer "+rewardObjDesc);
break;
case deactivateMapChangeArea:
label.setText("Deactivate mapchange area "+rewardObjDesc+" on map "+reward.map_name);
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);
@@ -765,12 +773,14 @@ public class DialogueEditor extends JSONElementEditor {
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 {
@@ -1027,6 +1037,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

@@ -124,6 +124,7 @@ public class TMXMapEditor extends Editor {
private JPanel layerDetailsPane;
private BooleanBasedCheckBox layerVisibleBox;
private BooleanBasedCheckBox activeLayerBox;
private JTextField layerNameField;
private MapObjectsListModel groupObjectsListModel;
private JList groupObjectsList;
@@ -147,6 +148,7 @@ public class TMXMapEditor extends Editor {
private JComboBox evaluateTriggerBox;
private JSpinner quantityField;
private JCheckBox activeForNewGame;
private JTextField spawngroupField;
private JList npcList;
private SpawnGroupNpcListModel npcListModel;
@@ -307,6 +309,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);
@@ -539,14 +542,15 @@ 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);
@@ -1681,6 +1685,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();
@@ -1690,6 +1699,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()) {
@@ -1697,7 +1709,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);
@@ -1705,10 +1717,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) {

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

@@ -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