Compare commits

...

5 Commits

Author SHA1 Message Date
Zukero
bd8576df0c v0.5.4 released! Keyword is data-protection. Many small bugfixes, but
main changes are:
- Modified marker (* character before name) goes up the project tree by
marking all parents of a modified object as modified.
- Impact management when changing an object's ID. Allows for some
refactoring to occur, while marking the impacted elements as modified,
or aven creating "altered" versions if imapcted element was only in game
source.
2017-04-07 10:01:31 +02:00
Zukero
49f19abb91 Forgot the necessary cleanup of old jars in windows NSIS version. 2017-04-03 17:57:03 +02:00
Zukero
300b7bbbdd Fixed caching issue with spritesheet chooser. Improved actor condition
management for items.
2017-04-03 17:53:44 +02:00
Zukero
bbee5bef25 Bug fix regarding object groups and spawn areas "active in a new game"
parameter.
2017-03-31 09:29:53 +02:00
Zukero
1fc1cef233 Fixed issue with batch scripts being overly painful to use, and have
horrible quoting and escaping rules.
2017-03-06 18:01:05 +01:00
47 changed files with 733 additions and 146 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jardesc>
<jar path="ATContentStudio/ATCS_v0.5.2.jar"/>
<jar path="ATContentStudio/ATCS_v0.5.4.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/ATContentStudio/ATCS_JAR.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>

View File

@@ -1,20 +1,20 @@
@echo off
set ATCS_DIR=%~dp0
set MAX_MEM=512M
set CP=%ATCS_DIR%lib\*
set JAVA=javaw.exe
set JAVA_OPTS=
set ENV_FILE=%ATCS_DIR%ATCS.env.bat
set MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio
set "ATCS_DIR=%~dp0"
set "MAX_MEM=512M"
set "CP=%ATCS_DIR%lib\*"
set "JAVA=javaw.exe"
set "JAVA_OPTS="
set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"
set "MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio"
if exist "%ENV_FILE%" (
call "%ENV_FILE%"
) else (
echo REM set MAX_MEM=%MAX_MEM% > "%ENV_FILE%"
echo REM set JAVA=%JAVA% >> "%ENV_FILE%"
echo REM set JAVA_OPTS=%JAVA_OPTS% >> "%ENV_FILE%"
echo. >> "%ENV_FILE%"
echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"
echo REM set "JAVA=%JAVA%">>"%ENV_FILE%"
echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%"
echo.>>"%ENV_FILE%"
)
start "" "%JAVA%" %JAVA_OPTS% -Xmx%MAX_MEM% -cp "%CP%" %MAIN_CLASS%

View File

@@ -1,20 +1,20 @@
@echo off
set ATCS_DIR=%~dp0
set MAX_MEM=512M
set CP=%ATCS_DIR%lib\*
set JAVA=javaw.exe
set JAVA_OPTS=
set ENV_FILE=%ATCS_DIR%ATCS.env.bat
set MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio
set "ATCS_DIR=%~dp0"
set "MAX_MEM=512M"
set "CP=%ATCS_DIR%lib\*"
set "JAVA=javaw.exe"
set "JAVA_OPTS="
set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"
set "MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio"
if exist "%ENV_FILE%" (
call "%ENV_FILE%"
) else (
echo REM set MAX_MEM=%MAX_MEM% > "%ENV_FILE%"
echo REM set JAVA=%JAVA% >> "%ENV_FILE%"
echo REM set JAVA_OPTS=%JAVA_OPTS% >> "%ENV_FILE%"
echo. >> "%ENV_FILE%"
echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"
echo REM set "JAVA=%JAVA%">>"%ENV_FILE%"
echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%"
echo.>>"%ENV_FILE%"
)
start "" "%JAVA%" %JAVA_OPTS% -Xmx%MAX_MEM% -cp "%CP%" %MAIN_CLASS%

View File

@@ -1,6 +1,6 @@
!include MUI2.nsh
!define VERSION "0.5.2"
!define VERSION "0.5.4"
!define TRAINER_VERSION "0.1.3"
!define JAVA_BIN "javaw"
@@ -55,26 +55,28 @@ Section install
SetOutPath $INSTDIR
file "ATCS.ico"
Delete "$INSTDIR\lib\*"
Call GetJRE
Pop $R0
FileOpen $9 "ATCS.cmd" w
FileWrite $9 '@echo off$\r$\n'
FileWrite $9 '$\r$\n'
FileWrite $9 'set ATCS_DIR=%~dp0$\r$\n'
FileWrite $9 'set MAX_MEM=512M$\r$\n'
FileWrite $9 'set CP=%ATCS_DIR%lib\*$\r$\n'
FileWrite $9 'set JAVA=$R0$\r$\n'
FileWrite $9 'set JAVA_OPTS=$\r$\n'
FileWrite $9 'set ENV_FILE=%ATCS_DIR%ATCS.env.bat$\r$\n'
FileWrite $9 'set MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio$\r$\n'
FileWrite $9 'set "ATCS_DIR=%~dp0"$\r$\n'
FileWrite $9 'set "MAX_MEM=512M"$\r$\n'
FileWrite $9 'set "CP=%ATCS_DIR%lib\*"$\r$\n'
FileWrite $9 'set "JAVA=$R0"$\r$\n'
FileWrite $9 'set "JAVA_OPTS="$\r$\n'
FileWrite $9 'set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"$\r$\n'
FileWrite $9 'set "MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio"$\r$\n'
FileWrite $9 '$\r$\n'
FileWrite $9 'if exist "%ENV_FILE%" ($\r$\n'
FileWrite $9 ' call "%ENV_FILE%"$\r$\n'
FileWrite $9 ') else ($\r$\n'
FileWrite $9 ' echo REM set MAX_MEM=%MAX_MEM% > "%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM set JAVA=%JAVA% >> "%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM set JAVA_OPTS=%JAVA_OPTS% >> "%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo. >> "%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM set "JAVA=%JAVA%">>"%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo.>>"%ENV_FILE%"$\r$\n'
FileWrite $9 ')$\r$\n'
FileWrite $9 '$\r$\n'
FileWrite $9 'start "" "%JAVA%" %JAVA_OPTS% -Xmx%MAX_MEM% -cp "%CP%" %MAIN_CLASS%$\r$\n'

View File

@@ -5,6 +5,8 @@ import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -22,10 +24,13 @@ 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.5.2";
public static final String APP_VERSION = "v0.5.4";
public static boolean STARTED = false;
public static StudioFrame frame = null;
//Need to keep a strong reference to it, to avoid garbage collection that'll reset these loggers.
public static final List<Logger> configuredLoggers = new LinkedList<Logger>();
/**
* @param args
@@ -34,8 +39,6 @@ public class ATContentStudio {
ConfigCache.init();
Logger.getLogger(ExpressionParser.class.getName()).setLevel(Level.OFF);
try {
String laf = ConfigCache.getFavoriteLaFClassName();
if (laf == null) laf = UIManager.getSystemLookAndFeelClassName();
@@ -50,6 +53,10 @@ public class ATContentStudio {
e.printStackTrace();
}
//Need to keep a strong reference to it, to avoid garbage collection that'll reset this setting.
Logger l = Logger.getLogger(ExpressionParser.class.getName());
l.setLevel(Level.OFF);
configuredLoggers.add(l);
final WorkspaceSelector wsSelect = new WorkspaceSelector();
wsSelect.pack();
@@ -69,7 +76,7 @@ public class ATContentStudio {
Workspace.setActive(workspaceRoot);
frame = new StudioFrame(APP_NAME+" "+APP_VERSION);
frame.setVisible(true);
frame.setDefaultCloseOperation(StudioFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(StudioFrame.DO_NOTHING_ON_CLOSE);
};
});
for (File f : ConfigCache.getKnownWorkspaces()) {

View File

@@ -116,4 +116,9 @@ public class ClosedProject implements ProjectTreeNode {
return true;
}
@Override
public boolean needsSaving() {
return false;
}
}

View File

@@ -176,6 +176,10 @@ public abstract class GameDataElement implements ProjectTreeNode, Serializable {
return false;
}
public boolean needsSaving() {
return this.state == State.modified || this.state == State.created;
}
public abstract String getProjectFilename();
public abstract void save();

View File

@@ -213,11 +213,11 @@ public class GameSource implements ProjectTreeNode, Serializable {
@Override
public String getDesc() {
switch(type) {
case altered: return "Altered data";
case created: return "Created data";
case referenced: return "Referenced data";
case source: return "AT Source"; //The fact that it is from "source" is already mentionned by its parent.
default: return "Game data";
case altered: return (needsSaving() ? "*" : "")+"Altered data";
case created: return (needsSaving() ? "*" : "")+"Created data";
case referenced: return (needsSaving() ? "*" : "")+"Referenced data";
case source: return (needsSaving() ? "*" : "")+"AT Source"; //The fact that it is from "source" is already mentionned by its parent.
default: return (needsSaving() ? "*" : "")+"Game data";
}
}
@@ -283,4 +283,12 @@ public class GameSource implements ProjectTreeNode, Serializable {
public WorldmapSegment getWorldmapSegment(String id) {
return worldmap.getWorldmapSegment(id);
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -191,7 +191,7 @@ public class Project implements ProjectTreeNode, Serializable {
}
@Override
public String getDesc() {
return name;
return (needsSaving() ? "*" : "")+name;
}
@@ -265,7 +265,7 @@ public class Project implements ProjectTreeNode, Serializable {
}
}
for (ProjectTreeNode node : baseContent.gameMaps.tmxMaps) {
((TMXMap)node).parse();
((TMXMap)node).link();
}
for (ProjectTreeNode node : alteredContent.gameData.v.getNonEmptyIterable()) {
if (node instanceof GameDataCategory<?>) {
@@ -275,7 +275,7 @@ public class Project implements ProjectTreeNode, Serializable {
}
}
for (ProjectTreeNode node : alteredContent.gameMaps.tmxMaps) {
((TMXMap)node).parse();
((TMXMap)node).link();
}
for (ProjectTreeNode node : createdContent.gameData.v.getNonEmptyIterable()) {
if (node instanceof GameDataCategory<?>) {
@@ -285,9 +285,6 @@ public class Project implements ProjectTreeNode, Serializable {
}
}
for (ProjectTreeNode node : createdContent.gameMaps.tmxMaps) {
((TMXMap)node).parse();
}
for (ProjectTreeNode node : baseContent.gameMaps.tmxMaps) {
((TMXMap)node).link();
}
@@ -665,6 +662,26 @@ public class Project implements ProjectTreeNode, Serializable {
return sheet;
}
public int getSpritesheetCount() {
return createdContent.gameSprites.spritesheets.size() + baseContent.gameSprites.spritesheets.size();
}
public Spritesheet getSpritesheet(int index) {
if (index < createdContent.gameSprites.spritesheets.size()) {
return createdContent.gameSprites.spritesheets.get(index);
} else if (index < getQuestCount()){
return getSpritesheet(baseContent.gameSprites.spritesheets.get(index - createdContent.gameSprites.spritesheets.size()).id);
}
return null;
}
public int getSpritesheetIndex(Spritesheet spritesheet) {
if (spritesheet.getDataType() == GameSource.Type.created) {
return createdContent.gameSprites.spritesheets.indexOf(spritesheet);
} else {
return createdContent.gameSprites.spritesheets.size() + baseContent.gameSprites.spritesheets.indexOf(baseContent.gameSprites.getSpritesheet(spritesheet.id));
}
}
public TMXMap getMap(String id) {
TMXMap map = createdContent.gameMaps.getMap(id);
@@ -1111,6 +1128,13 @@ public class Project implements ProjectTreeNode, Serializable {
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
if (node.needsSaving()) return true;
}
return false;
}

View File

@@ -53,5 +53,7 @@ public interface ProjectTreeNode extends TreeNode {
public GameSource.Type getDataType();
public boolean isEmpty();
public boolean needsSaving();
}

View File

@@ -140,8 +140,15 @@ public class Workspace implements ProjectTreeNode, Serializable {
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
if (projectsTreeModel != null) projectsTreeModel.changeNode(new TreePath(path.toArray()));
ATContentStudio.frame.editorChanged(path.get(path.size() - 1));
ProjectTreeNode last = path.get(path.size() - 1);
if (projectsTreeModel != null) {
while (path.size() > 1) {
projectsTreeModel.changeNode(new TreePath(path.toArray()));
path.remove(path.size()-1);
}
}
ATContentStudio.frame.editorChanged(last);
}
@Override
@@ -346,5 +353,14 @@ public class Workspace implements ProjectTreeNode, Serializable {
public boolean isEmpty() {
return projects.isEmpty();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : projects) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -63,20 +63,14 @@ public class WorkspaceSettings {
reader = new FileReader(f);
@SuppressWarnings("rawtypes")
Map jsonSettings = (Map) parser.parse(reader);
Integer version = (Integer) jsonSettings.get(VERSION_KEY);
Integer version = ((Number) jsonSettings.get(VERSION_KEY)).intValue();
if (version != null) {
if (version >= 1) {
loadv1(jsonSettings);
}
}
} catch (FileNotFoundException e) {
Notification.addError("Error while parsing workspace settings: "+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Notification.addError("Error while parsing workspace settings: "+e.getMessage());
e.printStackTrace();
} catch (ParseException e) {
} catch (Exception e) {
Notification.addError("Error while parsing workspace settings: "+e.getMessage());
e.printStackTrace();
} finally {
@@ -110,7 +104,7 @@ public class WorkspaceSettings {
return;
}
json.put(VERSION_KEY, ATContentStudio.APP_VERSION);
json.put(VERSION_KEY, SETTINGS_VERSION);
StringWriter writer = new JsonPrettyWriter();
try {
JSONObject.writeJSONString(json, writer);

View File

@@ -20,6 +20,8 @@ import com.gpl.rpg.atcontentstudio.model.GameSource;
public class ActorCondition extends JSONElement {
private static final long serialVersionUID = -3969824899972048507L;
public static final Integer CLEAR_AC_MAGNITUDE = -99;
// Available from init state
//public String id; inherited.
@@ -86,7 +88,7 @@ public class ActorCondition extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+display_name+" ("+id+")";
return (needsSaving() ? "*" : "")+display_name+" ("+id+")";
}
@SuppressWarnings("rawtypes")

View File

@@ -92,7 +92,7 @@ public class Dialogue extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+id;
return (needsSaving() ? "*" : "")+id;
}
public static String getStaticDesc() {

View File

@@ -47,7 +47,7 @@ public class Droplist extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+id;
return (needsSaving() ? "*" : "")+id;
}
public static String getStaticDesc() {

View File

@@ -102,7 +102,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
}
@Override
public String getDesc() {
return this.name;
return (needsSaving() ? "*" : "")+this.name;
}
@Override
@@ -208,7 +208,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
impactedCategory = getProject().createdContent.gameData.getCategory(node.getClass());
impactedFileName = node.getProjectFilename();
}
} else if (node.state == GameDataElement.State.modified) {
} else if (node.needsSaving()) {
events.add(new SaveEvent(SaveEvent.Type.alsoSave, node));
}
if (containedIds.containsKey(node.id)) {
@@ -242,5 +242,12 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return result;
}
@Override
public boolean needsSaving() {
for (E node : this) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -236,7 +236,7 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
}
@Override
public String getDesc() {
return "JSON data";
return (needsSaving() ? "*" : "")+"JSON data";
}
@@ -463,4 +463,11 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
return null;
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -102,7 +102,7 @@ public class Item extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+name+" ("+id+")";
return (needsSaving() ? "*" : "")+name+" ("+id+")";
}
public static String getStaticDesc() {

View File

@@ -100,7 +100,7 @@ public class ItemCategory extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+name+" ("+id+")";
return (needsSaving() ? "*" : "")+name+" ("+id+")";
}
public static String getStaticDesc() {

View File

@@ -96,7 +96,7 @@ public class NPC extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+name+" ("+id+")";
return (needsSaving() ? "*" : "")+name+" ("+id+")";
}
public static String getStaticDesc() {

View File

@@ -49,7 +49,7 @@ public class Quest extends JSONElement {
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+name+" ("+id+")";
return (needsSaving() ? "*" : "")+name+" ("+id+")";
}
public static String getStaticDesc() {

View File

@@ -120,6 +120,7 @@ public class Requirement extends JSONElement {
break;
}
if (this.required_obj != null) this.required_obj.addBacklink((GameDataElement) this.parent);
this.state = State.linked;
}
@Override

View File

@@ -62,7 +62,6 @@ public class TMXMap extends GameDataElement {
public Integer outside = null;
public ColorFilter colorFilter = null;
public boolean writable = false;
public boolean changedOnDisk = false;
public int dismissNextChangeNotif = 0;
@@ -129,6 +128,7 @@ public class TMXMap extends GameDataElement {
clone.groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
group.link();
clone.groups.add(group);
}
}
@@ -201,7 +201,7 @@ public class TMXMap extends GameDataElement {
}
@Override
public String getDesc() {
return ((this.state == State.modified || this.state == State.created) ? "*" : "")+id;
return (needsSaving() ? "*" : "")+id;
}
@Override
@@ -315,7 +315,7 @@ public class TMXMap extends GameDataElement {
if (this.state == GameDataElement.State.init) {
parse();
}
if (this.state == GameDataElement.State.parsed || this.state == GameDataElement.State.created) {
if (this.state == GameDataElement.State.parsed) {
if (groups != null) {
for (MapObjectGroup group : groups) {
group.link();

View File

@@ -187,7 +187,7 @@ public class TMXMapSet implements ProjectTreeNode {
}
@Override
public String getDesc() {
return "TMX Maps";
return (needsSaving() ? "*" : "")+"TMX Maps";
}
@Override
@@ -262,4 +262,12 @@ public class TMXMapSet implements ProjectTreeNode {
return tmxMaps.get(index);
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : tmxMaps) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -173,7 +173,7 @@ public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeN
@Override
public String getDesc() {
return "Worldmap";
return (needsSaving() ? "*" : "")+"Worldmap";
}
@Override
public void notifyCreated() {
@@ -277,6 +277,13 @@ public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeN
e.printStackTrace();
}
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : this) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -52,7 +52,7 @@ public class WorldmapSegment extends GameDataElement {
@Override
public String getDesc() {
return id;
return (needsSaving() ? "*" : "")+id;
}
@Override

View File

@@ -97,7 +97,7 @@ public class SavedGame extends GameDataElement {
}
@Override
public String getDesc() {
return loadedSave.displayInfo;
return (needsSaving() ? "*" : "")+loadedSave.displayInfo;
}
@Override

View File

@@ -128,7 +128,7 @@ public class SavedGamesSet implements ProjectTreeNode, Serializable {
}
@Override
public String getDesc() {
return "Saved games";
return (needsSaving() ? "*" : "")+"Saved games";
}
@Override
@@ -168,4 +168,13 @@ public class SavedGamesSet implements ProjectTreeNode, Serializable {
public boolean isEmpty() {
return saves.isEmpty();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : saves) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -102,7 +102,7 @@ public class SpriteSheetSet implements ProjectTreeNode {
}
@Override
public String getDesc() {
return "Spritesheets";
return (needsSaving() ? "*" : "")+"Spritesheets";
}
@Override
@@ -151,4 +151,12 @@ public class SpriteSheetSet implements ProjectTreeNode {
}
return null;
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : spritesheets) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -118,7 +118,7 @@ public class Spritesheet extends GameDataElement {
}
@Override
public String getDesc() {
return spritesheetFile.getName();
return (needsSaving() ? "*" : "")+spritesheetFile.getName();
}
@Override

View File

@@ -413,7 +413,7 @@ public class WriterModeData extends GameDataElement {
@Override
public String getDesc() {
return (this.state == State.modified ? "*" : "")+id;
return (needsSaving() ? "*" : "")+id;
}
@Override
public Project getProject() {

View File

@@ -110,7 +110,7 @@ public class WriterModeDataSet implements ProjectTreeNode, Serializable {
@Override
public String getDesc() {
return "Dialogue sketchs";
return (needsSaving() ? "*" : "")+"Dialogue sketchs";
}
@Override
@@ -195,7 +195,7 @@ public class WriterModeDataSet implements ProjectTreeNode, Serializable {
public List<SaveEvent> attemptSave() {
List<SaveEvent> events = new ArrayList<SaveEvent>();
for (WriterModeData data : writerModeDataList) {
if (data.state == State.created || data.state == State.modified) {
if (data.needsSaving()) {
events.add(new SaveEvent(SaveEvent.Type.alsoSave, data));
}
}
@@ -262,5 +262,14 @@ public class WriterModeDataSet implements ProjectTreeNode, Serializable {
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : writerModeDataList) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -0,0 +1,100 @@
package com.gpl.rpg.atcontentstudio.ui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Vector;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.jidesoft.swing.JideBoxLayout;
public class IdChangeImpactWizard extends JDialog {
private static final long serialVersionUID = 8532169707953315739L;
public static enum Result {
ok, cancel
}
Result result = null;
private IdChangeImpactWizard(GameDataElement changing, List<GameDataElement> toModify, List<GameDataElement> toAlter) {
super(ATContentStudio.frame, true);
JPanel pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS));
pane.add(new JLabel("Changing the id for \""+changing.getDesc()+"\" has impacts on your project:"), JideBoxLayout.FIX);
pane.add(new JLabel("The following elements from your project will be modified:"), JideBoxLayout.FIX);
JList<GameDataElement> modifList = new JList<GameDataElement>(new Vector<GameDataElement>(toModify));
modifList.setCellRenderer(new ChangeImpactListCellRenderer());
pane.add(new JScrollPane(modifList), JideBoxLayout.FIX);
pane.add(new JLabel("The following elements from the game source will be altered:"), JideBoxLayout.FIX);
JList<GameDataElement> alterList = new JList<GameDataElement>(new Vector<GameDataElement>(toAlter));
alterList.setCellRenderer(new ChangeImpactListCellRenderer());
pane.add(new JScrollPane(alterList), JideBoxLayout.FIX);
pane.add(new JLabel("Press Ok to apply the changes, or Cancel to cancel your edition of the object's ID"), JideBoxLayout.FIX);
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
result = Result.cancel;
dispose();
}
});
buttonPane.add(cancelButton, JideBoxLayout.FIX);
JButton okButton = new JButton("Ok");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
result = Result.ok;
dispose();
}
});
buttonPane.add(okButton, JideBoxLayout.FIX);
pane.add(buttonPane, JideBoxLayout.FIX);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
pack();
}
public static Result showIdChangeImapctWizard(GameDataElement changing, List<GameDataElement> toModify, List<GameDataElement> toAlter) {
IdChangeImpactWizard wizard = new IdChangeImpactWizard(changing, toModify, toAlter);
wizard.setVisible(true);
return wizard.result;
}
public class ChangeImpactListCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 5764079243906396333L;
@Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) {
JLabel label = (JLabel) c;
GameDataElement target = ((GameDataElement)value);
label.setIcon(new ImageIcon(target.getIcon()));
label.setText(target.getDataType().toString()+"/"+target.getDesc());
}
return c;
}
}
}

View File

@@ -118,6 +118,7 @@ public class StudioFrame extends JFrame {
@Override
public void windowClosing(WindowEvent e) {
Workspace.saveActive();
actions.exitATCS.actionPerformed(null);
}
});
}

View File

@@ -95,14 +95,14 @@ public class WorkspaceActions {
public void actionPerformed(ActionEvent e) {
if (!(selectedNode instanceof GameDataElement)) return;
final GameDataElement node = ((GameDataElement)selectedNode);
if (node.state == GameDataElement.State.modified){
if (node.needsSaving()){
node.save();
ATContentStudio.frame.nodeChanged(node);
}
};
public void selectionChanged(ProjectTreeNode selectedNode, TreePath[] selectedPaths) {
if (selectedNode instanceof GameDataElement) {
setEnabled(((GameDataElement)selectedNode).state == GameDataElement.State.modified);
setEnabled(((GameDataElement)selectedNode).needsSaving());
} else {
setEnabled(false);
}
@@ -330,8 +330,14 @@ public class WorkspaceActions {
public ATCSAction exitATCS = new ATCSAction("Exit", "Closes the program"){
public void actionPerformed(ActionEvent e) {
//TODO ouch.
System.exit(0);
if (Workspace.activeWorkspace.needsSaving()) {
int answer = JOptionPane.showConfirmDialog(ATContentStudio.frame, "There are unsaved changes in your workspace.\nExiting ATCS will discard these changes.\nDo you really want to exit?", "Unsaved changes. Confirm exit.", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION) {
System.exit(0);
}
} else {
System.exit(0);
}
};
};

View File

@@ -147,10 +147,22 @@ public class ActorConditionEditor extends JSONElementEditor {
public void valueChanged(JComponent source, Object value) {
ActorCondition aCond = (ActorCondition)target;
if (source == idField) {
aCond.id = (String) value;
ActorConditionEditor.this.name = aCond.getDesc();
aCond.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ActorConditionEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
aCond.id = (String) value;
ActorConditionEditor.this.name = aCond.getDesc();
aCond.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ActorConditionEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == nameField) {
aCond.display_name = (String) value;
ActorConditionEditor.this.name = aCond.getDesc();

View File

@@ -1075,10 +1075,22 @@ public class DialogueEditor extends JSONElementEditor {
public void valueChanged(JComponent source, Object value) {
Dialogue dialogue = (Dialogue) target;
if (source == idField) {
dialogue.id = (String) value;
DialogueEditor.this.name = dialogue.getDesc();
dialogue.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DialogueEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
dialogue.id = (String) value;
DialogueEditor.this.name = dialogue.getDesc();
dialogue.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DialogueEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == messageField) {
dialogue.message = (String) value;
} else if (source == switchToNpcBox) {

View File

@@ -248,10 +248,22 @@ public class DroplistEditor extends JSONElementEditor {
public void valueChanged(JComponent source, Object value) {
Droplist droplist = ((Droplist)target);
if (source == idField) {
droplist.id = (String) value;
DroplistEditor.this.name = droplist.getDesc();
droplist.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DroplistEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
droplist.id = (String) value;
DroplistEditor.this.name = droplist.getDesc();
droplist.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DroplistEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == itemCombo) {
if (selectedItem.item != null) {
selectedItem.item.removeBacklink(droplist);

View File

@@ -87,10 +87,22 @@ public class ItemCategoryEditor extends JSONElementEditor {
public void valueChanged(JComponent source, Object value) {
ItemCategory ic = (ItemCategory)target;
if (source == idField) {
ic.id = (String) value;
ItemCategoryEditor.this.name = ic.getDesc();
ic.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ItemCategoryEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
ic.id = (String) value;
ItemCategoryEditor.this.name = ic.getDesc();
ic.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ItemCategoryEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == nameField) {
ic.name = (String) value;
ItemCategoryEditor.this.name = ic.getDesc();

View File

@@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@@ -15,6 +16,7 @@ import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;
@@ -98,6 +100,8 @@ public class ItemEditor extends JSONElementEditor {
@SuppressWarnings("rawtypes")
private JList hitSourceConditionsList;
private MyComboBox hitSourceConditionBox;
private JRadioButton hitSourceConditionClear;
private JRadioButton hitSourceConditionApply;
private JSpinner hitSourceConditionMagnitude;
private JSpinner hitSourceConditionDuration;
private JSpinner hitSourceConditionChance;
@@ -105,6 +109,8 @@ public class ItemEditor extends JSONElementEditor {
@SuppressWarnings("rawtypes")
private JList hitTargetConditionsList;
private MyComboBox hitTargetConditionBox;
private JRadioButton hitTargetConditionClear;
private JRadioButton hitTargetConditionApply;
private JSpinner hitTargetConditionMagnitude;
private JSpinner hitTargetConditionDuration;
private JSpinner hitTargetConditionChance;
@@ -119,6 +125,8 @@ public class ItemEditor extends JSONElementEditor {
@SuppressWarnings("rawtypes")
private JList killSourceConditionsList;
private MyComboBox killSourceConditionBox;
private JRadioButton killSourceConditionClear;
private JRadioButton killSourceConditionApply;
private JSpinner killSourceConditionMagnitude;
private JSpinner killSourceConditionDuration;
private JSpinner killSourceConditionChance;
@@ -461,55 +469,169 @@ public class ItemEditor extends JSONElementEditor {
}
public void updateHitSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, FieldUpdateListener listener) {
public void updateHitSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll();
if (hitSourceConditionBox != null) {
removeElementListener(hitSourceConditionBox);
}
if (condition == null) {
pane.revalidate();
pane.repaint();
return;
}
boolean writable = ((Item)target).writable;
Project proj = ((Item)target).getProject();
hitSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener);
hitSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude, false, writable, listener);
hitSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener);
hitSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener);
hitSourceConditionApply = new JRadioButton("Apply new condition");
pane.add(hitSourceConditionApply, JideBoxLayout.FIX);
hitSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, false, writable, listener);
hitSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener);
hitSourceConditionClear = new JRadioButton("Clear active condition");
pane.add(hitSourceConditionClear, JideBoxLayout.FIX);
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(hitSourceConditionApply);
radioGroup.add(hitSourceConditionClear);
if (condition != null && condition.magnitude != null && condition.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) {
hitSourceConditionClear.setSelected(true);
hitSourceConditionApply.setSelected(false);
hitSourceConditionMagnitude.setEnabled(false);
hitSourceConditionDuration.setEnabled(false);
} else {
hitSourceConditionClear.setSelected(false);
hitSourceConditionApply.setSelected(true);
hitSourceConditionMagnitude.setEnabled(true);
hitSourceConditionDuration.setEnabled(true);
}
hitSourceConditionClear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listener.valueChanged(hitSourceConditionClear, new Boolean(hitSourceConditionClear.isSelected()));
}
});
hitSourceConditionApply.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listener.valueChanged(hitSourceConditionApply, new Boolean(hitSourceConditionApply.isSelected()));
}
});
pane.revalidate();
pane.repaint();
}
public void updateHitTargetTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, FieldUpdateListener listener) {
public void updateHitTargetTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll();
if (hitTargetConditionBox != null) {
removeElementListener(hitTargetConditionBox);
}
if (condition == null) {
pane.revalidate();
pane.repaint();
return;
}
boolean writable = ((Item)target).writable;
Project proj = ((Item)target).getProject();
hitTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener);
hitTargetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude, false, writable, listener);
hitTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener);
hitTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener);
hitTargetConditionApply = new JRadioButton("Apply new condition");
pane.add(hitTargetConditionApply, JideBoxLayout.FIX);
hitTargetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, false, writable, listener);
hitTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener);
hitTargetConditionClear = new JRadioButton("Clear active condition");
pane.add(hitTargetConditionClear, JideBoxLayout.FIX);
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(hitTargetConditionApply);
radioGroup.add(hitTargetConditionClear);
if (condition != null && condition.magnitude != null && condition.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) {
hitTargetConditionClear.setSelected(true);
hitTargetConditionApply.setSelected(false);
hitTargetConditionMagnitude.setEnabled(false);
hitTargetConditionDuration.setEnabled(false);
} else {
hitTargetConditionClear.setSelected(false);
hitTargetConditionApply.setSelected(true);
hitTargetConditionMagnitude.setEnabled(true);
hitTargetConditionDuration.setEnabled(true);
}
hitTargetConditionClear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listener.valueChanged(hitTargetConditionClear, new Boolean(hitTargetConditionClear.isSelected()));
}
});
hitTargetConditionApply.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listener.valueChanged(hitTargetConditionApply, new Boolean(hitTargetConditionApply.isSelected()));
}
});
pane.revalidate();
pane.repaint();
}
public void updateKillSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, FieldUpdateListener listener) {
public void updateKillSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll();
if (killSourceConditionBox != null) {
removeElementListener(killSourceConditionBox);
}
if (condition == null) {
pane.revalidate();
pane.repaint();
return;
}
boolean writable = ((Item)target).writable;
Project proj = ((Item)target).getProject();
killSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener);
killSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude, false, writable, listener);
killSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener);
killSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener);
killSourceConditionApply = new JRadioButton("Apply new condition");
pane.add(killSourceConditionApply, JideBoxLayout.FIX);
killSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, false, writable, listener);
killSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener);
killSourceConditionClear = new JRadioButton("Clear active condition");
pane.add(killSourceConditionClear, JideBoxLayout.FIX);
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(killSourceConditionApply);
radioGroup.add(killSourceConditionClear);
if (condition != null && condition.magnitude != null && condition.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) {
killSourceConditionClear.setSelected(true);
killSourceConditionApply.setSelected(false);
killSourceConditionMagnitude.setEnabled(false);
killSourceConditionDuration.setEnabled(false);
} else {
killSourceConditionClear.setSelected(false);
killSourceConditionApply.setSelected(true);
killSourceConditionMagnitude.setEnabled(true);
killSourceConditionDuration.setEnabled(true);
}
killSourceConditionClear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listener.valueChanged(killSourceConditionClear, new Boolean(killSourceConditionClear.isSelected()));
}
});
killSourceConditionApply.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
listener.valueChanged(killSourceConditionApply, new Boolean(killSourceConditionApply.isSelected()));
}
});
pane.revalidate();
pane.repaint();
}
@@ -519,6 +641,11 @@ public class ItemEditor extends JSONElementEditor {
if (equipConditionBox != null) {
removeElementListener(equipConditionBox);
}
if (condition == null) {
pane.revalidate();
pane.repaint();
return;
}
boolean writable = ((Item)target).writable;
Project proj = ((Item)target).getProject();
@@ -666,7 +793,11 @@ public class ItemEditor extends JSONElementEditor {
if (effect.condition != null) {
label.setIcon(new ImageIcon(effect.condition.getIcon()));
label.setText(effect.chance+"% chances to give "+effect.duration+" rounds of "+effect.condition.getDesc()+" x"+effect.magnitude);
if (effect.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) {
label.setText(effect.chance+"% chances to clear "+effect.condition.getDesc());
} else {
label.setText(effect.chance+"% chances to give "+effect.duration+" rounds of "+effect.condition.getDesc()+" x"+effect.magnitude);
}
} else {
label.setText("New, undefined actor condition effect.");
}
@@ -805,10 +936,22 @@ public class ItemEditor extends JSONElementEditor {
boolean updatePrice, updateEquip, updateHit, updateKill;
updatePrice = updateEquip = updateHit = updateKill = false;
if (source == idField) {
item.id = (String) value;
ItemEditor.this.name = item.getDesc();
item.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ItemEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
item.id = (String) value;
ItemEditor.this.name = item.getDesc();
item.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ItemEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == nameField) {
item.name = (String) value;
ItemEditor.this.name = item.getDesc();
@@ -984,6 +1127,20 @@ public class ItemEditor extends JSONElementEditor {
}
hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition);
updateHit = true;
} else if (source == hitSourceConditionClear) {
selectedHitEffectSourceCondition.magnitude = ActorCondition.CLEAR_AC_MAGNITUDE;
selectedHitEffectSourceCondition.duration = null;
hitSourceConditionMagnitude.setEnabled(false);
hitSourceConditionDuration.setEnabled(false);
hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition);
updateHit = true;
} else if (source == hitSourceConditionApply) {
selectedHitEffectSourceCondition.magnitude = 0;
selectedHitEffectSourceCondition.duration = 0;
hitSourceConditionMagnitude.setEnabled(true);
hitSourceConditionDuration.setEnabled(true);
hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition);
updateHit = true;
} else if (source == hitSourceConditionMagnitude) {
selectedHitEffectSourceCondition.magnitude = (Integer) value;
hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition);
@@ -1011,6 +1168,20 @@ public class ItemEditor extends JSONElementEditor {
}
hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition);
updateHit = true;
} else if (source == hitTargetConditionClear) {
selectedHitEffectTargetCondition.magnitude = ActorCondition.CLEAR_AC_MAGNITUDE;
selectedHitEffectTargetCondition.duration = null;
hitTargetConditionMagnitude.setEnabled(false);
hitTargetConditionDuration.setEnabled(false);
hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition);
updateHit = true;
} else if (source == hitTargetConditionApply) {
selectedHitEffectTargetCondition.magnitude = 0;
selectedHitEffectTargetCondition.duration = 0;
hitTargetConditionMagnitude.setEnabled(true);
hitTargetConditionDuration.setEnabled(true);
hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition);
updateHit = true;
} else if (source == hitTargetConditionMagnitude) {
selectedHitEffectTargetCondition.magnitude = (Integer) value;
hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition);
@@ -1054,6 +1225,20 @@ public class ItemEditor extends JSONElementEditor {
}
killSourceConditionsModel.itemChanged(selectedKillEffectCondition);
updateKill = true;
} else if (source == killSourceConditionClear) {
selectedKillEffectCondition.magnitude = ActorCondition.CLEAR_AC_MAGNITUDE;
selectedKillEffectCondition.duration = null;
killSourceConditionMagnitude.setEnabled(false);
killSourceConditionDuration.setEnabled(false);
killSourceConditionsModel.itemChanged(selectedKillEffectCondition);
updateKill = true;
} else if (source == killSourceConditionApply) {
selectedKillEffectCondition.magnitude = 0;
selectedKillEffectCondition.duration = 0;
killSourceConditionMagnitude.setEnabled(true);
killSourceConditionDuration.setEnabled(true);
killSourceConditionsModel.itemChanged(selectedKillEffectCondition);
updateKill = true;
} else if (source == killSourceConditionMagnitude) {
selectedKillEffectCondition.magnitude = (Integer) value;
killSourceConditionsModel.itemChanged(selectedKillEffectCondition);

View File

@@ -6,6 +6,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -14,6 +15,8 @@ import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
@@ -26,10 +29,13 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataCategory;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.Editor;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.IdChangeImpactWizard;
import com.gpl.rpg.atcontentstudio.ui.SaveItemsWizard;
import com.gpl.rpg.atcontentstudio.ui.sprites.SpriteChooser;
import com.jidesoft.swing.JideBoxLayout;
@@ -275,4 +281,64 @@ public abstract class JSONElementEditor extends Editor {
message.revalidate();
message.repaint();
}
public boolean idChanging() {
JSONElement node = (JSONElement) target;
List<GameDataElement> toModify = new LinkedList<GameDataElement>();
List<GameDataElement> toAlter = new LinkedList<GameDataElement>();
for (GameDataElement element : node.getBacklinks()) {
GameDataElement activeElement = element;
if (element instanceof JSONElement) {
activeElement = node.getProject().getGameDataElement((Class<? extends JSONElement>) element.getClass(), element.id);
} else if (element instanceof TMXMap) {
activeElement = node.getProject().getMap(element.id);
} else if (element instanceof WorldmapSegment) {
activeElement = node.getProject().getWorldmapSegment(element.id);
}
if (activeElement.writable) {
//No need to alter. Check if we flag a new modification.
if (!activeElement.needsSaving()) {
toModify.add(activeElement);
}
} else {
toAlter.add(activeElement);
}
}
if (!(toModify.isEmpty() && toAlter.isEmpty())) {
IdChangeImpactWizard.Result result = IdChangeImpactWizard.showIdChangeImapctWizard(target, toModify, toAlter);
if (result == IdChangeImpactWizard.Result.ok) {
for (GameDataElement element : toModify) {
element.state = GameDataElement.State.modified;
element.childrenChanged(new ArrayList<ProjectTreeNode>());
}
for (GameDataElement element : toAlter) {
if (element instanceof JSONElement) {
node.getProject().makeWritable((JSONElement)element);
} else if (element instanceof TMXMap) {
node.getProject().makeWritable((TMXMap)element);
} else if (element instanceof WorldmapSegment) {
node.getProject().makeWritable((WorldmapSegment)element);
}
}
return true;
}
} else {
return true;
}
return false;
}
//setText in cancelIdEdit generates to edit events, one replacing the contents with the empty string, and one with the target.id. We want to skip the first one.
public boolean skipNext = false;
public void cancelIdEdit(final JTextField idField) {
Runnable revertField = new Runnable(){
@Override
public void run() {
skipNext = true;
idField.setText(target.id);
}
};
SwingUtilities.invokeLater(revertField);
}
}

View File

@@ -166,7 +166,7 @@ public class NPCEditor extends JSONElementEditor {
public void insertFormViewDataField(JPanel pane) {
final NPC npc = (NPC) target;
final FieldUpdateListener listener = new NPCFieldUpdate();
final FieldUpdateListener listener = new NPCFieldUpdater();
npcIcon = createButtonPane(pane, npc.getProject(), npc, NPC.class, npc.getImage(), Spritesheet.Category.monster, listener);
@@ -504,17 +504,29 @@ public class NPCEditor extends JSONElementEditor {
return true;
}
public class NPCFieldUpdate implements FieldUpdateListener {
public class NPCFieldUpdater implements FieldUpdateListener {
@Override
public void valueChanged(JComponent source, Object value) {
NPC npc = (NPC)target;
boolean updateHit = false;
if (source == idField) {
npc.id = (String) value;
NPCEditor.this.name = npc.getDesc();
npc.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(NPCEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
npc.id = (String) value;
NPCEditor.this.name = npc.getDesc();
npc.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(NPCEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == nameField) {
npc.name = (String) value;
NPCEditor.this.name = npc.getDesc();

View File

@@ -314,10 +314,22 @@ public class QuestEditor extends JSONElementEditor {
public void valueChanged(JComponent source, Object value) {
Quest quest = (Quest) target;
if (source == idField) {
quest.id = (String) value;
QuestEditor.this.name = quest.getDesc();
quest.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(QuestEditor.this);
//Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
skipNext = false;
return;
}
if (target.id.equals((String) value)) return;
if (idChanging()) {
quest.id = (String) value;
QuestEditor.this.name = quest.getDesc();
quest.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(QuestEditor.this);
} else {
cancelIdEdit(idField);
return;
}
} else if (source == nameField) {
quest.name = (String) value;
QuestEditor.this.name = quest.getDesc();

View File

@@ -131,7 +131,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
private JPanel layerDetailsPane;
private BooleanBasedCheckBox layerVisibleBox;
//private BooleanBasedCheckBox activeLayerBox;
private JCheckBox groupActiveForNewGame;
private JTextField layerNameField;
private MapObjectsListModel groupObjectsListModel;
@SuppressWarnings("rawtypes")
@@ -160,7 +160,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
@SuppressWarnings("rawtypes")
private JComboBox evaluateTriggerBox;
private JSpinner quantityField;
private JCheckBox activeForNewGame;
private JCheckBox spawnActiveForNewGame;
private JTextField spawngroupField;
@SuppressWarnings("rawtypes")
private JList npcList;
@@ -332,7 +332,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
break;
}
}
activeForNewGame = addBooleanBasedCheckBox(groupDetailPane, "Active for new game", objGroup.active, map.writable, listener);
groupActiveForNewGame = addBooleanBasedCheckBox(groupDetailPane, "Active for new game", objGroup.active, map.writable, listener);
groupObjectsListModel = new MapObjectsListModel(objGroup);
groupObjectsList = new JList(groupObjectsListModel);
groupObjectsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
@@ -576,7 +576,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
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);
spawnActiveForNewGame = addBooleanBasedCheckBox(pane, "Active in a new game: ", ((SpawnArea)selected).active, ((TMXMap)target).writable, listener);
npcListModel = new SpawnGroupNpcListModel((SpawnArea) selected);
npcList = new JList(npcListModel);
npcList.setCellRenderer(new GDERenderer(true, ((TMXMap)target).writable));
@@ -1615,7 +1615,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
gdeIcon.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (map.state == GameDataElement.State.modified || map.state == GameDataElement.State.created) {
if (map.needsSaving()) {
int confirm = JOptionPane.showConfirmDialog(TMXMapEditor.this, "You have unsaved changes in ATCS.\nYou'd better save your changes in ATCS before opening this map with the external editor.\nDo you want to save before opening the file?", "Save before opening?", JOptionPane.YES_NO_CANCEL_OPTION);
if (confirm == JOptionPane.CANCEL_OPTION) return;
if (confirm == JOptionPane.YES_OPTION) {
@@ -1633,7 +1633,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
@Override
public void actionPerformed(ActionEvent e) {
if (map.state == GameDataElement.State.modified) {
if (map.needsSaving()) {
int confirm = JOptionPane.showConfirmDialog(TMXMapEditor.this, "You modified this map in ATCS. All ATCS-made changes will be lost if you confirm.\n On the other hand, if you save using ATCS, all external changes will be lost.\n Do you want to reload?", "Confirm reload?", JOptionPane.OK_CANCEL_OPTION);
if (confirm == JOptionPane.CANCEL_OPTION) return;
}
@@ -1775,9 +1775,9 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
modified = false;
tmxViewer.revalidate();
tmxViewer.repaint();
} else if (source == activeForNewGame) {
} else if (source == groupActiveForNewGame) {
if (selectedLayer instanceof tiled.core.ObjectGroup) {
map.getGroup((tiled.core.ObjectGroup) selectedLayer).active = activeForNewGame.isSelected();
map.getGroup((tiled.core.ObjectGroup) selectedLayer).active = groupActiveForNewGame.isSelected();
}
modified = true;
} else if (source == layerList) {
@@ -1904,7 +1904,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
SpawnArea area = (SpawnArea) selectedMapObject;
area.quantity = (Integer) value;
}
} else if (source == activeForNewGame) {
} else if (source == spawnActiveForNewGame) {
if (selectedMapObject instanceof SpawnArea) {
SpawnArea area = (SpawnArea) selectedMapObject;
area.active = (Boolean) value;

View File

@@ -63,7 +63,8 @@ public class WorldMapEditor extends Editor {
public String mapBeingAddedID = null;
public String selectedLabel = null;
WorldMapView mapView = null;
public WorldMapEditor(WorldmapSegment worldmap) {
target = worldmap;
this.name = worldmap.id;
@@ -114,7 +115,7 @@ public class WorldMapEditor extends Editor {
addLabelField(pane, "Worldmap File: ", ((Worldmap)worldmap.getParent()).worldmapFile.getAbsolutePath());
pane.add(createButtonPane(worldmap), JideBoxLayout.FIX);
final WorldMapView mapView = new WorldMapView(worldmap);
mapView = new WorldMapView(worldmap);
JScrollPane mapScroller = new JScrollPane(mapView);
final JViewport vPort = mapScroller.getViewport();
@@ -296,6 +297,7 @@ public class WorldMapEditor extends Editor {
for (String s : mapView.selected) {
map.labelledMaps.get(selectedLabel).add(s);
}
notifyModelModified();
mapView.revalidate();
mapView.repaint();
}
@@ -319,6 +321,7 @@ public class WorldMapEditor extends Editor {
worldmap.labels.put(created.id, created);
worldmap.labels.remove(selectedLabel);
selectedLabel = created.id;
notifyModelModified();
mapView.revalidate();
mapView.repaint();
}
@@ -334,6 +337,7 @@ public class WorldMapEditor extends Editor {
worldmap.labelledMaps.remove(selectedLabel);
worldmap.labels.remove(selectedLabel);
selectedLabel = null;
notifyModelModified();
mapView.revalidate();
mapView.repaint();
}
@@ -348,6 +352,7 @@ public class WorldMapEditor extends Editor {
public void labelCreated(NamedArea created) {
worldmap.labelledMaps.put(created.id, new ArrayList<String>());
worldmap.labelledMaps.get(created.id).addAll(mapView.selected);
notifyModelModified();
mapView.revalidate();
mapView.repaint();
}
@@ -436,11 +441,12 @@ public class WorldMapEditor extends Editor {
mapView.selected.remove(selectedMap);
mapSelectionChanged();
mapView.updateFromModel();
notifyModelModified();
update = true;
} else if (editMode == EditMode.addMap && mapBeingAddedID != null) {
if (e.getButton() == MouseEvent.BUTTON1) {
mapView.recomputeSize();
mapView.pushToModel();
pushToModel();
}
mapView.updateFromModel();
update = true;
@@ -463,7 +469,7 @@ public class WorldMapEditor extends Editor {
public void mouseReleased(MouseEvent e) {
dragStart = null;
if (editMode == EditMode.moveMaps) {
mapView.pushToModel();
pushToModel();
}
}
@@ -713,4 +719,16 @@ public class WorldMapEditor extends Editor {
message.repaint();
}
public void pushToModel() {
mapView.pushToModel();
notifyModelModified();
}
public void notifyModelModified() {
target.state = GameDataElement.State.modified;
this.name = ((WorldmapSegment)target).getDesc();
target.childrenChanged(new ArrayList<ProjectTreeNode>());
}
}

View File

@@ -35,13 +35,26 @@ public class SpriteChooser extends JDialog {
private static final int MAX_PER_ROW = 10;
public static Map<Project, Map<Spritesheet.Category, SpriteChooser>> cache = new LinkedHashMap<Project, Map<Spritesheet.Category,SpriteChooser>>();
public static Map<Project, Map<Spritesheet.Category, List<Spritesheet>>> cacheValidator = new LinkedHashMap<Project, Map<Category,List<Spritesheet>>>();
public static SpriteChooser getChooser(Project proj, Spritesheet.Category category) {
if (cache.get(proj) == null) {
cache.put(proj, new LinkedHashMap<Spritesheet.Category, SpriteChooser>());
}
if (cache.get(proj).get(category) == null) {
cache.get(proj).put(category, new SpriteChooser(proj, category));
} else {
List<Spritesheet> spritesheets = new ArrayList<Spritesheet>();
for (int i=0; i<proj.getSpritesheetCount(); i++) {
Spritesheet sheet = proj.getSpritesheet(i);
if (sheet.category == category) {
spritesheets.add(sheet);
}
}
if ( !spritesheets.equals(cacheValidator.get(proj).get(category)) ) {
cache.get(proj).put(category, new SpriteChooser(proj, category));
}
}
SpriteChooser wanted = cache.get(proj).get(category);
wanted.group.clearSelection();
@@ -65,11 +78,16 @@ public class SpriteChooser extends JDialog {
setTitle("Select a sprite");
setModalityType(ModalityType.APPLICATION_MODAL);
List<Spritesheet> spritesheets = new ArrayList<Spritesheet>();
for (Spritesheet sheet : proj.baseContent.gameSprites.spritesheets) {
for (int i=0; i<proj.getSpritesheetCount(); i++) {
Spritesheet sheet = proj.getSpritesheet(i);
if (sheet.category == category) {
spritesheets.add(sheet);
}
}
if (cacheValidator.get(proj) == null) {
cacheValidator.put(proj, new LinkedHashMap<Spritesheet.Category, List<Spritesheet>>());
}
cacheValidator.get(proj).put(category, spritesheets);
JPanel pane = new JPanel();

View File

@@ -445,6 +445,7 @@ public class SpritesheetEditor extends Editor {
} else if (source == categoryBox) {
sheet.category = (Spritesheet.Category) value;
}
sheet.save();
}
}