Compare commits

...

45 Commits

Author SHA1 Message Date
OMGeeky
775aba3a3f refactor: improve bounds checking in getElementAt method in CommonEditor 2025-06-18 13:53:49 +02:00
OMGeeky
bec4ddb71c refactor: update object handling in ReplaceArea and TMXMapEditor for consistency 2025-06-18 13:53:31 +02:00
OMGeeky
58603d32a1 add todo 2025-06-16 12:38:12 +02:00
OMGeeky
829bb336b8 cleanup 2025-06-16 12:38:00 +02:00
OMGeeky
57cf71da17 refactor: simplify panel creation for rewards and conditions in DialogueEditor & NPCEditor 2025-06-16 12:33:35 +02:00
OMGeeky
84dbca6ce1 refactor: encapsulate death effect panel creation in CommonEditor 2025-06-16 12:12:25 +02:00
OMGeeky
d6d742feac cleanup 2025-06-16 11:46:54 +02:00
OMGeeky
b775be08fc refactor: update createListPanel to return a result object containing both panel and list 2025-06-16 11:46:22 +02:00
OMGeeky
63d6397da5 refactor: streamline list panel creation in DroplistEditor & ItemEditor 2025-06-16 11:16:12 +02:00
OMGeeky
ee6907efdd refactor: streamline requirements panel creation in DialogueEditor 2025-06-16 10:50:32 +02:00
OMGeeky
02210d7581 refactor: clean up formatting and remove unnecessary line breaks in editor classes 2025-06-16 10:45:01 +02:00
OMGeeky
8a7ad08aa7 refactor: add navigation handling for replies in CommonEditor and DialogueEditor 2025-06-16 10:44:44 +02:00
OMGeeky
0081c325bb refactor: simplify stages panel creation in QuestEditor 2025-06-16 10:25:50 +02:00
OMGeeky
e10bcfe20f refactor: remove isCollapsed parameter and handle collapsing logic in DialogueEditor 2025-06-16 10:17:30 +02:00
OMGeeky
9deac7047f formatting 2025-06-16 10:11:41 +02:00
OMGeeky
0befc5563b refactor: change more ListModel implementations to AtListModel 2025-06-16 10:11:06 +02:00
OMGeeky
f747c40520 refactor: change StagesListModel to AtListModel 2025-06-16 09:57:17 +02:00
OMGeeky
92be506c11 refactor: add option to enable up down buttons or not 2025-06-16 09:56:40 +02:00
OMGeeky
64ea5377bf refactor: extract common ListModel implementation to AtListModel
and use that for moving elements up and down
2025-06-16 09:46:14 +02:00
OMGeeky
719be70744 refactor: extract replies panel creation to CommonEditor 2025-06-16 09:28:21 +02:00
OMGeeky
8f846c6098 add lambda call interfaces for single and multiple arguments 2025-06-16 09:27:19 +02:00
OMGeeky
975d13f36f extract wordWrap function to common class 2025-06-16 08:31:22 +02:00
OMGeeky
0a1fef4198 refactor: simplify link method by extracting parsing/linking logic 2025-06-16 08:23:43 +02:00
OMGeeky
5809d33bb4 refactor: remove unnecessary blank lines in multiple classes 2025-06-16 08:23:31 +02:00
OMGeeky
d8797fa826 add .output.txt to .gitignore 2025-06-16 07:49:46 +02:00
OMGeeky
70055be6d2 improve usings 2025-05-03 20:16:57 +02:00
OMGeeky
286d95d83d improve imports 2025-05-03 20:14:45 +02:00
OMGeeky
04b704daf0 more de-duplication 2025-05-03 20:10:36 +02:00
OMGeeky
3f1f988808 fix missed null check 2025-05-03 20:07:28 +02:00
OMGeeky
e232c33339 more de-duplication 2025-05-03 20:07:28 +02:00
OMGeeky
4239beb825 de-dupe code 2025-05-03 20:07:28 +02:00
Nut.andor
e2fdf08fec new spritesheets index 2025-02-15 23:48:39 +01:00
Nut.andor
1555bd63db Version with actor condition description is 21 2025-02-15 17:04:23 +01:00
Nut.andor
56fff8a730 nsi 2025-02-15 16:53:27 +01:00
Nut.andor
dd7b3d5300 version nbr 2025-02-15 16:44:40 +01:00
Nut.andor
68affdde8c misc 2025-02-15 16:44:13 +01:00
Nut.andor
6cec8b835e nsi 2025-02-15 16:36:45 +01:00
Nut.andor
aa43382296 Merge branch 'pulls/1195352/7' 2025-02-15 16:34:58 +01:00
Nut.andor
ec346e9c98 command parameters 2025-02-15 16:33:12 +01:00
Nut.andor
61d5af822c Build scripts 2025-02-15 16:12:38 +01:00
Nut.andor
c2d05b2bff Pull Request #7: Build scripts 2025-02-15 16:03:43 +01:00
Nut.andor
6578236775 Merge branch 'pulls/1195352/6' 2025-02-15 14:38:30 +01:00
Nut.andor
5550b257ca add description field to actor conditions 2024-12-28 14:53:02 +01:00
Nut.andor
619aa1075f Pull Request #6: add description field to actor conditions 2024-12-27 13:05:53 +01:00
OMGeeky
38a3ad85c8 add description field to actor conditions 2024-12-27 10:12:48 +01:00
36 changed files with 7131 additions and 8394 deletions

4
.gitignore vendored
View File

@@ -8,3 +8,7 @@ packaging/common/ATCS.jar
packaging/ATCS_*.zip packaging/ATCS_*.zip
ATCS_v*.tar.gz ATCS_v*.tar.gz
ATCS.jar ATCS.jar
/packaging/common/ATCS.env.bat
/packaging/common/ATCS.env
/packaging/common/ATCS_v*.zip
/.output.txt

2
.idea/misc.xml generated
View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" default="true" />
</project> </project>

View File

@@ -1 +1 @@
v0.6.19 v0.6.21

View File

@@ -1,8 +1,9 @@
!include MUI2.nsh !include MUI2.nsh
!define VERSION "0.6.20" !define VERSION "0.6.21"
!define TRAINER_VERSION "0.1.5" !define TRAINER_VERSION "0.1.5"
!define JAVA_BIN "java" !define JAVA_BIN "java"
!define ATCS_SOURCE_DIR "C:\ATCS"
Name "Andor's Trail Content Studio v${VERSION}" Name "Andor's Trail Content Studio v${VERSION}"
OutFile "ATCS_v${VERSION}_Setup.exe" OutFile "ATCS_v${VERSION}_Setup.exe"
@@ -13,8 +14,8 @@ InstallDir "$PROGRAMFILES\ATCS\"
Var StartMenuFolder Var StartMenuFolder
!define MUI_WELCOMEPAGE_TITLE "Welcome to Andor's Trail Content Studio installer" !define MUI_WELCOMEPAGE_TITLE "Welcome to Andor's Trail Content Studio installer"
!define MUI_WELCOMEPAGE_TEXT "This will install Andor's Trail Content Studio v${VERSION} installer" !define MUI_WELCOMEPAGE_TEXT "This will install Andor's Trail Content Studio v${VERSION}"
!define MUI_FINISHPAGE_TEXT "Andor's Trail Content Studio v${VERSION} install completed !" !define MUI_FINISHPAGE_TEXT "Andor's Trail Content Studio v${VERSION} - Install completed !"
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Andor's Trail Content Studio" !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Andor's Trail Content Studio"
!define MUI_PAGE_HEADER_TEXT "Installing Andor's Trail Content Studio v${VERSION}" !define MUI_PAGE_HEADER_TEXT "Installing Andor's Trail Content Studio v${VERSION}"
@@ -46,31 +47,33 @@ Var StartMenuFolder
!insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "English"
;------------------------------------------------------------------------------------
Section install Section install
;--- Create in ...\packaging\common\ ATCS.cmd ATCT.ico ATCS.jar
SetOutPath $INSTDIR SetOutPath $INSTDIR
file "ATCS.ico" file "ATCS.ico"
file "${ATCS_SOURCE_DIR}\packaging\common\ATCS.jar"
Delete "$INSTDIR\lib\*"
Call GetJRE Call GetJRE
Pop $R0 Pop $R0
; file "${ATCS_SOURCE_DIR}\packaging\common\ATCS.cmd"
; !insertmacro _ReplaceInFile "ATCS.cmd" "java.exe" "$R0" (It was too much work this way)
FileOpen $9 "ATCS.cmd" w FileOpen $9 "ATCS.cmd" w
FileWrite $9 '@echo off$\r$\n' FileWrite $9 '@echo off$\r$\n'
FileWrite $9 '$\r$\n' FileWrite $9 '$\r$\n'
FileWrite $9 'set "ATCS_DIR=%~dp0"$\r$\n' FileWrite $9 'set "ATCS_DIR=%~dp0"$\r$\n'
FileWrite $9 'set "MAX_MEM=512M"$\r$\n' FileWrite $9 'set "MAX_MEM=1024M"$\r$\n'
FileWrite $9 'set "CP=%ATCS_DIR%lib\*"$\r$\n' FileWrite $9 'set "CP=%ATCS_DIR%lib\*"$\r$\n'
FileWrite $9 'set "JAVA=$R0"$\r$\n' FileWrite $9 'set "JAVA=$R0"$\r$\n'
FileWrite $9 'set "JAVA_OPTS="$\r$\n' FileWrite $9 'set "JAVA_OPTS="$\r$\n'
FileWrite $9 'set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"$\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 "MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio"$\r$\n'
FileWrite $9 '$\r$\n' FileWrite $9 '$\r$\n'
FileWrite $9 'if exist "%ENV_FILE%" ($\r$\n' FileWrite $9 'if exist "%ENV_FILE%" ($\r$\n'
FileWrite $9 ' call "%ENV_FILE%"$\r$\n' FileWrite $9 ' call "%ENV_FILE%"$\r$\n'
FileWrite $9 ') else ($\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 "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"$\r$\n'
@@ -79,29 +82,15 @@ Section install
FileWrite $9 ' echo.>>"%ENV_FILE%"$\r$\n' FileWrite $9 ' echo.>>"%ENV_FILE%"$\r$\n'
FileWrite $9 ')$\r$\n' FileWrite $9 ')$\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' FileWrite $9 'start "" "%JAVA%" %JAVA_OPTS% -Xmx%MAX_MEM% -jar ATCS.jar$\r$\n'
FileClose $9 FileClose $9
SetOutPath "$INSTDIR\lib\"
file "C:\AT\ATCS_source\lib\jide-oss.jar"
file "C:\AT\ATCS_source\lib\ui.jar"
file "C:\AT\ATCS_source\lib\AndorsTrainer_v${TRAINER_VERSION}.jar"
file "C:\AT\ATCS_source\lib\junit-4.10.jar"
file "C:\AT\ATCS_source\lib\json_simple-1.1.jar"
file "C:\AT\temp\ATCS_v0.6.20\ATCS_v${VERSION}.jar"
file "C:\AT\ATCS_source\lib\rsyntaxtextarea.jar"
file "C:\AT\ATCS_source\lib\prefuse.jar"
file "C:\AT\ATCS_source\lib\bsh-2.0b4.jar"
file "C:\AT\ATCS_source\lib\jsoup-1.10.2.jar"
SetOutPath $INSTDIR
WriteUninstaller "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe"
!insertmacro MUI_STARTMENU_WRITE_BEGIN "ATCS" !insertmacro MUI_STARTMENU_WRITE_BEGIN "ATCS"
;Create shortcuts ;--- Create shortcuts
CreateDirectory "$SMPROGRAMS\$StartMenuFolder" CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Andor's Trail Content Studio.lnk" "$INSTDIR\ATCS.cmd" "" "$INSTDIR\ATCS.ico" CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Andor's Trail Content Studio.lnk" "$INSTDIR\ATCS.cmd" "" "$INSTDIR\ATCS.ico"
CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe" CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
@@ -110,6 +99,8 @@ Section install
SectionEnd SectionEnd
;------------------------------------------------------------------------------------
Section uninstall Section uninstall
Delete "$INSTDIR\lib\jide-oss.jar" Delete "$INSTDIR\lib\jide-oss.jar"
@@ -117,18 +108,17 @@ Section uninstall
Delete "$INSTDIR\lib\junit-4.10.jar" Delete "$INSTDIR\lib\junit-4.10.jar"
Delete "$INSTDIR\lib\json_simple-1.1.jar" Delete "$INSTDIR\lib\json_simple-1.1.jar"
Delete "$INSTDIR\lib\AndorsTrainer_v${TRAINER_VERSION}.jar" Delete "$INSTDIR\lib\AndorsTrainer_v${TRAINER_VERSION}.jar"
Delete "$INSTDIR\lib\ATCS_v${VERSION}.jar"
Delete "$INSTDIR\lib\rsyntaxtextarea.jar" Delete "$INSTDIR\lib\rsyntaxtextarea.jar"
Delete "$INSTDIR\lib\prefuse.jar" Delete "$INSTDIR\lib\prefuse.jar"
Delete "$INSTDIR\lib\bsh-2.0b4.jar" Delete "$INSTDIR\lib\bsh-2.0b4.jar"
Delete "$INSTDIR\lib\jsoup-1.10.2.jar" Delete "$INSTDIR\lib\jsoup-1.10.2.jar"
RMDir "$INSTDIR\lib\" RMDir "$INSTDIR\lib\"
Delete "$INSTDIR\ATCS.ico" Delete "$INSTDIR\ATCS.ico"
Delete "$INSTDIR\ATCS.cmd" Delete "$INSTDIR\ATCS.cmd"
Delete "$INSTDIR\ATCS.env.bat" Delete "$INSTDIR\ATCS.env.bat"
Delete "$INSTDIR\ATCS.jar"
Delete "$INSTDIR\Uninstall.exe" Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR" RMDir "$INSTDIR"
!insertmacro MUI_STARTMENU_GETFOLDER "ATCS" $StartMenuFolder !insertmacro MUI_STARTMENU_GETFOLDER "ATCS" $StartMenuFolder
@@ -140,19 +130,20 @@ Section uninstall
SectionEnd SectionEnd
;------------------------------------------------------------------------------------
Function GetJRE Function GetJRE
; ;
; Find JRE (javaw.exe) ; Find JRE (java.exe)
; DISABLED 1 - in .\jre directory (JRE Installed with application) ; DISABLED 1 - in .\jre directory (JRE Installed with application)
; 2 - in JAVA_HOME environment variable ; 2 - in JAVA_HOME environment variable
; 3 - in the registry ; 3 - in the registry
; 4 - assume javaw.exe in current dir or PATH ; 4 - assume java.exe in current dir or PATH
Push $R0 Push $R0
Push $R1 Push $R1
;ClearErrors ;ClearErrors
;StrCpy $R0 "$EXEDIR\jre\bin\javaw.exe" ;StrCpy $R0 "$EXEDIR\jre\bin\java.exe"
;IfFileExists $R0 JreFound ;IfFileExists $R0 JreFound
;StrCpy $R0 "" ;StrCpy $R0 ""

View File

@@ -1,8 +1,8 @@
@echo off @echo off
set "ATCS_DIR=%~dp0" set "ATCS_DIR=%~dp0"
set "MAX_MEM=512M" set "MAX_MEM=1024M"
set "JAVA=javaw.exe" set "JAVA=java.exe"
set "JAVA_OPTS=-DFONT_SCALE=1.0 -Dswing.aatext=true" set "JAVA_OPTS=-DFONT_SCALE=1.0 -Dswing.aatext=true"
set "ENV_FILE=%ATCS_DIR%ATCS.env.bat" set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"

View File

@@ -1,4 +0,0 @@
#MAX_MEM=512M
#JAVA=java
#JAVA_OPTS=-DFONT_SCALE=1.0 -Dswing.aatext=true

View File

@@ -1,6 +1,7 @@
atcs.spritesheet.actorconditions_1.category=actorcondition atcs.spritesheet.actorconditions_1.category=actorcondition
atcs.spritesheet.actorconditions_2.category=actorcondition atcs.spritesheet.actorconditions_2.category=actorcondition
atcs.spritesheet.actorconditions_japozero.category=actorcondition atcs.spritesheet.actorconditions_japozero.category=actorcondition
atcs.spritesheet.actorconditions_newb.category=actorcondition
atcs.spritesheet.actorconditions_omi1.category=actorcondition atcs.spritesheet.actorconditions_omi1.category=actorcondition
atcs.spritesheet.actorconditions_omi2.category=actorcondition atcs.spritesheet.actorconditions_omi2.category=actorcondition
@@ -60,6 +61,7 @@ atcs.spritesheet.monsters_gisons.category=monster
atcs.spritesheet.monsters_guynmart.category=monster atcs.spritesheet.monsters_guynmart.category=monster
atcs.spritesheet.monsters_insects.category=monster atcs.spritesheet.monsters_insects.category=monster
atcs.spritesheet.monsters_johny.category=monster
atcs.spritesheet.monsters_karvis1.category=monster atcs.spritesheet.monsters_karvis1.category=monster
atcs.spritesheet.monsters_karvis2.category=monster atcs.spritesheet.monsters_karvis2.category=monster
atcs.spritesheet.monsters_ld1.category=monster atcs.spritesheet.monsters_ld1.category=monster

View File

@@ -42,7 +42,7 @@ import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector;
public class ATContentStudio { public class ATContentStudio {
public static final String APP_NAME = "Andor's Trail Content Studio"; public static final String APP_NAME = "Andor's Trail Content Studio";
public static final String APP_VERSION = "v0.6.20"; public static final String APP_VERSION = "v0.6.21";
public static final String CHECK_UPDATE_URL = "https://andorstrail.com/static/ATCS_latest"; public static final String CHECK_UPDATE_URL = "https://andorstrail.com/static/ATCS_latest";
public static final String DOWNLOAD_URL = "https://andorstrail.com/viewtopic.php?f=6&t=4806"; public static final String DOWNLOAD_URL = "https://andorstrail.com/viewtopic.php?f=6&t=4806";

View File

@@ -1,193 +1,219 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image; import java.awt.Image;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry; import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry;
public abstract class GameDataElement implements ProjectTreeNode, Serializable { public abstract class GameDataElement implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = 2028934451226743389L; private static final long serialVersionUID = 2028934451226743389L;
public static enum State { public static enum State {
init, // We know the object exists, and have its key/ID. init, // We know the object exists, and have its key/ID.
parsed, // We know the object's properties, but related objects are referenced by ID only. parsed, // We know the object's properties, but related objects are referenced by ID only.
linked, // We know the object fully, and all links to related objects point to objects in the parsed state at least. linked, // We know the object fully, and all links to related objects point to objects in the parsed state at least.
created, // This is an object we are creating created, // This is an object we are creating
modified, // Whether altered or created, this item has been modified since creation from scratch or from JSON. modified, // Whether altered or created, this item has been modified since creation from scratch or from JSON.
saved // Whether altered or created, this item has been saved since last modification. saved // Whether altered or created, this item has been saved since last modification.
} }
public State state = State.init; public State state = State.init;
//Available from state init. //Available from state init.
public ProjectTreeNode parent; public ProjectTreeNode parent;
public boolean writable = false; public boolean writable = false;
public BookmarkEntry bookmark = null; public BookmarkEntry bookmark = null;
//List of objects whose transition to "linked" state made them point to this instance. //List of objects whose transition to "linked" state made them point to this instance.
private Map<GameDataElement, Integer> backlinks = new ConcurrentHashMap<GameDataElement, Integer>(); private Map<GameDataElement, Integer> backlinks = new ConcurrentHashMap<GameDataElement, Integer>();
public String id = null; public String id = null;
@Override @Override
public Enumeration<ProjectTreeNode> children() { public Enumeration<ProjectTreeNode> children() {
return null; return null;
} }
@Override @Override
public boolean getAllowsChildren() { public boolean getAllowsChildren() {
return false; return false;
} }
@Override @Override
public TreeNode getChildAt(int arg0) { public TreeNode getChildAt(int arg0) {
return null; return null;
} }
@Override @Override
public int getChildCount() { public int getChildCount() {
return 0; return 0;
} }
@Override @Override
public int getIndex(TreeNode arg0) { public int getIndex(TreeNode arg0) {
return 0; return 0;
} }
@Override @Override
public TreeNode getParent() { public TreeNode getParent() {
return parent; return parent;
} }
@Override @Override
public boolean isLeaf() { public boolean isLeaf() {
return true; return true;
} }
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this); path.add(0,this);
parent.childrenAdded(path); parent.childrenAdded(path);
} }
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this); path.add(0,this);
parent.childrenChanged(path); parent.childrenChanged(path);
} }
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0,this); path.add(0,this);
parent.childrenRemoved(path); parent.childrenRemoved(path);
} }
@Override @Override
public void notifyCreated() { public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>()); childrenAdded(new ArrayList<ProjectTreeNode>());
} }
@Override @Override
public abstract String getDesc(); public abstract String getDesc();
public static String getStaticDesc() { public static String getStaticDesc() {
return "GameDataElements"; return "GameDataElements";
} }
public abstract void parse(); public abstract void parse();
public abstract void link(); public abstract void link();
@Override @Override
public Project getProject() { public Project getProject() {
return parent == null ? null : parent.getProject(); return parent == null ? null : parent.getProject();
} }
public Image getIcon() { public Image getIcon() {
return null; return null;
} }
@Override @Override
public Image getClosedIcon() {return null;} public Image getClosedIcon() {return null;}
@Override @Override
public Image getOpenIcon() {return null;} public Image getOpenIcon() {return null;}
@Override @Override
public Image getLeafIcon() { public Image getLeafIcon() {
return getIcon(); return getIcon();
} }
public abstract GameDataElement clone(); public abstract GameDataElement clone();
public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne); public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne);
@Override @Override
public GameSource.Type getDataType() { public GameSource.Type getDataType() {
if (parent == null) { if (parent == null) {
System.out.println("blerf."); System.out.println("blerf.");
} }
return parent.getDataType(); return parent.getDataType();
} }
public List<BacklinksListener> backlinkListeners = new ArrayList<GameDataElement.BacklinksListener>(); public List<BacklinksListener> backlinkListeners = new ArrayList<GameDataElement.BacklinksListener>();
public void addBacklinkListener(BacklinksListener l) { public void addBacklinkListener(BacklinksListener l) {
backlinkListeners.add(l); backlinkListeners.add(l);
} }
public void removeBacklinkListener(BacklinksListener l) { public void removeBacklinkListener(BacklinksListener l) {
backlinkListeners.remove(l); backlinkListeners.remove(l);
} }
public void addBacklink(GameDataElement gde) { public void addBacklink(GameDataElement gde) {
if (!backlinks.containsKey(gde)) { if (!backlinks.containsKey(gde)) {
backlinks.put(gde, 1); backlinks.put(gde, 1);
for (BacklinksListener l : backlinkListeners) { for (BacklinksListener l : backlinkListeners) {
l.backlinkAdded(gde); l.backlinkAdded(gde);
} }
} else { } else {
backlinks.put(gde, backlinks.get(gde) + 1); backlinks.put(gde, backlinks.get(gde) + 1);
} }
} }
public void removeBacklink(GameDataElement gde) { public void removeBacklink(GameDataElement gde) {
if (backlinks.get(gde) == null) return; if (backlinks.get(gde) == null) return;
backlinks.put(gde, backlinks.get(gde) - 1); backlinks.put(gde, backlinks.get(gde) - 1);
if (backlinks.get(gde) == 0) { if (backlinks.get(gde) == 0) {
backlinks.remove(gde); backlinks.remove(gde);
for (BacklinksListener l : backlinkListeners) { for (BacklinksListener l : backlinkListeners) {
l.backlinkRemoved(gde); l.backlinkRemoved(gde);
} }
} }
} }
public Set<GameDataElement> getBacklinks() { public Set<GameDataElement> getBacklinks() {
return backlinks.keySet(); return backlinks.keySet();
} }
public static interface BacklinksListener { public static interface BacklinksListener {
public void backlinkAdded(GameDataElement gde); public void backlinkAdded(GameDataElement gde);
public void backlinkRemoved(GameDataElement gde); public void backlinkRemoved(GameDataElement gde);
} }
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return false; return false;
} }
public boolean needsSaving() { public boolean needsSaving() {
return this.state == State.modified || this.state == State.created; return this.state == State.modified || this.state == State.created;
} }
public abstract String getProjectFilename(); public abstract String getProjectFilename();
public abstract void save(); public abstract void save();
public abstract List<SaveEvent> attemptSave(); public abstract List<SaveEvent> attemptSave();
} /**
* Checks if the current state indicates that parsing/linking should be skipped.
* @return true if the operation should be skipped, false otherwise
*/
protected boolean shouldSkipParseOrLink() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) {
//This type of state is unrelated to parsing/linking.
return true;
}
if (this.state == State.linked) {
//Already linked.
return true;
}
return false;
}
/**
* Ensures the element is parsed if needed based on its current state.
*/
protected void ensureParseIfNeeded() {
if (this.state == State.init) {
//Not parsed yet.
this.parse();
}
}
}

View File

@@ -1,377 +1,374 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
public class ActorCondition extends JSONElement { public class ActorCondition extends JSONElement {
private static final long serialVersionUID = -3969824899972048507L; private static final long serialVersionUID = -3969824899972048507L;
public static final Integer MAGNITUDE_CLEAR = -99; public static final Integer MAGNITUDE_CLEAR = -99;
public static final Integer DURATION_FOREVER = 999;; public static final Integer DURATION_FOREVER = 999;;
public static final Integer DURATION_NONE = 0; public static final Integer DURATION_NONE = 0;
// Available from init state // Available from init state
//public String id; inherited. //public String id; inherited.
public String icon_id; public String icon_id;
public String display_name; public String display_name;
public String description;
// Available from parsed state
public ACCategory category = null; // Available from parsed state
public Integer positive = null; public ACCategory category = null;
public Integer stacking = null; public Integer positive = null;
public RoundEffect round_effect = null; public Integer stacking = null;
public RoundEffect full_round_effect = null; public RoundEffect round_effect = null;
public AbilityEffect constant_ability_effect = null; public RoundEffect full_round_effect = null;
public AbilityEffect constant_ability_effect = null;
public enum ACCategory {
spiritual, public enum ACCategory {
mental, spiritual,
physical, mental,
blood physical,
} blood
}
public static enum VisualEffectID {
redSplash public static enum VisualEffectID {
,blueSwirl redSplash
,greenSplash ,blueSwirl
,miss ,greenSplash
} ,miss
}
public static class RoundEffect implements Cloneable {
// Available from parsed state public static class RoundEffect implements Cloneable {
public VisualEffectID visual_effect = null; // Available from parsed state
public Integer hp_boost_min = null; public VisualEffectID visual_effect = null;
public Integer hp_boost_max = null; public Integer hp_boost_min = null;
public Integer ap_boost_min = null; public Integer hp_boost_max = null;
public Integer ap_boost_max = null; public Integer ap_boost_min = null;
public Integer ap_boost_max = null;
public Object clone() {
try { public Object clone() {
return super.clone(); try {
} catch (CloneNotSupportedException e) { return super.clone();
e.printStackTrace(); } catch (CloneNotSupportedException e) {
} e.printStackTrace();
return null; }
} return null;
} }
}
public static class AbilityEffect implements Cloneable {
// Available from parsed state public static class AbilityEffect implements Cloneable {
public Integer max_hp_boost = null; // Available from parsed state
public Integer max_ap_boost = null; public Integer max_hp_boost = null;
public Integer increase_move_cost = null; public Integer max_ap_boost = null;
public Integer increase_use_cost = null; public Integer increase_move_cost = null;
public Integer increase_reequip_cost = null; public Integer increase_use_cost = null;
public Integer increase_attack_cost = null; public Integer increase_reequip_cost = null;
public Integer increase_attack_chance = null; public Integer increase_attack_cost = null;
public Integer increase_damage_min = null; public Integer increase_attack_chance = null;
public Integer increase_damage_max = null; public Integer increase_damage_min = null;
public Integer increase_critical_skill = null; public Integer increase_damage_max = null;
public Integer increase_block_chance = null; public Integer increase_critical_skill = null;
public Integer increase_damage_resistance = null; public Integer increase_block_chance = null;
public Integer increase_damage_resistance = null;
public Object clone() {
try { public Object clone() {
return super.clone(); try {
} catch (CloneNotSupportedException e) { return super.clone();
e.printStackTrace(); } catch (CloneNotSupportedException e) {
} e.printStackTrace();
return null; }
} return null;
} }
}
@Override
public String getDesc() { @Override
return (needsSaving() ? "*" : "")+display_name+" ("+id+")"; public String getDesc() {
} return (needsSaving() ? "*" : "")+display_name+" ("+id+")";
}
@SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<ActorCondition> category) { @SuppressWarnings("rawtypes")
JSONParser parser = new JSONParser(); public static void fromJson(File jsonFile, GameDataCategory<ActorCondition> category) {
FileReader reader = null; JSONParser parser = new JSONParser();
try { FileReader reader = null;
reader = new FileReader(jsonFile); try {
List actorConditions = (List) parser.parse(reader); reader = new FileReader(jsonFile);
for (Object obj : actorConditions) { List actorConditions = (List) parser.parse(reader);
Map aCondJson = (Map)obj; for (Object obj : actorConditions) {
ActorCondition aCond = fromJson(aCondJson); Map aCondJson = (Map)obj;
aCond.jsonFile = jsonFile; ActorCondition aCond = fromJson(aCondJson);
aCond.parent = category; aCond.jsonFile = jsonFile;
if (aCond.getDataType() == GameSource.Type.created || aCond.getDataType() == GameSource.Type.altered) { aCond.parent = category;
aCond.writable = true; if (aCond.getDataType() == GameSource.Type.created || aCond.getDataType() == GameSource.Type.altered) {
} aCond.writable = true;
category.add(aCond); }
} category.add(aCond);
} catch (FileNotFoundException e) { }
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); } catch (FileNotFoundException e) {
e.printStackTrace(); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
} catch (IOException e) { e.printStackTrace();
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); } catch (IOException e) {
e.printStackTrace(); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
} catch (ParseException e) { e.printStackTrace();
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); } catch (ParseException e) {
e.printStackTrace(); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
} finally { e.printStackTrace();
if (reader != null) } finally {
try { if (reader != null)
reader.close(); try {
} catch (IOException e) { reader.close();
e.printStackTrace(); } catch (IOException e) {
} e.printStackTrace();
} }
} }
}
@SuppressWarnings("rawtypes")
public static ActorCondition fromJson(String jsonString) throws ParseException { @SuppressWarnings("rawtypes")
Map aCondJson = (Map) new JSONParser().parse(jsonString); public static ActorCondition fromJson(String jsonString) throws ParseException {
ActorCondition aCond = fromJson(aCondJson); Map aCondJson = (Map) new JSONParser().parse(jsonString);
aCond.parse(aCondJson); ActorCondition aCond = fromJson(aCondJson);
return aCond; aCond.parse(aCondJson);
} return aCond;
}
@SuppressWarnings("rawtypes")
public static ActorCondition fromJson(Map aCondJson) { @SuppressWarnings("rawtypes")
ActorCondition aCond = new ActorCondition(); public static ActorCondition fromJson(Map aCondJson) {
aCond.icon_id = (String) aCondJson.get("iconID"); ActorCondition aCond = new ActorCondition();
aCond.id = (String) aCondJson.get("id"); aCond.icon_id = (String) aCondJson.get("iconID");
aCond.display_name = (String) aCondJson.get("name"); aCond.id = (String) aCondJson.get("id");
return aCond; aCond.display_name = (String) aCondJson.get("name");
} return aCond;
}
@SuppressWarnings("rawtypes")
@Override @SuppressWarnings("rawtypes")
public void parse(Map aCondJson) { @Override
public void parse(Map aCondJson) {
if (aCondJson.get("category") != null) this.category = ACCategory.valueOf((String) aCondJson.get("category"));
this.positive = JSONElement.getInteger((Number) aCondJson.get("isPositive")); if (aCondJson.get("description") != null) this.description = (String) aCondJson.get("description");
Map abilityEffect = (Map) aCondJson.get("abilityEffect"); if (aCondJson.get("category") != null) this.category = ACCategory.valueOf((String) aCondJson.get("category"));
if (abilityEffect != null) { this.positive = JSONElement.getInteger((Number) aCondJson.get("isPositive"));
this.constant_ability_effect = new AbilityEffect(); Map abilityEffect = (Map) aCondJson.get("abilityEffect");
this.constant_ability_effect.increase_attack_chance = JSONElement.getInteger((Number) abilityEffect.get("increaseAttackChance")); if (abilityEffect != null) {
if (abilityEffect.get("increaseAttackDamage") != null) { this.constant_ability_effect = new AbilityEffect();
this.constant_ability_effect.increase_damage_min = JSONElement.getInteger((Number) (((Map)abilityEffect.get("increaseAttackDamage")).get("min"))); this.constant_ability_effect.increase_attack_chance = JSONElement.getInteger((Number) abilityEffect.get("increaseAttackChance"));
this.constant_ability_effect.increase_damage_max = JSONElement.getInteger((Number) (((Map)abilityEffect.get("increaseAttackDamage")).get("max"))); if (abilityEffect.get("increaseAttackDamage") != null) {
} this.constant_ability_effect.increase_damage_min = JSONElement.getInteger((Number) (((Map)abilityEffect.get("increaseAttackDamage")).get("min")));
this.constant_ability_effect.max_hp_boost = JSONElement.getInteger((Number) abilityEffect.get("increaseMaxHP")); this.constant_ability_effect.increase_damage_max = JSONElement.getInteger((Number) (((Map)abilityEffect.get("increaseAttackDamage")).get("max")));
this.constant_ability_effect.max_ap_boost = JSONElement.getInteger((Number) abilityEffect.get("increaseMaxAP")); }
this.constant_ability_effect.increase_move_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseMoveCost")); this.constant_ability_effect.max_hp_boost = JSONElement.getInteger((Number) abilityEffect.get("increaseMaxHP"));
this.constant_ability_effect.increase_use_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseUseItemCost")); this.constant_ability_effect.max_ap_boost = JSONElement.getInteger((Number) abilityEffect.get("increaseMaxAP"));
this.constant_ability_effect.increase_reequip_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseReequipCost")); this.constant_ability_effect.increase_move_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseMoveCost"));
this.constant_ability_effect.increase_attack_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseAttackCost")); this.constant_ability_effect.increase_use_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseUseItemCost"));
this.constant_ability_effect.increase_critical_skill = JSONElement.getInteger((Number) abilityEffect.get("increaseCriticalSkill")); this.constant_ability_effect.increase_reequip_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseReequipCost"));
this.constant_ability_effect.increase_block_chance = JSONElement.getInteger((Number) abilityEffect.get("increaseBlockChance")); this.constant_ability_effect.increase_attack_cost = JSONElement.getInteger((Number) abilityEffect.get("increaseAttackCost"));
this.constant_ability_effect.increase_damage_resistance = JSONElement.getInteger((Number) abilityEffect.get("increaseDamageResistance")); this.constant_ability_effect.increase_critical_skill = JSONElement.getInteger((Number) abilityEffect.get("increaseCriticalSkill"));
} this.constant_ability_effect.increase_block_chance = JSONElement.getInteger((Number) abilityEffect.get("increaseBlockChance"));
this.stacking = JSONElement.getInteger((Number) aCondJson.get("isStacking")); this.constant_ability_effect.increase_damage_resistance = JSONElement.getInteger((Number) abilityEffect.get("increaseDamageResistance"));
Map roundEffect = (Map) aCondJson.get("roundEffect"); }
if (roundEffect != null) { this.stacking = JSONElement.getInteger((Number) aCondJson.get("isStacking"));
this.round_effect = new RoundEffect(); Map roundEffect = (Map) aCondJson.get("roundEffect");
if (roundEffect.get("increaseCurrentHP") != null) { if (roundEffect != null) {
this.round_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentHP")).get("max"))); this.round_effect = new RoundEffect();
this.round_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentHP")).get("min"))); if (roundEffect.get("increaseCurrentHP") != null) {
} this.round_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentHP")).get("max")));
if (roundEffect.get("increaseCurrentAP") != null) { this.round_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentHP")).get("min")));
this.round_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentAP")).get("max"))); }
this.round_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentAP")).get("min"))); if (roundEffect.get("increaseCurrentAP") != null) {
} this.round_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentAP")).get("max")));
String vfx = (String) roundEffect.get("visualEffectID"); this.round_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)roundEffect.get("increaseCurrentAP")).get("min")));
this.round_effect.visual_effect = null; }
if (vfx != null) { String vfx = (String) roundEffect.get("visualEffectID");
try { this.round_effect.visual_effect = null;
this.round_effect.visual_effect = VisualEffectID.valueOf(vfx); if (vfx != null) {
} catch(IllegalArgumentException e) {} try {
} this.round_effect.visual_effect = VisualEffectID.valueOf(vfx);
} } catch(IllegalArgumentException e) {}
Map fullRoundEffect = (Map) aCondJson.get("fullRoundEffect"); }
if (fullRoundEffect != null) { }
this.full_round_effect = new RoundEffect(); Map fullRoundEffect = (Map) aCondJson.get("fullRoundEffect");
if (fullRoundEffect.get("increaseCurrentHP") != null) { if (fullRoundEffect != null) {
this.full_round_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentHP")).get("max"))); this.full_round_effect = new RoundEffect();
this.full_round_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentHP")).get("min"))); if (fullRoundEffect.get("increaseCurrentHP") != null) {
} this.full_round_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentHP")).get("max")));
if (fullRoundEffect.get("increaseCurrentAP") != null) { this.full_round_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentHP")).get("min")));
this.full_round_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentAP")).get("max"))); }
this.full_round_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentAP")).get("min"))); if (fullRoundEffect.get("increaseCurrentAP") != null) {
} this.full_round_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentAP")).get("max")));
String vfx = (String) fullRoundEffect.get("visualEffectID"); this.full_round_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)fullRoundEffect.get("increaseCurrentAP")).get("min")));
this.full_round_effect.visual_effect = null; }
if (vfx != null) { String vfx = (String) fullRoundEffect.get("visualEffectID");
try { this.full_round_effect.visual_effect = null;
this.full_round_effect.visual_effect = VisualEffectID.valueOf(vfx); if (vfx != null) {
} catch(IllegalArgumentException e) {} try {
} this.full_round_effect.visual_effect = VisualEffectID.valueOf(vfx);
} } catch(IllegalArgumentException e) {}
this.state = State.parsed; }
}
} this.state = State.parsed;
@Override }
public void link() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { @Override
//This type of state is unrelated to parsing/linking. public void link() {
return; if (shouldSkipParseOrLink()) {
} return;
if (this.state == State.init) { }
//Not parsed yet. ensureParseIfNeeded();
this.parse(); if (this.icon_id != null) {
} else if (this.state == State.linked) { String spritesheetId = this.icon_id.split(":")[0];
//Already linked. if (getProject().getSpritesheet(spritesheetId) == null) {
return; System.out.println("Actor Condition");
} System.out.println(this.id);
if (this.icon_id != null) { System.out.println("failed to load spritesheet:");
String spritesheetId = this.icon_id.split(":")[0]; System.out.println(spritesheetId);
if (getProject().getSpritesheet(spritesheetId) == null) { System.out.println("while creating backlink for icon_id:");
System.out.println("Actor Condition"); System.out.println(this.icon_id);
System.out.println(this.id); }
System.out.println("failed to load spritesheet:"); getProject().getSpritesheet(spritesheetId).addBacklink(this);
System.out.println(spritesheetId); }
System.out.println("while creating backlink for icon_id:");
System.out.println(this.icon_id); this.state = State.linked;
} }
getProject().getSpritesheet(spritesheetId).addBacklink(this);
}
public static String getStaticDesc() {
this.state = State.linked; return "Actor Conditions";
} }
public static String getStaticDesc() { @Override
return "Actor Conditions"; public Image getIcon() {
} return getProject().getIcon(icon_id);
}
@Override public Image getImage() {
public Image getIcon() { return getProject().getImage(icon_id);
return getProject().getIcon(icon_id); }
}
@Override
public Image getImage() { public JSONElement clone() {
return getProject().getImage(icon_id); ActorCondition clone = new ActorCondition();
} clone.jsonFile = this.jsonFile;
clone.state = this.state;
@Override clone.id = this.id;
public JSONElement clone() { clone.display_name = this.display_name;
ActorCondition clone = new ActorCondition(); clone.description = this.description;
clone.jsonFile = this.jsonFile; clone.icon_id = this.icon_id;
clone.state = this.state; clone.category = this.category;
clone.id = this.id; clone.positive = this.positive;
clone.display_name = this.display_name; clone.stacking = this.stacking;
clone.icon_id = this.icon_id; if (this.round_effect != null) {
clone.category = this.category; clone.round_effect = (RoundEffect) this.round_effect.clone();
clone.positive = this.positive; }
clone.stacking = this.stacking; if (this.constant_ability_effect != null) {
if (this.round_effect != null) { clone.constant_ability_effect = (AbilityEffect) constant_ability_effect.clone();
clone.round_effect = (RoundEffect) this.round_effect.clone(); }
} if (this.full_round_effect != null) {
if (this.constant_ability_effect != null) { clone.full_round_effect = (RoundEffect) this.full_round_effect.clone();
clone.constant_ability_effect = (AbilityEffect) constant_ability_effect.clone(); }
} return clone;
if (this.full_round_effect != null) { }
clone.full_round_effect = (RoundEffect) this.full_round_effect.clone();
} @Override
return clone; public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} //Nothing to link to.
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { @SuppressWarnings({ "rawtypes", "unchecked" })
//Nothing to link to. @Override
} public Map toJson() {
Map jsonAC = new LinkedHashMap();
@SuppressWarnings({ "rawtypes", "unchecked" }) jsonAC.put("id", this.id);
@Override if (this.icon_id != null) jsonAC.put("iconID", this.icon_id);
public Map toJson() { if (this.display_name != null) jsonAC.put("name", this.display_name);
Map jsonAC = new LinkedHashMap(); if (this.description != null) jsonAC.put("description", this.description);
jsonAC.put("id", this.id); if (this.category != null) jsonAC.put("category", this.category.toString());
if (this.icon_id != null) jsonAC.put("iconID", this.icon_id); if (this.positive != null && this.positive == 1) jsonAC.put("isPositive", this.positive);
if (this.display_name != null) jsonAC.put("name", this.display_name); if (this.stacking != null && this.stacking == 1) jsonAC.put("isStacking", this.stacking);
if (this.category != null) jsonAC.put("category", this.category.toString()); if (this.round_effect != null) {
if (this.positive != null && this.positive == 1) jsonAC.put("isPositive", this.positive); Map jsonRound = new LinkedHashMap();
if (this.stacking != null && this.stacking == 1) jsonAC.put("isStacking", this.stacking); if (this.round_effect.visual_effect != null) jsonRound.put("visualEffectID", this.round_effect.visual_effect.toString());
if (this.round_effect != null) { if (this.round_effect.hp_boost_min != null || this.round_effect.hp_boost_max != null) {
Map jsonRound = new LinkedHashMap(); Map jsonHP = new LinkedHashMap();
if (this.round_effect.visual_effect != null) jsonRound.put("visualEffectID", this.round_effect.visual_effect.toString()); if (this.round_effect.hp_boost_min != null) jsonHP.put("min", this.round_effect.hp_boost_min);
if (this.round_effect.hp_boost_min != null || this.round_effect.hp_boost_max != null) { else jsonHP.put("min", 0);
Map jsonHP = new LinkedHashMap(); if (this.round_effect.hp_boost_max != null) jsonHP.put("max", this.round_effect.hp_boost_max);
if (this.round_effect.hp_boost_min != null) jsonHP.put("min", this.round_effect.hp_boost_min); else jsonHP.put("max", 0);
else jsonHP.put("min", 0); jsonRound.put("increaseCurrentHP", jsonHP);
if (this.round_effect.hp_boost_max != null) jsonHP.put("max", this.round_effect.hp_boost_max); }
else jsonHP.put("max", 0); if (this.round_effect.ap_boost_min != null || this.round_effect.ap_boost_max != null) {
jsonRound.put("increaseCurrentHP", jsonHP); Map jsonAP = new LinkedHashMap();
} if (this.round_effect.ap_boost_min != null) jsonAP.put("min", this.round_effect.ap_boost_min);
if (this.round_effect.ap_boost_min != null || this.round_effect.ap_boost_max != null) { else jsonAP.put("min", 0);
Map jsonAP = new LinkedHashMap(); if (this.round_effect.ap_boost_max != null) jsonAP.put("max", this.round_effect.ap_boost_max);
if (this.round_effect.ap_boost_min != null) jsonAP.put("min", this.round_effect.ap_boost_min); else jsonAP.put("max", 0);
else jsonAP.put("min", 0); jsonRound.put("increaseCurrentAP", jsonAP);
if (this.round_effect.ap_boost_max != null) jsonAP.put("max", this.round_effect.ap_boost_max); }
else jsonAP.put("max", 0); jsonAC.put("roundEffect", jsonRound);
jsonRound.put("increaseCurrentAP", jsonAP); }
} if (this.full_round_effect != null) {
jsonAC.put("roundEffect", jsonRound); Map jsonFullRound = new LinkedHashMap();
} if (this.full_round_effect.visual_effect != null) jsonFullRound.put("visualEffectID", this.full_round_effect.visual_effect.toString());
if (this.full_round_effect != null) { if (this.full_round_effect.hp_boost_min != null || this.full_round_effect.hp_boost_max != null) {
Map jsonFullRound = new LinkedHashMap(); Map jsonHP = new LinkedHashMap();
if (this.full_round_effect.visual_effect != null) jsonFullRound.put("visualEffectID", this.full_round_effect.visual_effect.toString()); if (this.full_round_effect.hp_boost_min != null) jsonHP.put("min", this.full_round_effect.hp_boost_min);
if (this.full_round_effect.hp_boost_min != null || this.full_round_effect.hp_boost_max != null) { else jsonHP.put("min", 0);
Map jsonHP = new LinkedHashMap(); if (this.full_round_effect.hp_boost_max != null) jsonHP.put("max", this.full_round_effect.hp_boost_max);
if (this.full_round_effect.hp_boost_min != null) jsonHP.put("min", this.full_round_effect.hp_boost_min); else jsonHP.put("max", 0);
else jsonHP.put("min", 0); jsonFullRound.put("increaseCurrentHP", jsonHP);
if (this.full_round_effect.hp_boost_max != null) jsonHP.put("max", this.full_round_effect.hp_boost_max); }
else jsonHP.put("max", 0); if (this.full_round_effect.ap_boost_min != null || this.full_round_effect.ap_boost_max != null) {
jsonFullRound.put("increaseCurrentHP", jsonHP); Map jsonAP = new LinkedHashMap();
} if (this.full_round_effect.ap_boost_min != null) jsonAP.put("min", this.full_round_effect.ap_boost_min);
if (this.full_round_effect.ap_boost_min != null || this.full_round_effect.ap_boost_max != null) { else jsonAP.put("min", 0);
Map jsonAP = new LinkedHashMap(); if (this.full_round_effect.ap_boost_max != null) jsonAP.put("max", this.full_round_effect.ap_boost_max);
if (this.full_round_effect.ap_boost_min != null) jsonAP.put("min", this.full_round_effect.ap_boost_min); else jsonAP.put("max", 0);
else jsonAP.put("min", 0); jsonFullRound.put("increaseCurrentAP", jsonAP);
if (this.full_round_effect.ap_boost_max != null) jsonAP.put("max", this.full_round_effect.ap_boost_max); }
else jsonAP.put("max", 0); jsonAC.put("fullRoundEffect", jsonFullRound);
jsonFullRound.put("increaseCurrentAP", jsonAP); }
} if (this.constant_ability_effect != null) {
jsonAC.put("fullRoundEffect", jsonFullRound); Map jsonAbility = new LinkedHashMap();
} if (this.constant_ability_effect.increase_attack_chance != null) jsonAbility.put("increaseAttackChance", this.constant_ability_effect.increase_attack_chance);
if (this.constant_ability_effect != null) { if (this.constant_ability_effect.increase_damage_min != null || this.constant_ability_effect.increase_damage_max != null) {
Map jsonAbility = new LinkedHashMap(); Map jsonAD = new LinkedHashMap();
if (this.constant_ability_effect.increase_attack_chance != null) jsonAbility.put("increaseAttackChance", this.constant_ability_effect.increase_attack_chance); if (this.constant_ability_effect.increase_damage_min != null) jsonAD.put("min", this.constant_ability_effect.increase_damage_min);
if (this.constant_ability_effect.increase_damage_min != null || this.constant_ability_effect.increase_damage_max != null) { else jsonAD.put("min", 0);
Map jsonAD = new LinkedHashMap(); if (this.constant_ability_effect.increase_damage_max != null) jsonAD.put("max", this.constant_ability_effect.increase_damage_max);
if (this.constant_ability_effect.increase_damage_min != null) jsonAD.put("min", this.constant_ability_effect.increase_damage_min); else jsonAD.put("max", 0);
else jsonAD.put("min", 0); jsonAbility.put("increaseAttackDamage", jsonAD);
if (this.constant_ability_effect.increase_damage_max != null) jsonAD.put("max", this.constant_ability_effect.increase_damage_max); }
else jsonAD.put("max", 0); if (this.constant_ability_effect.max_hp_boost != null) jsonAbility.put("increaseMaxHP", this.constant_ability_effect.max_hp_boost);
jsonAbility.put("increaseAttackDamage", jsonAD); if (this.constant_ability_effect.max_ap_boost != null) jsonAbility.put("increaseMaxAP", this.constant_ability_effect.max_ap_boost);
} if (this.constant_ability_effect.increase_move_cost != null) jsonAbility.put("increaseMoveCost", this.constant_ability_effect.increase_move_cost);
if (this.constant_ability_effect.max_hp_boost != null) jsonAbility.put("increaseMaxHP", this.constant_ability_effect.max_hp_boost); if (this.constant_ability_effect.increase_use_cost != null) jsonAbility.put("increaseUseItemCost", this.constant_ability_effect.increase_use_cost);
if (this.constant_ability_effect.max_ap_boost != null) jsonAbility.put("increaseMaxAP", this.constant_ability_effect.max_ap_boost); if (this.constant_ability_effect.increase_reequip_cost != null) jsonAbility.put("increaseReequipCost", this.constant_ability_effect.increase_reequip_cost);
if (this.constant_ability_effect.increase_move_cost != null) jsonAbility.put("increaseMoveCost", this.constant_ability_effect.increase_move_cost); if (this.constant_ability_effect.increase_attack_cost != null) jsonAbility.put("increaseAttackCost", this.constant_ability_effect.increase_attack_cost);
if (this.constant_ability_effect.increase_use_cost != null) jsonAbility.put("increaseUseItemCost", this.constant_ability_effect.increase_use_cost); if (this.constant_ability_effect.increase_critical_skill != null) jsonAbility.put("increaseCriticalSkill", this.constant_ability_effect.increase_critical_skill);
if (this.constant_ability_effect.increase_reequip_cost != null) jsonAbility.put("increaseReequipCost", this.constant_ability_effect.increase_reequip_cost); if (this.constant_ability_effect.increase_block_chance != null) jsonAbility.put("increaseBlockChance", this.constant_ability_effect.increase_block_chance);
if (this.constant_ability_effect.increase_attack_cost != null) jsonAbility.put("increaseAttackCost", this.constant_ability_effect.increase_attack_cost); if (this.constant_ability_effect.increase_damage_resistance != null) jsonAbility.put("increaseDamageResistance", this.constant_ability_effect.increase_damage_resistance);
if (this.constant_ability_effect.increase_critical_skill != null) jsonAbility.put("increaseCriticalSkill", this.constant_ability_effect.increase_critical_skill); jsonAC.put("abilityEffect", jsonAbility);
if (this.constant_ability_effect.increase_block_chance != null) jsonAbility.put("increaseBlockChance", this.constant_ability_effect.increase_block_chance); }
if (this.constant_ability_effect.increase_damage_resistance != null) jsonAbility.put("increaseDamageResistance", this.constant_ability_effect.increase_damage_resistance); return jsonAC;
jsonAC.put("abilityEffect", jsonAbility); }
}
return jsonAC; @Override
} public String getProjectFilename() {
return "actorconditions_"+getProject().name+".json";
@Override }
public String getProjectFilename() {
return "actorconditions_"+getProject().name+".json"; }
}
}

View File

@@ -0,0 +1,184 @@
package com.gpl.rpg.atcontentstudio.model.gamedata;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public final class Common {
public static void linkConditions(List<?extends ConditionEffect> conditions, Project proj, GameDataElement backlink) {
if (conditions != null) {
for (ConditionEffect ce : conditions) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(backlink);
}
}
}
public static class TimedConditionEffect extends ConditionEffect {
//Available from parsed state
public Integer duration = null;
public Double chance = null;
public TimedConditionEffect createClone() {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = this.magnitude;
cclone.condition_id = this.condition_id;
cclone.condition = this.condition;
cclone.chance = this.chance;
cclone.duration = this.duration;
return cclone;
}
}
public static class ConditionEffect {
//Available from parsed state
public Integer magnitude = null;
public String condition_id = null;
//Available from linked state
public ActorCondition condition = null;
}
@SuppressWarnings("rawtypes")
public static ArrayList<TimedConditionEffect> parseTimedConditionEffects(List conditionsSourceJson) {
ArrayList<TimedConditionEffect> conditions_source;
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
conditions_source = new ArrayList<>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map) conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
readConditionEffect(condition, conditionJson);
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null)
condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
conditions_source.add(condition);
}
} else {
conditions_source = null;
}
return conditions_source;
}
@SuppressWarnings("rawtypes")
private static void readConditionEffect(ConditionEffect condition, Map conditionJson) {
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
}
@SuppressWarnings("rawtypes")
public static Common.DeathEffect parseDeathEffect(Map killEffect) {
Common.DeathEffect kill_effect = new Common.DeathEffect();
readDeathEffect(killEffect, kill_effect);
return kill_effect;
}
@SuppressWarnings("rawtypes")
public static HitEffect parseHitEffect(Map hitEffect) {
Common.HitEffect hit_effect = new Common.HitEffect();
readHitEffect(hitEffect, hit_effect);
return hit_effect;
}
@SuppressWarnings("rawtypes")
public static HitReceivedEffect parseHitReceivedEffect(Map hitReceivedEffect) {
HitReceivedEffect hit_received_effect = new Common.HitReceivedEffect();
readHitEffect(hitReceivedEffect, hit_received_effect);
if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) {
hit_received_effect.hp_boost_max_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max")));
hit_received_effect.hp_boost_min_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min")));
}
if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) {
hit_received_effect.ap_boost_max_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max")));
hit_received_effect.ap_boost_min_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min")));
}
return hit_received_effect;
}
@SuppressWarnings("rawtypes")
private static void readDeathEffect(Map killEffect, DeathEffect kill_effect) {
if (killEffect.get("increaseCurrentHP") != null) {
kill_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentHP")).get("min")));
kill_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentHP")).get("max")));
}
if (killEffect.get("increaseCurrentAP") != null) {
kill_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentAP")).get("min")));
kill_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentAP")).get("max")));
}
List conditionsSourceJson = (List) killEffect.get("conditionsSource");
kill_effect.conditions_source = parseTimedConditionEffects(conditionsSourceJson);
}
@SuppressWarnings("rawtypes")
private static void readHitEffect(Map hitEffect, HitEffect hit_effect) {
readDeathEffect(hitEffect, hit_effect);
List conditionsTargetJson = (List) hitEffect.get("conditionsTarget");
hit_effect.conditions_target = parseTimedConditionEffects(conditionsTargetJson);
}
public static class DeathEffect {
//Available from parsed state
public Integer hp_boost_min = null;
public Integer hp_boost_max = null;
public Integer ap_boost_min = null;
public Integer ap_boost_max = null;
public List<TimedConditionEffect> conditions_source = null;
}
public static class HitEffect extends DeathEffect {
//Available from parsed state
public List<TimedConditionEffect> conditions_target = null;
}
public static class HitReceivedEffect extends Common.HitEffect {
//Available from parsed state
public Integer hp_boost_min_target = null;
public Integer hp_boost_max_target = null;
public Integer ap_boost_min_target = null;
public Integer ap_boost_max_target = null;
}
public static void copyDeathEffectValues(Common.DeathEffect target, Common.DeathEffect source, GameDataElement backlink) {
target.ap_boost_max = source.ap_boost_max;
target.ap_boost_min = source.ap_boost_min;
target.hp_boost_max = source.hp_boost_max;
target.hp_boost_min = source.hp_boost_min;
if (source.conditions_source != null) {
target.conditions_source = new ArrayList<>();
for (Common.TimedConditionEffect c : source.conditions_source) {
Common.TimedConditionEffect cclone = c.createClone();
if (cclone.condition != null) {
cclone.condition.addBacklink(backlink);
}
target.conditions_source.add(cclone);
}
}
}
public static void copyHitEffectValues(Common.HitEffect target, Common.HitEffect source, GameDataElement backlink) {
copyDeathEffectValues(target, source, backlink);
if (source.conditions_target != null) {
target.conditions_target = new ArrayList<>();
for (Common.TimedConditionEffect c : source.conditions_target) {
Common.TimedConditionEffect cclone = c.createClone();
if (cclone.condition != null) {
cclone.condition.addBacklink(backlink);
}
target.conditions_target.add(cclone);
}
}
}
public static void copyHitReceivedEffectValues(Common.HitReceivedEffect target, Common.HitReceivedEffect source, GameDataElement backlink) {
copyHitEffectValues(target, source, backlink);
target.ap_boost_max_target = source.ap_boost_max_target;
target.ap_boost_min_target = source.ap_boost_min_target;
target.hp_boost_max_target = source.hp_boost_max_target;
target.hp_boost_min_target = source.hp_boost_min_target;
}
}

View File

@@ -1,470 +1,463 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement.RequirementType; import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement.RequirementType;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class Dialogue extends JSONElement { public class Dialogue extends JSONElement {
private static final long serialVersionUID = -6872164604703134683L; private static final long serialVersionUID = -6872164604703134683L;
//Available from init state //Available from init state
//public String id = null; inherited. //public String id = null; inherited.
public String message = null; public String message = null;
//Available from parsed state; //Available from parsed state;
public List<Reward> rewards = null; public List<Reward> rewards = null;
public List<Reply> replies = null; public List<Reply> replies = null;
public String switch_to_npc_id = null; public String switch_to_npc_id = null;
//Available from linked state; //Available from linked state;
public NPC switch_to_npc = null; public NPC switch_to_npc = null;
public static class Reward { public static class Reward {
//Available from parsed state //Available from parsed state
public RewardType type = null; public RewardType type = null;
public String reward_obj_id = null; public String reward_obj_id = null;
public Integer reward_value = null; public Integer reward_value = null;
public String map_name = null; public String map_name = null;
//Available from linked state //Available from linked state
public GameDataElement reward_obj = null; public GameDataElement reward_obj = null;
public TMXMap map = null; public TMXMap map = null;
public enum RewardType { public enum RewardType {
questProgress, questProgress,
removeQuestProgress, removeQuestProgress,
dropList, dropList,
skillIncrease, skillIncrease,
actorCondition, actorCondition,
actorConditionImmunity, actorConditionImmunity,
alignmentChange, alignmentChange,
alignmentSet, alignmentSet,
giveItem, giveItem,
createTimer, createTimer,
spawnAll, spawnAll,
removeSpawnArea, removeSpawnArea,
deactivateSpawnArea, deactivateSpawnArea,
activateMapObjectGroup, activateMapObjectGroup,
deactivateMapObjectGroup, deactivateMapObjectGroup,
changeMapFilter, changeMapFilter,
mapchange mapchange
} }
} }
public static class Reply { public static class Reply {
public static final String GO_NEXT_TEXT = "N"; public static final String GO_NEXT_TEXT = "N";
public static final String SHOP_PHRASE_ID = "S"; public static final String SHOP_PHRASE_ID = "S";
public static final String FIGHT_PHRASE_ID = "F"; public static final String FIGHT_PHRASE_ID = "F";
public static final String EXIT_PHRASE_ID = "X"; public static final String EXIT_PHRASE_ID = "X";
public static final String REMOVE_PHRASE_ID = "R"; public static final String REMOVE_PHRASE_ID = "R";
public static final List<String> KEY_PHRASE_ID = Arrays.asList(new String[]{SHOP_PHRASE_ID, FIGHT_PHRASE_ID, EXIT_PHRASE_ID, REMOVE_PHRASE_ID}); public static final List<String> KEY_PHRASE_ID = Arrays.asList(new String[]{SHOP_PHRASE_ID, FIGHT_PHRASE_ID, EXIT_PHRASE_ID, REMOVE_PHRASE_ID});
//Available from parsed state //Available from parsed state
public String text = null; public String text = null;
public String next_phrase_id = null; public String next_phrase_id = null;
public List<Requirement> requirements = null; public List<Requirement> requirements = null;
//Available from linked state //Available from linked state
public Dialogue next_phrase = null; public Dialogue next_phrase = null;
} }
@Override @Override
public String getDesc() { public String getDesc() {
return (needsSaving() ? "*" : "")+id; return (needsSaving() ? "*" : "")+id;
} }
public static String getStaticDesc() { public static String getStaticDesc() {
return "Dialogues"; return "Dialogues";
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<Dialogue> category) { public static void fromJson(File jsonFile, GameDataCategory<Dialogue> category) {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
FileReader reader = null; FileReader reader = null;
try { try {
reader = new FileReader(jsonFile); reader = new FileReader(jsonFile);
List dialogues = (List) parser.parse(reader); List dialogues = (List) parser.parse(reader);
for (Object obj : dialogues) { for (Object obj : dialogues) {
Map dialogueJson = (Map)obj; Map dialogueJson = (Map)obj;
Dialogue dialogue = fromJson(dialogueJson); Dialogue dialogue = fromJson(dialogueJson);
dialogue.jsonFile = jsonFile; dialogue.jsonFile = jsonFile;
dialogue.parent = category; dialogue.parent = category;
if (dialogue.getDataType() == GameSource.Type.created || dialogue.getDataType() == GameSource.Type.altered) { if (dialogue.getDataType() == GameSource.Type.created || dialogue.getDataType() == GameSource.Type.altered) {
dialogue.writable = true; dialogue.writable = true;
} }
category.add(dialogue); category.add(dialogue);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (reader != null) if (reader != null)
try { try {
reader.close(); reader.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Dialogue fromJson(String jsonString) throws ParseException { public static Dialogue fromJson(String jsonString) throws ParseException {
Map dialogueJson = (Map) new JSONParser().parse(jsonString); Map dialogueJson = (Map) new JSONParser().parse(jsonString);
Dialogue dialogue = fromJson(dialogueJson); Dialogue dialogue = fromJson(dialogueJson);
dialogue.parse(dialogueJson); dialogue.parse(dialogueJson);
return dialogue; return dialogue;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Dialogue fromJson(Map dialogueJson) { public static Dialogue fromJson(Map dialogueJson) {
Dialogue dialogue = new Dialogue(); Dialogue dialogue = new Dialogue();
dialogue.id = (String) dialogueJson.get("id"); dialogue.id = (String) dialogueJson.get("id");
dialogue.message = (String) dialogueJson.get("message"); dialogue.message = (String) dialogueJson.get("message");
return dialogue; return dialogue;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public void parse(Map dialogueJson) { public void parse(Map dialogueJson) {
this.switch_to_npc_id = (String) dialogueJson.get("switchToNPC"); this.switch_to_npc_id = (String) dialogueJson.get("switchToNPC");
List repliesJson = (List) dialogueJson.get("replies"); List repliesJson = (List) dialogueJson.get("replies");
if (repliesJson != null && !repliesJson.isEmpty()) { if (repliesJson != null && !repliesJson.isEmpty()) {
this.replies = new ArrayList<Dialogue.Reply>(); this.replies = new ArrayList<Dialogue.Reply>();
for (Object replyJsonObj : repliesJson) { for (Object replyJsonObj : repliesJson) {
Map replyJson = (Map)replyJsonObj; Map replyJson = (Map)replyJsonObj;
Reply reply = new Reply(); Reply reply = new Reply();
reply.text = (String) replyJson.get("text"); reply.text = (String) replyJson.get("text");
reply.next_phrase_id = (String) replyJson.get("nextPhraseID"); reply.next_phrase_id = (String) replyJson.get("nextPhraseID");
List requirementsJson = (List) replyJson.get("requires"); List requirementsJson = (List) replyJson.get("requires");
if (requirementsJson != null && !requirementsJson.isEmpty()) { if (requirementsJson != null && !requirementsJson.isEmpty()) {
reply.requirements = new ArrayList<Requirement>(); reply.requirements = new ArrayList<Requirement>();
for (Object requirementJsonObj : requirementsJson) { for (Object requirementJsonObj : requirementsJson) {
Map requirementJson = (Map) requirementJsonObj; Map requirementJson = (Map) requirementJsonObj;
Requirement requirement = new Requirement(); Requirement requirement = new Requirement();
requirement.jsonFile = this.jsonFile; requirement.jsonFile = this.jsonFile;
requirement.parent = this; requirement.parent = this;
if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType")); if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType"));
requirement.required_obj_id = (String) requirementJson.get("requireID"); requirement.required_obj_id = (String) requirementJson.get("requireID");
if (requirementJson.get("value") != null) requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString())); if (requirementJson.get("value") != null) requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString()));
if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate"); if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate");
requirement.state = State.parsed; requirement.state = State.parsed;
reply.requirements.add(requirement); reply.requirements.add(requirement);
} }
} }
this.replies.add(reply); this.replies.add(reply);
} }
} }
List rewardsJson = (List) dialogueJson.get("rewards"); List rewardsJson = (List) dialogueJson.get("rewards");
if (rewardsJson != null && !rewardsJson.isEmpty()) { if (rewardsJson != null && !rewardsJson.isEmpty()) {
this.rewards = new ArrayList<Dialogue.Reward>(); this.rewards = new ArrayList<Dialogue.Reward>();
for (Object rewardJsonObj : rewardsJson) { for (Object rewardJsonObj : rewardsJson) {
Map rewardJson = (Map)rewardJsonObj; Map rewardJson = (Map)rewardJsonObj;
Reward reward = new Reward(); Reward reward = new Reward();
if (rewardJson.get("rewardType") != null) reward.type = Reward.RewardType.valueOf((String) rewardJson.get("rewardType")); if (rewardJson.get("rewardType") != null) reward.type = Reward.RewardType.valueOf((String) rewardJson.get("rewardType"));
if (rewardJson.get("rewardID") != null) reward.reward_obj_id = (String) rewardJson.get("rewardID"); if (rewardJson.get("rewardID") != null) reward.reward_obj_id = (String) rewardJson.get("rewardID");
if (rewardJson.get("value") != null) reward.reward_value = JSONElement.getInteger((Number) rewardJson.get("value")); if (rewardJson.get("value") != null) reward.reward_value = JSONElement.getInteger((Number) rewardJson.get("value"));
if (rewardJson.get("mapName") != null) reward.map_name = (String) rewardJson.get("mapName"); if (rewardJson.get("mapName") != null) reward.map_name = (String) rewardJson.get("mapName");
this.rewards.add(reward); this.rewards.add(reward);
} }
} }
this.state = State.parsed; this.state = State.parsed;
} }
@Override @Override
public void link() { public void link() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { if (shouldSkipParseOrLink()) {
//This type of state is unrelated to parsing/linking. return;
return; }
} ensureParseIfNeeded();
if (this.state == State.init) { Project proj = getProject();
//Not parsed yet. if (proj == null) {
this.parse(); Notification.addError("Error linking dialogue "+id+". No parent project found.");
} else if (this.state == State.linked) { return;
//Already linked. }
return; if (this.switch_to_npc_id != null) this.switch_to_npc = proj.getNPC(this.switch_to_npc_id);
} if (this.switch_to_npc != null) this.switch_to_npc.addBacklink(this);
Project proj = getProject();
if (proj == null) { if (replies != null) {
Notification.addError("Error linking dialogue "+id+". No parent project found."); for (Reply reply : replies) {
return; if (reply.next_phrase_id != null) {
} if (!Reply.KEY_PHRASE_ID.contains(reply.next_phrase_id)) {
if (this.switch_to_npc_id != null) this.switch_to_npc = proj.getNPC(this.switch_to_npc_id); reply.next_phrase = proj.getDialogue(reply.next_phrase_id);
if (this.switch_to_npc != null) this.switch_to_npc.addBacklink(this); }
}
if (replies != null) { if (reply.next_phrase != null) reply.next_phrase.addBacklink(this);
for (Reply reply : replies) { if (reply.requirements != null) {
if (reply.next_phrase_id != null) { for (Requirement requirement : reply.requirements) {
if (!Reply.KEY_PHRASE_ID.contains(reply.next_phrase_id)) { requirement.link();
reply.next_phrase = proj.getDialogue(reply.next_phrase_id); }
} }
} }
if (reply.next_phrase != null) reply.next_phrase.addBacklink(this); }
if (reply.requirements != null) { if (rewards != null) {
for (Requirement requirement : reply.requirements) { for (Reward reward : rewards) {
requirement.link(); if (reward.reward_obj_id != null) {
} switch (reward.type) {
} case activateMapObjectGroup:
} case deactivateMapObjectGroup:
} case spawnAll:
if (rewards != null) { case removeSpawnArea:
for (Reward reward : rewards) { case deactivateSpawnArea:
if (reward.reward_obj_id != null) { case changeMapFilter:
switch (reward.type) { case mapchange:
case activateMapObjectGroup: reward.map = reward.map_name != null ? proj.getMap(reward.map_name) : null;
case deactivateMapObjectGroup: break;
case spawnAll: case actorCondition:
case removeSpawnArea: case actorConditionImmunity:
case deactivateSpawnArea: reward.reward_obj = proj.getActorCondition(reward.reward_obj_id);
case changeMapFilter: break;
case mapchange: case alignmentChange:
reward.map = reward.map_name != null ? proj.getMap(reward.map_name) : null; case alignmentSet:
break; //Nothing to do (yet ?).
case actorCondition: break;
case actorConditionImmunity: case createTimer:
reward.reward_obj = proj.getActorCondition(reward.reward_obj_id); //Nothing to do.
break; break;
case alignmentChange: case dropList:
case alignmentSet: reward.reward_obj = proj.getDroplist(reward.reward_obj_id);
//Nothing to do (yet ?). break;
break; case giveItem:
case createTimer: reward.reward_obj = proj.getItem(reward.reward_obj_id);
//Nothing to do. break;
break; case questProgress:
case dropList: case removeQuestProgress:
reward.reward_obj = proj.getDroplist(reward.reward_obj_id); reward.reward_obj = proj.getQuest(reward.reward_obj_id);
break; if (reward.reward_obj != null && reward.reward_value != null) {
case giveItem: QuestStage stage = ((Quest)reward.reward_obj).getStage(reward.reward_value);
reward.reward_obj = proj.getItem(reward.reward_obj_id); if (stage != null) {
break; stage.addBacklink(this);
case questProgress: }
case removeQuestProgress: }
reward.reward_obj = proj.getQuest(reward.reward_obj_id); break;
if (reward.reward_obj != null && reward.reward_value != null) { case skillIncrease:
QuestStage stage = ((Quest)reward.reward_obj).getStage(reward.reward_value); //Nothing to do (yet ?).
if (stage != null) { break;
stage.addBacklink(this); }
} if (reward.reward_obj != null) reward.reward_obj.addBacklink(this);
} if (reward.map != null) reward.map.addBacklink(this);
break; }
case skillIncrease: }
//Nothing to do (yet ?). }
break;
} this.state = State.linked;
if (reward.reward_obj != null) reward.reward_obj.addBacklink(this); }
if (reward.map != null) reward.map.addBacklink(this);
}
}
} @Override
public Image getIcon() {
this.state = State.linked; return DefaultIcons.getDialogueIcon();
} }
public Image getImage() {
@Override return DefaultIcons.getDialogueImage();
public Image getIcon() { }
return DefaultIcons.getDialogueIcon();
} @Override
public GameDataElement clone() {
Dialogue clone = new Dialogue();
public Image getImage() { clone.jsonFile = this.jsonFile;
return DefaultIcons.getDialogueImage(); clone.state = this.state;
} clone.id = this.id;
clone.message = this.message;
@Override clone.switch_to_npc_id = this.switch_to_npc_id;
public GameDataElement clone() { clone.switch_to_npc = this.switch_to_npc;
Dialogue clone = new Dialogue(); if (clone.switch_to_npc != null) {
clone.jsonFile = this.jsonFile; clone.switch_to_npc.addBacklink(clone);
clone.state = this.state; }
clone.id = this.id; if (this.rewards != null) {
clone.message = this.message; clone.rewards = new ArrayList<Dialogue.Reward>();
clone.switch_to_npc_id = this.switch_to_npc_id; for (Reward r : this.rewards) {
clone.switch_to_npc = this.switch_to_npc; Reward rclone = new Reward();
if (clone.switch_to_npc != null) { rclone.type = r.type;
clone.switch_to_npc.addBacklink(clone); rclone.reward_obj_id = r.reward_obj_id;
} rclone.reward_value = r.reward_value;
if (this.rewards != null) { rclone.reward_obj = r.reward_obj;
clone.rewards = new ArrayList<Dialogue.Reward>(); if (rclone.reward_obj != null) {
for (Reward r : this.rewards) { rclone.reward_obj.addBacklink(clone);
Reward rclone = new Reward(); }
rclone.type = r.type; rclone.map = r.map;
rclone.reward_obj_id = r.reward_obj_id; rclone.map_name = r.map_name;
rclone.reward_value = r.reward_value; if (rclone.map != null) {
rclone.reward_obj = r.reward_obj; rclone.map.addBacklink(clone);
if (rclone.reward_obj != null) { }
rclone.reward_obj.addBacklink(clone); clone.rewards.add(rclone);
} }
rclone.map = r.map; }
rclone.map_name = r.map_name; if (this.replies != null) {
if (rclone.map != null) { clone.replies = new ArrayList<Dialogue.Reply>();
rclone.map.addBacklink(clone); for (Reply r : this.replies) {
} Reply rclone = new Reply();
clone.rewards.add(rclone); rclone.text = r.text;
} rclone.next_phrase_id = r.next_phrase_id;
} rclone.next_phrase = r.next_phrase;
if (this.replies != null) { if (rclone.next_phrase != null) {
clone.replies = new ArrayList<Dialogue.Reply>(); rclone.next_phrase.addBacklink(clone);
for (Reply r : this.replies) { }
Reply rclone = new Reply(); if (r.requirements != null) {
rclone.text = r.text; rclone.requirements = new ArrayList<Requirement>();
rclone.next_phrase_id = r.next_phrase_id; for (Requirement req : r.requirements) {
rclone.next_phrase = r.next_phrase; //Special clone method, as Requirement is a special GDE, hidden from the project tree.
if (rclone.next_phrase != null) { rclone.requirements.add((Requirement) req.clone(clone));
rclone.next_phrase.addBacklink(clone); }
} }
if (r.requirements != null) { clone.replies.add(rclone);
rclone.requirements = new ArrayList<Requirement>(); }
for (Requirement req : r.requirements) { }
//Special clone method, as Requirement is a special GDE, hidden from the project tree. return clone;
rclone.requirements.add((Requirement) req.clone(clone)); }
}
} @Override
clone.replies.add(rclone); public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} if (switch_to_npc == oldOne) {
} oldOne.removeBacklink(this);
return clone; switch_to_npc = (NPC) newOne;
} if (newOne != null) newOne.addBacklink(this);
} else {
@Override if (replies != null) {
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { for (Reply r : replies) {
if (switch_to_npc == oldOne) { if (r.next_phrase == oldOne) {
oldOne.removeBacklink(this); oldOne.removeBacklink(this);
switch_to_npc = (NPC) newOne; r.next_phrase = (Dialogue) newOne;
if (newOne != null) newOne.addBacklink(this); if (newOne != null) newOne.addBacklink(this);
} else { }
if (replies != null) { if (r.requirements != null) {
for (Reply r : replies) { for (Requirement req : r.requirements) {
if (r.next_phrase == oldOne) { req.elementChanged(oldOne, newOne);
oldOne.removeBacklink(this); }
r.next_phrase = (Dialogue) newOne; }
if (newOne != null) newOne.addBacklink(this); }
} }
if (r.requirements != null) { if (rewards != null) {
for (Requirement req : r.requirements) { for (Reward r : rewards) {
req.elementChanged(oldOne, newOne); if (r.reward_obj == oldOne) {
} oldOne.removeBacklink(this);
} r.reward_obj = newOne;
} if (newOne != null) newOne.addBacklink(this);
} }
if (rewards != null) { if (oldOne instanceof QuestStage) {
for (Reward r : rewards) { if (r.reward_obj != null && r.reward_obj.equals(oldOne.parent) && r.reward_value != null && r.reward_value.equals(((QuestStage) oldOne).progress)) {
if (r.reward_obj == oldOne) { oldOne.removeBacklink((GameDataElement) this);
oldOne.removeBacklink(this); if (newOne != null) newOne.addBacklink((GameDataElement) this);
r.reward_obj = newOne; }
if (newOne != null) newOne.addBacklink(this); }
} }
if (oldOne instanceof QuestStage) { }
if (r.reward_obj != null && r.reward_obj.equals(oldOne.parent) && r.reward_value != null && r.reward_value.equals(((QuestStage) oldOne).progress)) { }
oldOne.removeBacklink((GameDataElement) this); }
if (newOne != null) newOne.addBacklink((GameDataElement) this);
} @SuppressWarnings({ "rawtypes", "unchecked" })
} @Override
} public Map toJson() {
} Map dialogueJson = new LinkedHashMap();
} dialogueJson.put("id", this.id);
} if (this.message != null) dialogueJson.put("message", this.message);
if (this.switch_to_npc != null) {
@SuppressWarnings({ "rawtypes", "unchecked" }) dialogueJson.put("switchToNPC", this.switch_to_npc.id);
@Override } else if (this.switch_to_npc_id != null) {
public Map toJson() { dialogueJson.put("switchToNPC", this.switch_to_npc_id);
Map dialogueJson = new LinkedHashMap(); }
dialogueJson.put("id", this.id); if (this.replies != null) {
if (this.message != null) dialogueJson.put("message", this.message); List repliesJson = new ArrayList();
if (this.switch_to_npc != null) { dialogueJson.put("replies", repliesJson);
dialogueJson.put("switchToNPC", this.switch_to_npc.id); for (Reply reply : this.replies){
} else if (this.switch_to_npc_id != null) { Map replyJson = new LinkedHashMap();
dialogueJson.put("switchToNPC", this.switch_to_npc_id); repliesJson.add(replyJson);
} if (reply.text != null) replyJson.put("text", reply.text);
if (this.replies != null) { if (reply.next_phrase != null) {
List repliesJson = new ArrayList(); replyJson.put("nextPhraseID", reply.next_phrase.id);
dialogueJson.put("replies", repliesJson); } else if (reply.next_phrase_id != null) {
for (Reply reply : this.replies){ replyJson.put("nextPhraseID", reply.next_phrase_id);
Map replyJson = new LinkedHashMap(); }
repliesJson.add(replyJson); if (reply.requirements != null) {
if (reply.text != null) replyJson.put("text", reply.text); List requirementsJson = new ArrayList();
if (reply.next_phrase != null) { replyJson.put("requires", requirementsJson);
replyJson.put("nextPhraseID", reply.next_phrase.id); for (Requirement requirement : reply.requirements) {
} else if (reply.next_phrase_id != null) { Map requirementJson = new LinkedHashMap();
replyJson.put("nextPhraseID", reply.next_phrase_id); requirementsJson.add(requirementJson);
} if (requirement.type != null) requirementJson.put("requireType", requirement.type.toString());
if (reply.requirements != null) { if (requirement.required_obj != null) {
List requirementsJson = new ArrayList(); requirementJson.put("requireID", requirement.required_obj.id);
replyJson.put("requires", requirementsJson); } else if (requirement.required_obj_id != null) {
for (Requirement requirement : reply.requirements) { requirementJson.put("requireID", requirement.required_obj_id);
Map requirementJson = new LinkedHashMap(); }
requirementsJson.add(requirementJson); if (requirement.required_value != null) {
if (requirement.type != null) requirementJson.put("requireType", requirement.type.toString()); requirementJson.put("value", requirement.required_value);
if (requirement.required_obj != null) { }
requirementJson.put("requireID", requirement.required_obj.id); if (requirement.negated != null) requirementJson.put("negate", requirement.negated);
} else if (requirement.required_obj_id != null) { }
requirementJson.put("requireID", requirement.required_obj_id); }
} }
if (requirement.required_value != null) { }
requirementJson.put("value", requirement.required_value); if (this.rewards != null) {
} List rewardsJson = new ArrayList();
if (requirement.negated != null) requirementJson.put("negate", requirement.negated); dialogueJson.put("rewards", rewardsJson);
} for (Reward reward : this.rewards) {
} Map rewardJson = new LinkedHashMap();
} rewardsJson.add(rewardJson);
} if (reward.type != null) rewardJson.put("rewardType", reward.type.toString());
if (this.rewards != null) { if (reward.reward_obj != null) {
List rewardsJson = new ArrayList(); rewardJson.put("rewardID", reward.reward_obj.id);
dialogueJson.put("rewards", rewardsJson); } else if (reward.reward_obj_id != null) {
for (Reward reward : this.rewards) { rewardJson.put("rewardID", reward.reward_obj_id);
Map rewardJson = new LinkedHashMap(); }
rewardsJson.add(rewardJson); if (reward.reward_value != null) rewardJson.put("value", reward.reward_value);
if (reward.type != null) rewardJson.put("rewardType", reward.type.toString()); if (reward.map != null) {
if (reward.reward_obj != null) { rewardJson.put("mapName", reward.map.id);
rewardJson.put("rewardID", reward.reward_obj.id); } else if (reward.map_name != null) rewardJson.put("mapName", reward.map_name);
} else if (reward.reward_obj_id != null) { }
rewardJson.put("rewardID", reward.reward_obj_id); }
} return dialogueJson;
if (reward.reward_value != null) rewardJson.put("value", reward.reward_value); }
if (reward.map != null) {
rewardJson.put("mapName", reward.map.id); @Override
} else if (reward.map_name != null) rewardJson.put("mapName", reward.map_name); public String getProjectFilename() {
} return "conversationlist_"+getProject().name+".json";
} }
return dialogueJson;
} }
@Override
public String getProjectFilename() {
return "conversationlist_"+getProject().name+".json";
}
}

View File

@@ -1,242 +1,235 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class Droplist extends JSONElement { public class Droplist extends JSONElement {
private static final long serialVersionUID = -2903944916807382571L; private static final long serialVersionUID = -2903944916807382571L;
//Available from init state //Available from init state
//public String id = null; inherited. //public String id = null; inherited.
//Available from parsed state; //Available from parsed state;
public List<DroppedItem> dropped_items = null; public List<DroppedItem> dropped_items = null;
//Available from linked state; //Available from linked state;
//None //None
public static class DroppedItem { public static class DroppedItem {
//Available from parsed state; //Available from parsed state;
public String item_id = null; public String item_id = null;
public String chance = null; public String chance = null;
public Integer quantity_min = null; public Integer quantity_min = null;
public Integer quantity_max = null; public Integer quantity_max = null;
//Available from linked state; //Available from linked state;
public Item item = null; public Item item = null;
} }
@Override @Override
public String getDesc() { public String getDesc() {
return (needsSaving() ? "*" : "")+id; return (needsSaving() ? "*" : "")+id;
} }
public static String getStaticDesc() { public static String getStaticDesc() {
return "Droplists"; return "Droplists";
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<Droplist> category) { public static void fromJson(File jsonFile, GameDataCategory<Droplist> category) {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
FileReader reader = null; FileReader reader = null;
try { try {
reader = new FileReader(jsonFile); reader = new FileReader(jsonFile);
List droplists = (List) parser.parse(reader); List droplists = (List) parser.parse(reader);
for (Object obj : droplists) { for (Object obj : droplists) {
Map droplistJson = (Map)obj; Map droplistJson = (Map)obj;
Droplist droplist = fromJson(droplistJson); Droplist droplist = fromJson(droplistJson);
droplist.jsonFile = jsonFile; droplist.jsonFile = jsonFile;
droplist.parent = category; droplist.parent = category;
if (droplist.getDataType() == GameSource.Type.created || droplist.getDataType() == GameSource.Type.altered) { if (droplist.getDataType() == GameSource.Type.created || droplist.getDataType() == GameSource.Type.altered) {
droplist.writable = true; droplist.writable = true;
} }
category.add(droplist); category.add(droplist);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (reader != null) if (reader != null)
try { try {
reader.close(); reader.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Droplist fromJson(String jsonString) throws ParseException { public static Droplist fromJson(String jsonString) throws ParseException {
Map droplistJson = (Map) new JSONParser().parse(jsonString); Map droplistJson = (Map) new JSONParser().parse(jsonString);
Droplist droplist = fromJson(droplistJson); Droplist droplist = fromJson(droplistJson);
droplist.parse(droplistJson); droplist.parse(droplistJson);
return droplist; return droplist;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Droplist fromJson(Map droplistJson) { public static Droplist fromJson(Map droplistJson) {
Droplist droplist = new Droplist(); Droplist droplist = new Droplist();
droplist.id = (String) droplistJson.get("id"); droplist.id = (String) droplistJson.get("id");
return droplist; return droplist;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public void parse(Map droplistJson) { public void parse(Map droplistJson) {
List droppedItemsJson = (List) droplistJson.get("items"); List droppedItemsJson = (List) droplistJson.get("items");
if (droppedItemsJson != null && !droppedItemsJson.isEmpty()) { if (droppedItemsJson != null && !droppedItemsJson.isEmpty()) {
this.dropped_items = new ArrayList<DroppedItem>(); this.dropped_items = new ArrayList<DroppedItem>();
for (Object droppedItemJsonObj : droppedItemsJson) { for (Object droppedItemJsonObj : droppedItemsJson) {
Map droppedItemJson = (Map)droppedItemJsonObj; Map droppedItemJson = (Map)droppedItemJsonObj;
DroppedItem droppedItem = new DroppedItem(); DroppedItem droppedItem = new DroppedItem();
droppedItem.item_id = (String) droppedItemJson.get("itemID"); droppedItem.item_id = (String) droppedItemJson.get("itemID");
//if (droppedItemJson.get("chance") != null) droppedItem.chance = JSONElement.parseChance(droppedItemJson.get("chance").toString()); //if (droppedItemJson.get("chance") != null) droppedItem.chance = JSONElement.parseChance(droppedItemJson.get("chance").toString());
droppedItem.chance = (String) droppedItemJson.get("chance"); droppedItem.chance = (String) droppedItemJson.get("chance");
Map droppedItemQtyJson = (Map) droppedItemJson.get("quantity"); Map droppedItemQtyJson = (Map) droppedItemJson.get("quantity");
if (droppedItemQtyJson != null) { if (droppedItemQtyJson != null) {
droppedItem.quantity_min = JSONElement.getInteger((Number) droppedItemQtyJson.get("min")); droppedItem.quantity_min = JSONElement.getInteger((Number) droppedItemQtyJson.get("min"));
droppedItem.quantity_max = JSONElement.getInteger((Number) droppedItemQtyJson.get("max")); droppedItem.quantity_max = JSONElement.getInteger((Number) droppedItemQtyJson.get("max"));
} }
this.dropped_items.add(droppedItem); this.dropped_items.add(droppedItem);
} }
} }
this.state = State.parsed; this.state = State.parsed;
} }
@Override @Override
public void link() { public void link() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { if (shouldSkipParseOrLink()) {
//This type of state is unrelated to parsing/linking. return;
return; }
} ensureParseIfNeeded();
if (this.state == State.init) { Project proj = getProject();
//Not parsed yet. if (proj == null) {
this.parse(); Notification.addError("Error linking droplist "+id+". No parent project found.");
} else if (this.state == State.linked) { return;
//Already linked. }
return; if (dropped_items != null) {
} for (DroppedItem droppedItem : dropped_items) {
Project proj = getProject(); if (droppedItem.item_id != null) droppedItem.item = proj.getItem(droppedItem.item_id);
if (proj == null) { if (droppedItem.item != null) droppedItem.item.addBacklink(this);
Notification.addError("Error linking droplist "+id+". No parent project found."); }
return; }
} this.state = State.linked;
if (dropped_items != null) { }
for (DroppedItem droppedItem : dropped_items) {
if (droppedItem.item_id != null) droppedItem.item = proj.getItem(droppedItem.item_id);
if (droppedItem.item != null) droppedItem.item.addBacklink(this);
} public static Image getImage() {
} return DefaultIcons.getDroplistImage();
this.state = State.linked; }
}
@Override
public Image getIcon() {
return DefaultIcons.getDroplistIcon();
public static Image getImage() { }
return DefaultIcons.getDroplistImage();
} @Override
public GameDataElement clone() {
@Override Droplist clone = new Droplist();
public Image getIcon() { clone.jsonFile = this.jsonFile;
return DefaultIcons.getDroplistIcon(); clone.state = this.state;
} clone.id = this.id;
if (this.dropped_items != null) {
@Override clone.dropped_items = new ArrayList<Droplist.DroppedItem>();
public GameDataElement clone() { for (DroppedItem di : this.dropped_items) {
Droplist clone = new Droplist(); DroppedItem diclone = new DroppedItem();
clone.jsonFile = this.jsonFile; diclone.chance = di.chance;
clone.state = this.state; diclone.item_id = di.item_id;
clone.id = this.id; diclone.quantity_min = di.quantity_min;
if (this.dropped_items != null) { diclone.quantity_max = di.quantity_max;
clone.dropped_items = new ArrayList<Droplist.DroppedItem>(); diclone.item = di.item;
for (DroppedItem di : this.dropped_items) { if (diclone.item != null) {
DroppedItem diclone = new DroppedItem(); diclone.item.addBacklink(clone);
diclone.chance = di.chance; }
diclone.item_id = di.item_id; clone.dropped_items.add(diclone);
diclone.quantity_min = di.quantity_min; }
diclone.quantity_max = di.quantity_max; }
diclone.item = di.item; return clone;
if (diclone.item != null) { }
diclone.item.addBacklink(clone);
} @Override
clone.dropped_items.add(diclone); public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} if (dropped_items != null) {
} for (DroppedItem di : dropped_items) {
return clone; if (di.item == oldOne) {
} oldOne.removeBacklink(this);
di.item = (Item) newOne;
@Override if (newOne != null) newOne.addBacklink(this);
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { }
if (dropped_items != null) { }
for (DroppedItem di : dropped_items) { }
if (di.item == oldOne) { }
oldOne.removeBacklink(this);
di.item = (Item) newOne; @SuppressWarnings({ "rawtypes", "unchecked" })
if (newOne != null) newOne.addBacklink(this); @Override
} public Map toJson() {
} Map droplistJson = new LinkedHashMap();
} droplistJson.put("id", this.id);
} if (this.dropped_items != null) {
List droppedItemsJson = new ArrayList();
@SuppressWarnings({ "rawtypes", "unchecked" }) droplistJson.put("items", droppedItemsJson);
@Override for (DroppedItem droppedItem : this.dropped_items) {
public Map toJson() { Map droppedItemJson = new LinkedHashMap();
Map droplistJson = new LinkedHashMap(); droppedItemsJson.add(droppedItemJson);
droplistJson.put("id", this.id); if (droppedItem.item != null) {
if (this.dropped_items != null) { droppedItemJson.put("itemID", droppedItem.item.id);
List droppedItemsJson = new ArrayList(); } else if (droppedItem.item_id != null) {
droplistJson.put("items", droppedItemsJson); droppedItemJson.put("itemID", droppedItem.item_id);
for (DroppedItem droppedItem : this.dropped_items) { }
Map droppedItemJson = new LinkedHashMap(); //if (droppedItem.chance != null) droppedItemJson.put("chance", JSONElement.printJsonChance(droppedItem.chance));
droppedItemsJson.add(droppedItemJson); if (droppedItem.chance != null) droppedItemJson.put("chance", droppedItem.chance);
if (droppedItem.item != null) { if (droppedItem.quantity_min != null || droppedItem.quantity_max != null) {
droppedItemJson.put("itemID", droppedItem.item.id); Map quantityJson = new LinkedHashMap();
} else if (droppedItem.item_id != null) { droppedItemJson.put("quantity", quantityJson);
droppedItemJson.put("itemID", droppedItem.item_id); if (droppedItem.quantity_min != null) quantityJson.put("min", droppedItem.quantity_min);
} else quantityJson.put("min", 0);
//if (droppedItem.chance != null) droppedItemJson.put("chance", JSONElement.printJsonChance(droppedItem.chance)); if (droppedItem.quantity_max != null) quantityJson.put("max", droppedItem.quantity_max);
if (droppedItem.chance != null) droppedItemJson.put("chance", droppedItem.chance); else quantityJson.put("max", 0);
if (droppedItem.quantity_min != null || droppedItem.quantity_max != null) { }
Map quantityJson = new LinkedHashMap(); }
droppedItemJson.put("quantity", quantityJson); }
if (droppedItem.quantity_min != null) quantityJson.put("min", droppedItem.quantity_min); return droplistJson;
else quantityJson.put("min", 0); }
if (droppedItem.quantity_max != null) quantityJson.put("max", droppedItem.quantity_max);
else quantityJson.put("max", 0);
} @Override
} public String getProjectFilename() {
} return "droplists_"+getProject().name+".json";
return droplistJson; }
}
}
@Override
public String getProjectFilename() {
return "droplists_"+getProject().name+".json";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,329 +1,322 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
public class ItemCategory extends JSONElement { public class ItemCategory extends JSONElement {
private static final long serialVersionUID = -348864002519568300L; private static final long serialVersionUID = -348864002519568300L;
public static final String ICON_NO_SLOT_RES = "/com/gpl/rpg/atcontentstudio/img/equip_square.png"; public static final String ICON_NO_SLOT_RES = "/com/gpl/rpg/atcontentstudio/img/equip_square.png";
public static final String ICON_BODY_RES = "/com/gpl/rpg/atcontentstudio/img/equip_body.png"; public static final String ICON_BODY_RES = "/com/gpl/rpg/atcontentstudio/img/equip_body.png";
public static final String ICON_FEET_RES = "/com/gpl/rpg/atcontentstudio/img/equip_feet.png"; public static final String ICON_FEET_RES = "/com/gpl/rpg/atcontentstudio/img/equip_feet.png";
public static final String ICON_HAND_RES = "/com/gpl/rpg/atcontentstudio/img/equip_hand.png"; public static final String ICON_HAND_RES = "/com/gpl/rpg/atcontentstudio/img/equip_hand.png";
public static final String ICON_HEAD_RES = "/com/gpl/rpg/atcontentstudio/img/equip_head.png"; public static final String ICON_HEAD_RES = "/com/gpl/rpg/atcontentstudio/img/equip_head.png";
public static final String ICON_NECK_RES = "/com/gpl/rpg/atcontentstudio/img/equip_neck.png"; public static final String ICON_NECK_RES = "/com/gpl/rpg/atcontentstudio/img/equip_neck.png";
public static final String ICON_RING_RES = "/com/gpl/rpg/atcontentstudio/img/equip_ring.png"; public static final String ICON_RING_RES = "/com/gpl/rpg/atcontentstudio/img/equip_ring.png";
public static final String ICON_SHIELD_RES = "/com/gpl/rpg/atcontentstudio/img/equip_shield.png"; public static final String ICON_SHIELD_RES = "/com/gpl/rpg/atcontentstudio/img/equip_shield.png";
public static final String ICON_WEAPON_RES = "/com/gpl/rpg/atcontentstudio/img/equip_weapon.png"; public static final String ICON_WEAPON_RES = "/com/gpl/rpg/atcontentstudio/img/equip_weapon.png";
public static Image no_slot_image = null; public static Image no_slot_image = null;
public static Image no_slot_icon = null; public static Image no_slot_icon = null;
public static Image body_image = null; public static Image body_image = null;
public static Image body_icon = null; public static Image body_icon = null;
public static Image feet_image = null; public static Image feet_image = null;
public static Image feet_icon = null; public static Image feet_icon = null;
public static Image hand_image = null; public static Image hand_image = null;
public static Image hand_icon = null; public static Image hand_icon = null;
public static Image head_image = null; public static Image head_image = null;
public static Image head_icon = null; public static Image head_icon = null;
public static Image neck_image = null; public static Image neck_image = null;
public static Image neck_icon = null; public static Image neck_icon = null;
public static Image ring_image = null; public static Image ring_image = null;
public static Image ring_icon = null; public static Image ring_icon = null;
public static Image shield_image = null; public static Image shield_image = null;
public static Image shield_icon = null; public static Image shield_icon = null;
public static Image weapon_image = null; public static Image weapon_image = null;
public static Image weapon_icon = null; public static Image weapon_icon = null;
//Available from init state //Available from init state
//public String id = null; inherited. //public String id = null; inherited.
public String name = null; public String name = null;
public InventorySlot slot = null; public InventorySlot slot = null;
//Available from parsed state //Available from parsed state
public ActionType action_type = null; public ActionType action_type = null;
public Size size = null; public Size size = null;
//Available from linked state //Available from linked state
//None //None
public static enum ActionType { public static enum ActionType {
none, none,
use, use,
equip equip
} }
public static enum Size { public static enum Size {
none, none,
light, light,
std, std,
large large
} }
public static enum InventorySlot { public static enum InventorySlot {
weapon, weapon,
shield, shield,
head, head,
body, body,
hand, hand,
feet, feet,
neck, neck,
leftring, leftring,
rightring rightring
} }
@Override @Override
public String getDesc() { public String getDesc() {
return (needsSaving() ? "*" : "")+name+" ("+id+")"; return (needsSaving() ? "*" : "")+name+" ("+id+")";
} }
public static String getStaticDesc() { public static String getStaticDesc() {
return "Item categories"; return "Item categories";
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<ItemCategory> category) { public static void fromJson(File jsonFile, GameDataCategory<ItemCategory> category) {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
FileReader reader = null; FileReader reader = null;
try { try {
reader = new FileReader(jsonFile); reader = new FileReader(jsonFile);
List itemCategories = (List) parser.parse(reader); List itemCategories = (List) parser.parse(reader);
for (Object obj : itemCategories) { for (Object obj : itemCategories) {
Map itemCatJson = (Map)obj; Map itemCatJson = (Map)obj;
ItemCategory itemCat = fromJson(itemCatJson); ItemCategory itemCat = fromJson(itemCatJson);
itemCat.jsonFile = jsonFile; itemCat.jsonFile = jsonFile;
itemCat.parent = category; itemCat.parent = category;
if (itemCat.getDataType() == GameSource.Type.created || itemCat.getDataType() == GameSource.Type.altered) { if (itemCat.getDataType() == GameSource.Type.created || itemCat.getDataType() == GameSource.Type.altered) {
itemCat.writable = true; itemCat.writable = true;
} }
category.add(itemCat); category.add(itemCat);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (reader != null) if (reader != null)
try { try {
reader.close(); reader.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static ItemCategory fromJson(String jsonString) throws ParseException { public static ItemCategory fromJson(String jsonString) throws ParseException {
Map itemCatJson = (Map) new JSONParser().parse(jsonString); Map itemCatJson = (Map) new JSONParser().parse(jsonString);
ItemCategory item = fromJson(itemCatJson); ItemCategory item = fromJson(itemCatJson);
item.parse(itemCatJson); item.parse(itemCatJson);
return item; return item;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static ItemCategory fromJson(Map itemCatJson) { public static ItemCategory fromJson(Map itemCatJson) {
ItemCategory itemCat = new ItemCategory(); ItemCategory itemCat = new ItemCategory();
itemCat.id = (String) itemCatJson.get("id"); itemCat.id = (String) itemCatJson.get("id");
itemCat.name = (String) itemCatJson.get("name"); itemCat.name = (String) itemCatJson.get("name");
if (itemCatJson.get("inventorySlot") != null) itemCat.slot = InventorySlot.valueOf((String) itemCatJson.get("inventorySlot")); if (itemCatJson.get("inventorySlot") != null) itemCat.slot = InventorySlot.valueOf((String) itemCatJson.get("inventorySlot"));
return itemCat; return itemCat;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public void parse(Map itemCatJson) { public void parse(Map itemCatJson) {
if (itemCatJson.get("actionType") != null) action_type = ActionType.valueOf((String) itemCatJson.get("actionType")); if (itemCatJson.get("actionType") != null) action_type = ActionType.valueOf((String) itemCatJson.get("actionType"));
if (itemCatJson.get("size") != null) size = Size.valueOf((String) itemCatJson.get("size")); if (itemCatJson.get("size") != null) size = Size.valueOf((String) itemCatJson.get("size"));
this.state = State.parsed; this.state = State.parsed;
} }
@Override @Override
public void link() { public void link() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { if (shouldSkipParseOrLink()) {
//This type of state is unrelated to parsing/linking. return;
return; }
} ensureParseIfNeeded();
if (this.state == State.init) {
//Not parsed yet. //Nothing to link to :D
this.parse(); this.state = State.linked;
} else if (this.state == State.linked) { }
//Already linked.
return; @Override
} public Image getIcon() {
return getIcon(this.slot);
//Nothing to link to :D }
this.state = State.linked;
} public Image getImage() {
return getImage(this.slot);
@Override }
public Image getIcon() {
return getIcon(this.slot); public static Image getImage(InventorySlot slot) {
} if (slot == null) {
return getImage(ICON_NO_SLOT_RES, no_slot_image, "no_slot_image");
public Image getImage() { }
return getImage(this.slot); switch (slot) {
} case body:
return getImage(ICON_BODY_RES, body_image, "body_image");
public static Image getImage(InventorySlot slot) { case feet:
if (slot == null) { return getImage(ICON_FEET_RES, feet_image, "feet_image");
return getImage(ICON_NO_SLOT_RES, no_slot_image, "no_slot_image"); case hand:
} return getImage(ICON_HAND_RES, hand_image, "hand_image");
switch (slot) { case head:
case body: return getImage(ICON_HEAD_RES, head_image, "head_image");
return getImage(ICON_BODY_RES, body_image, "body_image"); case leftring:
case feet: case rightring:
return getImage(ICON_FEET_RES, feet_image, "feet_image"); return getImage(ICON_RING_RES, ring_image, "ring_image");
case hand: case neck:
return getImage(ICON_HAND_RES, hand_image, "hand_image"); return getImage(ICON_NECK_RES, neck_image, "neck_image");
case head: case shield:
return getImage(ICON_HEAD_RES, head_image, "head_image"); return getImage(ICON_SHIELD_RES, shield_image, "shield_image");
case leftring: case weapon:
case rightring: return getImage(ICON_WEAPON_RES, weapon_image, "weapon_image");
return getImage(ICON_RING_RES, ring_image, "ring_image"); default:
case neck: return getImage(ICON_NO_SLOT_RES, no_slot_image, "no_slot_image");
return getImage(ICON_NECK_RES, neck_image, "neck_image"); }
case shield: }
return getImage(ICON_SHIELD_RES, shield_image, "shield_image");
case weapon: public static Image getIcon(InventorySlot slot) {
return getImage(ICON_WEAPON_RES, weapon_image, "weapon_image"); if (slot == null) {
default: return getIcon(ICON_NO_SLOT_RES, no_slot_image, no_slot_icon, "no_slot_image", "no_slot_icon");
return getImage(ICON_NO_SLOT_RES, no_slot_image, "no_slot_image"); }
} switch (slot) {
} case body:
return getIcon(ICON_BODY_RES, body_image, body_icon, "body_image", "body_icon");
public static Image getIcon(InventorySlot slot) { case feet:
if (slot == null) { return getIcon(ICON_FEET_RES, feet_image, feet_icon, "feet_image", "feet_icon");
return getIcon(ICON_NO_SLOT_RES, no_slot_image, no_slot_icon, "no_slot_image", "no_slot_icon"); case hand:
} return getIcon(ICON_HAND_RES, hand_image, hand_icon, "hand_image", "hand_icon");
switch (slot) { case head:
case body: return getIcon(ICON_HEAD_RES, head_image, head_icon, "head_image", "head_icon");
return getIcon(ICON_BODY_RES, body_image, body_icon, "body_image", "body_icon"); case leftring:
case feet: case rightring:
return getIcon(ICON_FEET_RES, feet_image, feet_icon, "feet_image", "feet_icon"); return getIcon(ICON_RING_RES, ring_image, ring_icon, "ring_image", "ring_icon");
case hand: case neck:
return getIcon(ICON_HAND_RES, hand_image, hand_icon, "hand_image", "hand_icon"); return getIcon(ICON_NECK_RES, neck_image, neck_icon, "neck_image", "neck_icon");
case head: case shield:
return getIcon(ICON_HEAD_RES, head_image, head_icon, "head_image", "head_icon"); return getIcon(ICON_SHIELD_RES, shield_image, shield_icon, "shield_image", "shield_icon");
case leftring: case weapon:
case rightring: return getIcon(ICON_WEAPON_RES, weapon_image, weapon_icon, "weapon_image", "weapon_icon");
return getIcon(ICON_RING_RES, ring_image, ring_icon, "ring_image", "ring_icon"); default:
case neck: return getIcon(ICON_NO_SLOT_RES, no_slot_image, no_slot_icon, "no_slot_image", "no_slot_icon");
return getIcon(ICON_NECK_RES, neck_image, neck_icon, "neck_image", "neck_icon"); }
case shield: }
return getIcon(ICON_SHIELD_RES, shield_image, shield_icon, "shield_image", "shield_icon");
case weapon: public static Image getImage(String res, Image img, String fieldName) {
return getIcon(ICON_WEAPON_RES, weapon_image, weapon_icon, "weapon_image", "weapon_icon"); if (img == null) {
default: try {
return getIcon(ICON_NO_SLOT_RES, no_slot_image, no_slot_icon, "no_slot_image", "no_slot_icon"); img = ImageIO.read(ItemCategory.class.getResourceAsStream(res));
} ItemCategory.class.getField(fieldName).set(null, img);
} } catch (IllegalArgumentException e) {
e.printStackTrace();
public static Image getImage(String res, Image img, String fieldName) { } catch (SecurityException e) {
if (img == null) { e.printStackTrace();
try { } catch (IllegalAccessException e) {
img = ImageIO.read(ItemCategory.class.getResourceAsStream(res)); e.printStackTrace();
ItemCategory.class.getField(fieldName).set(null, img); } catch (NoSuchFieldException e) {
} catch (IllegalArgumentException e) { e.printStackTrace();
e.printStackTrace(); } catch (IOException e) {
} catch (SecurityException e) { Notification.addError("Failed to load item category icon "+res);
e.printStackTrace(); e.printStackTrace();
} catch (IllegalAccessException e) { }
e.printStackTrace(); }
} catch (NoSuchFieldException e) { return img;
e.printStackTrace(); }
} catch (IOException e) {
Notification.addError("Failed to load item category icon "+res); public static Image getIcon(String res, Image img, Image icon, String imgFieldName, String iconFieldName) {
e.printStackTrace(); if (icon == null) {
} icon = getImage(res, img, imgFieldName).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
} try {
return img; ItemCategory.class.getField(iconFieldName).set(null, icon);
} } catch (IllegalArgumentException e) {
e.printStackTrace();
public static Image getIcon(String res, Image img, Image icon, String imgFieldName, String iconFieldName) { } catch (SecurityException e) {
if (icon == null) { e.printStackTrace();
icon = getImage(res, img, imgFieldName).getScaledInstance(16, 16, Image.SCALE_SMOOTH); } catch (IllegalAccessException e) {
try { e.printStackTrace();
ItemCategory.class.getField(iconFieldName).set(null, icon); } catch (NoSuchFieldException e) {
} catch (IllegalArgumentException e) { e.printStackTrace();
e.printStackTrace(); }
} catch (SecurityException e) { }
e.printStackTrace(); return icon;
} catch (IllegalAccessException e) { }
e.printStackTrace();
} catch (NoSuchFieldException e) { @Override
e.printStackTrace(); public GameDataElement clone() {
} ItemCategory clone = new ItemCategory();
} clone.jsonFile = this.jsonFile;
return icon; clone.state = this.state;
} clone.id = this.id;
clone.name = this.name;
@Override clone.size = this.size;
public GameDataElement clone() { clone.slot = this.slot;
ItemCategory clone = new ItemCategory(); clone.action_type = this.action_type;
clone.jsonFile = this.jsonFile; return clone;
clone.state = this.state; }
clone.id = this.id;
clone.name = this.name; @Override
clone.size = this.size; public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
clone.slot = this.slot; // Nothing to link to.
clone.action_type = this.action_type; }
return clone;
} @SuppressWarnings({ "rawtypes", "unchecked" })
@Override
@Override public Map toJson() {
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { Map itemCatJson = new LinkedHashMap();
// Nothing to link to. itemCatJson.put("id", this.id);
} if (this.name != null) itemCatJson.put("name", this.name);
if (this.action_type != null) itemCatJson.put("actionType", this.action_type.toString());
@SuppressWarnings({ "rawtypes", "unchecked" }) if (this.size != null) itemCatJson.put("size", this.size.toString());
@Override if (this.slot != null) itemCatJson.put("inventorySlot", this.slot.toString());
public Map toJson() { return itemCatJson;
Map itemCatJson = new LinkedHashMap(); }
itemCatJson.put("id", this.id);
if (this.name != null) itemCatJson.put("name", this.name);
if (this.action_type != null) itemCatJson.put("actionType", this.action_type.toString()); @Override
if (this.size != null) itemCatJson.put("size", this.size.toString()); public String getProjectFilename() {
if (this.slot != null) itemCatJson.put("inventorySlot", this.slot.toString()); return "itemcategories_"+getProject().name+".json";
return itemCatJson; }
}
}
@Override
public String getProjectFilename() {
return "itemcategories_"+getProject().name+".json";
}
}

View File

@@ -1,180 +1,179 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
public abstract class JSONElement extends GameDataElement { public abstract class JSONElement extends GameDataElement {
private static final long serialVersionUID = -8015398814080503982L; private static final long serialVersionUID = -8015398814080503982L;
//Available from state init. //Available from state init.
public File jsonFile; public File jsonFile;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void parse() { public void parse() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { if (shouldSkipParseOrLink()) {
//This type of state is unrelated to parsing/linking. return;
return; }
} JSONParser parser = new JSONParser();
JSONParser parser = new JSONParser(); FileReader reader = null;
FileReader reader = null; try {
try { reader = new FileReader(jsonFile);
reader = new FileReader(jsonFile); List gameDataElements = (List) parser.parse(reader);
List gameDataElements = (List) parser.parse(reader); for (Object obj : gameDataElements) {
for (Object obj : gameDataElements) { Map jsonObj = (Map)obj;
Map jsonObj = (Map)obj; String id = (String) jsonObj.get("id");
String id = (String) jsonObj.get("id"); try {
try { if (id != null && id.equals(this.id )) {
if (id != null && id.equals(this.id )) { this.parse(jsonObj);
this.parse(jsonObj); this.state = State.parsed;
this.state = State.parsed; break;
break; }
} }
} catch(Exception e){
catch(Exception e){ System.out.println("Error in ID: " + id);
System.out.println("Error in ID: " + id); System.out.println(e.getMessage());
System.out.println(e.getMessage()); }
} }
} } catch (FileNotFoundException e) {
} catch (FileNotFoundException e) { Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); e.printStackTrace();
e.printStackTrace(); } catch (IOException e) {
} catch (IOException e) { Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); e.printStackTrace();
e.printStackTrace(); } catch (ParseException e) {
} catch (ParseException e) { Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); e.printStackTrace();
e.printStackTrace(); } catch (IllegalArgumentException e) {
} catch (IllegalArgumentException e) { System.out.println(id);
System.out.println(id); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); e.printStackTrace();
e.printStackTrace(); } finally {
} finally { if (reader != null)
if (reader != null) try {
try { reader.close();
reader.close(); } catch (IOException e) {
} catch (IOException e) { e.printStackTrace();
e.printStackTrace(); }
} }
}
}
}
public abstract void parse(@SuppressWarnings("rawtypes") Map jsonObj);
public abstract void parse(@SuppressWarnings("rawtypes") Map jsonObj);
@SuppressWarnings("rawtypes")
@SuppressWarnings("rawtypes") public abstract Map toJson();
public abstract Map toJson(); public String toJsonString() {
public String toJsonString() { StringWriter writer = new JsonPrettyWriter();
StringWriter writer = new JsonPrettyWriter(); try {
try { JSONObject.writeJSONString(this.toJson(), writer);
JSONObject.writeJSONString(this.toJson(), writer); } catch (IOException e) {
} catch (IOException e) { //Impossible with a StringWriter
//Impossible with a StringWriter }
} return writer.toString();
return writer.toString(); }
}
@Override
@Override public GameDataSet getDataSet() {
public GameDataSet getDataSet() { if (parent == null) {
if (parent == null) { System.out.println("blerf.");
System.out.println("blerf."); }
} return parent.getDataSet();
return parent.getDataSet(); }
}
public void save() {
public void save() { if (this.getParent() instanceof GameDataCategory<?> && writable) {
if (this.getParent() instanceof GameDataCategory<?> && writable) { ((GameDataCategory<?>)this.getParent()).save(this.jsonFile);
((GameDataCategory<?>)this.getParent()).save(this.jsonFile); }
} }
}
/**
/** * Returns null if save occurred (no notable events).
* Returns null if save occurred (no notable events). */
*/ public List<SaveEvent> attemptSave() {
public List<SaveEvent> attemptSave() { List<SaveEvent> events = ((GameDataCategory<?>)this.getParent()).attemptSave(true, this.jsonFile.getName());
List<SaveEvent> events = ((GameDataCategory<?>)this.getParent()).attemptSave(true, this.jsonFile.getName()); if (events == null || events.isEmpty()) {
if (events == null || events.isEmpty()) { return null;
return null; }
} if (events.size() == 1 && events.get(0).type == SaveEvent.Type.alsoSave && events.get(0).target == this) {
if (events.size() == 1 && events.get(0).type == SaveEvent.Type.alsoSave && events.get(0).target == this) { save();
save(); return null;
return null; }
} return events;
return events; }
}
public static Integer getInteger(Number n) {
public static Integer getInteger(Number n) { return n == null ? null : n.intValue();
return n == null ? null : n.intValue(); }
}
public static Double getDouble(Number n) {
public static Double getDouble(Number n) { return n == null ? null : n.doubleValue();
return n == null ? null : n.doubleValue(); }
}
public static Double parseChance(String s) {
public static Double parseChance(String s) { if (s.equals("100")) return 100d;
if (s.equals("100")) return 100d; else if (s.equals("70")) return 70d;
else if (s.equals("70")) return 70d; else if (s.equals("30")) return 30d;
else if (s.equals("30")) return 30d; else if (s.equals("25")) return 25d;
else if (s.equals("25")) return 25d; else if (s.equals("20")) return 20d;
else if (s.equals("20")) return 20d; else if (s.equals("10")) return 10d;
else if (s.equals("10")) return 10d; else if (s.equals("5")) return 5d;
else if (s.equals("5")) return 5d; else if (s.equals("1")) return 1d;
else if (s.equals("1")) return 1d; else if (s.equals("1/1000")) return 0.1;
else if (s.equals("1/1000")) return 0.1; else if (s.equals("1/10000")) return 0.01;
else if (s.equals("1/10000")) return 0.01; else if (s.indexOf('/') >= 0) {
else if (s.indexOf('/') >= 0) { int c = s.indexOf('/');
int c = s.indexOf('/'); double a = 1;
double a = 1; try {
try { a = Integer.parseInt(s.substring(0, c));
a = Integer.parseInt(s.substring(0, c)); } catch (NumberFormatException nfe) {}
} catch (NumberFormatException nfe) {} double b = 100;
double b = 100; try {
try { b = Integer.parseInt(s.substring(c+1));
b = Integer.parseInt(s.substring(c+1)); } catch (NumberFormatException nfe) {}
} catch (NumberFormatException nfe) {} return a/b;
return a/b; }
} else {
else { double a = 10;
double a = 10; try {
try { a = Double.parseDouble(s);
a = Double.parseDouble(s); } catch (NumberFormatException nfe) {}
} catch (NumberFormatException nfe) {} return a;
return a; }
} }
}
public static String printJsonChance(Double chance) {
public static String printJsonChance(Double chance) { if (chance.equals(100d)) return "100";
if (chance.equals(100d)) return "100"; else if (chance.equals(70d)) return "70";
else if (chance.equals(70d)) return "70"; else if (chance.equals(30d)) return "30";
else if (chance.equals(30d)) return "30"; else if (chance.equals(25d)) return "25";
else if (chance.equals(25d)) return "25"; else if (chance.equals(20d)) return "20";
else if (chance.equals(20d)) return "20"; else if (chance.equals(10d)) return "10";
else if (chance.equals(10d)) return "10"; else if (chance.equals(5d)) return "5";
else if (chance.equals(5d)) return "5"; else if (chance.equals(1d)) return "1";
else if (chance.equals(1d)) return "1"; else if (chance.equals(0.1d)) return "1/1000";
else if (chance.equals(0.1d)) return "1/1000"; else if (chance.equals(0.01d)) return "1/10000";
else if (chance.equals(0.01d)) return "1/10000"; else {
else { if (chance.intValue() == chance) return Integer.toString(chance.intValue());
if (chance.intValue() == chance) return Integer.toString(chance.intValue()); //TODO Better handling of fractions. Chance description need a complete overhaul in AT.
//TODO Better handling of fractions. Chance description need a complete overhaul in AT. //This part does not output the input content of parseDouble(String s) in the case of fractions.
//This part does not output the input content of parseDouble(String s) in the case of fractions. return chance.toString();
return chance.toString(); }
} }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,198 +1,191 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image; import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class Quest extends JSONElement { public class Quest extends JSONElement {
private static final long serialVersionUID = 2004839647483250099L; private static final long serialVersionUID = 2004839647483250099L;
//Available from init state //Available from init state
//public String id = null; inherited. //public String id = null; inherited.
public String name = null; public String name = null;
//Available in parsed state //Available in parsed state
public Integer visible_in_log = null; public Integer visible_in_log = null;
public List<QuestStage> stages = null; public List<QuestStage> stages = null;
@Override @Override
public String getDesc() { public String getDesc() {
return (needsSaving() ? "*" : "")+name+" ("+id+")"; return (needsSaving() ? "*" : "")+name+" ("+id+")";
} }
public static String getStaticDesc() { public static String getStaticDesc() {
return "Quests"; return "Quests";
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<Quest> category) { public static void fromJson(File jsonFile, GameDataCategory<Quest> category) {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
FileReader reader = null; FileReader reader = null;
try { try {
reader = new FileReader(jsonFile); reader = new FileReader(jsonFile);
List quests = (List) parser.parse(reader); List quests = (List) parser.parse(reader);
for (Object obj : quests) { for (Object obj : quests) {
Map questJson = (Map)obj; Map questJson = (Map)obj;
Quest quest = fromJson(questJson); Quest quest = fromJson(questJson);
quest.jsonFile = jsonFile; quest.jsonFile = jsonFile;
quest.parent = category; quest.parent = category;
if (quest.getDataType() == GameSource.Type.created || quest.getDataType() == GameSource.Type.altered) { if (quest.getDataType() == GameSource.Type.created || quest.getDataType() == GameSource.Type.altered) {
quest.writable = true; quest.writable = true;
} }
category.add(quest); category.add(quest);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage()); Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (reader != null) if (reader != null)
try { try {
reader.close(); reader.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Quest fromJson(String jsonString) throws ParseException { public static Quest fromJson(String jsonString) throws ParseException {
Map questJson = (Map) new JSONParser().parse(jsonString); Map questJson = (Map) new JSONParser().parse(jsonString);
Quest quest = fromJson(questJson); Quest quest = fromJson(questJson);
quest.parse(questJson); quest.parse(questJson);
return quest; return quest;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Quest fromJson(Map questJson) { public static Quest fromJson(Map questJson) {
Quest quest = new Quest(); Quest quest = new Quest();
quest.id = (String) questJson.get("id"); quest.id = (String) questJson.get("id");
quest.name = (String) questJson.get("name"); quest.name = (String) questJson.get("name");
//Quests have to be parsed to have their stages initialized. //Quests have to be parsed to have their stages initialized.
quest.parse(questJson); quest.parse(questJson);
return quest; return quest;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public void parse(Map questJson) { public void parse(Map questJson) {
this.visible_in_log = JSONElement.getInteger((Number) questJson.get("showInLog")); this.visible_in_log = JSONElement.getInteger((Number) questJson.get("showInLog"));
List questStagesJson = (List) questJson.get("stages"); List questStagesJson = (List) questJson.get("stages");
this.stages = new ArrayList<QuestStage>(); this.stages = new ArrayList<QuestStage>();
if (questStagesJson != null && !questStagesJson.isEmpty()) { if (questStagesJson != null && !questStagesJson.isEmpty()) {
for (Object questStageJsonObj : questStagesJson) { for (Object questStageJsonObj : questStagesJson) {
Map questStageJson = (Map)questStageJsonObj; Map questStageJson = (Map)questStageJsonObj;
QuestStage questStage = new QuestStage(this); QuestStage questStage = new QuestStage(this);
questStage.parse(questStageJson); questStage.parse(questStageJson);
this.stages.add(questStage); this.stages.add(questStage);
} }
} }
this.state = State.parsed; this.state = State.parsed;
} }
@Override @Override
public void link() { public void link() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { if (shouldSkipParseOrLink()) {
//This type of state is unrelated to parsing/linking. return;
return; }
} ensureParseIfNeeded();
if (this.state == State.init) {
//Not parsed yet. for (QuestStage stage : stages) {
this.parse(); stage.link();
} else if (this.state == State.linked) { }
//Already linked. //Nothing to link to :D
return; this.state = State.linked;
} }
for (QuestStage stage : stages) { @Override
stage.link(); public Image getIcon() {
} return DefaultIcons.getQuestIcon();
//Nothing to link to :D }
this.state = State.linked;
} public Image getImage() {
return DefaultIcons.getQuestImage();
@Override }
public Image getIcon() {
return DefaultIcons.getQuestIcon(); @Override
} public GameDataElement clone() {
Quest clone = new Quest();
public Image getImage() { clone.jsonFile = this.jsonFile;
return DefaultIcons.getQuestImage(); clone.state = this.state;
} clone.id = this.id;
clone.name = this.name;
@Override clone.visible_in_log = this.visible_in_log;
public GameDataElement clone() { if (this.stages != null) {
Quest clone = new Quest(); clone.stages = new ArrayList<QuestStage>();
clone.jsonFile = this.jsonFile; for (QuestStage stage : this.stages){
clone.state = this.state; clone.stages.add((QuestStage) stage.clone(clone));
clone.id = this.id; }
clone.name = this.name; }
clone.visible_in_log = this.visible_in_log; return clone;
if (this.stages != null) { }
clone.stages = new ArrayList<QuestStage>();
for (QuestStage stage : this.stages){ @Override
clone.stages.add((QuestStage) stage.clone(clone)); public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} //Nothing to link to.
} }
return clone;
} @SuppressWarnings({ "rawtypes", "unchecked" })
@Override
@Override public Map toJson() {
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { Map questJson = new LinkedHashMap();
//Nothing to link to. questJson.put("id", this.id);
} if (this.name != null) questJson.put("name", this.name);
if (this.visible_in_log != null) questJson.put("showInLog", this.visible_in_log);
@SuppressWarnings({ "rawtypes", "unchecked" }) if (this.stages != null) {
@Override List stagesJson = new ArrayList();
public Map toJson() { questJson.put("stages", stagesJson);
Map questJson = new LinkedHashMap(); for (QuestStage stage : this.stages) {
questJson.put("id", this.id); stagesJson.add(stage.toJson());
if (this.name != null) questJson.put("name", this.name); }
if (this.visible_in_log != null) questJson.put("showInLog", this.visible_in_log); }
if (this.stages != null) { return questJson;
List stagesJson = new ArrayList(); }
questJson.put("stages", stagesJson);
for (QuestStage stage : this.stages) {
stagesJson.add(stage.toJson()); @Override
} public String getProjectFilename() {
} return "questlist_"+getProject().name+".json";
return questJson; }
}
public QuestStage getStage(Integer stageId) {
for (QuestStage stage : stages) {
@Override if (stage.progress.equals(stageId)) {
public String getProjectFilename() { return stage;
return "questlist_"+getProject().name+".json"; }
} }
return null;
public QuestStage getStage(Integer stageId) { }
for (QuestStage stage : stages) {
if (stage.progress.equals(stageId)) { }
return stage;
}
}
return null;
}
}

View File

@@ -8,18 +8,18 @@ import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class QuestStage extends JSONElement { public class QuestStage extends JSONElement {
private static final long serialVersionUID = 8313645819951513431L; private static final long serialVersionUID = 8313645819951513431L;
public Integer progress = null; public Integer progress = null;
public String log_text = null; public String log_text = null;
public Integer exp_reward = null; public Integer exp_reward = null;
public Integer finishes_quest = null; public Integer finishes_quest = null;
public QuestStage(Quest parent){ public QuestStage(Quest parent){
this.parent = parent; this.parent = parent;
} }
public QuestStage clone(Quest cloneParent) { public QuestStage clone(Quest cloneParent) {
QuestStage clone = new QuestStage(cloneParent); QuestStage clone = new QuestStage(cloneParent);
clone.progress = progress != null ? new Integer(progress) : null; clone.progress = progress != null ? new Integer(progress) : null;
@@ -59,18 +59,11 @@ public class QuestStage extends JSONElement {
@Override @Override
public void link() { public void link() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { if (shouldSkipParseOrLink()) {
//This type of state is unrelated to parsing/linking.
return; return;
} }
if (this.state == State.init) { ensureParseIfNeeded();
//Not parsed yet.
this.parse();
} else if (this.state == State.linked) {
//Already linked.
return;
}
//Nothing to link to :D //Nothing to link to :D
this.state = State.linked; this.state = State.linked;
} }
@@ -89,15 +82,15 @@ public class QuestStage extends JSONElement {
public GameDataElement clone() { public GameDataElement clone() {
return null; return null;
} }
@Override @Override
public Image getIcon() { public Image getIcon() {
return DefaultIcons.getQuestIcon(); return DefaultIcons.getQuestIcon();
} }
public Image getImage() { public Image getImage() {
return DefaultIcons.getQuestImage(); return DefaultIcons.getQuestImage();
} }
} }

View File

@@ -71,6 +71,9 @@ public class ReplaceArea extends MapObject {
addReplacement(repl); addReplacement(repl);
return repl; return repl;
} }
public ReplaceArea.Replacement createReplacement(String source, String target) {
return new Replacement(source, target);
}
public void addReplacement(ReplaceArea.Replacement repl) { public void addReplacement(ReplaceArea.Replacement repl) {
if (replacements == null) replacements = new ArrayList<ReplaceArea.Replacement>(); if (replacements == null) replacements = new ArrayList<ReplaceArea.Replacement>();

View File

@@ -28,6 +28,7 @@ public class PotGenerator {
for (ActorCondition ac : gsrc.gameData.actorConditions) { for (ActorCondition ac : gsrc.gameData.actorConditions) {
pushString(stringsResources, resourcesStrings, ac.display_name, getPotContextComment(ac)); pushString(stringsResources, resourcesStrings, ac.display_name, getPotContextComment(ac));
pushString(stringsResources, resourcesStrings, ac.description, getPotContextComment(ac)+":description");
} }
for (Dialogue d : gsrc.gameData.dialogues ) { for (Dialogue d : gsrc.gameData.dialogues ) {

View File

@@ -30,6 +30,7 @@ public class ActorConditionEditor extends JSONElementEditor {
private JButton acIcon; private JButton acIcon;
private JTextField idField; private JTextField idField;
private JTextField nameField; private JTextField nameField;
private JTextField descriptionField;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private JComboBox categoryBox; private JComboBox categoryBox;
private IntegerBasedCheckBox positiveBox; private IntegerBasedCheckBox positiveBox;
@@ -81,6 +82,7 @@ public class ActorConditionEditor extends JSONElementEditor {
idField = addTextField(pane, "Internal ID: ", ac.id, ac.writable, listener); idField = addTextField(pane, "Internal ID: ", ac.id, ac.writable, listener);
nameField = addTranslatableTextField(pane, "Display name: ", ac.display_name, ac.writable, listener); nameField = addTranslatableTextField(pane, "Display name: ", ac.display_name, ac.writable, listener);
descriptionField = addTranslatableTextField(pane, "Description: ", ac.description, ac.writable, listener);
categoryBox = addEnumValueBox(pane, "Category: ", ActorCondition.ACCategory.values(), ac.category, ac.writable, listener); categoryBox = addEnumValueBox(pane, "Category: ", ActorCondition.ACCategory.values(), ac.category, ac.writable, listener);
positiveBox = addIntegerBasedCheckBox(pane, "Positive", ac.positive, ac.writable, listener); positiveBox = addIntegerBasedCheckBox(pane, "Positive", ac.positive, ac.writable, listener);
stackingBox = addIntegerBasedCheckBox(pane, "Stacking", ac.stacking, ac.writable, listener); stackingBox = addIntegerBasedCheckBox(pane, "Stacking", ac.stacking, ac.writable, listener);
@@ -172,6 +174,10 @@ public class ActorConditionEditor extends JSONElementEditor {
ActorConditionEditor.this.name = aCond.getDesc(); ActorConditionEditor.this.name = aCond.getDesc();
aCond.childrenChanged(new ArrayList<ProjectTreeNode>()); aCond.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ActorConditionEditor.this); ATContentStudio.frame.editorChanged(ActorConditionEditor.this);
}else if (source == descriptionField) {
aCond.description = (String) value;
aCond.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(ActorConditionEditor.this);
} else if (source == acIcon) { } else if (source == acIcon) {
aCond.icon_id = (String) value; aCond.icon_id = (String) value;
aCond.childrenChanged(new ArrayList<ProjectTreeNode>()); aCond.childrenChanged(new ArrayList<ProjectTreeNode>());

View File

@@ -1,299 +1,205 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors; package com.gpl.rpg.atcontentstudio.ui.gamedataeditors;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ActionEvent; import java.util.ArrayList;
import java.awt.event.ActionListener; import java.util.List;
import java.util.ArrayList;
import java.util.List; import javax.swing.DefaultListCellRenderer;
import java.util.concurrent.CopyOnWriteArrayList; import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.DefaultListCellRenderer; import javax.swing.JLabel;
import javax.swing.ImageIcon; import javax.swing.JList;
import javax.swing.JButton; import javax.swing.JPanel;
import javax.swing.JComponent; import javax.swing.JSpinner;
import javax.swing.JLabel; import javax.swing.JTextField;
import javax.swing.JList;
import javax.swing.JPanel; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import javax.swing.JScrollPane; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import javax.swing.JSpinner; import com.gpl.rpg.atcontentstudio.model.Project;
import javax.swing.JTextField; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import javax.swing.ListModel; import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist;
import javax.swing.ListSelectionModel; import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist.DroppedItem;
import javax.swing.event.ListDataEvent; import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import javax.swing.event.ListDataListener; import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel;
import javax.swing.event.ListSelectionEvent; import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import javax.swing.event.ListSelectionListener; import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import com.jidesoft.swing.JideBoxLayout;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; public class DroplistEditor extends JSONElementEditor {
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; private static final long serialVersionUID = 1139455254096811058L;
import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist;
import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist.DroppedItem; private static final String form_view_id = "Form";
import com.gpl.rpg.atcontentstudio.model.gamedata.Item; private static final String json_view_id = "JSON";
import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; private Droplist.DroppedItem selectedItem;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.jidesoft.swing.JideBoxLayout; private JTextField idField;
private MyComboBox itemCombo;
public class DroplistEditor extends JSONElementEditor { private DroppedItemsListModel droppedItemsListModel;
private JSpinner qtyMinField;
private static final long serialVersionUID = 1139455254096811058L; private JSpinner qtyMaxField;
private JComponent chanceField;
private static final String form_view_id = "Form";
private static final String json_view_id = "JSON"; public DroplistEditor(Droplist droplist) {
super(droplist, droplist.getDesc(), droplist.getIcon());
private Droplist.DroppedItem selectedItem; addEditorTab(form_view_id, getFormView());
addEditorTab(json_view_id, getJSONView());
private JTextField idField; }
private MyComboBox itemCombo;
private DroppedItemsListModel droppedItemsListModel; @Override
private JSpinner qtyMinField; public void insertFormViewDataField(JPanel pane) {
private JSpinner qtyMaxField;
private JComponent chanceField; final Droplist droplist = (Droplist)target;
final FieldUpdateListener listener = new DroplistFieldUpdater();
public DroplistEditor(Droplist droplist) {
super(droplist, droplist.getDesc(), droplist.getIcon()); createButtonPane(pane, droplist.getProject(), droplist, Droplist.class, Droplist.getImage(), null, listener);
addEditorTab(form_view_id, getFormView());
addEditorTab(json_view_id, getJSONView()); idField = addTextField(pane, "Droplist ID: ", droplist.id, droplist.writable, listener);
}
String title = "Items in this droplist: ";
@SuppressWarnings({ "rawtypes", "unchecked" }) DroppedItemsCellRenderer cellRenderer = new DroppedItemsCellRenderer();
@Override droppedItemsListModel = new DroppedItemsListModel(droplist);
public void insertFormViewDataField(JPanel pane) { final boolean moveUpDownEnabled = false;
final Droplist droplist = (Droplist)target; CollapsiblePanel itemsPane = CommonEditor.createListPanel(
final FieldUpdateListener listener = new DroplistFieldUpdater(); title,
cellRenderer,
createButtonPane(pane, droplist.getProject(), droplist, Droplist.class, Droplist.getImage(), null, listener); droppedItemsListModel,
droplist.writable,
idField = addTextField(pane, "Droplist ID: ", droplist.id, droplist.writable, listener); moveUpDownEnabled,
(e) -> selectedItem = e,
CollapsiblePanel itemsPane = new CollapsiblePanel("Items in this droplist: "); () -> selectedItem,
itemsPane.setLayout(new JideBoxLayout(itemsPane, JideBoxLayout.PAGE_AXIS)); this::updateDroppedItemsEditorPane,
droppedItemsListModel = new DroppedItemsListModel(droplist); listener,
final JList itemsList = new JList(droppedItemsListModel); Droplist.DroppedItem::new).panel;
itemsList.setCellRenderer(new DroppedItemsCellRenderer());
itemsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); if (droplist.dropped_items == null || droplist.dropped_items.isEmpty()) {
itemsPane.add(new JScrollPane(itemsList), JideBoxLayout.FIX); itemsPane.collapse();
final JPanel droppedItemsEditorPane = new JPanel(); }
final JButton createDroppedItem = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
final JButton deleteDroppedItem = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); pane.add(itemsPane, JideBoxLayout.FIX);
deleteDroppedItem.setEnabled(false);
itemsList.addListSelectionListener(new ListSelectionListener() { }
@Override
public void valueChanged(ListSelectionEvent e) { public void updateDroppedItemsEditorPane(JPanel pane, DroppedItem di, FieldUpdateListener listener) {
selectedItem = (Droplist.DroppedItem) itemsList.getSelectedValue(); boolean writable = target.writable;
if (selectedItem == null) { Project proj = target.getProject();
deleteDroppedItem.setEnabled(false); pane.removeAll();
} else { if (itemCombo != null) {
deleteDroppedItem.setEnabled(true); removeElementListener(itemCombo);
} }
updateDroppedItemsEditorPane(droppedItemsEditorPane, selectedItem, listener); if (di != null) {
} itemCombo = addItemBox(pane, proj, "Item: ", di.item, writable, listener);
}); qtyMinField = addIntegerField(pane, "Quantity min: ", di.quantity_min, false, writable, listener);
if (droplist.writable) { qtyMaxField = addIntegerField(pane, "Quantity max: ", di.quantity_max, false, writable, listener);
JPanel listButtonsPane = new JPanel(); chanceField = addChanceField(pane, "Chance: ", di.chance, "100", writable, listener);//addDoubleField(pane, "Chance: ", di.chance, writable, listener);
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); }
createDroppedItem.addActionListener(new ActionListener() { pane.revalidate();
@Override pane.repaint();
public void actionPerformed(ActionEvent e) { }
Droplist.DroppedItem tempItem = new Droplist.DroppedItem();
droppedItemsListModel.addItem(tempItem); public static class DroppedItemsListModel extends CommonEditor.AtListModel<Droplist.DroppedItem, Droplist> {
itemsList.setSelectedValue(tempItem, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. public DroppedItemsListModel(Droplist droplist) {
} super(droplist);
}); }
deleteDroppedItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { protected List<Droplist.DroppedItem> getInner() {
if (selectedItem != null) { return source.dropped_items;
droppedItemsListModel.removeItem(selectedItem); }
selectedItem = null;
itemsList.clearSelection(); @Override
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. protected void setInner(List<Droplist.DroppedItem> value) {
} source.dropped_items = value;
} }
}); }
listButtonsPane.add(createDroppedItem, JideBoxLayout.FIX); public static class DroppedItemsCellRenderer extends DefaultListCellRenderer {
listButtonsPane.add(deleteDroppedItem, JideBoxLayout.FIX); private static final long serialVersionUID = 7987880146189575234L;
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
itemsPane.add(listButtonsPane, JideBoxLayout.FIX); @Override
} public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
droppedItemsEditorPane.setLayout(new JideBoxLayout(droppedItemsEditorPane, JideBoxLayout.PAGE_AXIS)); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
itemsPane.add(droppedItemsEditorPane, JideBoxLayout.FIX); if (c instanceof JLabel) {
if (droplist.dropped_items == null || droplist.dropped_items.isEmpty()) { JLabel label = ((JLabel)c);
itemsPane.collapse(); Droplist.DroppedItem di = (Droplist.DroppedItem)value;
} if (di.item != null) {
label.setIcon(new ImageIcon(di.item.getIcon()));
pane.add(itemsPane, JideBoxLayout.FIX); label.setText(di.chance+(di.chance != null && di.chance.contains("/") ? "" : "%")+" to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item.getDesc());
} else if (!isNull(di)) {
} label.setText(di.chance+(di.chance != null && di.chance.contains("/") ? "" : "%")+" to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item_id);
} else {
public void updateDroppedItemsEditorPane(JPanel pane, DroppedItem di, FieldUpdateListener listener) { label.setText("New, undefined, dropped item.");
boolean writable = ((Droplist)target).writable; }
Project proj = ((Droplist)target).getProject(); }
pane.removeAll(); return c;
if (itemCombo != null) { }
removeElementListener(itemCombo);
} public boolean isNull(Droplist.DroppedItem item) {
if (di != null) { return ((item == null) || (
itemCombo = addItemBox(pane, proj, "Item: ", di.item, writable, listener); item.item == null &&
qtyMinField = addIntegerField(pane, "Quantity min: ", di.quantity_min, false, writable, listener); item.item_id == null &&
qtyMaxField = addIntegerField(pane, "Quantity max: ", di.quantity_max, false, writable, listener); item.quantity_min == null &&
chanceField = addChanceField(pane, "Chance: ", di.chance, "100", writable, listener);//addDoubleField(pane, "Chance: ", di.chance, writable, listener); item.quantity_max == null &&
} item.chance == null
pane.revalidate(); ));
pane.repaint(); }
} }
public class DroppedItemsListModel implements ListModel<Droplist.DroppedItem> {
public class DroplistFieldUpdater implements FieldUpdateListener {
Droplist source; @Override
public void valueChanged(JComponent source, Object value) {
public DroppedItemsListModel(Droplist droplist) { Droplist droplist = ((Droplist)target);
this.source = droplist; if (source == idField) {
} //Events caused by cancel an ID edition. Dismiss.
if (skipNext) {
@Override skipNext = false;
public int getSize() { return;
if (source.dropped_items == null) return 0; }
return source.dropped_items.size(); if (target.id.equals(value)) return;
}
if (idChanging()) {
@Override droplist.id = (String) value;
public Droplist.DroppedItem getElementAt(int index) { DroplistEditor.this.name = droplist.getDesc();
if (source.dropped_items == null) return null; droplist.childrenChanged(new ArrayList<>());
return source.dropped_items.get(index); ATContentStudio.frame.editorChanged(DroplistEditor.this);
} } else {
cancelIdEdit(idField);
public void addItem(Droplist.DroppedItem item) { return;
if (source.dropped_items == null) { }
source.dropped_items = new ArrayList<Droplist.DroppedItem>(); } else if (source == itemCombo) {
} if (selectedItem.item != null) {
source.dropped_items.add(item); selectedItem.item.removeBacklink(droplist);
int index = source.dropped_items.indexOf(item); }
for (ListDataListener l : listeners) { selectedItem.item = (Item) value;
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index)); if (selectedItem.item != null) {
} selectedItem.item_id = selectedItem.item.id;
} selectedItem.item.addBacklink(droplist);
} else {
public void removeItem(Droplist.DroppedItem item) { selectedItem.item_id = null;
int index = source.dropped_items.indexOf(item); }
source.dropped_items.remove(item); droppedItemsListModel.itemChanged(selectedItem);
if (source.dropped_items.isEmpty()) { } else if (source == qtyMinField) {
source.dropped_items = null; selectedItem.quantity_min = (Integer) value;
} droppedItemsListModel.itemChanged(selectedItem);
for (ListDataListener l : listeners) { } else if (source == qtyMaxField) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index)); selectedItem.quantity_max = (Integer) value;
} droppedItemsListModel.itemChanged(selectedItem);
} } else if (source == chanceField) {
selectedItem.chance = (String) value;
public void itemChanged(Droplist.DroppedItem item) { droppedItemsListModel.itemChanged(selectedItem);
int index = source.dropped_items.indexOf(item); }
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index)); if (droplist.state != GameDataElement.State.modified) {
} droplist.state = GameDataElement.State.modified;
} DroplistEditor.this.name = droplist.getDesc();
droplist.childrenChanged(new ArrayList<>());
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>(); ATContentStudio.frame.editorChanged(DroplistEditor.this);
}
@Override updateJsonViewText(droplist.toJsonString());
public void addListDataListener(ListDataListener l) { }
listeners.add(l); }
} }
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
public static class DroppedItemsCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 7987880146189575234L;
@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);
Droplist.DroppedItem di = (Droplist.DroppedItem)value;
if (di.item != null) {
label.setIcon(new ImageIcon(di.item.getIcon()));
label.setText(di.chance+(di.chance != null && di.chance.contains("/") ? "" : "%")+" to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item.getDesc());
} else if (!isNull(di)) {
label.setText(di.chance+(di.chance != null && di.chance.contains("/") ? "" : "%")+" to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item_id);
} else {
label.setText("New, undefined, dropped item.");
}
}
return c;
}
public boolean isNull(Droplist.DroppedItem item) {
return ((item == null) || (
item.item == null &&
item.item_id == null &&
item.quantity_min == null &&
item.quantity_max == null &&
item.chance == null
));
}
}
public class DroplistFieldUpdater implements FieldUpdateListener {
@Override
public void valueChanged(JComponent source, Object value) {
Droplist droplist = ((Droplist)target);
if (source == idField) {
//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);
}
selectedItem.item = (Item) value;
if (selectedItem.item != null) {
selectedItem.item_id = selectedItem.item.id;
selectedItem.item.addBacklink(droplist);
} else {
selectedItem.item_id = null;
}
droppedItemsListModel.itemChanged(selectedItem);
} else if (source == qtyMinField) {
selectedItem.quantity_min = (Integer) value;
droppedItemsListModel.itemChanged(selectedItem);
} else if (source == qtyMaxField) {
selectedItem.quantity_max = (Integer) value;
droppedItemsListModel.itemChanged(selectedItem);
} else if (source == chanceField) {
selectedItem.chance = (String) value;
droppedItemsListModel.itemChanged(selectedItem);
}
if (droplist.state != GameDataElement.State.modified) {
droplist.state = GameDataElement.State.modified;
DroplistEditor.this.name = droplist.getDesc();
droplist.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DroplistEditor.this);
}
updateJsonViewText(droplist.toJsonString());
}
}
}

View File

@@ -1,29 +1,18 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors; package com.gpl.rpg.atcontentstudio.ui.gamedataeditors;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
@@ -31,9 +20,9 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.Quest; import com.gpl.rpg.atcontentstudio.model.gamedata.Quest;
import com.gpl.rpg.atcontentstudio.model.gamedata.QuestStage; import com.gpl.rpg.atcontentstudio.model.gamedata.QuestStage;
import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel; import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener; import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox; import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
public class QuestEditor extends JSONElementEditor { public class QuestEditor extends JSONElementEditor {
@@ -77,94 +66,26 @@ public class QuestEditor extends JSONElementEditor {
nameField = addTranslatableTextField(pane, "Quest Name: ", quest.name, quest.writable, listener); nameField = addTranslatableTextField(pane, "Quest Name: ", quest.name, quest.writable, listener);
visibleBox = addIntegerBasedCheckBox(pane, "Visible in quest log", quest.visible_in_log, quest.writable, listener); visibleBox = addIntegerBasedCheckBox(pane, "Visible in quest log", quest.visible_in_log, quest.writable, listener);
CollapsiblePanel stagesPane = new CollapsiblePanel("Quest stages: "); String title = "Quest stages: ";
stagesPane.setLayout(new JideBoxLayout(stagesPane, JideBoxLayout.PAGE_AXIS)); StagesCellRenderer cellRenderer = new StagesCellRenderer();
stagesListModel = new StagesListModel(quest); stagesListModel = new StagesListModel(quest);
stagesList = new JList<QuestStage>(stagesListModel); final boolean moveUpDownEnabled = true;
stagesList.setCellRenderer(new StagesCellRenderer());
stagesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); CollapsiblePanel stagesPane = CommonEditor.createListPanel(
stagesPane.add(new JScrollPane(stagesList), JideBoxLayout.FIX); title,
final JPanel stagesEditorPane = new JPanel(); cellRenderer,
final JButton createStage = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); stagesListModel,
final JButton deleteStage = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); quest.writable,
final JButton moveStageUp = new JButton(new ImageIcon(DefaultIcons.getArrowUpIcon())); moveUpDownEnabled,
final JButton moveStageDown = new JButton(new ImageIcon(DefaultIcons.getArrowDownIcon())); (e)->selectedStage=e,
deleteStage.setEnabled(false); ()->selectedStage,
moveStageUp.setEnabled(false); this::updateStageEditorPane,
moveStageDown.setEnabled(false); listener,
stagesList.addListSelectionListener(new ListSelectionListener() { ()->new QuestStage(quest)).panel;
@Override
public void valueChanged(ListSelectionEvent e) {
selectedStage = (QuestStage) stagesList.getSelectedValue();
if (selectedStage != null) {
deleteStage.setEnabled(true);
moveStageUp.setEnabled(stagesList.getSelectedIndex() > 0);
moveStageDown.setEnabled(stagesList.getSelectedIndex() < (stagesListModel.getSize() - 1));
} else {
deleteStage.setEnabled(false);
moveStageUp.setEnabled(false);
moveStageDown.setEnabled(false);
}
updateStageEditorPane(stagesEditorPane, selectedStage, listener);
}
});
if (quest.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createStage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
QuestStage stage = new QuestStage(quest);
stagesListModel.addItem(stage);
stagesList.setSelectedValue(stage, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteStage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedStage != null) {
stagesListModel.removeItem(selectedStage);
selectedStage = null;
stagesList.clearSelection();
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
moveStageUp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedStage != null) {
stagesListModel.moveUp(selectedStage);
stagesList.setSelectedValue(selectedStage, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
moveStageDown.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedStage != null) {
stagesListModel.moveDown(selectedStage);
stagesList.setSelectedValue(selectedStage, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createStage, JideBoxLayout.FIX);
listButtonsPane.add(deleteStage, JideBoxLayout.FIX);
listButtonsPane.add(moveStageUp, JideBoxLayout.FIX);
listButtonsPane.add(moveStageDown, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
stagesPane.add(listButtonsPane, JideBoxLayout.FIX);
}
if (quest.stages == null || quest.stages.isEmpty()) { if (quest.stages == null || quest.stages.isEmpty()) {
stagesPane.collapse(); stagesPane.collapse();
} }
stagesEditorPane.setLayout(new JideBoxLayout(stagesEditorPane, JideBoxLayout.PAGE_AXIS));
stagesPane.add(stagesEditorPane, JideBoxLayout.FIX);
pane.add(stagesPane, JideBoxLayout.FIX); pane.add(stagesPane, JideBoxLayout.FIX);
} }
@@ -184,88 +105,21 @@ public class QuestEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public static class StagesListModel implements ListModel<QuestStage> { public static class StagesListModel extends CommonEditor.AtListModel<QuestStage,Quest> {
Quest source;
public StagesListModel(Quest quest) { public StagesListModel(Quest quest) {
this.source = quest; super(quest);
}
@Override
public int getSize() {
if (source.stages == null) return 0;
return source.stages.size();
} }
@Override @Override
public QuestStage getElementAt(int index) { protected List<QuestStage> getInner() {
if (source.stages == null) return null; return source.stages;
return source.stages.get(index);
}
public void addItem(QuestStage item) {
if (source.stages == null) {
source.stages = new ArrayList<QuestStage>();
}
source.stages.add(item);
int index = source.stages.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(QuestStage item) {
int index = source.stages.indexOf(item);
source.stages.remove(item);
if (source.stages.isEmpty()) {
source.stages = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(QuestStage item) {
int index = source.stages.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
public void moveUp(QuestStage item) {
int index = source.stages.indexOf(item);
QuestStage exchanged = source.stages.get(index - 1);
source.stages.set(index, exchanged);
source.stages.set(index - 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index - 1, index));
}
}
public void moveDown(QuestStage item) {
int index = source.stages.indexOf(item);
QuestStage exchanged = source.stages.get(index + 1);
source.stages.set(index, exchanged);
source.stages.set(index + 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index + 1));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
public void removeListDataListener(ListDataListener l) { protected void setInner(List<QuestStage> value) {
listeners.remove(l); source.stages = value;
} }
} }

View File

@@ -18,6 +18,7 @@ import javax.swing.JToolTip;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.ToolTipManager; import javax.swing.ToolTipManager;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import prefuse.Display; import prefuse.Display;
import prefuse.Visualization; import prefuse.Visualization;
import prefuse.action.ActionList; import prefuse.action.ActionList;
@@ -321,23 +322,7 @@ public class DialogueGraphView extends Display {
@Override @Override
protected String getText(VisualItem item) { protected String getText(VisualItem item) {
return wordWrap(super.getText(item), 40); return CommonEditor.wordWrap(super.getText(item), 40);
}
public String wordWrap(String in, int length) {
final String newline = "\n";
//:: Trim
while(in.length() > 0 && (in.charAt(0) == '\t' || in.charAt(0) == ' ')) in = in.substring(1);
//:: If Small Enough Already, Return Original
if(in.length() < length) return in;
//:: If Next length Contains Newline, Split There
if(in.substring(0, length).contains(newline)) return in.substring(0, in.indexOf(newline)).trim() + newline + wordWrap(in.substring(in.indexOf("\n") + 1), length);
//:: Otherwise, Split Along Nearest Previous Space/Tab/Dash
int spaceIndex = Math.max(Math.max( in.lastIndexOf(" ", length), in.lastIndexOf("\t", length)), in.lastIndexOf("-", length));
//:: If No Nearest Space, Split At length
if(spaceIndex == -1) spaceIndex = length;
//:: Split
return in.substring(0, spaceIndex).trim() + newline + wordWrap(in.substring(spaceIndex), length);
} }
} }

View File

@@ -62,6 +62,7 @@ import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeModel; import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
@@ -378,7 +379,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addMapchange.addActionListener(new ActionListener() { addMapchange.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newMapchange(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newMapchange(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -391,7 +392,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addSpawn.addActionListener(new ActionListener() { addSpawn.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newSpawnArea(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newSpawnArea(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -404,7 +405,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addRest.addActionListener(new ActionListener() { addRest.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newRest(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newRest(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -417,7 +418,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addKey.addActionListener(new ActionListener() { addKey.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newKey(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newKey(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -430,7 +431,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addReplace.addActionListener(new ActionListener() { addReplace.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newReplace(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newReplace(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -443,7 +444,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addScript.addActionListener(new ActionListener() { addScript.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newScript(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newScript(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -456,7 +457,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addContainer.addActionListener(new ActionListener() { addContainer.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newContainer(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newContainer(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -469,7 +470,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addSign.addActionListener(new ActionListener() { addSign.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.addObject(MapObject.newSign(new tiled.core.MapObject(0, 0, 32, 32), map)); groupObjectsListModel.addItem(MapObject.newSign(new tiled.core.MapObject(0, 0, 32, 32), map));
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -482,7 +483,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
deleteObject.addActionListener(new ActionListener() { deleteObject.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
groupObjectsListModel.removeObject(selectedMapObject); groupObjectsListModel.removeItem(selectedMapObject);
map.state = GameDataElement.State.modified; map.state = GameDataElement.State.modified;
map.childrenChanged(new ArrayList<ProjectTreeNode>()); map.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(TMXMapEditor.this); ATContentStudio.frame.editorChanged(TMXMapEditor.this);
@@ -587,7 +588,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
addReplacement.addActionListener(new ActionListener() { addReplacement.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
replacementsListModel.addObject(null, null); replacementsListModel.addReplacement(null, null);
} }
}); });
deleteReplacement = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); deleteReplacement = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
@@ -596,7 +597,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
deleteReplacement.addActionListener(new ActionListener() { deleteReplacement.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
replacementsListModel.removeObject(selectedReplacement); replacementsListModel.removeItem(selectedReplacement);
} }
}); });
replacementListButtonsPane.add(new JPanel(), JideBoxLayout.VARY); replacementListButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
@@ -1153,61 +1154,22 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} }
} }
public class ReplacementsListModel implements ListModel<ReplaceArea.Replacement> { public class ReplacementsListModel extends CommonEditor.AtListModel<ReplaceArea.Replacement, ReplaceArea> {
public ReplaceArea area;
public ReplacementsListModel(ReplaceArea area) { public ReplacementsListModel(ReplaceArea area) {
this.area = area; super(area);
} }
@Override @Override
public int getSize() { protected List<ReplaceArea.Replacement> getInner() {
if (area.replacements == null) return 0; return source.replacements;
return area.replacements.size();
} }
@Override @Override
public ReplaceArea.Replacement getElementAt(int index) { protected void setInner(List<ReplaceArea.Replacement> value) {
if (index < 0 || index > getSize()) return null; source.replacements = value;
if (area.replacements == null) return null;
return area.replacements.get(index);
} }
public void addReplacement(String source, String target) {
public void objectChanged(ReplaceArea.Replacement repl) { addItem(this.source.createReplacement(source, target));
int index = area.replacements.indexOf(repl);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
public void addObject(String source, String target) {
ReplaceArea.Replacement repl = area.addReplacement(source, target);
int index = area.replacements.indexOf(repl);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeObject(ReplaceArea.Replacement repl) {
int index = area.replacements.indexOf(repl);
area.removeReplacement(repl);
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
} }
} }
@@ -1286,58 +1248,20 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} }
} }
public class MapObjectsListModel implements ListModel<MapObject> { public class MapObjectsListModel extends CommonEditor.AtListModel<MapObject, MapObjectGroup> {
public MapObjectGroup group;
public MapObjectsListModel(MapObjectGroup group) { public MapObjectsListModel(MapObjectGroup group) {
this.group = group; super(group);
}
@Override
public int getSize() {
return group.mapObjects.size();
} }
@Override @Override
public MapObject getElementAt(int index) { protected List<MapObject> getInner() {
return group.mapObjects.get(index); return source.mapObjects;
}
public void objectChanged(MapObject area) {
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(groupObjectsList, ListDataEvent.CONTENTS_CHANGED, group.mapObjects.indexOf(area), group.mapObjects.indexOf(area)));
}
}
public void addObject(MapObject area) {
group.mapObjects.add(area);
int index = group.mapObjects.indexOf(area);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(groupObjectsList, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeObject(MapObject area) {
int index = group.mapObjects.indexOf(area);
group.mapObjects.remove(area);
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(groupObjectsList, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
public void removeListDataListener(ListDataListener l) { protected void setInner(List<MapObject> value) {
listeners.remove(l); source.mapObjects = value;
} }
} }
public class GroupObjectsRenderer extends DefaultListCellRenderer { public class GroupObjectsRenderer extends DefaultListCellRenderer {
@@ -1353,36 +1277,20 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} }
} }
public class SpawnGroupNpcListModel implements ListModel<NPC> { public class SpawnGroupNpcListModel extends CommonEditor.AtListModel<NPC, SpawnArea> {
public SpawnArea area;
public SpawnGroupNpcListModel(SpawnArea area) { public SpawnGroupNpcListModel(SpawnArea area) {
this.area = area; super(area);
}
@Override
public int getSize() {
return area.spawnGroup.size();
} }
@Override @Override
public NPC getElementAt(int index) { protected List<NPC> getInner() {
return area.spawnGroup.get(index); return source.spawnGroup;
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
public void removeListDataListener(ListDataListener l) { protected void setInner(List<NPC> value) {
listeners.remove(l); source.spawnGroup = value;
} }
} }
@@ -1956,7 +1864,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
area.oldSchoolRequirement = false; area.oldSchoolRequirement = false;
} }
} }
groupObjectsListModel.objectChanged(selectedMapObject); groupObjectsListModel.itemChanged(selectedMapObject);
} }
} else if (source == spawngroupField) { } else if (source == spawngroupField) {
if (selectedMapObject instanceof SpawnArea) { if (selectedMapObject instanceof SpawnArea) {
@@ -1969,7 +1877,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
area.spawngroup_id = (String) value; area.spawngroup_id = (String) value;
selectedMapObject.link(); selectedMapObject.link();
npcList.setModel(new SpawnGroupNpcListModel(area)); npcList.setModel(new SpawnGroupNpcListModel(area));
groupObjectsListModel.objectChanged(area); groupObjectsListModel.itemChanged(area);
npcList.revalidate(); npcList.revalidate();
npcList.repaint(); npcList.repaint();
tmxViewer.revalidate(); tmxViewer.revalidate();
@@ -1998,7 +1906,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} else { } else {
area.name = null; area.name = null;
} }
groupObjectsListModel.objectChanged(area); groupObjectsListModel.itemChanged(area);
tmxViewer.revalidate(); tmxViewer.revalidate();
tmxViewer.repaint(); tmxViewer.repaint();
} }
@@ -2027,7 +1935,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} else { } else {
area.name = null; area.name = null;
} }
groupObjectsListModel.objectChanged(area); groupObjectsListModel.itemChanged(area);
tmxViewer.revalidate(); tmxViewer.revalidate();
tmxViewer.repaint(); tmxViewer.repaint();
} else if (selectedMapObject instanceof SignArea) { } else if (selectedMapObject instanceof SignArea) {
@@ -2041,7 +1949,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} else { } else {
area.name = null; area.name = null;
} }
groupObjectsListModel.objectChanged(area); groupObjectsListModel.itemChanged(area);
tmxViewer.revalidate(); tmxViewer.revalidate();
tmxViewer.repaint(); tmxViewer.repaint();
} }
@@ -2226,12 +2134,12 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} }
} else if (source == sourceLayer) { } else if (source == sourceLayer) {
selectedReplacement.sourceLayer = (String)value; selectedReplacement.sourceLayer = (String)value;
replacementsListModel.objectChanged(selectedReplacement); replacementsListModel.itemChanged(selectedReplacement);
groupObjectsListModel.objectChanged(selectedMapObject); groupObjectsListModel.itemChanged(selectedMapObject);
} else if (source == targetLayer) { } else if (source == targetLayer) {
selectedReplacement.targetLayer = (String)value; selectedReplacement.targetLayer = (String)value;
replacementsListModel.objectChanged(selectedReplacement); replacementsListModel.itemChanged(selectedReplacement);
groupObjectsListModel.objectChanged(selectedMapObject); groupObjectsListModel.itemChanged(selectedMapObject);
} }
if (modified) { if (modified) {
if (map.state != GameDataElement.State.modified) { if (map.state != GameDataElement.State.modified) {

View File

@@ -0,0 +1,282 @@
package com.gpl.rpg.atcontentstudio.ui.tools;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Common;
import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel;
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.utils.lambda.CallWithReturn;
import com.gpl.rpg.atcontentstudio.utils.lambda.CallWithSingleArg;
import com.gpl.rpg.atcontentstudio.utils.lambda.CallWithThreeArgs;
import com.jidesoft.swing.JideBoxLayout;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public final class CommonEditor {
public static class PanelCreateResult<E>{
public CollapsiblePanel panel;
public JList<E> list;
}
public static <E, S> PanelCreateResult<E> createListPanel(String title,
ListCellRenderer<? super E> cellRenderer,
AtListModel<E, S> listModel,
boolean writable,
boolean moveUpDownEnabled,
CallWithSingleArg<E> selectedValueSetter,
CallWithReturn<E> selectedValueGetter,
CallWithThreeArgs<JPanel, E, FieldUpdateListener> updateRepliesEditorPane,
FieldUpdateListener listener,
CallWithReturn<E> createNew) {
CollapsiblePanel replies = new CollapsiblePanel(title);
replies.setLayout(new JideBoxLayout(replies, JideBoxLayout.PAGE_AXIS));
JList<E> repliesList = new JList<>(listModel);
repliesList.setCellRenderer(cellRenderer);
repliesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
replies.add(new JScrollPane(repliesList), JideBoxLayout.FIX);
final JPanel repliesEditorPane = new JPanel();
final JButton createReply = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
final JButton deleteReply = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
final JButton moveReplyUp = new JButton(new ImageIcon(DefaultIcons.getArrowUpIcon()));
final JButton moveReplyDown = new JButton(new ImageIcon(DefaultIcons.getArrowDownIcon()));
deleteReply.setEnabled(false);
moveReplyUp.setEnabled(false);
moveReplyDown.setEnabled(false);
repliesList.addListSelectionListener(e -> {
E selectedReply = repliesList.getSelectedValue();
selectedValueSetter.call(selectedReply);
if (selectedReply != null) {
deleteReply.setEnabled(true);
if (moveUpDownEnabled) {
moveReplyUp.setEnabled(repliesList.getSelectedIndex() > 0);
moveReplyDown.setEnabled(repliesList.getSelectedIndex() < (listModel.getSize() - 1));
}
} else {
deleteReply.setEnabled(false);
if (moveUpDownEnabled) {
moveReplyUp.setEnabled(false);
moveReplyDown.setEnabled(false);
}
}
updateRepliesEditorPane.call(repliesEditorPane, selectedReply, listener);
});
repliesList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
GameDataElement navObj = listModel.getNavigationElement( repliesList.getSelectedValue());
if (navObj != null) {
ATContentStudio.frame.openEditor(navObj);
ATContentStudio.frame.selectInTree(navObj);
}
}
}
});
repliesList.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
GameDataElement navObj = listModel.getNavigationElement( repliesList.getSelectedValue());
ATContentStudio.frame.openEditor(navObj);
ATContentStudio.frame.selectInTree(navObj);
}
}
});
if (writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createReply.addActionListener(e -> {
E created = createNew.call();
listModel.addItem(created);
repliesList.setSelectedValue(created, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
});
deleteReply.addActionListener(e -> {
E selected = selectedValueGetter.call();
if (selected != null) {
listModel.removeItem(selected);
selected = null;
selectedValueSetter.call(selected);
repliesList.clearSelection();
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
if (moveUpDownEnabled) {
moveReplyUp.addActionListener(e -> {
E selected = selectedValueGetter.call();
if (selected != null) {
listModel.moveUp(selected);
repliesList.setSelectedValue(selected, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
moveReplyDown.addActionListener(e -> {
E selected = selectedValueGetter.call();
if (selected != null) {
listModel.moveDown(selected);
repliesList.setSelectedValue(selected, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
}
listButtonsPane.add(createReply, JideBoxLayout.FIX);
listButtonsPane.add(deleteReply, JideBoxLayout.FIX);
if (moveUpDownEnabled) {
listButtonsPane.add(moveReplyUp, JideBoxLayout.FIX);
listButtonsPane.add(moveReplyDown, JideBoxLayout.FIX);
}
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
replies.add(listButtonsPane, JideBoxLayout.FIX);
}
repliesEditorPane.setLayout(new JideBoxLayout(repliesEditorPane, JideBoxLayout.PAGE_AXIS));
replies.add(repliesEditorPane, JideBoxLayout.FIX);
PanelCreateResult<E> ePanelCreateResult = new PanelCreateResult<>();
ePanelCreateResult.panel =replies;
ePanelCreateResult.list = repliesList;
return ePanelCreateResult;
}
public static class CreateDeathEffectPanelResult {
public CollapsiblePanel panel;
public JSpinner HPMin;
public JSpinner HPMax;
public JSpinner APMin;
public JSpinner APMax;
}
public static CreateDeathEffectPanelResult createDeathEffectPanel(Common.DeathEffect hitEffect, boolean writable, FieldUpdateListener listener, String title){
CreateDeathEffectPanelResult result = new CreateDeathEffectPanelResult();
result.panel = new CollapsiblePanel(title);
result.panel.setLayout(new JideBoxLayout(result.panel, JideBoxLayout.PAGE_AXIS));
result.HPMin = Editor.addIntegerField(result.panel, "HP bonus min: ", hitEffect.hp_boost_min, true, writable, listener);
result.HPMax = Editor.addIntegerField(result.panel, "HP bonus max: ", hitEffect.hp_boost_max, true, writable, listener);
result.APMin = Editor.addIntegerField(result.panel, "AP bonus min: ", hitEffect.ap_boost_min, true, writable, listener);
result.APMax = Editor.addIntegerField(result.panel, "AP bonus max: ", hitEffect.ap_boost_max, true, writable, listener);
return result;
}
public static String wordWrap(String in, int length) {
if (in == null) return null;
final String newline = "\n";
//:: Trim
while (!in.isEmpty() && (in.charAt(0) == '\t' || in.charAt(0) == ' ')) in = in.substring(1);
//:: If Small Enough Already, Return Original
if (in.length() < length) return in;
//:: If Next length Contains Newline, Split There
if (in.substring(0, length).contains(newline))
return in.substring(0, in.indexOf(newline)).trim() + newline + wordWrap(in.substring(in.indexOf("\n") + 1), length);
//:: Otherwise, Split Along Nearest Previous Space/Tab/Dash
int spaceIndex = Math.max(Math.max(in.lastIndexOf(" ", length), in.lastIndexOf("\t", length)), in.lastIndexOf("-", length));
//:: If No Nearest Space, Split At length
if (spaceIndex == -1) spaceIndex = length;
//:: Split
return in.substring(0, spaceIndex).trim() + newline + wordWrap(in.substring(spaceIndex), length);
}
public abstract static class AtListModel<E, S> implements ListModel<E> {
protected S source;
protected abstract List<E> getInner();
protected abstract void setInner(List<E> value);
protected GameDataElement getNavigationElement(E element){
return null;
}
public AtListModel(S source) {
this.source = source;
}
@Override
public int getSize() {
if (getInner() == null) return 0;
return getInner().size();
}
@Override
public E getElementAt(int index) {
if (index < 0 || index >= getSize()) return null;
return getInner().get(index);
}
public void addItem(E item) {
if (getInner() == null) {
setInner(new ArrayList<>());
}
getInner().add(item);
int index = getInner().indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(E item) {
int index = getInner().indexOf(item);
getInner().remove(item);
if (getInner().isEmpty()) {
setInner(null);
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(E item) {
int index = getInner().indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
public void moveUp(E item) {
int index = getInner().indexOf(item);
E exchanged = getInner().get(index - 1);
getInner().set(index, exchanged);
getInner().set(index - 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index - 1, index));
}
}
public void moveDown(E item) {
int index = getInner().indexOf(item);
E exchanged = getInner().get(index + 1);
getInner().set(index, exchanged);
getInner().set(index + 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index + 1));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
}

View File

@@ -5,14 +5,7 @@ import java.util.List;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition; import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.model.gamedata.ItemCategory;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.gamedata.Quest;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement;
import com.gpl.rpg.atcontentstudio.model.maps.ContainerArea; import com.gpl.rpg.atcontentstudio.model.maps.ContainerArea;
import com.gpl.rpg.atcontentstudio.model.maps.KeyArea; import com.gpl.rpg.atcontentstudio.model.maps.KeyArea;
import com.gpl.rpg.atcontentstudio.model.maps.MapChange; import com.gpl.rpg.atcontentstudio.model.maps.MapChange;
@@ -111,18 +104,18 @@ public class GDEVisitor {
visit(element.category, visited, includeSource); visit(element.category, visited, includeSource);
if (element.icon_id != null) visit(element.getProject().getSpritesheet(element.icon_id.split(":")[0]), visited, includeSource); if (element.icon_id != null) visit(element.getProject().getSpritesheet(element.icon_id.split(":")[0]), visited, includeSource);
if (element.equip_effect != null && element.equip_effect.conditions != null) { if (element.equip_effect != null && element.equip_effect.conditions != null) {
for (Item.ConditionEffect condEffect : element.equip_effect.conditions) { for (Common.ConditionEffect condEffect : element.equip_effect.conditions) {
visit(condEffect.condition, visited, includeSource); visit(condEffect.condition, visited, includeSource);
} }
} }
if (element.hit_effect != null) { if (element.hit_effect != null) {
if (element.hit_effect.conditions_source != null) { if (element.hit_effect.conditions_source != null) {
for (Item.ConditionEffect condEffect : element.hit_effect.conditions_source) { for (Common.ConditionEffect condEffect : element.hit_effect.conditions_source) {
visit(condEffect.condition, visited, includeSource); visit(condEffect.condition, visited, includeSource);
} }
} }
if (element.hit_effect.conditions_target != null) { if (element.hit_effect.conditions_target != null) {
for (Item.ConditionEffect condEffect : element.hit_effect.conditions_target) { for (Common.ConditionEffect condEffect : element.hit_effect.conditions_target) {
visit(condEffect.condition, visited, includeSource); visit(condEffect.condition, visited, includeSource);
} }
} }
@@ -144,12 +137,12 @@ public class GDEVisitor {
if (element.icon_id != null) visit(element.getProject().getSpritesheet(element.icon_id.split(":")[0]), visited, includeSource); if (element.icon_id != null) visit(element.getProject().getSpritesheet(element.icon_id.split(":")[0]), visited, includeSource);
if (element.hit_effect != null) { if (element.hit_effect != null) {
if (element.hit_effect.conditions_source != null) { if (element.hit_effect.conditions_source != null) {
for (NPC.TimedConditionEffect condEffect : element.hit_effect.conditions_source) { for (Common.TimedConditionEffect condEffect : element.hit_effect.conditions_source) {
visit(condEffect.condition, visited, includeSource); visit(condEffect.condition, visited, includeSource);
} }
} }
if (element.hit_effect.conditions_target != null) { if (element.hit_effect.conditions_target != null) {
for (NPC.TimedConditionEffect condEffect : element.hit_effect.conditions_target) { for (Common.TimedConditionEffect condEffect : element.hit_effect.conditions_target) {
visit(condEffect.condition, visited, includeSource); visit(condEffect.condition, visited, includeSource);
} }
} }

View File

@@ -27,6 +27,7 @@ import javax.swing.JTextArea;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import javax.swing.plaf.basic.BasicInternalFrameUI; import javax.swing.plaf.basic.BasicInternalFrameUI;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import prefuse.Display; import prefuse.Display;
import prefuse.Visualization; import prefuse.Visualization;
import prefuse.action.Action; import prefuse.action.Action;
@@ -415,25 +416,9 @@ public class WriterModeEditor extends Editor {
@Override @Override
protected String getText(VisualItem item) { protected String getText(VisualItem item) {
if (!item.getBoolean(IS_REPLY) && super.getText(item) == null) return "[Selector]"; if (!item.getBoolean(IS_REPLY) && super.getText(item) == null) return "[Selector]";
return wordWrap(super.getText(item), 40); return CommonEditor.wordWrap(super.getText(item), 40);
}
public String wordWrap(String in, int length) {
if (in == null) return null;
final String newline = "\n";
//:: Trim
while(in.length() > 0 && (in.charAt(0) == '\t' || in.charAt(0) == ' ')) in = in.substring(1);
//:: If Small Enough Already, Return Original
if(in.length() < length) return in;
//:: If Next length Contains Newline, Split There
if(in.substring(0, length).contains(newline)) return in.substring(0, in.indexOf(newline)).trim() + newline + wordWrap(in.substring(in.indexOf("\n") + 1), length);
//:: Otherwise, Split Along Nearest Previous Space/Tab/Dash
int spaceIndex = Math.max(Math.max( in.lastIndexOf(" ", length), in.lastIndexOf("\t", length)), in.lastIndexOf("-", length));
//:: If No Nearest Space, Split At length
if(spaceIndex == -1) spaceIndex = length;
//:: Split
return in.substring(0, spaceIndex).trim() + newline + wordWrap(in.substring(spaceIndex), length);
} }
} }
class NodeStrokeColorAction extends ColorAction { class NodeStrokeColorAction extends ColorAction {

View File

@@ -0,0 +1,5 @@
package com.gpl.rpg.atcontentstudio.utils.lambda;
public interface CallWithReturn<T> {
T call();
}

View File

@@ -0,0 +1,7 @@
package com.gpl.rpg.atcontentstudio.utils.lambda;
public interface CallWithSingleArg<T> {
void call(T arg);
}

View File

@@ -0,0 +1,5 @@
package com.gpl.rpg.atcontentstudio.utils.lambda;
public interface CallWithThreeArgs<T1, T2, T3> {
void call(T1 arg1, T2 arg2, T3 arg3);
}

View File

@@ -0,0 +1,6 @@
package com.gpl.rpg.atcontentstudio.utils.lambda;
public interface CallWithTwoArgs<T1, T2> {
void call(T1 arg1, T2 arg2);
}