Compare commits

..

25 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
156 changed files with 32711 additions and 30163 deletions

6
.gitattributes vendored
View File

@@ -1,6 +0,0 @@
# Set default behavior to automatically normalize line endings.
* text=auto
# Force bash scripts to always use LF line endings so that if a repo is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lf

View File

@@ -1,56 +0,0 @@
name: Release Build
on:
release:
types: [created]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Get Version
id: get_version
shell: bash
run: |
echo "Reading version from file:"
cat res/ATCS_latest
echo ""
VERSION=$(tr -d '[:space:]' < "res/ATCS_latest")
echo "Processed version: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Environment variable set to: $VERSION"
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Build JAR
shell: bash
run: |
cd packaging
chmod +x package.sh
echo "Building JAR and ZIP for version: ${{ env.VERSION }}"
./package.sh -windows
echo "Created artifacts:"
ls -la common/ATCS.jar
ls -la ATCS_${{ env.VERSION }}.zip
- name: Install NSIS
uses: joncloud/makensis-action@v4
with:
script-file: packaging/Windows/ATCS_Installer.nsi
arguments: /DVERSION="${{ env.VERSION }}"
- name: Upload Release Assets
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: |
./packaging/ATCS_${{ env.VERSION }}.zip
./packaging/ATCS_${{ env.VERSION }}_Setup.exe

1
.gitignore vendored
View File

@@ -11,3 +11,4 @@ ATCS.jar
/packaging/common/ATCS.env.bat /packaging/common/ATCS.env.bat
/packaging/common/ATCS.env /packaging/common/ATCS.env
/packaging/common/ATCS_v*.zip /packaging/common/ATCS_v*.zip
/.output.txt

View File

@@ -10,6 +10,7 @@
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jsoup-1.10.2.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/jsoup-1.10.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/json_simple-1.1.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/json_simple-1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/ui.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/ui.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/AndorsTrainer_v0.1.5.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jide-oss.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/jide-oss.jar" path-in-jar="/" />
</element> </element>
</root> </root>

View File

@@ -1,19 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="JD_P_AT_EMPTY_LINES" value="false" />
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="200" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="SOFT_MARGINS" value="120" />
</codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

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="temurin-11" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" default="true" />
</project> </project>

View File

@@ -61,8 +61,6 @@ if not exist %2\%1\.gitignore (
echo .workspace > .gitignore echo .workspace > .gitignore
echo .project >> .gitignore echo .project >> .gitignore
echo .workspace.json >> .gitignore
echo .project.json >> .gitignore
echo altered/drawable >> .gitignore echo altered/drawable >> .gitignore
echo altered/drawable/* >> .gitignore echo altered/drawable/* >> .gitignore
echo created/drawable >> .gitignore echo created/drawable >> .gitignore

View File

@@ -43,7 +43,7 @@ public class MapObject implements Cloneable
{ {
private Properties properties = new Properties(); private Properties properties = new Properties();
private ObjectGroup objectGroup; private ObjectGroup objectGroup;
private Rectangle bounds; private Rectangle bounds = new Rectangle();
private String name = "Object"; private String name = "Object";
private String type = ""; private String type = "";
private String imageSource = ""; private String imageSource = "";

View File

@@ -57,7 +57,7 @@ public class Sprite
private String name = null; private String name = null;
private int id = -1; private int id = -1;
private int flags; private int flags = KEY_LOOP;
private float frameRate = 1.0f; //one fps private float frameRate = 1.0f; //one fps
private Tile[] frames; private Tile[] frames;

View File

@@ -98,11 +98,7 @@ public class TileSet implements Iterable<Tile>
File f = new File(imgFilename); File f = new File(imgFilename);
BufferedImage image; BufferedImage image = ImageIO.read(f.getCanonicalFile());
try {
image = ImageIO.read(f.getCanonicalFile());
} catch (IOException e) { throw new IOException("Failed to load " + imgFilename);
}
if (image == null) { if (image == null) {
throw new IOException("Failed to load " + imgFilename); throw new IOException("Failed to load " + imgFilename);
} }

View File

@@ -588,7 +588,7 @@ public class TMXMapWriter
} }
// Iterate while parents are the same // Iterate while parents are the same
int shared; int shared = 0;
int maxShared = Math.min(fromParents.size(), toParents.size()); int maxShared = Math.min(fromParents.size(), toParents.size());
for (shared = 0; shared < maxShared; shared++) { for (shared = 0; shared < maxShared; shared++) {
String fromParent = fromParents.get(shared); String fromParent = fromParents.get(shared);

Binary file not shown.

Binary file not shown.

2
packaging/Linux/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/ATCS_v*.zip
/ATCS_v*.zip.rename

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,22 @@
#!/bin/bash
ATCS_DIR=$(dirname $(readlink -f "$0" || greadlink -f "$0" || stat -f "$0"))
MAX_MEM=512M
CP=$(find ${ATCS_DIR}/lib/ -name '*.jar' | paste -sd: -)
JAVA=java
JAVA_OPTS='-DFONT_SCALE=1.0 -Dswing.aatext=true'
ENV_FILE=${ATCS_DIR}/ATCS.env
MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio
if [ -f ${ENV_FILE} ]
then
source ${ENV_FILE}
else
echo "#MAX_MEM=${MAX_MEM}" > ${ENV_FILE}
echo "#JAVA=${JAVA}" >> ${ENV_FILE}
echo "#JAVA_OPTS=${JAVA_OPTS}" >> ${ENV_FILE}
echo "" >> ${ENV_FILE}
fi
export ENV_FILE
$JAVA ${JAVA_OPTS} -Xmx${MAX_MEM} -cp ${CP} ${MAIN_CLASS}

1
packaging/Linux/ATCS/lib/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.jar

View File

@@ -1,12 +1,12 @@
!include MUI2.nsh !include MUI2.nsh
; Version will be passed as /DVERSION=vx.x.x !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 "..\..\" !define ATCS_SOURCE_DIR "C:\ATCS"
Name "Andor's Trail Content Studio ${VERSION}" Name "Andor's Trail Content Studio v${VERSION}"
OutFile "..\ATCS_${VERSION}_Setup.exe" OutFile "ATCS_v${VERSION}_Setup.exe"
InstallDir "$PROGRAMFILES\ATCS\" InstallDir "$PROGRAMFILES\ATCS\"
;SetCompressor /SOLID /FINAL lzma ;SetCompressor /SOLID /FINAL lzma
@@ -14,10 +14,10 @@ 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 ${VERSION}" !define MUI_WELCOMEPAGE_TEXT "This will install Andor's Trail Content Studio v${VERSION}"
!define MUI_FINISHPAGE_TEXT "Andor's Trail Content Studio ${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 ${VERSION}" !define MUI_PAGE_HEADER_TEXT "Installing Andor's Trail Content Studio v${VERSION}"
;Start Menu Folder Page Configuration ;Start Menu Folder Page Configuration
@@ -86,23 +86,23 @@ Section install
FileClose $9 FileClose $9
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"
!insertmacro MUI_STARTMENU_WRITE_END !insertmacro MUI_STARTMENU_WRITE_END
SectionEnd SectionEnd
;------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------
Section uninstall Section uninstall
Delete "$INSTDIR\lib\jide-oss.jar" Delete "$INSTDIR\lib\jide-oss.jar"
Delete "$INSTDIR\lib\ui.jar" Delete "$INSTDIR\lib\ui.jar"
Delete "$INSTDIR\lib\junit-4.10.jar" Delete "$INSTDIR\lib\junit-4.10.jar"
@@ -120,13 +120,13 @@ Section uninstall
Delete "$INSTDIR\ATCS.jar" 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
Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk"
Delete "$SMPROGRAMS\$StartMenuFolder\Andor's Trail Content Studio.lnk" Delete "$SMPROGRAMS\$StartMenuFolder\Andor's Trail Content Studio.lnk"
RMDir "$SMPROGRAMS\$StartMenuFolder" RMDir "$SMPROGRAMS\$StartMenuFolder"
SectionEnd SectionEnd
@@ -138,28 +138,28 @@ Function GetJRE
; 2 - in JAVA_HOME environment variable ; 2 - in JAVA_HOME environment variable
; 3 - in the registry ; 3 - in the registry
; 4 - assume java.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\java.exe" ;StrCpy $R0 "$EXEDIR\jre\bin\java.exe"
;IfFileExists $R0 JreFound ;IfFileExists $R0 JreFound
;StrCpy $R0 "" ;StrCpy $R0 ""
ClearErrors ClearErrors
ReadEnvStr $R0 "JAVA_HOME" ReadEnvStr $R0 "JAVA_HOME"
StrCpy $R0 "$R0\bin\${JAVA_BIN}.exe" StrCpy $R0 "$R0\bin\${JAVA_BIN}.exe"
IfErrors 0 JreFound IfErrors 0 JreFound
ClearErrors ClearErrors
ReadRegStr $R1 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" "CurrentVersion" ReadRegStr $R1 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" "CurrentVersion"
ReadRegStr $R0 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment\$R1" "JavaHome" ReadRegStr $R0 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment\$R1" "JavaHome"
StrCpy $R0 "$R0\bin\${JAVA_BIN}.exe" StrCpy $R0 "$R0\bin\${JAVA_BIN}.exe"
IfErrors 0 JreFound IfErrors 0 JreFound
StrCpy $R0 "${JAVA_BIN}.exe" StrCpy $R0 "${JAVA_BIN}.exe"
JreFound: JreFound:
Pop $R1 Pop $R1
Exch $R0 Exch $R0

View File

@@ -1,26 +1,21 @@
#!/bin/bash #!/bin/bash
ATCS_DIR="$(dirname "$(readlink -f "$0" || greadlink -f "$0" || stat -f "$0")")" ATCS_DIR=$(dirname $(readlink -f "$0" || greadlink -f "$0" || stat -f "$0"))
echo "ATCS_DIR: '${ATCS_DIR}'"
MAX_MEM="512M" MAX_MEM=512M
JAVA="java"
JAVA=java
JAVA_OPTS='-DFONT_SCALE=1.0 -Dswing.aatext=true' JAVA_OPTS='-DFONT_SCALE=1.0 -Dswing.aatext=true'
ENV_FILE=${ATCS_DIR}/ATCS.env
ENV_FILE="${ATCS_DIR}/ATCS.env" if [ -f ${ENV_FILE} ]; then
source ${ENV_FILE}
if [ -f "${ENV_FILE}" ]; then
source "${ENV_FILE}"
else else
{ echo "#MAX_MEM=${MAX_MEM}" >${ENV_FILE}
echo "#MAX_MEM=\"${MAX_MEM}\"" echo "#JAVA=${JAVA}" >>${ENV_FILE}
echo "#JAVA=\"${JAVA}\"" echo "#JAVA_OPTS=${JAVA_OPTS}" >>${ENV_FILE}
echo "#JAVA_OPTS=\"${JAVA_OPTS}\"" echo "" >>${ENV_FILE}
echo ""
}>"${ENV_FILE}"
fi fi
export ENV_FILE export ENV_FILE
# shellcheck disable=SC2086 $JAVA ${JAVA_OPTS} -Xmx${MAX_MEM} -jar ${ATCS_DIR}/ATCS.jar
# (spellchecker is disabled for this line, because we want it to be split into multiple arguments)
$JAVA ${JAVA_OPTS} -Xmx${MAX_MEM} -jar "${ATCS_DIR}/ATCS.jar"

View File

@@ -18,9 +18,10 @@ ATCS_SOURCE_DIR=$(dirname "${PACKAGING_DIR}")
TEMP_DIR="${PACKAGING_DIR}/tmp" TEMP_DIR="${PACKAGING_DIR}/tmp"
JAR_LOCATION="${PACKAGING_DIR}/ATCS.jar" # Output JAR location as per script JAR_LOCATION="${PACKAGING_DIR}/ATCS.jar" # Output JAR location as per script
MANIFEST_LOCATION="${PACKAGING_DIR}/Manifest.txt" MANIFEST_LOCATION="${PACKAGING_DIR}/Manifest.txt"
VERSION_FILE="${ATCS_SOURCE_DIR}/res/ATCS_latest" VERSION_FILE="${PACKAGING_DIR}/ATCS_latest"
SOURCE_BASE_DIR="${ATCS_SOURCE_DIR}/src" # Base directory for standard source code SOURCE_BASE_DIR="${ATCS_SOURCE_DIR}/src" # Base directory for standard source code
LIB_BASE_DIR="${ATCS_SOURCE_DIR}/lib" # Base directory for libraries LIB_BASE_DIR="${ATCS_SOURCE_DIR}/lib" # Base directory for libraries
OUTPUT_JAR_DIR="${PACKAGING_DIR}" # Directory where the final JAR will be placed - as per script
# --- **ADDITIONAL SOURCE CODE FOLDERS** --- # --- **ADDITIONAL SOURCE CODE FOLDERS** ---
EXTRA_SOURCE_DIRS=( EXTRA_SOURCE_DIRS=(
@@ -29,8 +30,9 @@ EXTRA_SOURCE_DIRS=(
"siphash-zackehh/src/main/java" "siphash-zackehh/src/main/java"
) )
# --- Libraries to include --- # --- Libraries to include (from IntelliJ artifact definition) ---
LIBRARIES=( LIBRARIES=(
"AndorsTrainer_v0.1.5.jar"
"bsh-2.0b4.jar" "bsh-2.0b4.jar"
"jide-oss.jar" "jide-oss.jar"
"json_simple-1.1.jar" "json_simple-1.1.jar"
@@ -43,7 +45,7 @@ LIBRARIES=(
# --- Get version --- # --- Get version ---
echo "Getting version" echo "Getting version"
VERSION=$(tr -d '[:space:]' < "${VERSION_FILE}") VERSION=$(cat "${VERSION_FILE}")
echo "Got version ${VERSION}" echo "Got version ${VERSION}"
# --- Prepare temporary directory --- # --- Prepare temporary directory ---
@@ -61,7 +63,7 @@ done
# --- Set ClassPath --- # --- Set ClassPath ---
echo "Getting source files" echo "Getting source files"
# Find all java files in source directories # Find all java files in source directories and compile them
SOURCE_FILES=$(find "${SOURCE_BASE_DIR}" "${EXTRA_SOURCE_DIRS[@]/#/${ATCS_SOURCE_DIR}/}" -name "*.java" -print) SOURCE_FILES=$(find "${SOURCE_BASE_DIR}" "${EXTRA_SOURCE_DIRS[@]/#/${ATCS_SOURCE_DIR}/}" -name "*.java" -print)
#echo "SourceFiles: ${SOURCE_FILES}" #echo "SourceFiles: ${SOURCE_FILES}"
echo "" echo ""
@@ -69,8 +71,6 @@ echo ""
# --- Build Java classes --- # --- Build Java classes ---
echo 'Building java classes' echo 'Building java classes'
# shellcheck disable=SC2086
# (we need word splitting here to pass multiple files)
javac -cp "${TEMP_DIR}" -d "${TEMP_DIR}" ${SOURCE_FILES} javac -cp "${TEMP_DIR}" -d "${TEMP_DIR}" ${SOURCE_FILES}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Compilation failed. Please check errors above." echo "Compilation failed. Please check errors above."
@@ -85,7 +85,6 @@ mkdir -p "${TEMP_DIR}/com/gpl/rpg/atcontentstudio/img"
mkdir -p "${TEMP_DIR}/tiled/io/resources/" mkdir -p "${TEMP_DIR}/tiled/io/resources/"
cp -r "${ATCS_SOURCE_DIR}"/src/com/gpl/rpg/atcontentstudio/img/* "${TEMP_DIR}/com/gpl/rpg/atcontentstudio/img/" # some icons cp -r "${ATCS_SOURCE_DIR}"/src/com/gpl/rpg/atcontentstudio/img/* "${TEMP_DIR}/com/gpl/rpg/atcontentstudio/img/" # some icons
cp -r "${ATCS_SOURCE_DIR}"/hacked-libtiled/tiled/io/resources/* "${TEMP_DIR}/tiled/io/resources/" # dtd file for tmx maps cp -r "${ATCS_SOURCE_DIR}"/hacked-libtiled/tiled/io/resources/* "${TEMP_DIR}/tiled/io/resources/" # dtd file for tmx maps
cp "${VERSION_FILE}" "${TEMP_DIR}/" # Copy version file
# --- Create JAR file --- # --- Create JAR file ---
echo "" echo ""
@@ -104,22 +103,17 @@ cd "${PACKAGING_DIR}" || exit # Go back to packaging dir
echo '' echo ''
echo "Done creating jar at ${JAR_LOCATION}" echo "Done creating jar at ${JAR_LOCATION}"
cp -f "${JAR_LOCATION}" "${PACKAGING_DIR}/common/ATCS.jar" # Copy JAR to versioned name cp -f "${JAR_LOCATION}" "${OUTPUT_JAR_DIR}/common/ATCS.jar" # Copy JAR to versioned name
# --- Create archive --- # --- Create archive ---
cd "${PACKAGING_DIR}" || exit if [ "$PLATFORM" = "LINUX" ]; then
echo "Creating archive" cd "${OUTPUT_JAR_DIR}" || exit
if [ "$PLATFORM" = "WINDOWS" ]; then echo "Creating archive"
# Use PowerShell's Compress-Archive which is available by default on Windows tar caf "ATCS_${VERSION}.tar.gz" common/* # archive the 'common' folder which now contains the JAR and libs
powershell.exe -Command "Compress-Archive -Path './common/*' -DestinationPath './ATCS_${VERSION}.zip' -Force" echo "Created archive at ${OUTPUT_JAR_DIR}/ATCS_${VERSION}.tar.gz"
cd "${PACKAGING_DIR}" || exit
else else
# Use zip command on Linux echo "Can't create zip files on windows yet. Please pack the content of the '${OUTPUT_JAR_DIR}/common/' folder yourself"
zip -r "ATCS_${VERSION}.zip" common/* # archive the 'common' folder which now contains the JAR and libs
fi fi
if [ $? -ne 0 ]; then
echo "Archive creation failed."
exit 1
fi
echo "Created archive at ${PACKAGING_DIR}/ATCS_${VERSION}.zip"
echo "Script finished." echo "Script finished."

View File

@@ -1,16 +1,10 @@
package com.gpl.rpg.atcontentstudio; package com.gpl.rpg.atcontentstudio;
import com.gpl.rpg.atcontentstudio.model.Workspace; import java.awt.Color;
import com.gpl.rpg.atcontentstudio.ui.StudioFrame; import java.awt.Desktop;
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog; import java.awt.Dimension;
import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector; import java.awt.Font;
import prefuse.data.expression.parser.ExpressionParser; import java.awt.Toolkit;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.plaf.FontUIResource;
import java.awt.*;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.io.BufferedReader; import java.io.BufferedReader;
@@ -20,235 +14,221 @@ import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.http.HttpTimeoutException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.*; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.plaf.FontUIResource;
import prefuse.data.expression.parser.ExpressionParser;
import com.gpl.rpg.atcontentstudio.model.Workspace;
import com.gpl.rpg.atcontentstudio.ui.StudioFrame;
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog;
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 = readVersionFromFile(); 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";
public static final String FONT_SCALE_ENV_VAR_NAME = "FONT_SCALE"; public static final String FONT_SCALE_ENV_VAR_NAME = "FONT_SCALE";
public static boolean STARTED = false; public static boolean STARTED = false;
public static float SCALING = 1.0f; public static float SCALING = 1.0f;
public static StudioFrame frame = null; public static StudioFrame frame = null;
// Need to keep a strong reference to it, to avoid garbage collection that'll // Need to keep a strong reference to it, to avoid garbage collection that'll
// reset these loggers. // reset these loggers.
public static final List<Logger> configuredLoggers = new LinkedList<Logger>(); public static final List<Logger> configuredLoggers = new LinkedList<Logger>();
/** /**
* @param args * @param args
*/ */
public static void main(String[] args) { public static void main(String[] args) {
String fontScaling = System.getProperty(FONT_SCALE_ENV_VAR_NAME); String fontScaling = System.getProperty(FONT_SCALE_ENV_VAR_NAME);
Float fontScale; Float fontScale = null;
if (fontScaling != null) { if (fontScaling != null) {
try { try {
fontScale = Float.parseFloat(fontScaling); fontScale = Float.parseFloat(fontScaling);
SCALING = fontScale; SCALING = fontScale;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.err.println("Failed to parse font scaling parameter. Using default."); System.err.println("Failed to parse font scaling parameter. Using default.");
e.printStackTrace(); e.printStackTrace();
} }
} }
ConfigCache.init(); ConfigCache.init();
String laf = ConfigCache.getFavoriteLaFClassName(); try {
setLookAndFeel(laf); String laf = ConfigCache.getFavoriteLaFClassName();
if (laf == null)
laf = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(laf);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
// Need to keep a strong reference to it, to avoid garbage collection that'll scaleUIFont();
// reset this setting.
Logger l = Logger.getLogger(ExpressionParser.class.getName());
l.setLevel(Level.OFF);
configuredLoggers.add(l);
final WorkspaceSelector wsSelect = new WorkspaceSelector(); // Need to keep a strong reference to it, to avoid garbage collection that'll
wsSelect.pack(); // reset this setting.
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize(); Logger l = Logger.getLogger(ExpressionParser.class.getName());
Dimension wdim = wsSelect.getSize(); l.setLevel(Level.OFF);
wsSelect.setLocation((sdim.width - wdim.width) / 2, (sdim.height - wdim.height) / 2); configuredLoggers.add(l);
wsSelect.setVisible(true);
wsSelect.addWindowListener(new WindowAdapter() { final WorkspaceSelector wsSelect = new WorkspaceSelector();
@Override wsSelect.pack();
public synchronized void windowClosed(WindowEvent e) { Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
if (wsSelect.selected != null && !STARTED) { Dimension wdim = wsSelect.getSize();
ATContentStudio.STARTED = true; wsSelect.setLocation((sdim.width - wdim.width) / 2, (sdim.height - wdim.height) / 2);
final File workspaceRoot = new File(wsSelect.selected); wsSelect.setVisible(true);
WorkerDialog.showTaskMessage("Loading your workspace...", null, new Runnable() {
public void run() {
Workspace.setActive(workspaceRoot);
if (Workspace.activeWorkspace.settings.useInternet.getCurrentValue()
&& Workspace.activeWorkspace.settings.checkUpdates.getCurrentValue()) {
new Thread() {
public void run() {
checkUpdate();
}
}.start();
}
frame = new StudioFrame(APP_NAME + " " + APP_VERSION);
frame.setVisible(true);
frame.setDefaultCloseOperation(StudioFrame.DO_NOTHING_ON_CLOSE);
}
});
for (File f : ConfigCache.getKnownWorkspaces()) {
if (workspaceRoot.equals(f)) {
if (!workspaceRoot.equals(ConfigCache.getLatestWorkspace())) {
ConfigCache.setLatestWorkspace(f);
}
return;
}
}
ConfigCache.addWorkspace(workspaceRoot);
ConfigCache.setLatestWorkspace(workspaceRoot);
} wsSelect.addWindowListener(new WindowAdapter() {
} @Override
}); public synchronized void windowClosed(WindowEvent e) {
} if (wsSelect.selected != null && !STARTED) {
ATContentStudio.STARTED = true;
final File workspaceRoot = new File(wsSelect.selected);
WorkerDialog.showTaskMessage("Loading your workspace...", null, new Runnable() {
public void run() {
Workspace.setActive(workspaceRoot);
if (Workspace.activeWorkspace.settings.useInternet.getCurrentValue()
&& Workspace.activeWorkspace.settings.checkUpdates.getCurrentValue()) {
new Thread() {
public void run() {
checkUpdate();
}
}.start();
}
frame = new StudioFrame(APP_NAME + " " + APP_VERSION);
frame.setVisible(true);
frame.setDefaultCloseOperation(StudioFrame.DO_NOTHING_ON_CLOSE);
};
});
for (File f : ConfigCache.getKnownWorkspaces()) {
if (workspaceRoot.equals(f)) {
if (!workspaceRoot.equals(ConfigCache.getLatestWorkspace())) {
ConfigCache.setLatestWorkspace(f);
}
return;
}
}
ConfigCache.addWorkspace(workspaceRoot);
ConfigCache.setLatestWorkspace(workspaceRoot);
public static void setLookAndFeel(String laf) { }
if (laf == null) }
{ });
System.out.println("No look and feel specified, using system default."); }
laf = UIManager.getSystemLookAndFeelClassName();
}
System.out.println("Info: Setting look and feel to: " + laf);
try { private static void checkUpdate() {
UIManager.setLookAndFeel(laf); BufferedReader in = null;
} catch (ClassNotFoundException e) { try {
System.err.println("Failed to load system look and feel. "); URL url = new URL(CHECK_UPDATE_URL);
System.err.println("Installed look and feel classes: "); in = new BufferedReader(new InputStreamReader(url.openStream()));
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
System.err.println(" " + info.getName() + " (" + info.getClassName() + ")");
}
System.err.println("Tried to load: " + laf + " but got this error:");
e.printStackTrace(); String inputLine, lastLine = null;
} catch (InstantiationException | UnsupportedLookAndFeelException | IllegalAccessException e) { while ((inputLine = in.readLine()) != null) {
e.printStackTrace(); lastLine = inputLine;
} }
var newLaF = UIManager.getLookAndFeel(); if (lastLine != null && !lastLine.equals(APP_VERSION)) {
System.out.println("Using look and feel: " + newLaF.getName() + " (" + newLaF.getClass().getName() + ")");
scaleUIFont(); // for copying style
} JLabel label = new JLabel();
Font font = label.getFont();
Color color = label.getBackground();
private static void checkUpdate() { // create some css from the label's font
BufferedReader in = null; StringBuffer style = new StringBuffer("font-family:" + font.getFamily() + ";");
try { style.append("font-weight:" + (font.isBold() ? "bold" : "normal") + ";");
URL url = new URL(CHECK_UPDATE_URL); style.append("font-size:" + font.getSize() + "pt;");
in = new BufferedReader(new InputStreamReader(url.openStream())); style.append("background-color: rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue()
+ ");");
String inputLine, lastLine = null; JEditorPane ep = new JEditorPane("text/html",
while ((inputLine = in.readLine()) != null) { "<html><body style=\"" + style + "\">" + "You are not running the latest ATCS version.<br/>"
lastLine = inputLine; + "You can get the latest version (" + lastLine + ") by clicking the link below.<br/>"
} + "<a href=\"" + DOWNLOAD_URL + "\">" + DOWNLOAD_URL + "</a><br/>" + "<br/>"
if (lastLine != null && !lastLine.equals(APP_VERSION)) { + "</body></html>");
// for copying style ep.setEditable(false);
JLabel label = new JLabel(); ep.setBorder(null);
Font font = label.getFont();
Color color = label.getBackground();
// create some css from the label's font ep.addHyperlinkListener(new HyperlinkListener() {
StringBuffer style = new StringBuffer("font-family:" + font.getFamily() + ";");
style.append("font-weight:" + (font.isBold() ? "bold" : "normal") + ";");
style.append("font-size:" + font.getSize() + "pt;");
style.append("background-color: rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue()
+ ");");
JEditorPane ep = new JEditorPane("text/html", @Override
"<html><body style=\"" + style + "\">" + "You are not running the latest ATCS version.<br/>" public void hyperlinkUpdate(HyperlinkEvent e) {
+ "You can get the latest version (" + lastLine + ") by clicking the link below.<br/>" try {
+ "<a href=\"" + DOWNLOAD_URL + "\">" + DOWNLOAD_URL + "</a><br/>" + "<br/>" if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
+ "</body></html>"); Desktop.getDesktop().browse(e.getURL().toURI());
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
}
});
ep.setEditable(false); JOptionPane.showMessageDialog(null, ep, "Update available", JOptionPane.INFORMATION_MESSAGE);
ep.setBorder(null); }
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ep.addHyperlinkListener(new HyperlinkListener() { public static void scaleUIFont() {
if (SCALING != 1.0f) {
@Override System.out.println("Scaling fonts to " + SCALING);
public void hyperlinkUpdate(HyperlinkEvent e) { UIDefaults defaults = UIManager.getLookAndFeelDefaults();
try { Map<Object, Object> newDefaults = new HashMap<Object, Object>();
if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { for (Enumeration<Object> e = defaults.keys(); e.hasMoreElements();) {
Desktop.getDesktop().browse(e.getURL().toURI()); Object key = e.nextElement();
} Object value = defaults.get(key);
} catch (IOException e1) { if (value instanceof Font) {
e1.printStackTrace(); Font font = (Font) value;
} catch (URISyntaxException e1) { int newSize = (int) (font.getSize() * SCALING);
e1.printStackTrace(); if (value instanceof FontUIResource) {
} newDefaults.put(key, new FontUIResource(font.getName(), font.getStyle(), newSize));
} } else {
}); newDefaults.put(key, new Font(font.getName(), font.getStyle(), newSize));
}
JOptionPane.showMessageDialog(null, ep, "Update available", JOptionPane.INFORMATION_MESSAGE); }
} }
} catch (MalformedURLException e) { for (Object key : newDefaults.keySet()) {
e.printStackTrace(); defaults.put(key, newDefaults.get(key));
} catch (HttpTimeoutException e) { }
System.out.println("Could not connect to url to check for updates (timeout): " + CHECK_UPDATE_URL); }
} catch (IOException e) { }
if (e.getMessage() != null && e.getMessage().startsWith("Server returned HTTP response code:")) {
System.out.println("Could not fetch current version from server to check for updates (non-success-status): " + e.getMessage());
} else {
System.out.println("Could not check for updates: '" + CHECK_UPDATE_URL + "' - " + e.getMessage());
}
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void scaleUIFont() {
if (SCALING != 1.0f) {
System.out.println("Scaling fonts to " + SCALING);
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
Map<Object, Object> newDefaults = new HashMap<Object, Object>();
for (Enumeration<Object> e = defaults.keys(); e.hasMoreElements(); ) {
Object key = e.nextElement();
Object value = defaults.get(key);
if (value instanceof Font) {
Font font = (Font) value;
int newSize = (int) (font.getSize() * SCALING);
if (value instanceof FontUIResource) {
newDefaults.put(key, new FontUIResource(font.getName(), font.getStyle(), newSize));
} else {
newDefaults.put(key, new Font(font.getName(), font.getStyle(), newSize));
}
}
}
for (Object key : newDefaults.keySet()) {
defaults.put(key, newDefaults.get(key));
}
}
}
private static String readVersionFromFile() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
Objects.requireNonNull(ATContentStudio.class.getResourceAsStream("/ATCS_latest"))))) {
return reader.readLine();
} catch (IOException e) {
e.printStackTrace();
return "unknown";
}
}
} }

View File

@@ -1,104 +1,103 @@
package com.gpl.rpg.atcontentstudio; package com.gpl.rpg.atcontentstudio;
import com.gpl.rpg.atcontentstudio.io.SettingsSave;
import java.io.File; import java.io.File;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.gpl.rpg.atcontentstudio.io.SettingsSave;
public class ConfigCache implements Serializable { public class ConfigCache implements Serializable {
private static final long serialVersionUID = 4584324644282843961L; private static final long serialVersionUID = 4584324644282843961L;
private static final File CONFIG_CACHE_STORAGE; private static final File CONFIG_CACHE_STORAGE;
private static ConfigCache instance = null; private static ConfigCache instance = null;
static { static {
if (System.getenv("APPDATA") != null) { if (System.getenv("APPDATA") != null) {
CONFIG_CACHE_STORAGE = new File(System.getenv("APPDATA") + File.separator + ATContentStudio.APP_NAME + File.separator + "configCache"); CONFIG_CACHE_STORAGE = new File(System.getenv("APPDATA")+File.separator+ATContentStudio.APP_NAME+File.separator+"configCache" );
} else { } else {
CONFIG_CACHE_STORAGE = new File(System.getenv("HOME") + File.separator + "." + ATContentStudio.APP_NAME + File.separator + "configCache"); CONFIG_CACHE_STORAGE = new File(System.getenv("HOME")+File.separator+"."+ATContentStudio.APP_NAME+File.separator+"configCache" );
} }
CONFIG_CACHE_STORAGE.getParentFile().mkdirs(); CONFIG_CACHE_STORAGE.getParentFile().mkdirs();
if (CONFIG_CACHE_STORAGE.exists()) { if (CONFIG_CACHE_STORAGE.exists()) {
ConfigCache.instance = (ConfigCache) SettingsSave.loadInstance(CONFIG_CACHE_STORAGE, "Configuration cache"); ConfigCache.instance = (ConfigCache) SettingsSave.loadInstance(CONFIG_CACHE_STORAGE, "Configuration cache");
if (ConfigCache.instance == null) { if (ConfigCache.instance == null) {
ConfigCache.instance = new ConfigCache(); ConfigCache.instance = new ConfigCache();
} }
} else { } else {
ConfigCache.instance = new ConfigCache(); ConfigCache.instance = new ConfigCache();
} }
} }
private void save() { private void save() {
SettingsSave.saveInstance(instance, ConfigCache.CONFIG_CACHE_STORAGE, "Configuration cache"); SettingsSave.saveInstance(instance, ConfigCache.CONFIG_CACHE_STORAGE, "Configuration cache");
} }
private List<File> knownWorkspaces = new ArrayList<File>(); private List<File> knownWorkspaces = new ArrayList<File>();
private File latestWorkspace = null; private File latestWorkspace = null;
private String favoriteLaFClassName = null; private String favoriteLaFClassName = null;
private boolean[] notifConfig = new boolean[]{true, true, true, true}; private boolean[] notifConfig = new boolean[]{true, true, true, true};
public static List<File> getKnownWorkspaces() {
return instance.knownWorkspaces;
}
public static void addWorkspace(File w) {
instance.knownWorkspaces.add(w);
instance.save();
}
public static void removeWorkspace(File w) {
instance.knownWorkspaces.remove(w);
instance.save();
}
public static File getLatestWorkspace() {
return instance.latestWorkspace;
}
public static List<File> getKnownWorkspaces() { public static void setLatestWorkspace(File latestWorkspace) {
return instance.knownWorkspaces; instance.latestWorkspace = latestWorkspace;
} instance.save();
}
public static void addWorkspace(File w) { public static String getFavoriteLaFClassName() {
instance.knownWorkspaces.add(w); return instance.favoriteLaFClassName;
instance.save(); }
}
public static void setFavoriteLaFClassName(String favoriteLaFClassName) {
instance.favoriteLaFClassName = favoriteLaFClassName;
instance.save();
}
public static void removeWorkspace(File w) { public static void putNotifViewConfig(boolean[] view) {
instance.knownWorkspaces.remove(w); for (int i=instance.notifConfig.length; i<0; --i) {
instance.save(); instance.notifConfig[i] = view[i];
} }
instance.save();
}
public static File getLatestWorkspace() { public static boolean[] getNotifViewConfig() {
return instance.latestWorkspace; if (instance == null || instance.notifConfig == null) {
} //Not yet initialized. All flags on to help corner out init issues.
return new boolean[]{true, true, true, true};
}
return instance.notifConfig;
}
public static void setLatestWorkspace(File latestWorkspace) { public static void init() {}
instance.latestWorkspace = latestWorkspace;
instance.save();
}
public static String getFavoriteLaFClassName() { public static void clear() {
return instance.favoriteLaFClassName; instance.knownWorkspaces.clear();
} setFavoriteLaFClassName(null);
instance.notifConfig = new boolean[]{true, true, true, true};
public static void setFavoriteLaFClassName(String favoriteLaFClassName) { instance.save();
instance.favoriteLaFClassName = favoriteLaFClassName; }
instance.save();
}
public static void putNotifViewConfig(boolean[] view) {
for (int i = instance.notifConfig.length; i < 0; --i) {
instance.notifConfig[i] = view[i];
}
instance.save();
}
public static boolean[] getNotifViewConfig() {
if (instance == null || instance.notifConfig == null) {
//Not yet initialized. All flags on to help corner out init issues.
return new boolean[]{true, true, true, true};
}
return instance.notifConfig;
}
public static void init() {
}
public static void clear() {
instance.knownWorkspaces.clear();
setFavoriteLaFClassName(null);
instance.notifConfig = new boolean[]{true, true, true, true};
instance.save();
}
} }

View File

@@ -6,87 +6,87 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class Notification { public class Notification {
public static List<Notification> notifs = new ArrayList<Notification>(); public static List<Notification> notifs = new ArrayList<Notification>();
private static List<NotificationListener> listeners = new CopyOnWriteArrayList<NotificationListener>(); private static List<NotificationListener> listeners = new CopyOnWriteArrayList<NotificationListener>();
public static boolean showS, showI, showW, showE; public static boolean showS = true, showI = true, showW = true, showE = true;
static { static {
boolean[] config = ConfigCache.getNotifViewConfig(); boolean[] config = ConfigCache.getNotifViewConfig();
showS = config[0]; showS = config[0];
showI = config[1]; showI = config[1];
showW = config[2]; showW = config[2];
showE = config[3]; showE = config[3];
} }
public static enum Type { public static enum Type {
SUCCESS, SUCCESS,
INFO, INFO,
WARN, WARN,
ERROR ERROR
} }
public Type type; public Type type;
public String text; public String text;
public Notification(Type type, String text) { public Notification(Type type, String text) {
this.type = type; this.type = type;
this.text = text; this.text = text;
} }
public String toString() { public String toString() {
return "[" + type.toString() + "] " + text; return "["+type.toString()+"] "+text;
} }
public static void clear() { public static void clear() {
int i = notifs.size(); int i = notifs.size();
notifs.clear(); notifs.clear();
for (NotificationListener l : listeners) { for (NotificationListener l : listeners) {
l.onListCleared(i); l.onListCleared(i);
} }
} }
public static void addSuccess(String text) {
if (!showS) return;
Notification n = new Notification(Notification.Type.SUCCESS, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addInfo(String text) {
if (!showI) return;
Notification n = new Notification(Notification.Type.INFO, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addWarn(String text) {
if (!showW) return;
Notification n = new Notification(Notification.Type.WARN, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addError(String text) {
if (!showE) return;
Notification n = new Notification(Notification.Type.ERROR, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addNotificationListener(NotificationListener l) {
listeners.add(l);
}
public static void removeNotificationListener(NotificationListener l) {
listeners.remove(l);
}
public static void addSuccess(String text) {
if (!showS) return;
Notification n = new Notification(Notification.Type.SUCCESS, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addInfo(String text) {
if (!showI) return;
Notification n = new Notification(Notification.Type.INFO, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addWarn(String text) {
if (!showW) return;
Notification n = new Notification(Notification.Type.WARN, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addError(String text) {
if (!showE) return;
Notification n = new Notification(Notification.Type.ERROR, text);
notifs.add(n);
for (NotificationListener l : listeners) {
l.onNewNotification(n);
}
}
public static void addNotificationListener(NotificationListener l) {
listeners.add(l);
}
public static void removeNotificationListener(NotificationListener l) {
listeners.remove(l);
}
} }

View File

@@ -2,8 +2,7 @@ package com.gpl.rpg.atcontentstudio;
public interface NotificationListener { public interface NotificationListener {
public void onNewNotification(Notification n); public void onNewNotification(Notification n);
public void onListCleared(int i);
public void onListCleared(int i);
} }

View File

@@ -4,50 +4,50 @@ import java.io.StringWriter;
public class JsonPrettyWriter extends StringWriter { public class JsonPrettyWriter extends StringWriter {
private int indentLevel = 0; private int indentLevel = 0;
private String indentText = " "; private String indentText = " ";
public JsonPrettyWriter() {
super();
}
public JsonPrettyWriter(String indent) {
super();
this.indentText = indent;
}
public JsonPrettyWriter() { @Override
super(); public void write(int c) {
} if (((char) c) == '[' || ((char) c) == '{') {
super.write(c);
super.write('\n');
indentLevel++;
writeIndentation();
} else if (((char) c) == ',') {
super.write(c);
super.write('\n');
writeIndentation();
} else if (((char) c) == ']' || ((char) c) == '}') {
super.write('\n');
indentLevel--;
writeIndentation();
super.write(c);
} else {
super.write(c);
}
public JsonPrettyWriter(String indent) { }
super();
this.indentText = indent; //Horrible hack to remove the horrible escaping of slashes in json-simple....
} @Override
public void write(String str) {
super.write(str.replaceAll("\\\\/", "/"));
}
@Override private void writeIndentation() {
public void write(int c) { for (int i = 0; i < indentLevel; i++) {
if (((char) c) == '[' || ((char) c) == '{') { super.write(indentText);
super.write(c); }
super.write('\n'); }
indentLevel++;
writeIndentation();
} else if (((char) c) == ',') {
super.write(c);
super.write('\n');
writeIndentation();
} else if (((char) c) == ']' || ((char) c) == '}') {
super.write('\n');
indentLevel--;
writeIndentation();
super.write(c);
} else {
super.write(c);
}
}
//Horrible hack to remove the horrible escaping of slashes in json-simple....
@Override
public void write(String str) {
super.write(str.replaceAll("\\\\/", "/"));
}
private void writeIndentation() {
for (int i = 0; i < indentLevel; i++) {
super.write(indentText);
}
}
} }

View File

@@ -1,8 +0,0 @@
package com.gpl.rpg.atcontentstudio.io;
import java.util.Map;
public interface JsonSerializable {
Map toMap();
void fromMap(Map map);
}

View File

@@ -1,70 +1,76 @@
package com.gpl.rpg.atcontentstudio.io; package com.gpl.rpg.atcontentstudio.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import java.io.*;
public class SettingsSave { public class SettingsSave {
public static void saveInstance(Object obj, File f, String type) { public static void saveInstance(Object obj, File f, String type) {
try { try {
FileOutputStream fos = new FileOutputStream(f); FileOutputStream fos = new FileOutputStream(f);
try { try {
ObjectOutputStream oos = new ObjectOutputStream(fos); ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj); oos.writeObject(obj);
oos.flush(); oos.flush();
oos.close(); oos.close();
Notification.addSuccess(type + " successfully saved."); Notification.addSuccess(type+" successfully saved.");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " saving error: " + e.getMessage()); Notification.addError(type+" saving error: "+e.getMessage());
} finally { } finally {
try { try {
fos.close(); fos.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " saving error: " + e.getMessage()); Notification.addError(type+" saving error: "+e.getMessage());
} }
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " saving error: " + e.getMessage()); Notification.addError(type+" saving error: "+e.getMessage());
} }
} }
public static Object loadInstance(File f, String type) { public static Object loadInstance(File f, String type) {
FileInputStream fis; FileInputStream fis;
Object result = null; Object result = null;
try { try {
fis = new FileInputStream(f); fis = new FileInputStream(f);
ObjectInputStream ois; ObjectInputStream ois;
try { try {
ois = new ObjectInputStream(fis); ois = new ObjectInputStream(fis);
try { try {
result = ois.readObject(); result = ois.readObject();
Notification.addSuccess(type + " successfully loaded."); Notification.addSuccess(type+" successfully loaded.");
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " loading error: " + e.getMessage()); Notification.addError(type+" loading error: "+e.getMessage());
} finally { } finally {
ois.close(); ois.close();
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " loading error: " + e.getMessage()); Notification.addError(type+" loading error: "+e.getMessage());
} finally { } finally {
try { try {
fis.close(); fis.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " loading error: " + e.getMessage()); Notification.addError(type+" loading error: "+e.getMessage());
} }
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
Notification.addError(type + " loading error: " + e.getMessage()); Notification.addError(type+" loading error: "+e.getMessage());
} }
return result; return result;
} }
} }

View File

@@ -1,135 +1,124 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class ClosedProject implements ProjectTreeNode { public class ClosedProject implements ProjectTreeNode {
String name; String name;
Workspace parent; Workspace parent;
public ClosedProject(Workspace w, String name) {
this.parent = w;
this.name = name;
}
public ClosedProject(Workspace w, String name) { @Override
this.parent = w; public TreeNode getChildAt(int childIndex) {
this.name = name; return null;
} }
@Override
public int getChildCount() {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public int getIndex(TreeNode node) {
return 0;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override @Override
public TreeNode getChildAt(int childIndex) { public String getDesc() {
return null; return name+" [closed]";
} }
@Override @Override
public int getChildCount() { public Project getProject() {
return 0; return null;
} }
@Override
public TreeNode getParent() {
return parent;
}
@Override
public int getIndex(TreeNode node) {
return 0;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return name + " [closed]";
}
@Override
public Project getProject() {
return null;
}
@Override @Override
public Image getIcon() { public Image getIcon() {
return getOpenIcon(); return getOpenIcon();
} }
@Override
@Override public Image getClosedIcon() {
public Image getClosedIcon() { //TODO Create a cool Project icon.
//TODO Create a cool Project icon. return DefaultIcons.getStdClosedIcon();
return DefaultIcons.getStdClosedIcon(); }
} @Override
public Image getLeafIcon() {
@Override //TODO Create a cool Project icon.
public Image getLeafIcon() { return DefaultIcons.getStdClosedIcon();
//TODO Create a cool Project icon. }
return DefaultIcons.getStdClosedIcon(); @Override
} public Image getOpenIcon() {
//TODO Create a cool Project icon.
@Override return DefaultIcons.getStdOpenIcon();
public Image getOpenIcon() { }
//TODO Create a cool Project icon.
return DefaultIcons.getStdOpenIcon(); @Override
} public GameDataSet getDataSet() {
return null;
@Override }
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean needsSaving() {
return false;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean needsSaving() {
return false;
}
} }

View File

@@ -1,237 +1,219 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry; import java.awt.Image;
import java.io.Serializable;
import javax.swing.tree.TreeNode; import java.util.ArrayList;
import java.awt.*; import java.util.Enumeration;
import java.io.Serializable; import java.util.List;
import java.util.List; import java.util.Map;
import java.util.*; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public abstract class GameDataElement implements ProjectTreeNode, Serializable { import javax.swing.tree.TreeNode;
private static final long serialVersionUID = 2028934451226743389L; import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry;
public static enum State { public abstract class GameDataElement implements ProjectTreeNode, Serializable {
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. private static final long serialVersionUID = 2028934451226743389L;
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 public static enum State {
modified, // Whether altered or created, this item has been modified since creation from scratch or from JSON. init, // We know the object exists, and have its key/ID.
saved // Whether altered or created, this item has been saved since last modification. 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.
created, // This is an object we are creating
public State state = State.init; 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.
//Available from state init. }
public ProjectTreeNode parent;
public State state = State.init;
public boolean writable = false;
//Available from state init.
public BookmarkEntry bookmark = null; public ProjectTreeNode parent;
//List of objects whose transition to "linked" state made them point to this instance. public boolean writable = false;
private Map<GameDataElement, Integer> backlinks = new ConcurrentHashMap<GameDataElement, Integer>();
public BookmarkEntry bookmark = null;
public String id = null;
//List of objects whose transition to "linked" state made them point to this instance.
@Override private Map<GameDataElement, Integer> backlinks = new ConcurrentHashMap<GameDataElement, Integer>();
public Enumeration<ProjectTreeNode> children() {
return null; public String id = null;
}
@Override
@Override public Enumeration<ProjectTreeNode> children() {
public boolean getAllowsChildren() { return null;
return false; }
} @Override
public boolean getAllowsChildren() {
@Override return false;
public TreeNode getChildAt(int arg0) { }
return null; @Override
} public TreeNode getChildAt(int arg0) {
return null;
@Override }
public int getChildCount() { @Override
return 0; public int getChildCount() {
} 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
public boolean isLeaf() {
@Override return true;
public boolean isLeaf() { }
return true; @Override
} public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
@Override parent.childrenAdded(path);
public void childrenAdded(List<ProjectTreeNode> path) { }
path.add(0, this);
parent.childrenAdded(path); @Override
} public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
@Override parent.childrenChanged(path);
public void childrenChanged(List<ProjectTreeNode> path) { }
path.add(0, this);
parent.childrenChanged(path); @Override
} public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0,this);
@Override parent.childrenRemoved(path);
public void childrenRemoved(List<ProjectTreeNode> path) { }
path.add(0, this); @Override
parent.childrenRemoved(path); public void notifyCreated() {
} childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override @Override
public void notifyCreated() { public abstract String getDesc();
childrenAdded(new ArrayList<ProjectTreeNode>());
} public static String getStaticDesc() {
return "GameDataElements";
@Override }
public abstract String getDesc();
public abstract void parse();
public static String getStaticDesc() { public abstract void link();
return "GameDataElements";
}
public abstract void parse(); @Override
public Project getProject() {
public abstract void link(); return parent == null ? null : parent.getProject();
}
@Override
public Project getProject() { public Image getIcon() {
return parent == null ? null : parent.getProject(); return null;
} }
@Override
public Image getClosedIcon() {return null;}
public Image getIcon() { @Override
return null; public Image getOpenIcon() {return null;}
} @Override
public Image getLeafIcon() {
@Override return getIcon();
public Image getClosedIcon() { }
return null;
}
public abstract GameDataElement clone();
@Override
public Image getOpenIcon() { public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne);
return null;
}
@Override
@Override public GameSource.Type getDataType() {
public Image getLeafIcon() { if (parent == null) {
return getIcon(); System.out.println("blerf.");
} }
return parent.getDataType();
}
public abstract GameDataElement clone();
public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne); public List<BacklinksListener> backlinkListeners = new ArrayList<GameDataElement.BacklinksListener>();
public void addBacklinkListener(BacklinksListener l) {
@Override backlinkListeners.add(l);
public GameSource.Type getDataType() { }
if (parent == null) {
System.out.println("blerf."); public void removeBacklinkListener(BacklinksListener l) {
} backlinkListeners.remove(l);
return parent.getDataType(); }
}
public void addBacklink(GameDataElement gde) {
if (!backlinks.containsKey(gde)) {
public List<BacklinksListener> backlinkListeners = new ArrayList<GameDataElement.BacklinksListener>(); backlinks.put(gde, 1);
for (BacklinksListener l : backlinkListeners) {
public void addBacklinkListener(BacklinksListener l) { l.backlinkAdded(gde);
backlinkListeners.add(l); }
} } else {
backlinks.put(gde, backlinks.get(gde) + 1);
public void removeBacklinkListener(BacklinksListener l) { }
backlinkListeners.remove(l); }
}
public void removeBacklink(GameDataElement gde) {
public void addBacklink(GameDataElement gde) { if (backlinks.get(gde) == null) return;
if (!backlinks.containsKey(gde)) { backlinks.put(gde, backlinks.get(gde) - 1);
backlinks.put(gde, 1); if (backlinks.get(gde) == 0) {
for (BacklinksListener l : backlinkListeners) { backlinks.remove(gde);
l.backlinkAdded(gde); for (BacklinksListener l : backlinkListeners) {
} l.backlinkRemoved(gde);
} else { }
backlinks.put(gde, backlinks.get(gde) + 1); }
} }
}
public Set<GameDataElement> getBacklinks() {
public void removeBacklink(GameDataElement gde) { return backlinks.keySet();
if (backlinks.get(gde) == null) return; }
backlinks.put(gde, backlinks.get(gde) - 1);
if (backlinks.get(gde) == 0) { public static interface BacklinksListener {
backlinks.remove(gde); public void backlinkAdded(GameDataElement gde);
for (BacklinksListener l : backlinkListeners) { public void backlinkRemoved(GameDataElement gde);
l.backlinkRemoved(gde); }
}
} @Override
} public boolean isEmpty() {
return false;
public Set<GameDataElement> getBacklinks() { }
return backlinks.keySet();
} public boolean needsSaving() {
return this.state == State.modified || this.state == State.created;
public static interface BacklinksListener { }
public void backlinkAdded(GameDataElement gde);
public abstract String getProjectFilename();
public void backlinkRemoved(GameDataElement gde);
} public abstract void save();
@Override public abstract List<SaveEvent> attemptSave();
public boolean isEmpty() {
return false; /**
} * Checks if the current state indicates that parsing/linking should be skipped.
* @return true if the operation should be skipped, false otherwise
public boolean needsSaving() { */
return this.state == State.modified || this.state == State.created; 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.
public abstract String getProjectFilename(); return true;
}
public abstract void save(); if (this.state == State.linked) {
//Already linked.
public abstract List<SaveEvent> attemptSave(); return true;
}
/** return false;
* Checks if the current state indicates that parsing/linking should be skipped. }
*
* @return true if the operation should be skipped, false otherwise /**
*/ * Ensures the element is parsed if needed based on its current state.
protected boolean shouldSkipParseOrLink() { */
if (shouldSkipParse()) return true; protected void ensureParseIfNeeded() {
if (this.state == State.linked) { if (this.state == State.init) {
//Already linked. //Not parsed yet.
return true; this.parse();
} }
return false; }
}
}
protected boolean shouldSkipParse() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) {
//This type of state is unrelated to parsing/linking.
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,6 +1,28 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable; import java.awt.Image;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet; import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
@@ -10,317 +32,263 @@ import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.swing.tree.TreeNode; public class GameSource implements ProjectTreeNode, Serializable {
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.*;
public class GameSource implements ProjectTreeNode, Serializable, JsonSerializable { private static final long serialVersionUID = -1512979360971918158L;
public static final String DEFAULT_REL_PATH_FOR_GAME_RESOURCE = "res"+File.separator+"values"+File.separator+"loadresources.xml";
public static final String DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE = "res"+File.separator+"values"+File.separator+"loadresources_debug.xml";
public transient GameDataSet gameData;
public transient TMXMapSet gameMaps;
public transient SpriteSheetSet gameSprites;
public transient Worldmap worldmap;
public transient WriterModeDataSet writerModeDataSet;
private transient SavedSlotCollection v;
public static enum Type {
source,
referenced,
altered,
created
}
public File baseFolder;
public Type type;
public transient Project parent = null;
public transient Map<String, List<String>> referencedSourceFiles = null;
public GameSource(File folder, Project parent) {
this.parent = parent;
this.baseFolder = folder;
this.type = Type.source;
initData();
}
public GameSource(Project parent, Type type) {
this.parent = parent;
this.baseFolder = new File(parent.baseFolder, type.toString());
this.type = type;
initData();
}
public void refreshTransients(Project p) {
parent = p;
initData();
}
private static final long serialVersionUID = -1512979360971918158L; public void initData() {
if (type == Type.source) {
public static final String DEFAULT_REL_PATH_FOR_GAME_RESOURCE = "res" + File.separator + "values" + File.separator + "loadresources.xml"; if (parent.sourceSetToUse == ResourceSet.gameData || parent.sourceSetToUse == ResourceSet.debugData) {
public static final String DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE = "res" + File.separator + "values" + File.separator + "loadresources_debug.xml"; referencedSourceFiles = new LinkedHashMap<String, List<String>>();
readResourceList();
public transient GameDataSet gameData; }
public transient TMXMapSet gameMaps; }
public transient SpriteSheetSet gameSprites; if (type == Type.created) {
public transient Worldmap worldmap; this.writerModeDataSet = new WriterModeDataSet(this);
public transient WriterModeDataSet writerModeDataSet; }
private transient SavedSlotCollection v; this.gameData = new GameDataSet(this);
this.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this);
@Override this.worldmap = new Worldmap(this);
public Map toMap() { v = new SavedSlotCollection();
Map map = new HashMap(); v.add(gameData);
map.put("type", type.toString()); v.add(gameMaps);
map.put("baseFolder", baseFolder.getPath()); v.add(gameSprites);
return map; v.add(worldmap);
} if (type == Type.created) {
v.add(writerModeDataSet);
@Override }
public void fromMap(Map map) { }
if(map==null)return;
type = Enum.valueOf(Type.class, (String)map.get("type")); public void readResourceList() {
baseFolder = new File((String) map.get("baseFolder")); File xmlFile = null;
} if (parent.sourceSetToUse == ResourceSet.gameData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_GAME_RESOURCE);
public static enum Type { } else if (parent.sourceSetToUse == ResourceSet.debugData) {
source, xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE);
referenced, } else {
altered, return;
created }
}
if (!xmlFile.exists()) return;
public File baseFolder; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
public Type type; Document doc;
try {
public transient Project parent; factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
public transient Map<String, List<String>> referencedSourceFiles = null; factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
public GameSource(Map json, Project parent) { InputSource insrc = new InputSource(new FileInputStream(xmlFile));
fromMap(json);
refreshTransients(parent);
}
public GameSource(File folder, Project parent) {
this.parent = parent;
this.baseFolder = folder;
this.type = Type.source;
initData();
}
public GameSource(Project parent, Type type) {
this.parent = parent;
this.baseFolder = new File(parent.baseFolder, type.toString());
this.type = type;
initData();
}
public void refreshTransients(Project p) {
parent = p;
initData();
}
public void initData() {
if (type == Type.source) {
if (parent.sourceSetToUse == ResourceSet.gameData || parent.sourceSetToUse == ResourceSet.debugData) {
referencedSourceFiles = new LinkedHashMap<String, List<String>>();
readResourceList();
}
}
if (type == Type.created) {
this.writerModeDataSet = new WriterModeDataSet(this);
}
this.gameData = new GameDataSet(this);
this.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this);
this.worldmap = new Worldmap(this);
v = new SavedSlotCollection();
v.add(gameData);
v.add(gameMaps);
v.add(gameSprites);
v.add(worldmap);
if (type == Type.created) {
v.add(writerModeDataSet);
}
}
public void readResourceList() {
File xmlFile;
if (parent.sourceSetToUse == ResourceSet.gameData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_GAME_RESOURCE);
} else if (parent.sourceSetToUse == ResourceSet.debugData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE);
} else {
return;
}
if (!xmlFile.exists()) return;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc;
try {
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(xmlFile));
// insrc.setSystemId("http://worldmap/"); // insrc.setSystemId("http://worldmap/");
insrc.setEncoding("UTF-8"); insrc.setEncoding("UTF-8");
doc = builder.parse(insrc); doc = builder.parse(insrc);
Element root = (Element) doc.getElementsByTagName("resources").item(0);
if (root != null) {
NodeList arraysList = root.getElementsByTagName("array");
if (arraysList != null) {
for (int i = 0; i < arraysList.getLength(); i++) {
Element arrayNode = (Element) arraysList.item(i);
String name = arrayNode.getAttribute("name");
List<String> arrayContents = new ArrayList<String>();
NodeList arrayItems = arrayNode.getElementsByTagName("item");
if (arrayItems != null) {
for (int j = 0; j < arrayItems.getLength(); j++) {
arrayContents.add(((Element)arrayItems.item(j)).getTextContent());
}
referencedSourceFiles.put(name, arrayContents);
}
}
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements();
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return v.getNonEmptyElementAt(arg0);
}
@Override
public int getChildCount() {
return v.getNonEmptySize();
}
@Override
public int getIndex(TreeNode arg0) {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
switch(type) {
case altered: return (needsSaving() ? "*" : "")+"Altered data";
case created: return (needsSaving() ? "*" : "")+"Created data";
case referenced: return (needsSaving() ? "*" : "")+"Referenced data";
case source: return (needsSaving() ? "*" : "")+"AT Source"; //The fact that it is from "source" is already mentionned by its parent.
default: return (needsSaving() ? "*" : "")+"Game data";
}
}
@Override
public Project getProject() {
return parent == null ? null : parent.getProject();
}
Element root = (Element) doc.getElementsByTagName("resources").item(0); public Image getIcon(String iconId) {
if (root != null) { String[] data = iconId.split(":");
NodeList arraysList = root.getElementsByTagName("array"); for (Spritesheet sheet : gameSprites.spritesheets) {
if (arraysList != null) { if (sheet.id.equals(data[0])) {
for (int i = 0; i < arraysList.getLength(); i++) { return sheet.getIcon(Integer.parseInt(data[1]));
Element arrayNode = (Element) arraysList.item(i); }
String name = arrayNode.getAttribute("name"); }
List<String> arrayContents = new ArrayList<String>(); return null;
NodeList arrayItems = arrayNode.getElementsByTagName("item"); }
if (arrayItems != null) {
for (int j = 0; j < arrayItems.getLength(); j++) { public Image getImage(String iconId) {
arrayContents.add(((Element) arrayItems.item(j)).getTextContent()); String[] data = iconId.split(":");
} for (Spritesheet sheet : gameSprites.spritesheets) {
referencedSourceFiles.put(name, arrayContents); if (sheet.id.equals(data[0])) {
} return sheet.getImage(Integer.parseInt(data[1]));
} }
} }
} return null;
} catch (SAXException e) { }
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override @Override
public Enumeration<ProjectTreeNode> children() { public Image getIcon() {
return v.getNonEmptyElements(); return getOpenIcon();
} }
@Override
public Image getClosedIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getATOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override @Override
public boolean getAllowsChildren() { public Type getDataType() {
return true; return type;
} }
@Override
public boolean isEmpty() {
return v.isEmpty();
}
@Override public WorldmapSegment getWorldmapSegment(String id) {
public TreeNode getChildAt(int arg0) { return worldmap.getWorldmapSegment(id);
return v.getNonEmptyElementAt(arg0); }
}
@Override
@Override public boolean needsSaving() {
public int getChildCount() { for (ProjectTreeNode node : v.getNonEmptyIterable()) {
return v.getNonEmptySize(); if (node.needsSaving()) return true;
} }
return false;
@Override }
public int getIndex(TreeNode arg0) {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
switch (type) {
case altered:
return (needsSaving() ? "*" : "") + "Altered data";
case created:
return (needsSaving() ? "*" : "") + "Created data";
case referenced:
return (needsSaving() ? "*" : "") + "Referenced data";
case source:
return (needsSaving() ? "*" : "") + "AT Source"; //The fact that it is from "source" is already mentionned by its parent.
default:
return (needsSaving() ? "*" : "") + "Game data";
}
}
@Override
public Project getProject() {
return parent == null ? null : parent.getProject();
}
public Image getIcon(String iconId) {
String[] data = iconId.split(":");
for (Spritesheet sheet : gameSprites.spritesheets) {
if (sheet.id.equals(data[0])) {
return sheet.getIcon(Integer.parseInt(data[1]));
}
}
return null;
}
public Image getImage(String iconId) {
String[] data = iconId.split(":");
for (Spritesheet sheet : gameSprites.spritesheets) {
if (sheet.id.equals(data[0])) {
return sheet.getImage(Integer.parseInt(data[1]));
}
}
return null;
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getATOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return type;
}
@Override
public boolean isEmpty() {
return v.isEmpty();
}
public WorldmapSegment getWorldmapSegment(String id) {
return worldmap.getWorldmapSegment(id);
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,53 +1,19 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable; import java.awt.Dimension;
import java.awt.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Preferences implements Serializable, JsonSerializable { public class Preferences implements Serializable {
private static final long serialVersionUID = 2455802658424031276L; private static final long serialVersionUID = 2455802658424031276L;
public Dimension windowSize = null;
public Map<String, Integer> splittersPositions = new HashMap<String, Integer>();
public Preferences() {
public Dimension windowSize = null; }
public Map<String, Integer> splittersPositions = new HashMap<>();
public Preferences() {
}
@Override
public Map toMap() {
Map map = new HashMap();
if(windowSize!= null){
Map windowSizeMap = new HashMap<>();
windowSizeMap.put("width", windowSize.width);
windowSizeMap.put("height", windowSize.height);
map.put("windowSize", windowSizeMap);
}
map.put("splittersPositions", splittersPositions);
return map;
}
@Override
public void fromMap(Map map) {
if(map == null) return;
Map windowSize1 = (Map) map.get("windowSize");
if(windowSize1 != null){
windowSize = new Dimension(((Number) windowSize1.get("width")).intValue(), ((Number) windowSize1.get("height")).intValue());
}
Map<String, Number> splitters = (Map<String, Number>) map.get("splittersPositions");
Map<String, Integer> splittersInt = new HashMap<>(splitters.size());
for (Map.Entry<String, Number> entry : splitters. entrySet()){
splittersInt.put(entry.getKey(), entry.getValue().intValue());
}
splittersPositions = splittersInt;
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,10 +2,10 @@ package com.gpl.rpg.atcontentstudio.model;
public interface ProjectElementListener { public interface ProjectElementListener {
public void elementAdded(GameDataElement added, int index); public void elementAdded(GameDataElement added, int index);
public void elementRemoved(GameDataElement removed, int index); public void elementRemoved(GameDataElement removed, int index);
public Class<? extends GameDataElement> getDataType(); public Class<? extends GameDataElement> getDataType();
} }

View File

@@ -1,64 +1,59 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.List;
public interface ProjectTreeNode extends TreeNode { public interface ProjectTreeNode extends TreeNode {
public void childrenAdded(List<ProjectTreeNode> path);
public void childrenChanged(List<ProjectTreeNode> path);
public void childrenRemoved(List<ProjectTreeNode> path);
public void notifyCreated();
public String getDesc();
public void childrenAdded(List<ProjectTreeNode> path); /**
* Unnecessary for anything not below a Project. Can return null.
* @return the parent Project or null.
*/
public Project getProject();
public void childrenChanged(List<ProjectTreeNode> path); /**
* Unnecessary for anything not below a GameDataSet. Can return null.
public void childrenRemoved(List<ProjectTreeNode> path); * @return the parent GameDataSet or null.
*/
public void notifyCreated(); public GameDataSet getDataSet();
public String getDesc(); public Image getIcon();
/**
/** *
* Unnecessary for anything not below a Project. Can return null. * @return The icon depicting this node when it is an open folder. Can be null for leaves.
* */
* @return the parent Project or null. public Image getOpenIcon();
*/ /**
public Project getProject(); *
* @return The icon depicting this node when it is a closed folder. Can be null for leaves.
*/
/** public Image getClosedIcon();
* Unnecessary for anything not below a GameDataSet. Can return null. /**
* *
* @return the parent GameDataSet or null. * @return The icon depicting this node when it is a leaf. Should return the closed one for empty folders.
*/ */
public GameDataSet getDataSet(); public Image getLeafIcon();
public Image getIcon(); /**
* Unnecessary for anything not below a GameSource. Can return null.
/** * @return the parent GameSource or null.
* @return The icon depicting this node when it is an open folder. Can be null for leaves. */
*/ public GameSource.Type getDataType();
public Image getOpenIcon();
public boolean isEmpty();
/**
* @return The icon depicting this node when it is a closed folder. Can be null for leaves. public boolean needsSaving();
*/
public Image getClosedIcon();
/**
* @return The icon depicting this node when it is a leaf. Should return the closed one for empty folders.
*/
public Image getLeafIcon();
/**
* Unnecessary for anything not below a GameSource. Can return null.
*
* @return the parent GameSource or null.
*/
public GameSource.Type getDataType();
public boolean isEmpty();
public boolean needsSaving();
} }

View File

@@ -1,35 +1,35 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
public class SaveEvent { public class SaveEvent {
public enum Type { public enum Type {
moveToAltered, moveToAltered,
moveToCreated, moveToCreated,
alsoSave alsoSave
} }
public Type type; public Type type;
public GameDataElement target; public GameDataElement target;
public boolean error = false; public boolean error = false;
public String errorText; public String errorText;
public SaveEvent(SaveEvent.Type type, GameDataElement target) { public SaveEvent(SaveEvent.Type type, GameDataElement target) {
this.type = type; this.type = type;
this.target = target; this.target = target;
} }
public SaveEvent(SaveEvent.Type type, GameDataElement target, boolean error, String errorText) { public SaveEvent(SaveEvent.Type type, GameDataElement target, boolean error, String errorText) {
this.type = type; this.type = type;
this.target = target; this.target = target;
this.error = error; this.error = error;
this.errorText = errorText; this.errorText = errorText;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof SaveEvent)) return false; if (!(obj instanceof SaveEvent)) return false;
else return (((SaveEvent) obj).type == this.type) && (((SaveEvent) obj).target == this.target); else return (((SaveEvent)obj).type == this.type) && (((SaveEvent)obj).target == this.target);
} }
} }

View File

@@ -5,67 +5,67 @@ import java.util.Vector;
public class SavedSlotCollection { public class SavedSlotCollection {
Vector<ProjectTreeNode> contents = new Vector<ProjectTreeNode>(); Vector<ProjectTreeNode> contents = new Vector<ProjectTreeNode>();
public void add(ProjectTreeNode node) { public void add(ProjectTreeNode node) {
contents.add(node); contents.add(node);
} }
public int getNonEmptySize() { public int getNonEmptySize() {
// return contents.size(); // return contents.size();
int size = 0; int size = 0;
for (ProjectTreeNode node : contents) { for (ProjectTreeNode node : contents) {
if (!node.isEmpty()) size++; if (!node.isEmpty()) size++;
} }
return size; return size;
} }
public Enumeration<ProjectTreeNode> getNonEmptyElements() { public Enumeration<ProjectTreeNode> getNonEmptyElements() {
// return contents.elements(); // return contents.elements();
Vector<ProjectTreeNode> v = new Vector<ProjectTreeNode>(); Vector<ProjectTreeNode> v = new Vector<ProjectTreeNode>();
for (ProjectTreeNode node : contents) { for (ProjectTreeNode node : contents) {
if (!node.isEmpty()) v.add(node); if (!node.isEmpty()) v.add(node);
} }
return v.elements(); return v.elements();
} }
public ProjectTreeNode getNonEmptyElementAt(int index) { public ProjectTreeNode getNonEmptyElementAt(int index) {
// return contents.get(index); // return contents.get(index);
int i = 0; int i = 0;
while (i < contents.size()) { while (i < contents.size()) {
if (!contents.get(i).isEmpty()) index--; if (!contents.get(i).isEmpty()) index--;
if (index == -1) return contents.get(i); if (index == -1) return contents.get(i);
i++; i++;
} }
return null; return null;
} }
public int getNonEmptyIndexOf(ProjectTreeNode node) { public int getNonEmptyIndexOf(ProjectTreeNode node) {
// return contents.indexOf(node); // return contents.indexOf(node);
int index = contents.indexOf(node); int index = contents.indexOf(node);
int trueIndex = index; int trueIndex = index;
for (int i = 0; i < trueIndex; i++) { for (int i = 0; i < trueIndex; i++) {
if (contents.get(i).isEmpty()) index--; if (contents.get(i).isEmpty()) index--;
} }
return index; return index;
} }
public Vector<ProjectTreeNode> getNonEmptyIterable() {
public Vector<ProjectTreeNode> getNonEmptyIterable() {
// return contents; // return contents;
Vector<ProjectTreeNode> v = new Vector<ProjectTreeNode>(); Vector<ProjectTreeNode> v = new Vector<ProjectTreeNode>();
for (ProjectTreeNode node : contents) { for (ProjectTreeNode node : contents) {
if (!node.isEmpty()) v.add(node); if (!node.isEmpty()) v.add(node);
} }
return v; return v;
} }
public boolean isEmpty() { public boolean isEmpty() {
// return contents.isEmpty(); // return contents.isEmpty();
for (ProjectTreeNode node : contents) { for (ProjectTreeNode node : contents) {
if (!node.isEmpty()) return false; if (!node.isEmpty()) return false;
} }
return true; return true;
} }
} }

View File

@@ -1,423 +1,369 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import com.gpl.rpg.atcontentstudio.io.SettingsSave; import com.gpl.rpg.atcontentstudio.io.SettingsSave;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.ProjectsTree.ProjectsTreeModel; import com.gpl.rpg.atcontentstudio.ui.ProjectsTree.ProjectsTreeModel;
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog; import com.gpl.rpg.atcontentstudio.ui.WorkerDialog;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.jsoup.SerializationException;
import javax.swing.tree.TreeNode; public class Workspace implements ProjectTreeNode, Serializable {
import javax.swing.tree.TreePath;
import java.awt.*;
import java.io.*;
import java.nio.file.Files;
import java.util.List;
import java.util.*;
public class Workspace implements ProjectTreeNode, Serializable, JsonSerializable { private static final long serialVersionUID = 7938633033601384956L;
private static final long serialVersionUID = 7938633033601384956L; public static final String WS_SETTINGS_FILE = ".workspace";
public static final String WS_SETTINGS_FILE = ".workspace"; public static Workspace activeWorkspace;
public static final String WS_SETTINGS_FILE_JSON = ".workspace.json";
public static Workspace activeWorkspace; public Preferences preferences = new Preferences();
public File baseFolder;
public File settingsFile;
public transient WorkspaceSettings settings;
public transient List<ProjectTreeNode> projects = new ArrayList<ProjectTreeNode>();
public Set<String> projectsName = new HashSet<String>();
public Map<String, Boolean> projectsOpenByName = new HashMap<String, Boolean>();
public Set<File> knownMapSourcesFolders = new HashSet<File>();
public Preferences preferences = new Preferences(); public transient ProjectsTreeModel projectsTreeModel = null;
public File baseFolder;
public File settingsFile;
public transient WorkspaceSettings settings;
public transient List<ProjectTreeNode> projects = new ArrayList<ProjectTreeNode>();
public Set<String> projectsName = new HashSet<String>();
public Map<String, Boolean> projectsOpenByName = new HashMap<String, Boolean>();
public Set<File> knownMapSourcesFolders = new HashSet<File>();
public transient ProjectsTreeModel projectsTreeModel = null; public Workspace(File workspaceRoot) {
baseFolder = workspaceRoot;
if (!workspaceRoot.exists()) {
try {
workspaceRoot.mkdir();
} catch (SecurityException e) {
Notification.addError("Error creating workspace directory: "
+ e.getMessage());
e.printStackTrace();
}
}
settings = new WorkspaceSettings(this);
settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE);
if (!settingsFile.exists()) {
try {
settingsFile.createNewFile();
} catch (IOException e) {
Notification.addError("Error creating workspace datafile: "
+ e.getMessage());
e.printStackTrace();
}
}
Notification.addSuccess("New workspace created: "
+ workspaceRoot.getAbsolutePath());
save();
}
public Workspace(File workspaceRoot) { public static void setActive(File workspaceRoot) {
boolean freshWorkspace = false; Workspace w = null;
baseFolder = workspaceRoot; File f = new File(workspaceRoot, WS_SETTINGS_FILE);
if (!workspaceRoot.exists()) { if (!workspaceRoot.exists() || !f.exists()) {
try { w = new Workspace(workspaceRoot);
workspaceRoot.mkdir(); } else {
} catch (SecurityException e) { w = (Workspace) SettingsSave.loadInstance(f, "Workspace");
Notification.addError("Error creating workspace directory: " if (w == null) {
+ e.getMessage()); w = new Workspace(workspaceRoot);
e.printStackTrace(); } else {
} w.refreshTransients();
} }
settings = new WorkspaceSettings(this); }
settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE_JSON); activeWorkspace = w;
if (!settingsFile.exists()) { }
try {
settingsFile.createNewFile();
freshWorkspace = true;
} catch (IOException e) {
Notification.addError("Error creating workspace datafile: "
+ e.getMessage());
e.printStackTrace();
}
Notification.addSuccess("New workspace created: "
+ workspaceRoot.getAbsolutePath());
}
if (freshWorkspace)
save();
}
@Override public static void saveActive() {
public Map toMap() { activeWorkspace.save();
Map map = new HashMap(); }
map.put("serialVersionUID", serialVersionUID);
map.put("preferences", preferences.toMap());
map.put("projectsName", (new ArrayList<String>(projectsName)));
map.put("projectsOpenByName", projectsOpenByName);
List<String> l = new ArrayList<>(knownMapSourcesFolders.size());
for (File f: knownMapSourcesFolders){
l.add(f.getPath());
}
map.put("knownMapSourcesFolders", l);
return map;
}
@Override public void save() {
public void fromMap(Map map) { settings.save();
if(serialVersionUID != (long) map.get("serialVersionUID")){ SettingsSave.saveInstance(this, settingsFile, "Workspace");
throw new SerializationException("wrong seriaVersionUID"); }
}
preferences.fromMap((Map) map.get("preferences")); @Override
public Enumeration<ProjectTreeNode> children() {
return Collections.enumeration(projects);
}
projectsName = new HashSet<>((List<String>) map.getOrDefault("projectsName", new HashSet<String>())); @Override
public boolean getAllowsChildren() {
return true;
}
projectsOpenByName = (Map<String, Boolean>) map.getOrDefault("projectsOpenByName", new HashMap<String, Boolean>() ); @Override
public TreeNode getChildAt(int arg0) {
return projects.get(arg0);
}
List<String> knownMapSourcesFolders1 = (List<String>) map.getOrDefault("knownMapSourcesFolders", new ArrayList<String>()); @Override
knownMapSourcesFolders = new HashSet<>(); public int getChildCount() {
if (knownMapSourcesFolders1 != null){ return projects.size();
int size = knownMapSourcesFolders1.size(); }
for (String path: knownMapSourcesFolders1) {
//TODO: catch invalid paths...?
knownMapSourcesFolders.add(new File(path));
}
}
} @Override
public int getIndex(TreeNode arg0) {
return projects.indexOf(arg0);
}
public static void setActive(File workspaceRoot) { @Override
Workspace w; public TreeNode getParent() {
File f2 = new File(workspaceRoot, WS_SETTINGS_FILE_JSON); return null;
if (f2.exists()) { }
w = loadWorkspaceFromJson(workspaceRoot, f2);
w.refreshTransients();
} else {
Notification.addInfo("Could not find json workspace file. Checking for binary file");
File f = new File(workspaceRoot, WS_SETTINGS_FILE);
if (!workspaceRoot.exists() || !f.exists()) {
w = new Workspace(workspaceRoot);
} else {
w = (Workspace) SettingsSave.loadInstance(f, "Workspace");
if (w == null) {
w = new Workspace(workspaceRoot);
} else {
w.settingsFile = f2;
w.baseFolder = workspaceRoot;
Notification.addInfo("Switched workspace to json format.");
w.refreshTransients();
}
w.save();
}
}
activeWorkspace = w;
}
private static Workspace loadWorkspaceFromJson(File workspaceRoot, File settingsFile) { @Override
Workspace w = w = new Workspace(workspaceRoot); public boolean isLeaf() {
Map json = FileUtils.mapFromJsonFile(settingsFile); return false;
if (json!= null) { }
w.fromMap(json);
}
return w;
}
public static void saveActive() { @Override
activeWorkspace.save(); public void childrenAdded(List<ProjectTreeNode> path) {
} path.add(0, this);
if (projectsTreeModel != null)
projectsTreeModel.insertNode(new TreePath(path.toArray()));
}
public void save() { @Override
settings.save(); public void childrenChanged(List<ProjectTreeNode> path) {
FileUtils.writeStringToFile(FileUtils.toJsonString(this), settingsFile, "Workspace"); path.add(0, this);
} ProjectTreeNode last = path.get(path.size() - 1);
if (projectsTreeModel != null) {
while (path.size() > 1) {
projectsTreeModel.changeNode(new TreePath(path.toArray()));
path.remove(path.size()-1);
}
}
ATContentStudio.frame.editorChanged(last);
}
@Override @Override
public Enumeration<ProjectTreeNode> children() { public void childrenRemoved(List<ProjectTreeNode> path) {
return Collections.enumeration(projects); path.add(0, this);
} if (projectsTreeModel != null)
projectsTreeModel.removeNode(new TreePath(path.toArray()));
}
@Override @Override
public boolean getAllowsChildren() { public void notifyCreated() {
return true; childrenAdded(new ArrayList<ProjectTreeNode>());
} for (ProjectTreeNode node : projects) {
if (node != null)
node.notifyCreated();
}
}
@Override @Override
public TreeNode getChildAt(int arg0) { public String getDesc() {
return projects.get(arg0); return "Workspace: " + baseFolder.getAbsolutePath();
} }
@Override public static void createProject(final String projectName,
public int getChildCount() { final File gameSourceFolder, final Project.ResourceSet sourceSet) {
return projects.size(); WorkerDialog.showTaskMessage("Creating project " + projectName + "...",
} ATContentStudio.frame, new Runnable() {
@Override
public void run() {
if (activeWorkspace.projectsName.contains(projectName)) {
Notification.addError("A project named "
+ projectName
+ " already exists in this workspace.");
return;
}
Project p = new Project(activeWorkspace, projectName,
gameSourceFolder, sourceSet);
activeWorkspace.projects.add(p);
activeWorkspace.projectsName.add(projectName);
activeWorkspace.projectsOpenByName.put(projectName,
p.open);
activeWorkspace.knownMapSourcesFolders
.add(gameSourceFolder);
p.notifyCreated();
Notification.addSuccess("Project " + projectName
+ " successfully created");
saveActive();
}
});
}
@Override public static void closeProject(Project p) {
public int getIndex(TreeNode arg0) { int index = activeWorkspace.projects.indexOf(p);
return projects.indexOf(arg0); if (index < 0) {
} Notification.addError("Cannot close unknown project " + p.name);
return;
}
p.close();
ClosedProject cp = new ClosedProject(activeWorkspace, p.name);
activeWorkspace.projects.set(index, cp);
activeWorkspace.projectsOpenByName.put(p.name, false);
cp.notifyCreated();
saveActive();
}
@Override public static void openProject(final ClosedProject cp) {
public TreeNode getParent() { WorkerDialog.showTaskMessage("Opening project " + cp.name + "...",
return null; ATContentStudio.frame, new Runnable() {
} @Override
public void run() {
int index = activeWorkspace.projects.indexOf(cp);
if (index < 0) {
Notification
.addError("Cannot open unknown project "
+ cp.name);
return;
}
cp.childrenRemoved(new ArrayList<ProjectTreeNode>());
Project p = Project.fromFolder(activeWorkspace,
new File(activeWorkspace.baseFolder, cp.name));
p.open();
activeWorkspace.projects.set(index, p);
activeWorkspace.projectsOpenByName.put(p.name, true);
p.notifyCreated();
saveActive();
}
});
}
@Override public void refreshTransients() {
public boolean isLeaf() { this.settings = new WorkspaceSettings(this);
return false; this.projects = new ArrayList<ProjectTreeNode>();
} Set<String> projectsFailed = new HashSet<String>();
for (String projectName : projectsName) {
if (projectsOpenByName.get(projectName)) {
File projRoot = new File(this.baseFolder, projectName);
if (projRoot.exists()) {
Project p = Project.fromFolder(this, projRoot);
if (p != null) {
projects.add(p);
} else {
Notification
.addError("Failed to open project "
+ projectName
+ ". Removing it from workspace (not from filesystem though).");
projectsFailed.add(projectName);
}
} else {
Notification.addError("Unable to find project "
+ projectName
+ "'s root folder. Removing it from workspace");
projectsFailed.add(projectName);
}
} else {
projects.add(new ClosedProject(this, projectName));
}
}
for (String projectName : projectsFailed) {
projectsName.remove(projectName);
projectsOpenByName.remove(projectName);
}
notifyCreated();
}
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public Project getProject() {
path.add(0, this); return null;
if (projectsTreeModel != null) }
projectsTreeModel.insertNode(new TreePath(path.toArray()));
}
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public Image getIcon() {
path.add(0, this); return null;
ProjectTreeNode last = path.get(path.size() - 1); }
if (projectsTreeModel != null) {
while (path.size() > 1) {
projectsTreeModel.changeNode(new TreePath(path.toArray()));
path.remove(path.size() - 1);
}
} @Override
ATContentStudio.frame.editorChanged(last); public Image getClosedIcon() {
} return null;
}
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public Image getLeafIcon() {
path.add(0, this); return null;
if (projectsTreeModel != null) }
projectsTreeModel.removeNode(new TreePath(path.toArray()));
}
@Override @Override
public void notifyCreated() { public Image getOpenIcon() {
childrenAdded(new ArrayList<ProjectTreeNode>()); return null;
for (ProjectTreeNode node : projects) { }
if (node != null)
node.notifyCreated();
}
}
@Override public static void deleteProject(ClosedProject cp) {
public String getDesc() { cp.childrenRemoved(new ArrayList<ProjectTreeNode>());
return "Workspace: " + baseFolder.getAbsolutePath(); activeWorkspace.projects.remove(cp);
} activeWorkspace.projectsOpenByName.remove(cp.name);
activeWorkspace.projectsName.remove(cp.name);
if (delete(new File(activeWorkspace.baseFolder, cp.name))) {
Notification.addSuccess("Closed project " + cp.name
+ " successfully deleted.");
} else {
Notification.addError("Error while deleting closed project "
+ cp.name + ". Files may remain in the workspace.");
}
cp = null;
saveActive();
}
public static void createProject(final String projectName, public static void deleteProject(Project p) {
final File gameSourceFolder, final Project.ResourceSet sourceSet) { p.childrenRemoved(new ArrayList<ProjectTreeNode>());
WorkerDialog.showTaskMessage("Creating project " + projectName + "...", activeWorkspace.projects.remove(p);
ATContentStudio.frame, new Runnable() { activeWorkspace.projectsOpenByName.remove(p.name);
@Override activeWorkspace.projectsName.remove(p.name);
public void run() { if (delete(p.baseFolder)) {
if (activeWorkspace.projectsName.contains(projectName)) { Notification.addSuccess("Project " + p.name
Notification.addError("A project named " + " successfully deleted.");
+ projectName } else {
+ " already exists in this workspace."); Notification.addError("Error while deleting project " + p.name
return; + ". Files may remain in the workspace.");
} }
Project p = new Project(activeWorkspace, projectName, p = null;
gameSourceFolder, sourceSet); saveActive();
activeWorkspace.projects.add(p); }
activeWorkspace.projectsName.add(projectName);
activeWorkspace.projectsOpenByName.put(projectName,
p.open);
activeWorkspace.knownMapSourcesFolders
.add(gameSourceFolder);
p.notifyCreated();
Notification.addSuccess("Project " + projectName
+ " successfully created");
saveActive();
}
});
}
public static void closeProject(Project p) { private static boolean delete(File f) {
int index = activeWorkspace.projects.indexOf(p); boolean b = true;
if (index < 0) { if (Files.isSymbolicLink(f.toPath())) {
Notification.addError("Cannot close unknown project " + p.name); b &= f.delete();
return; } else if (f.isDirectory()) {
} for (File c : f.listFiles())
p.close(); b &= delete(c);
ClosedProject cp = new ClosedProject(activeWorkspace, p.name); }
activeWorkspace.projects.set(index, cp); return b &= f.delete();
activeWorkspace.projectsOpenByName.put(p.name, false); }
cp.notifyCreated();
saveActive();
}
public static void openProject(final ClosedProject cp) { @Override
WorkerDialog.showTaskMessage("Opening project " + cp.name + "...", public GameDataSet getDataSet() {
ATContentStudio.frame, new Runnable() { return null;
@Override }
public void run() {
int index = activeWorkspace.projects.indexOf(cp);
if (index < 0) {
Notification
.addError("Cannot open unknown project "
+ cp.name);
return;
}
cp.childrenRemoved(new ArrayList<ProjectTreeNode>());
Project p = Project.fromFolder(activeWorkspace,
new File(activeWorkspace.baseFolder, cp.name));
p.open();
activeWorkspace.projects.set(index, p);
activeWorkspace.projectsOpenByName.put(p.name, true);
p.notifyCreated();
saveActive();
}
});
}
public void refreshTransients() { @Override
this.settings = new WorkspaceSettings(this); public Type getDataType() {
this.projects = new ArrayList<ProjectTreeNode>(); return null;
Set<String> projectsFailed = new HashSet<String>(); }
for (String projectName : projectsName) {
if (projectsOpenByName.get(projectName)) {
File projRoot = new File(this.baseFolder, projectName);
if (projRoot.exists()) {
Project p = Project.fromFolder(this, projRoot);
if (p != null) {
projects.add(p);
} else {
Notification
.addError("Failed to open project "
+ projectName
+ ". Removing it from workspace (not from filesystem though).");
projectsFailed.add(projectName);
}
} else {
Notification.addError("Unable to find project "
+ projectName
+ "'s root folder. Removing it from workspace");
projectsFailed.add(projectName);
}
} else {
projects.add(new ClosedProject(this, projectName));
}
}
for (String projectName : projectsFailed) {
projectsName.remove(projectName);
projectsOpenByName.remove(projectName);
}
notifyCreated();
}
@Override @Override
public Project getProject() { public boolean isEmpty() {
return null; return projects.isEmpty();
} }
@Override @Override
public Image getIcon() { public boolean needsSaving() {
return null; for (ProjectTreeNode node : projects) {
} if (node.needsSaving()) return true;
}
return false;
}
@Override
public Image getClosedIcon() {
return null;
}
@Override
public Image getLeafIcon() {
return null;
}
@Override
public Image getOpenIcon() {
return null;
}
public static void deleteProject(ClosedProject cp) {
cp.childrenRemoved(new ArrayList<ProjectTreeNode>());
activeWorkspace.projects.remove(cp);
activeWorkspace.projectsOpenByName.remove(cp.name);
activeWorkspace.projectsName.remove(cp.name);
if (delete(new File(activeWorkspace.baseFolder, cp.name))) {
Notification.addSuccess("Closed project " + cp.name
+ " successfully deleted.");
} else {
Notification.addError("Error while deleting closed project "
+ cp.name + ". Files may remain in the workspace.");
}
saveActive();
}
public static void deleteProject(Project p) {
p.childrenRemoved(new ArrayList<ProjectTreeNode>());
activeWorkspace.projects.remove(p);
activeWorkspace.projectsOpenByName.remove(p.name);
activeWorkspace.projectsName.remove(p.name);
if (delete(p.baseFolder)) {
Notification.addSuccess("Project " + p.name
+ " successfully deleted.");
} else {
Notification.addError("Error while deleting project " + p.name
+ ". Files may remain in the workspace.");
}
saveActive();
}
private static boolean delete(File f) {
boolean b = true;
if (Files.isSymbolicLink(f.toPath())) {
b &= f.delete();
} else if (f.isDirectory()) {
for (File c : f.listFiles())
b &= delete(c);
}
return b & f.delete();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return projects.isEmpty();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : projects) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,199 +1,220 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.Notification; import java.io.File;
import com.gpl.rpg.atcontentstudio.utils.FileUtils; import java.io.FileReader;
import org.json.simple.parser.JSONParser; import java.io.FileWriter;
import java.io.IOException;
import java.io.*; import java.io.StringWriter;
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.JSONObject;
import org.json.simple.parser.JSONParser;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
public class WorkspaceSettings { public class WorkspaceSettings {
public static final String VERSION_KEY = "ATCS_Version";
public static final String FILENAME = "workspace_settings.json";
public static final int SETTINGS_VERSION = 1;
public static final String VERSION_KEY = "ATCS_Version"; public Workspace parent;
public static final String FILENAME = "workspace_settings.json"; public File file;
public static Boolean DEFAULT_USE_SYS_MAP_EDITOR = true;
public Setting<Boolean> useSystemDefaultMapEditor = new PrimitiveSetting<Boolean>("useSystemDefaultMapEditor", DEFAULT_USE_SYS_MAP_EDITOR);
public static String DEFAULT_MAP_EDITOR_COMMAND = "tiled";
public Setting<String> mapEditorCommand = new PrimitiveSetting<String>("mapEditorCommand", DEFAULT_MAP_EDITOR_COMMAND);
public static Boolean DEFAULT_USE_SYS_IMG_VIEWER = true;
public Setting<Boolean> useSystemDefaultImageViewer = new PrimitiveSetting<Boolean>("useSystemDefaultImageViewer", DEFAULT_USE_SYS_IMG_VIEWER);
public static Boolean DEFAULT_USE_SYS_IMG_EDITOR = false;
public Setting<Boolean> useSystemDefaultImageEditor = new PrimitiveSetting<Boolean>("useSystemDefaultImageEditor", DEFAULT_USE_SYS_IMG_EDITOR);
public static String DEFAULT_IMG_EDITOR_COMMAND = "gimp";
public Setting<String> imageEditorCommand = new PrimitiveSetting<String>("imageEditorCommand", DEFAULT_IMG_EDITOR_COMMAND);
public static final int SETTINGS_VERSION = 1; public static String[] LANGUAGE_LIST = new String[]{null, "de", "ru", "pl", "fr", "it", "es", "nl", "uk", "ca", "sv", "pt", "pt_BR", "zh_Hant", "zh_Hans", "ja", "cs", "tr", "ko", "hu", "sl", "bg", "id", "fi", "th", "gl", "ms" ,"pa", "az", "nb"};
public Setting<String> translatorLanguage = new NullDefaultPrimitiveSetting<String>("translatorLanguage");
public static Boolean DEFAULT_ALLOW_INTERNET = true;
public Setting<Boolean> useInternet = new PrimitiveSetting<Boolean>("useInternet", DEFAULT_ALLOW_INTERNET);
public static Boolean DEFAULT_CHECK_UPDATE = true;
public Setting<Boolean> checkUpdates = new PrimitiveSetting<Boolean>("checkUpdates", DEFAULT_CHECK_UPDATE);
public Workspace parent; public List<Setting<? extends Object>> settings = new ArrayList<Setting<? extends Object>>();
public File file;
public WorkspaceSettings(Workspace parent) {
this.parent = parent;
settings.add(useSystemDefaultMapEditor);
settings.add(mapEditorCommand);
settings.add(useSystemDefaultImageViewer);
settings.add(useSystemDefaultImageEditor);
settings.add(imageEditorCommand);
settings.add(translatorLanguage);
settings.add(useInternet);
settings.add(checkUpdates);
file = new File(parent.baseFolder, FILENAME);
if (file.exists()) {
load(file);
}
}
public void load(File f) {
JSONParser parser = new JSONParser();
FileReader reader = null;
try {
reader = new FileReader(f);
@SuppressWarnings("rawtypes")
Map jsonSettings = (Map) parser.parse(reader);
Integer version = ((Number) jsonSettings.get(VERSION_KEY)).intValue();
if (version != null) {
if (version >= 1) {
loadv1(jsonSettings);
}
}
} catch (Exception e) {
Notification.addError("Error while parsing workspace settings: "+e.getMessage());
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SuppressWarnings("rawtypes")
private void loadv1(Map jsonSettings) {
for (Setting s : settings) {
s.readFromJson(jsonSettings);
}
}
public static Boolean DEFAULT_USE_SYS_MAP_EDITOR = true; @SuppressWarnings("unchecked")
public Setting<Boolean> useSystemDefaultMapEditor = new PrimitiveSetting<Boolean>("useSystemDefaultMapEditor", DEFAULT_USE_SYS_MAP_EDITOR); public void save() {
public static String DEFAULT_MAP_EDITOR_COMMAND = "tiled"; @SuppressWarnings("rawtypes")
public Setting<String> mapEditorCommand = new PrimitiveSetting<String>("mapEditorCommand", DEFAULT_MAP_EDITOR_COMMAND); Map json = new LinkedHashMap();
for (Setting<? extends Object> s : settings) {
s.saveToJson(json);
}
if (json.isEmpty()) {
//Everything is default.
file.delete();
return;
}
public static Boolean DEFAULT_USE_SYS_IMG_VIEWER = true; json.put(VERSION_KEY, SETTINGS_VERSION);
public Setting<Boolean> useSystemDefaultImageViewer = new PrimitiveSetting<Boolean>("useSystemDefaultImageViewer", DEFAULT_USE_SYS_IMG_VIEWER); StringWriter writer = new JsonPrettyWriter();
public static Boolean DEFAULT_USE_SYS_IMG_EDITOR = false; try {
public Setting<Boolean> useSystemDefaultImageEditor = new PrimitiveSetting<Boolean>("useSystemDefaultImageEditor", DEFAULT_USE_SYS_IMG_EDITOR); JSONObject.writeJSONString(json, writer);
public static String DEFAULT_IMG_EDITOR_COMMAND = "gimp"; } catch (IOException e) {
public Setting<String> imageEditorCommand = new PrimitiveSetting<String>("imageEditorCommand", DEFAULT_IMG_EDITOR_COMMAND); //Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(file);
w.write(toWrite);
w.close();
Notification.addSuccess("Workspace settings saved.");
} catch (IOException e) {
Notification.addError("Error while saving workspace settings : "+e.getMessage());
e.printStackTrace();
}
}
public void resetDefault() {
for (Setting<? extends Object> s : settings) {
s.resetDefault();
}
}
public abstract class Setting<X extends Object> {
public static String[] LANGUAGE_LIST = new String[]{null, "de", "ru", "pl", "fr", "it", "es", "nl", "uk", "ca", "sv", "pt", "pt_BR", "zh_Hant", "zh_Hans", "ja", "cs", "tr", "ko", "hu", "sl", "bg", "id", "fi", "th", "gl", "ms", "pa", "az", "nb"}; public String id;
public Setting<String> translatorLanguage = new NullDefaultPrimitiveSetting<String>("translatorLanguage"); public X value, defaultValue;
public static Boolean DEFAULT_ALLOW_INTERNET = true;
public Setting<Boolean> useInternet = new PrimitiveSetting<Boolean>("useInternet", DEFAULT_ALLOW_INTERNET); public void setCurrentValue(X value) {
public static Boolean DEFAULT_CHECK_UPDATE = true; this.value = value;
public Setting<Boolean> checkUpdates = new PrimitiveSetting<Boolean>("checkUpdates", DEFAULT_CHECK_UPDATE); }
public X getCurrentValue() {
public List<Setting<? extends Object>> settings = new ArrayList<Setting<? extends Object>>(); return value;
}
public WorkspaceSettings(Workspace parent) {
this.parent = parent; public X getDefaultValue() {
settings.add(useSystemDefaultMapEditor); return defaultValue;
settings.add(mapEditorCommand); }
settings.add(useSystemDefaultImageViewer);
settings.add(useSystemDefaultImageEditor); public void resetDefault() {
settings.add(imageEditorCommand); value = defaultValue;
settings.add(translatorLanguage); }
settings.add(useInternet);
settings.add(checkUpdates); public abstract void readFromJson(@SuppressWarnings("rawtypes") Map json);
file = new File(parent.baseFolder, FILENAME);
if (file.exists()) { @SuppressWarnings({ "rawtypes", "unchecked" })
load(file); public void saveToJson(Map json) {
} if (!defaultValue.equals(value)) json.put(id, value);
} }
}
public void load(File f) {
JSONParser parser = new JSONParser(); public class PrimitiveSetting<X extends Object> extends Setting<X> {
FileReader reader = null;
try {
reader = new FileReader(f); public PrimitiveSetting(String id, X defaultValue) {
@SuppressWarnings("rawtypes") this.id = id;
Map jsonSettings = (Map) parser.parse(reader); this.value = this.defaultValue = defaultValue;
Integer version = ((Number) jsonSettings.get(VERSION_KEY)).intValue(); }
if (version != null) {
if (version >= 1) { @SuppressWarnings({ "rawtypes", "unchecked" })
loadv1(jsonSettings); public void readFromJson(Map json) {
} if (json.get(id) != null) value = (X)json.get(id);
} }
} catch (Exception e) {
Notification.addError("Error while parsing workspace settings: " + e.getMessage()); }
e.printStackTrace();
} finally { public class NullDefaultPrimitiveSetting<X extends Object> extends PrimitiveSetting<X> {
if (reader != null)
try { public NullDefaultPrimitiveSetting(String id) {
reader.close(); super(id, null);
} catch (IOException e) { }
e.printStackTrace();
} @SuppressWarnings({ "unchecked", "rawtypes" })
} @Override
} public void saveToJson(Map json) {
if (value != null) json.put(id, value);
@SuppressWarnings("rawtypes") }
private void loadv1(Map jsonSettings) { }
for (Setting s : settings) {
s.readFromJson(jsonSettings); public class ListSetting<X extends Object> extends Setting<List<X>> {
}
}
@SuppressWarnings("unchecked")
public void save() {
@SuppressWarnings("rawtypes")
Map json = new LinkedHashMap();
for (Setting<? extends Object> s : settings) {
s.saveToJson(json);
}
if (json.isEmpty()) {
//Everything is default.
file.delete();
return;
}
json.put(VERSION_KEY, SETTINGS_VERSION);
String toWrite = FileUtils.toJsonString(json);
FileUtils.writeStringToFile(toWrite, file, "Workspace settings");
}
public void resetDefault() {
for (Setting<? extends Object> s : settings) {
s.resetDefault();
}
}
public abstract class Setting<X extends Object> {
public String id;
public X value, defaultValue;
public void setCurrentValue(X value) {
this.value = value;
}
public X getCurrentValue() {
return value;
}
public X getDefaultValue() {
return defaultValue;
}
public void resetDefault() {
value = defaultValue;
}
public abstract void readFromJson(@SuppressWarnings("rawtypes") Map json);
@SuppressWarnings({"rawtypes", "unchecked"})
public void saveToJson(Map json) {
if (!defaultValue.equals(value)) json.put(id, value);
}
}
public class PrimitiveSetting<X extends Object> extends Setting<X> {
public PrimitiveSetting(String id, X defaultValue) {
this.id = id;
this.value = this.defaultValue = defaultValue;
}
@SuppressWarnings({"rawtypes", "unchecked"})
public void readFromJson(Map json) {
if (json.get(id) != null) value = (X) json.get(id);
}
}
public class NullDefaultPrimitiveSetting<X extends Object> extends PrimitiveSetting<X> {
public NullDefaultPrimitiveSetting(String id) {
super(id, null);
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public void saveToJson(Map json) {
if (value != null) json.put(id, value);
}
}
public class ListSetting<X extends Object> extends Setting<List<X>> {
public ListSetting(String id, List<X> defaultValue) {
this.id = id;
this.value = this.defaultValue = defaultValue;
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void readFromJson(Map json) {
value = new ArrayList<X>();
if (json.get(id) != null) {
for (Object o : ((List) json.get(id))) {
value.add((X) o);
}
}
}
}
public ListSetting(String id, List<X> defaultValue) {
this.id = id;
this.value = this.defaultValue = defaultValue;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void readFromJson(Map json) {
value = new ArrayList<X>();
if (json.get(id) != null) {
for (Object o : ((List)json.get(id))) {
value.add((X)o);
}
}
}
}
} }

View File

@@ -1,5 +1,12 @@
package com.gpl.rpg.atcontentstudio.model.bookmarks; package com.gpl.rpg.atcontentstudio.model.bookmarks;
import java.awt.Image;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
@@ -8,154 +15,141 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
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 javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class BookmarkEntry implements BookmarkNode { public class BookmarkEntry implements BookmarkNode {
public GameDataElement bookmarkedElement; public GameDataElement bookmarkedElement;
public BookmarkFolder parent; public BookmarkFolder parent;
public BookmarkEntry(BookmarkFolder parent, GameDataElement target) {
this.parent = parent;
this.bookmarkedElement = target;
target.bookmark = this;
parent.contents.add(this);
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
public BookmarkEntry(BookmarkFolder parent, GameDataElement target) { @Override
this.parent = parent; public boolean getAllowsChildren() {
this.bookmarkedElement = target; return false;
target.bookmark = this; }
parent.contents.add(this);
}
@Override @Override
public Enumeration<ProjectTreeNode> children() { public TreeNode getChildAt(int childIndex) {
return null; return null;
} }
@Override @Override
public boolean getAllowsChildren() { public int getChildCount() {
return false; return 0;
} }
@Override @Override
public TreeNode getChildAt(int childIndex) { public int getIndex(TreeNode node) {
return null; return 0;
} }
@Override @Override
public int getChildCount() { public TreeNode getParent() {
return 0; return parent;
} }
@Override @Override
public int getIndex(TreeNode node) { public boolean isLeaf() {
return 0; return true;
} }
@Override @Override
public TreeNode getParent() { public void childrenAdded(List<ProjectTreeNode> path) {
return parent; path.add(0,this);
} parent.childrenAdded(path);
}
@Override @Override
public boolean isLeaf() { public void childrenChanged(List<ProjectTreeNode> path) {
return true; path.add(0,this);
} parent.childrenChanged(path);
}
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0, this); path.add(0,this);
parent.childrenAdded(path); parent.childrenRemoved(path);
} }
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public String getDesc() {
path.add(0, this); if (bookmarkedElement instanceof QuestStage) {
parent.childrenChanged(path); String text = ((GameDataElement)bookmarkedElement).getDesc();
} if (text.length() > 60) {
text = text.substring(0, 57)+"...";
}
return ((GameDataElement)bookmarkedElement).getDataType().toString()+"/"+((Quest)((QuestStage)bookmarkedElement).parent).id+"#"+((QuestStage)bookmarkedElement).progress+":"+text;
} else {
return ((GameDataElement)bookmarkedElement).getDataType().toString()+"/"+((GameDataElement)bookmarkedElement).getDesc();
}
}
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public Project getProject() {
path.add(0, this); return parent.getProject();
parent.childrenRemoved(path); }
}
@Override @Override
public void notifyCreated() { public GameDataSet getDataSet() {
childrenAdded(new ArrayList<ProjectTreeNode>()); return null;
} }
@Override @Override
public String getDesc() { public Image getIcon() {
if (bookmarkedElement instanceof QuestStage) { return bookmarkedElement.getIcon();
String text = ((GameDataElement) bookmarkedElement).getDesc(); }
if (text.length() > 60) {
text = text.substring(0, 57) + "...";
}
return ((GameDataElement) bookmarkedElement).getDataType().toString() +
"/" +
((Quest) ((QuestStage) bookmarkedElement).parent).id +
"#" +
((QuestStage) bookmarkedElement).progress +
":" +
text;
} else {
return ((GameDataElement) bookmarkedElement).getDataType().toString() + "/" + ((GameDataElement) bookmarkedElement).getDesc();
}
}
@Override @Override
public Project getProject() { public Image getOpenIcon() {
return parent.getProject(); return null;
} }
@Override @Override
public GameDataSet getDataSet() { public Image getClosedIcon() {
return null; return null;
} }
@Override @Override
public Image getIcon() { public Image getLeafIcon() {
return bookmarkedElement.getIcon(); return getIcon();
} }
@Override @Override
public Image getOpenIcon() { public Type getDataType() {
return null; return null;
} }
@Override @Override
public Image getClosedIcon() { public boolean isEmpty() {
return null; return true;
} }
@Override @Override
public Image getLeafIcon() { public boolean needsSaving() {
return getIcon(); return false;
} }
@Override public void delete() {
public Type getDataType() { bookmarkedElement.bookmark = null;
return null; parent.delete(this);
} }
@Override @Override
public boolean isEmpty() { public void save() {
return true; parent.save();
} }
@Override
public boolean needsSaving() {
return false;
}
public void delete() {
bookmarkedElement.bookmark = null;
parent.delete(this);
}
@Override
public void save() {
parent.save();
}
} }

View File

@@ -1,165 +1,168 @@
package com.gpl.rpg.atcontentstudio.model.bookmarks; package com.gpl.rpg.atcontentstudio.model.bookmarks;
import java.awt.Image;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.List;
import java.util.*;
public class BookmarkFolder implements BookmarkNode { public class BookmarkFolder implements BookmarkNode {
List<BookmarkNode> contents = new LinkedList<BookmarkNode>(); List<BookmarkNode> contents = new LinkedList<BookmarkNode>();
BookmarkNode parent; BookmarkNode parent;
String name; String name;
Image closedIcon, openIcon; Image closedIcon, openIcon;
public BookmarkFolder(BookmarkNode parent, String name) { public BookmarkFolder(BookmarkNode parent, String name) {
this(parent, name, DefaultIcons.getStdClosedIcon(), DefaultIcons.getStdOpenIcon()); this(parent, name, DefaultIcons.getStdClosedIcon(), DefaultIcons.getStdOpenIcon());
} }
public BookmarkFolder(BookmarkNode parent, String name, Image closedIcon, Image openIcon) {
this.parent = parent;
this.name = name;
this.closedIcon = closedIcon;
this.openIcon = openIcon;
}
@Override
public Enumeration<? extends ProjectTreeNode> children() {
return Collections.enumeration(contents);
}
public BookmarkFolder(BookmarkNode parent, String name, Image closedIcon, Image openIcon) { @Override
this.parent = parent; public boolean getAllowsChildren() {
this.name = name; return true;
this.closedIcon = closedIcon; }
this.openIcon = openIcon;
}
@Override @Override
public Enumeration<? extends ProjectTreeNode> children() { public TreeNode getChildAt(int childIndex) {
return Collections.enumeration(contents); return contents.get(childIndex);
} }
@Override @Override
public boolean getAllowsChildren() { public int getChildCount() {
return true; return contents.size();
} }
@Override @Override
public TreeNode getChildAt(int childIndex) { public int getIndex(TreeNode node) {
return contents.get(childIndex); return contents.indexOf(node);
} }
@Override @Override
public int getChildCount() { public TreeNode getParent() {
return contents.size(); return parent;
} }
@Override @Override
public int getIndex(TreeNode node) { public boolean isLeaf() {
return contents.indexOf(node); return false;
} }
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenAdded(path);
}
@Override @Override
public TreeNode getParent() { public void childrenChanged(List<ProjectTreeNode> path) {
return parent; path.add(0,this);
} parent.childrenChanged(path);
}
@Override @Override
public boolean isLeaf() { public void childrenRemoved(List<ProjectTreeNode> path) {
return false; if (path.size() == 1 && this.getChildCount() == 1) {
} childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public String getDesc() {
path.add(0, this); return name;
parent.childrenAdded(path); }
}
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public Project getProject() {
path.add(0, this); return parent.getProject();
parent.childrenChanged(path); }
}
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public GameDataSet getDataSet() {
if (path.size() == 1 && this.getChildCount() == 1) { return null;
childrenRemoved(new ArrayList<ProjectTreeNode>()); }
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override @Override
public void notifyCreated() { public Image getIcon() {
childrenAdded(new ArrayList<ProjectTreeNode>()); return getClosedIcon();
} }
@Override @Override
public String getDesc() { public Image getOpenIcon() {
return name; return openIcon;
} }
@Override @Override
public Project getProject() { public Image getClosedIcon() {
return parent.getProject(); return closedIcon;
} }
@Override @Override
public GameDataSet getDataSet() { public Image getLeafIcon() {
return null; return getClosedIcon();
} }
@Override @Override
public Image getIcon() { public Type getDataType() {
return getClosedIcon(); return null;
} }
@Override @Override
public Image getOpenIcon() { public boolean isEmpty() {
return openIcon; return contents.isEmpty();
} }
@Override @Override
public Image getClosedIcon() { public boolean needsSaving() {
return closedIcon; return false;
} }
@Override public void delete(BookmarkEntry bookmarkEntry) {
public Image getLeafIcon() { if (contents.contains(bookmarkEntry)) {
return getClosedIcon(); bookmarkEntry.childrenRemoved(new ArrayList<ProjectTreeNode>());
} contents.remove(bookmarkEntry);
save();
@Override }
public Type getDataType() { }
return null;
} public void delete(BookmarkFolder bookmarkFolder) {
// TODO Auto-generated method stub
@Override
public boolean isEmpty() { }
return contents.isEmpty();
} public void save() {
parent.save();
@Override }
public boolean needsSaving() {
return false; public void delete() {
}
}
public void delete(BookmarkEntry bookmarkEntry) {
if (contents.contains(bookmarkEntry)) {
bookmarkEntry.childrenRemoved(new ArrayList<ProjectTreeNode>());
contents.remove(bookmarkEntry);
save();
}
}
public void delete(BookmarkFolder bookmarkFolder) {
// TODO Auto-generated method stub
}
public void save() {
parent.save();
}
public void delete() {
}
} }

View File

@@ -2,10 +2,9 @@ package com.gpl.rpg.atcontentstudio.model.bookmarks;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
public interface BookmarkNode extends ProjectTreeNode { public interface BookmarkNode extends ProjectTreeNode{
public void save();
public void delete();
public void save();
public void delete();
} }

View File

@@ -1,206 +1,210 @@
package com.gpl.rpg.atcontentstudio.model.bookmarks; package com.gpl.rpg.atcontentstudio.model.bookmarks;
import java.awt.Image;
import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SavedSlotCollection; import com.gpl.rpg.atcontentstudio.model.SavedSlotCollection;
import com.gpl.rpg.atcontentstudio.model.gamedata.*; import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
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.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment; import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class BookmarksRoot implements BookmarkNode { public class BookmarksRoot implements BookmarkNode {
SavedSlotCollection v = new SavedSlotCollection(); SavedSlotCollection v = new SavedSlotCollection();
public transient Project parent; public transient Project parent = null;
BookmarkFolder ac, diag, dl, it, ic, npc, q, tmx, sp, wm;
public BookmarksRoot(Project parent) {
this.parent = parent;
BookmarkFolder ac, diag, dl, it, ic, npc, q, tmx, sp, wm; v.add(ac = new BookmarkFolder(this, ActorCondition.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(diag = new BookmarkFolder(this, Dialogue.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(dl = new BookmarkFolder(this, Droplist.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(it = new BookmarkFolder(this, Item.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(ic = new BookmarkFolder(this, ItemCategory.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(npc = new BookmarkFolder(this, NPC.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(q = new BookmarkFolder(this, Quest.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(tmx = new BookmarkFolder(this, "TMX Maps", DefaultIcons.getTmxClosedIcon(), DefaultIcons.getTmxOpenIcon()));
v.add(sp = new BookmarkFolder(this, "Spritesheets", DefaultIcons.getSpriteClosedIcon(), DefaultIcons.getSpriteOpenIcon()));
v.add(wm = new BookmarkFolder(this, "Worldmap", DefaultIcons.getSpriteClosedIcon(), DefaultIcons.getSpriteOpenIcon()));
}
@Override
public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements();
}
public BookmarksRoot(Project parent) { @Override
this.parent = parent; public boolean getAllowsChildren() {
return true;
}
v.add(ac = new BookmarkFolder(this, ActorCondition.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon())); @Override
v.add(diag = new BookmarkFolder(this, Dialogue.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon())); public TreeNode getChildAt(int arg0) {
v.add(dl = new BookmarkFolder(this, Droplist.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon())); return v.getNonEmptyElementAt(arg0);
v.add(it = new BookmarkFolder(this, Item.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon())); }
v.add(ic = new BookmarkFolder(this, ItemCategory.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(npc = new BookmarkFolder(this, NPC.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(q = new BookmarkFolder(this, Quest.getStaticDesc(), DefaultIcons.getJsonClosedIcon(), DefaultIcons.getJsonOpenIcon()));
v.add(tmx = new BookmarkFolder(this, "TMX Maps", DefaultIcons.getTmxClosedIcon(), DefaultIcons.getTmxOpenIcon())); @Override
v.add(sp = new BookmarkFolder(this, "Spritesheets", DefaultIcons.getSpriteClosedIcon(), DefaultIcons.getSpriteOpenIcon())); public int getChildCount() {
v.add(wm = new BookmarkFolder(this, "Worldmap", DefaultIcons.getSpriteClosedIcon(), DefaultIcons.getSpriteOpenIcon())); return v.getNonEmptySize();
} }
@Override @Override
public Enumeration<ProjectTreeNode> children() { public int getIndex(TreeNode arg0) {
return v.getNonEmptyElements(); return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
} }
@Override @Override
public boolean getAllowsChildren() { public TreeNode getParent() {
return true; return parent;
} }
@Override @Override
public TreeNode getChildAt(int arg0) { public boolean isLeaf() {
return v.getNonEmptyElementAt(arg0); return false;
} }
@Override @Override
public int getChildCount() { public void childrenAdded(List<ProjectTreeNode> path) {
return v.getNonEmptySize(); path.add(0, this);
} parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override @Override
public int getIndex(TreeNode arg0) { public String getDesc() {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0); return (needsSaving() ? "*" : "")+"Bookmarks";
} }
@Override @Override
public TreeNode getParent() { public Project getProject() {
return parent; return parent == null ? null : parent.getProject();
} }
@Override @Override
public boolean isLeaf() { public GameDataSet getDataSet() {
return false; return null;
} }
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public Image getIcon() {
path.add(0, this); return getOpenIcon();
parent.childrenAdded(path); }
}
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public Image getOpenIcon() {
path.add(0, this); return DefaultIcons.getBookmarkOpenIcon();
parent.childrenChanged(path); }
}
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public Image getClosedIcon() {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) { return DefaultIcons.getBookmarkClosedIcon();
childrenRemoved(new ArrayList<ProjectTreeNode>()); }
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override @Override
public void notifyCreated() { public Image getLeafIcon() {
childrenAdded(new ArrayList<ProjectTreeNode>()); return getClosedIcon();
for (ProjectTreeNode node : v.getNonEmptyIterable()) { }
node.notifyCreated();
}
}
@Override @Override
public String getDesc() { public Type getDataType() {
return (needsSaving() ? "*" : "") + "Bookmarks"; return null;
} }
@Override @Override
public Project getProject() { public boolean isEmpty() {
return parent == null ? null : parent.getProject(); return v.isEmpty();
} }
@Override @Override
public GameDataSet getDataSet() { public boolean needsSaving() {
return null; return false;
} }
@Override public void save() {
public Image getIcon() {
return getOpenIcon(); }
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getBookmarkOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getBookmarkClosedIcon();
}
@Override
public Image getLeafIcon() {
return getClosedIcon();
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return v.isEmpty();
}
@Override
public boolean needsSaving() {
return false;
}
public void save() {
}
@Override
public void delete() {
}
public void addBookmark(GameDataElement target) {
BookmarkEntry node;
BookmarkFolder folder;
if (target instanceof ActorCondition) {
folder = ac;
} else if (target instanceof Dialogue) {
folder = diag;
} else if (target instanceof Droplist) {
folder = dl;
} else if (target instanceof Item) {
folder = it;
} else if (target instanceof ItemCategory) {
folder = ic;
} else if (target instanceof NPC) {
folder = npc;
} else if (target instanceof Quest) {
folder = q;
} else if (target instanceof TMXMap) {
folder = tmx;
} else if (target instanceof Spritesheet) {
folder = sp;
} else if (target instanceof WorldmapSegment) {
folder = wm;
} else {
return;
}
ProjectTreeNode higherEmptyParent = folder;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode) higherEmptyParent.getParent()).isEmpty())
higherEmptyParent = (ProjectTreeNode) higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
node = new BookmarkEntry(folder, target);
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
@Override
public void delete() {}
public void addBookmark(GameDataElement target) {
BookmarkEntry node;
BookmarkFolder folder = null;
if (target instanceof ActorCondition) {
folder = ac;
} else if (target instanceof Dialogue) {
folder = diag;
} else if (target instanceof Droplist) {
folder = dl;
} else if (target instanceof Item) {
folder = it;
} else if (target instanceof ItemCategory) {
folder = ic;
} else if (target instanceof NPC) {
folder = npc;
} else if (target instanceof Quest) {
folder = q;
} else if (target instanceof TMXMap) {
folder = tmx;
} else if (target instanceof Spritesheet) {
folder = sp;
} else if (target instanceof WorldmapSegment) {
folder = wm;
} else {
return;
}
ProjectTreeNode higherEmptyParent = folder;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
node = new BookmarkEntry(folder, target);
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
} }

View File

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

View File

@@ -1,183 +1,29 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
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.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public final class Common { public final class Common {
public static <T extends ActorConditionEffect> void actorConditionElementChanged(List<T> list, GameDataElement oldOne, GameDataElement newOne, GameDataElement backlink) { public static void linkConditions(List<?extends ConditionEffect> conditions, Project proj, GameDataElement backlink) {
if (list != null) {
for (T c : list) {
if (c.condition == oldOne) {
oldOne.removeBacklink(backlink);
c.condition = (ActorCondition) newOne;
if (newOne != null) newOne.addBacklink(backlink);
}
}
}
}
//region link common stuff
public static void linkConditions(List<? extends ActorConditionEffect> conditions, Project proj, GameDataElement backlink) {
if (conditions != null) { if (conditions != null) {
for (ActorConditionEffect ce : conditions) { for (ConditionEffect ce : conditions) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(backlink); if (ce.condition != null) ce.condition.addBacklink(backlink);
} }
} }
} }
public static class TimedConditionEffect extends ConditionEffect {
public static void linkEffects(HitEffect effect, Project proj, GameDataElement backlink) {
linkEffects((DeathEffect) effect, proj, backlink);
if (effect != null) {
linkConditions(effect.conditions_target, proj, backlink);
}
}
public static void linkEffects(DeathEffect effect, Project proj, GameDataElement backlink) {
if (effect != null) {
linkConditions(effect.conditions_source, proj, backlink);
}
}
public static void linkIcon(Project proj, String iconId, GameDataElement backlink) {
if (iconId != null) {
String spritesheetId = iconId.split(":")[0];
if (proj.getSpritesheet(spritesheetId) == null) {
Notification.addError("Error Spritesheet " + spritesheetId + ". has no backlink. (" + iconId + ")");
return;
}
proj.getSpritesheet(spritesheetId).addBacklink(backlink);
}
}
//endregion
//region write common stuff
public static void writeMinMaxToMap(Map parent, Integer min, Integer max, int defaultValue) {
if (min != null || max != null) {
if (min != null)
parent.put("min", min);
else parent.put("min", defaultValue);
if (max != null)
parent.put("max", max);
else parent.put("max", defaultValue);
}
}
public static void writeMinMaxToMap(Map parent, String key, Integer min, Integer max, int defaultValue) {
if (min != null || max != null) {
Map minMaxMap = new LinkedHashMap();
parent.put(key, minMaxMap);
writeMinMaxToMap(minMaxMap, min, max, defaultValue);
}
}
public static void writeDescriptionToMap(Map parent, String description) {
if (description != null) parent.put("description", description);
}
public static void writeIconToMap(Map parent, String icon_id) {
if (icon_id != null) parent.put("iconID", icon_id);
}
public static void writeHitReceivedEffectToMap(Map parent, HitReceivedEffect effect) {
if (effect != null) {
writeHitEffectToMap(parent, effect);
writeBasicEffectObjectToMap(effect.target, parent, "increaseAttackerCurrentHP", "increaseAttackerCurrentAP");
}
}
public static void writeHitReceivedEffectToMap(Map parent, HitReceivedEffect effect, String key) {
if (effect != null) {
Map effectJson = new LinkedHashMap();
parent.put(key, effectJson);
writeHitReceivedEffectToMap(effectJson, effect);
}
}
public static void writeHitEffectToMap(Map parent, HitEffect effect) {
if (effect != null) {
writeDeathEffectToMap(parent, effect);
writeTimedActorConditionEffectObjectToMap(effect.conditions_target, parent, "conditionsTarget");
}
}
public static void writeHitEffectToMap(Map parent, HitEffect effect, String key) {
if (effect != null) {
Map effectJson = new LinkedHashMap();
parent.put(key, effectJson);
writeHitEffectToMap(effectJson, effect);
}
}
public static void writeDeathEffectToMap(Map parent, DeathEffect effect) {
writeBasicEffectObjectToMap(effect, parent, "increaseCurrentHP", "increaseCurrentAP");
writeTimedActorConditionEffectObjectToMap(effect.conditions_source, parent, "conditionsSource");
}
public static void writeDeathEffectToMap(Map parent, DeathEffect effect, String key) {
if (effect != null) {
Map effectJson = new LinkedHashMap();
parent.put(key, effectJson);
writeDeathEffectToMap(effectJson, effect);
}
}
public static void writeBasicEffectObjectToMap(BasicEffect effect, Map parent, String keyHP, String keyAP) {
writeMinMaxToMap(parent, keyHP, effect.hp_boost_min, effect.hp_boost_max, 0);
writeMinMaxToMap(parent, keyAP, effect.ap_boost_min, effect.ap_boost_max, 0);
}
public static void writeTimedActorConditionEffectObjectToMap(List<TimedActorConditionEffect> list, Map parent, String key) {
if (list != null) {
List conditionsSourceJson = new ArrayList();
parent.put(key, conditionsSourceJson);
for (TimedActorConditionEffect condition : list) {
Map conditionJson = new LinkedHashMap();
conditionsSourceJson.add(conditionJson);
writeTimedConditionEffectToMap(condition, conditionJson);
}
}
}
public static void writeConditionEffectToMap(ActorConditionEffect condition, Map parent) {
if (condition.condition != null) {
parent.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
parent.put("condition", condition.condition_id);
}
if (condition.magnitude != null) {
parent.put("magnitude", condition.magnitude);
}
}
public static void writeTimedConditionEffectToMap(TimedActorConditionEffect condition, Map parent) {
writeConditionEffectToMap(condition, parent);
if (condition.duration != null) {
parent.put("duration", condition.duration);
}
if (condition.chance != null) {
parent.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
//endregion
public static class TimedActorConditionEffect extends ActorConditionEffect {
//Available from parsed state //Available from parsed state
public Integer duration = null; public Integer duration = null;
public Double chance = null; public Double chance = null;
public TimedActorConditionEffect createClone() { public TimedConditionEffect createClone() {
TimedActorConditionEffect cclone = new TimedActorConditionEffect(); TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = this.magnitude; cclone.magnitude = this.magnitude;
cclone.condition_id = this.condition_id; cclone.condition_id = this.condition_id;
cclone.condition = this.condition; cclone.condition = this.condition;
@@ -185,42 +31,25 @@ public final class Common {
cclone.duration = this.duration; cclone.duration = this.duration;
return cclone; return cclone;
} }
public boolean isInfinite() {
return duration != null && duration.equals(ActorCondition.DURATION_FOREVER);
}
public boolean isImmunity() {
return (super.isClear()) && (duration != null && duration > ActorCondition.DURATION_NONE);
}
@Override
public boolean isClear() {
return (super.isClear()) && (duration == null || duration.equals(ActorCondition.DURATION_NONE));
}
} }
public static class ActorConditionEffect { public static class ConditionEffect {
//Available from parsed state //Available from parsed state
public Integer magnitude = null; public Integer magnitude = null;
public String condition_id = null; public String condition_id = null;
//Available from linked state //Available from linked state
public ActorCondition condition = null; public ActorCondition condition = null;
public boolean isClear() {
return magnitude == null || magnitude.equals(ActorCondition.MAGNITUDE_CLEAR);
}
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static ArrayList<TimedActorConditionEffect> parseTimedConditionEffects(List conditionsSourceJson) { public static ArrayList<TimedConditionEffect> parseTimedConditionEffects(List conditionsSourceJson) {
ArrayList<TimedActorConditionEffect> conditions_source; ArrayList<TimedConditionEffect> conditions_source;
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) { if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
conditions_source = new ArrayList<>(); conditions_source = new ArrayList<>();
for (Object conditionJsonObj : conditionsSourceJson) { for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map) conditionJsonObj; Map conditionJson = (Map) conditionJsonObj;
TimedActorConditionEffect condition = new TimedActorConditionEffect(); TimedConditionEffect condition = new TimedConditionEffect();
readConditionEffect(condition, conditionJson); readConditionEffect(condition, conditionJson);
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration")); condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) if (conditionJson.get("chance") != null)
@@ -234,7 +63,7 @@ public final class Common {
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private static void readConditionEffect(ActorConditionEffect condition, Map conditionJson) { private static void readConditionEffect(ConditionEffect condition, Map conditionJson) {
condition.condition_id = (String) conditionJson.get("condition"); condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude")); condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
} }
@@ -258,12 +87,12 @@ public final class Common {
HitReceivedEffect hit_received_effect = new Common.HitReceivedEffect(); HitReceivedEffect hit_received_effect = new Common.HitReceivedEffect();
readHitEffect(hitReceivedEffect, hit_received_effect); readHitEffect(hitReceivedEffect, hit_received_effect);
if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) { if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) {
hit_received_effect.target.hp_boost_max = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max"))); hit_received_effect.hp_boost_max_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max")));
hit_received_effect.target.hp_boost_min = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min"))); hit_received_effect.hp_boost_min_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min")));
} }
if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) { if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) {
hit_received_effect.target.ap_boost_max = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max"))); hit_received_effect.ap_boost_max_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max")));
hit_received_effect.target.ap_boost_min = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min"))); hit_received_effect.ap_boost_min_target = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min")));
} }
return hit_received_effect; return hit_received_effect;
} }
@@ -289,64 +118,39 @@ public final class Common {
hit_effect.conditions_target = parseTimedConditionEffects(conditionsTargetJson); hit_effect.conditions_target = parseTimedConditionEffects(conditionsTargetJson);
} }
public static class BasicEffect {
public static class DeathEffect {
//Available from parsed state
public Integer hp_boost_min = null; public Integer hp_boost_min = null;
public Integer hp_boost_max = null; public Integer hp_boost_max = null;
public Integer ap_boost_min = null; public Integer ap_boost_min = null;
public Integer ap_boost_max = null; public Integer ap_boost_max = null;
public List<TimedConditionEffect> conditions_source = null;
public boolean isNull() {
if (ap_boost_min != null) return false;
if (ap_boost_max != null) return false;
if (hp_boost_min != null) return false;
if (hp_boost_max != null) return false;
return true;
}
}
public static class DeathEffect extends BasicEffect {
//Available from parsed state
public List<TimedActorConditionEffect> conditions_source = null;
@Override
public boolean isNull() {
if (!super.isNull()) return false;
if (conditions_source != null) return false;
return true;
}
} }
public static class HitEffect extends DeathEffect { public static class HitEffect extends DeathEffect {
//Available from parsed state //Available from parsed state
public List<TimedActorConditionEffect> conditions_target = null; public List<TimedConditionEffect> conditions_target = null;
@Override
public boolean isNull() {
if (!super.isNull()) return false;
if (conditions_target != null) return false;
return true;
}
} }
public static class HitReceivedEffect extends Common.HitEffect { public static class HitReceivedEffect extends Common.HitEffect {
//Available from parsed state //Available from parsed state
public BasicEffect target = new BasicEffect(); public Integer hp_boost_min_target = null;
public Integer hp_boost_max_target = null;
@Override public Integer ap_boost_min_target = null;
public boolean isNull() { public Integer ap_boost_max_target = null;
if (!super.isNull()) return false;
if (!target.isNull()) return false;
return true;
}
} }
public static void copyDeathEffectValues(Common.DeathEffect target, Common.DeathEffect source, GameDataElement backlink) { public static void copyDeathEffectValues(Common.DeathEffect target, Common.DeathEffect source, GameDataElement backlink) {
copyEffectValues(target, source); 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) { if (source.conditions_source != null) {
target.conditions_source = new ArrayList<>(); target.conditions_source = new ArrayList<>();
for (TimedActorConditionEffect c : source.conditions_source) { for (Common.TimedConditionEffect c : source.conditions_source) {
TimedActorConditionEffect cclone = c.createClone(); Common.TimedConditionEffect cclone = c.createClone();
if (cclone.condition != null) { if (cclone.condition != null) {
cclone.condition.addBacklink(backlink); cclone.condition.addBacklink(backlink);
} }
@@ -355,19 +159,12 @@ public final class Common {
} }
} }
private static void copyEffectValues(BasicEffect target, BasicEffect source) {
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;
}
public static void copyHitEffectValues(Common.HitEffect target, Common.HitEffect source, GameDataElement backlink) { public static void copyHitEffectValues(Common.HitEffect target, Common.HitEffect source, GameDataElement backlink) {
copyDeathEffectValues(target, source, backlink); copyDeathEffectValues(target, source, backlink);
if (source.conditions_target != null) { if (source.conditions_target != null) {
target.conditions_target = new ArrayList<>(); target.conditions_target = new ArrayList<>();
for (TimedActorConditionEffect c : source.conditions_target) { for (Common.TimedConditionEffect c : source.conditions_target) {
TimedActorConditionEffect cclone = c.createClone(); Common.TimedConditionEffect cclone = c.createClone();
if (cclone.condition != null) { if (cclone.condition != null) {
cclone.condition.addBacklink(backlink); cclone.condition.addBacklink(backlink);
} }
@@ -378,7 +175,10 @@ public final class Common {
public static void copyHitReceivedEffectValues(Common.HitReceivedEffect target, Common.HitReceivedEffect source, GameDataElement backlink) { public static void copyHitReceivedEffectValues(Common.HitReceivedEffect target, Common.HitReceivedEffect source, GameDataElement backlink) {
copyHitEffectValues(target, source, backlink); copyHitEffectValues(target, source, backlink);
copyEffectValues(target.target, source.target); 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,461 +1,463 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import com.gpl.rpg.atcontentstudio.Notification; import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import java.io.File;
import com.gpl.rpg.atcontentstudio.model.GameSource; import java.io.FileNotFoundException;
import com.gpl.rpg.atcontentstudio.model.Project; import java.io.FileReader;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement.RequirementType; import java.io.IOException;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import java.util.ArrayList;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import java.util.Arrays;
import org.json.simple.parser.JSONParser; import java.util.LinkedHashMap;
import org.json.simple.parser.ParseException; import java.util.List;
import java.util.Map;
import java.awt.*;
import java.io.File; import org.json.simple.parser.JSONParser;
import java.io.FileNotFoundException; import org.json.simple.parser.ParseException;
import java.io.FileReader;
import java.io.IOException; import com.gpl.rpg.atcontentstudio.Notification;
import java.util.List; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import java.util.*; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement.RequirementType;
public class Dialogue extends JSONElement { import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
private static final long serialVersionUID = -6872164604703134683L;
public class Dialogue extends JSONElement {
//Available from init state
//public String id = null; inherited. private static final long serialVersionUID = -6872164604703134683L;
public String message = null;
//Available from parsed state; //Available from init state
public List<Reward> rewards = null; //public String id = null; inherited.
public List<Reply> replies = null; public String message = null;
public String switch_to_npc_id = null;
//Available from parsed state;
//Available from linked state; public List<Reward> rewards = null;
public NPC switch_to_npc = null; public List<Reply> replies = null;
public String switch_to_npc_id = null;
public static class Reward {
//Available from linked state;
//Available from parsed state public NPC switch_to_npc = null;
public RewardType type = null;
public String reward_obj_id = null; public static class Reward {
public Integer reward_value = null;
public String map_name = null; //Available from parsed state
public RewardType type = null;
//Available from linked state public String reward_obj_id = null;
public GameDataElement reward_obj = null; public Integer reward_value = null;
public TMXMap map = null; public String map_name = null;
public enum RewardType { //Available from linked state
questProgress, public GameDataElement reward_obj = null;
removeQuestProgress, public TMXMap map = null;
dropList,
skillIncrease, public enum RewardType {
actorCondition, questProgress,
actorConditionImmunity, removeQuestProgress,
alignmentChange, dropList,
alignmentSet, skillIncrease,
giveItem, actorCondition,
createTimer, actorConditionImmunity,
spawnAll, alignmentChange,
removeSpawnArea, alignmentSet,
deactivateSpawnArea, giveItem,
activateMapObjectGroup, createTimer,
deactivateMapObjectGroup, spawnAll,
changeMapFilter, removeSpawnArea,
mapchange deactivateSpawnArea,
} activateMapObjectGroup,
} deactivateMapObjectGroup,
changeMapFilter,
public static class Reply { mapchange
}
public static final String GO_NEXT_TEXT = "N"; }
public static final String SHOP_PHRASE_ID = "S";
public static final String FIGHT_PHRASE_ID = "F"; public static class Reply {
public static final String EXIT_PHRASE_ID = "X";
public static final String REMOVE_PHRASE_ID = "R"; public static final String GO_NEXT_TEXT = "N";
public static final String SHOP_PHRASE_ID = "S";
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 String FIGHT_PHRASE_ID = "F";
public static final String EXIT_PHRASE_ID = "X";
//Available from parsed state public static final String REMOVE_PHRASE_ID = "R";
public String text = null;
public String next_phrase_id = null; 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 List<Requirement> requirements = null;
//Available from parsed state
//Available from linked state public String text = null;
public Dialogue next_phrase = null; public String next_phrase_id = null;
public List<Requirement> requirements = null;
}
//Available from linked state
@Override public Dialogue next_phrase = null;
public String getDesc() {
return (needsSaving() ? "*" : "") + id; }
}
@Override
public static String getStaticDesc() { public String getDesc() {
return "Dialogues"; return (needsSaving() ? "*" : "")+id;
} }
@SuppressWarnings("rawtypes") public static String getStaticDesc() {
public static void fromJson(File jsonFile, GameDataCategory<Dialogue> category) { return "Dialogues";
JSONParser parser = new JSONParser(); }
FileReader reader = null;
try { @SuppressWarnings("rawtypes")
reader = new FileReader(jsonFile); public static void fromJson(File jsonFile, GameDataCategory<Dialogue> category) {
List dialogues = (List) parser.parse(reader); JSONParser parser = new JSONParser();
for (Object obj : dialogues) { FileReader reader = null;
Map dialogueJson = (Map) obj; try {
Dialogue dialogue = fromJson(dialogueJson); reader = new FileReader(jsonFile);
dialogue.jsonFile = jsonFile; List dialogues = (List) parser.parse(reader);
dialogue.parent = category; for (Object obj : dialogues) {
if (dialogue.getDataType() == GameSource.Type.created || dialogue.getDataType() == GameSource.Type.altered) { Map dialogueJson = (Map)obj;
dialogue.writable = true; Dialogue dialogue = fromJson(dialogueJson);
} dialogue.jsonFile = jsonFile;
category.add(dialogue); dialogue.parent = category;
} if (dialogue.getDataType() == GameSource.Type.created || dialogue.getDataType() == GameSource.Type.altered) {
} catch (FileNotFoundException e) { dialogue.writable = true;
Notification.addError("Error while parsing JSON file " + jsonFile.getAbsolutePath() + ": " + e.getMessage()); }
e.printStackTrace(); category.add(dialogue);
} catch (IOException 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 (ParseException 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());
} finally { e.printStackTrace();
if (reader != null) } catch (ParseException e) {
try { Notification.addError("Error while parsing JSON file "+jsonFile.getAbsolutePath()+": "+e.getMessage());
reader.close(); e.printStackTrace();
} catch (IOException e) { } finally {
e.printStackTrace(); if (reader != null)
} try {
} reader.close();
} } catch (IOException e) {
e.printStackTrace();
@SuppressWarnings("rawtypes") }
public static Dialogue fromJson(String jsonString) throws ParseException { }
Map dialogueJson = (Map) new JSONParser().parse(jsonString); }
Dialogue dialogue = fromJson(dialogueJson);
dialogue.parse(dialogueJson); @SuppressWarnings("rawtypes")
return dialogue; public static Dialogue fromJson(String jsonString) throws ParseException {
} Map dialogueJson = (Map) new JSONParser().parse(jsonString);
Dialogue dialogue = fromJson(dialogueJson);
@SuppressWarnings("rawtypes") dialogue.parse(dialogueJson);
public static Dialogue fromJson(Map dialogueJson) { return dialogue;
Dialogue dialogue = new Dialogue(); }
dialogue.id = (String) dialogueJson.get("id");
dialogue.message = (String) dialogueJson.get("message"); @SuppressWarnings("rawtypes")
return dialogue; public static Dialogue fromJson(Map dialogueJson) {
} Dialogue dialogue = new Dialogue();
dialogue.id = (String) dialogueJson.get("id");
@SuppressWarnings("rawtypes") dialogue.message = (String) dialogueJson.get("message");
@Override return dialogue;
public void parse(Map dialogueJson) { }
this.switch_to_npc_id = (String) dialogueJson.get("switchToNPC");
List repliesJson = (List) dialogueJson.get("replies"); @SuppressWarnings("rawtypes")
if (repliesJson != null && !repliesJson.isEmpty()) { @Override
this.replies = new ArrayList<Dialogue.Reply>(); public void parse(Map dialogueJson) {
for (Object replyJsonObj : repliesJson) { this.switch_to_npc_id = (String) dialogueJson.get("switchToNPC");
Map replyJson = (Map) replyJsonObj; List repliesJson = (List) dialogueJson.get("replies");
Reply reply = new Reply(); if (repliesJson != null && !repliesJson.isEmpty()) {
reply.text = (String) replyJson.get("text"); this.replies = new ArrayList<Dialogue.Reply>();
reply.next_phrase_id = (String) replyJson.get("nextPhraseID"); for (Object replyJsonObj : repliesJson) {
List requirementsJson = (List) replyJson.get("requires"); Map replyJson = (Map)replyJsonObj;
if (requirementsJson != null && !requirementsJson.isEmpty()) { Reply reply = new Reply();
reply.requirements = new ArrayList<Requirement>(); reply.text = (String) replyJson.get("text");
for (Object requirementJsonObj : requirementsJson) { reply.next_phrase_id = (String) replyJson.get("nextPhraseID");
Map requirementJson = (Map) requirementJsonObj; List requirementsJson = (List) replyJson.get("requires");
Requirement requirement = new Requirement(); if (requirementsJson != null && !requirementsJson.isEmpty()) {
requirement.jsonFile = this.jsonFile; reply.requirements = new ArrayList<Requirement>();
requirement.parent = this; for (Object requirementJsonObj : requirementsJson) {
if (requirementJson.get("requireType") != null) Map requirementJson = (Map) requirementJsonObj;
requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType")); Requirement requirement = new Requirement();
requirement.required_obj_id = (String) requirementJson.get("requireID"); requirement.jsonFile = this.jsonFile;
if (requirementJson.get("value") != null) requirement.parent = this;
requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString())); if (requirementJson.get("requireType") != null) requirement.type = RequirementType.valueOf((String) requirementJson.get("requireType"));
if (requirementJson.get("negate") != null) requirement.required_obj_id = (String) requirementJson.get("requireID");
requirement.negated = (Boolean) requirementJson.get("negate"); if (requirementJson.get("value") != null) requirement.required_value = JSONElement.getInteger(Integer.parseInt(requirementJson.get("value").toString()));
requirement.state = State.parsed; if (requirementJson.get("negate") != null) requirement.negated = (Boolean) requirementJson.get("negate");
reply.requirements.add(requirement); requirement.state = State.parsed;
} reply.requirements.add(requirement);
} }
this.replies.add(reply); }
} this.replies.add(reply);
} }
List rewardsJson = (List) dialogueJson.get("rewards"); }
if (rewardsJson != null && !rewardsJson.isEmpty()) { List rewardsJson = (List) dialogueJson.get("rewards");
this.rewards = new ArrayList<Dialogue.Reward>(); if (rewardsJson != null && !rewardsJson.isEmpty()) {
for (Object rewardJsonObj : rewardsJson) { this.rewards = new ArrayList<Dialogue.Reward>();
Map rewardJson = (Map) rewardJsonObj; for (Object rewardJsonObj : rewardsJson) {
Reward reward = new Reward(); Map rewardJson = (Map)rewardJsonObj;
if (rewardJson.get("rewardType") != null) Reward reward = new Reward();
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) if (rewardJson.get("value") != null) reward.reward_value = JSONElement.getInteger((Number) rewardJson.get("value"));
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
public void link() { @Override
if (shouldSkipParseOrLink()) { public void link() {
return; if (shouldSkipParseOrLink()) {
} return;
ensureParseIfNeeded(); }
Project proj = getProject(); ensureParseIfNeeded();
if (proj == null) { Project proj = getProject();
Notification.addError("Error linking dialogue " + id + ". No parent project found."); if (proj == null) {
return; Notification.addError("Error linking dialogue "+id+". No parent project found.");
} 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); 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);
if (replies != null) {
for (Reply reply : replies) { if (replies != null) {
if (reply.next_phrase_id != null) { for (Reply reply : replies) {
if (!Reply.KEY_PHRASE_ID.contains(reply.next_phrase_id)) { if (reply.next_phrase_id != null) {
reply.next_phrase = proj.getDialogue(reply.next_phrase_id); if (!Reply.KEY_PHRASE_ID.contains(reply.next_phrase_id)) {
} reply.next_phrase = proj.getDialogue(reply.next_phrase_id);
} }
if (reply.next_phrase != null) reply.next_phrase.addBacklink(this); }
if (reply.requirements != null) { if (reply.next_phrase != null) reply.next_phrase.addBacklink(this);
for (Requirement requirement : reply.requirements) { if (reply.requirements != null) {
requirement.link(); for (Requirement requirement : reply.requirements) {
} requirement.link();
} }
} }
} }
if (rewards != null) { }
for (Reward reward : rewards) { if (rewards != null) {
if (reward.reward_obj_id != null) { for (Reward reward : rewards) {
switch (reward.type) { if (reward.reward_obj_id != null) {
case activateMapObjectGroup: switch (reward.type) {
case deactivateMapObjectGroup: case activateMapObjectGroup:
case spawnAll: case deactivateMapObjectGroup:
case removeSpawnArea: case spawnAll:
case deactivateSpawnArea: case removeSpawnArea:
case changeMapFilter: case deactivateSpawnArea:
case mapchange: case changeMapFilter:
reward.map = reward.map_name != null ? proj.getMap(reward.map_name) : null; case mapchange:
break; reward.map = reward.map_name != null ? proj.getMap(reward.map_name) : null;
case actorCondition: break;
case actorConditionImmunity: case actorCondition:
reward.reward_obj = proj.getActorCondition(reward.reward_obj_id); case actorConditionImmunity:
break; reward.reward_obj = proj.getActorCondition(reward.reward_obj_id);
case alignmentChange: break;
case alignmentSet: case alignmentChange:
//Nothing to do (yet ?). case alignmentSet:
break; //Nothing to do (yet ?).
case createTimer: break;
//Nothing to do. case createTimer:
break; //Nothing to do.
case dropList: break;
reward.reward_obj = proj.getDroplist(reward.reward_obj_id); case dropList:
break; reward.reward_obj = proj.getDroplist(reward.reward_obj_id);
case giveItem: break;
reward.reward_obj = proj.getItem(reward.reward_obj_id); case giveItem:
break; reward.reward_obj = proj.getItem(reward.reward_obj_id);
case questProgress: break;
case removeQuestProgress: case questProgress:
reward.reward_obj = proj.getQuest(reward.reward_obj_id); case removeQuestProgress:
if (reward.reward_obj != null && reward.reward_value != null) { reward.reward_obj = proj.getQuest(reward.reward_obj_id);
QuestStage stage = ((Quest) reward.reward_obj).getStage(reward.reward_value); if (reward.reward_obj != null && reward.reward_value != null) {
if (stage != null) { QuestStage stage = ((Quest)reward.reward_obj).getStage(reward.reward_value);
stage.addBacklink(this); if (stage != null) {
} stage.addBacklink(this);
} }
break; }
case skillIncrease: break;
//Nothing to do (yet ?). case skillIncrease:
break; //Nothing to do (yet ?).
} break;
if (reward.reward_obj != null) reward.reward_obj.addBacklink(this); }
if (reward.map != null) reward.map.addBacklink(this); if (reward.reward_obj != null) reward.reward_obj.addBacklink(this);
} if (reward.map != null) reward.map.addBacklink(this);
} }
} }
}
this.state = State.linked;
} this.state = State.linked;
}
@Override
public Image getIcon() {
return DefaultIcons.getDialogueIcon(); @Override
} public Image getIcon() {
return DefaultIcons.getDialogueIcon();
}
public Image getImage() {
return DefaultIcons.getDialogueImage();
} public Image getImage() {
return DefaultIcons.getDialogueImage();
@Override }
public GameDataElement clone() {
Dialogue clone = new Dialogue(); @Override
clone.jsonFile = this.jsonFile; public GameDataElement clone() {
clone.state = this.state; Dialogue clone = new Dialogue();
clone.id = this.id; clone.jsonFile = this.jsonFile;
clone.message = this.message; clone.state = this.state;
clone.switch_to_npc_id = this.switch_to_npc_id; clone.id = this.id;
clone.switch_to_npc = this.switch_to_npc; clone.message = this.message;
if (clone.switch_to_npc != null) { clone.switch_to_npc_id = this.switch_to_npc_id;
clone.switch_to_npc.addBacklink(clone); clone.switch_to_npc = this.switch_to_npc;
} if (clone.switch_to_npc != null) {
if (this.rewards != null) { clone.switch_to_npc.addBacklink(clone);
clone.rewards = new ArrayList<Dialogue.Reward>(); }
for (Reward r : this.rewards) { if (this.rewards != null) {
Reward rclone = new Reward(); clone.rewards = new ArrayList<Dialogue.Reward>();
rclone.type = r.type; for (Reward r : this.rewards) {
rclone.reward_obj_id = r.reward_obj_id; Reward rclone = new Reward();
rclone.reward_value = r.reward_value; rclone.type = r.type;
rclone.reward_obj = r.reward_obj; rclone.reward_obj_id = r.reward_obj_id;
if (rclone.reward_obj != null) { rclone.reward_value = r.reward_value;
rclone.reward_obj.addBacklink(clone); rclone.reward_obj = r.reward_obj;
} if (rclone.reward_obj != null) {
rclone.map = r.map; rclone.reward_obj.addBacklink(clone);
rclone.map_name = r.map_name; }
if (rclone.map != null) { rclone.map = r.map;
rclone.map.addBacklink(clone); rclone.map_name = r.map_name;
} if (rclone.map != null) {
clone.rewards.add(rclone); rclone.map.addBacklink(clone);
} }
} clone.rewards.add(rclone);
if (this.replies != null) { }
clone.replies = new ArrayList<Dialogue.Reply>(); }
for (Reply r : this.replies) { if (this.replies != null) {
Reply rclone = new Reply(); clone.replies = new ArrayList<Dialogue.Reply>();
rclone.text = r.text; for (Reply r : this.replies) {
rclone.next_phrase_id = r.next_phrase_id; Reply rclone = new Reply();
rclone.next_phrase = r.next_phrase; rclone.text = r.text;
if (rclone.next_phrase != null) { rclone.next_phrase_id = r.next_phrase_id;
rclone.next_phrase.addBacklink(clone); rclone.next_phrase = r.next_phrase;
} if (rclone.next_phrase != null) {
if (r.requirements != null) { rclone.next_phrase.addBacklink(clone);
rclone.requirements = new ArrayList<Requirement>(); }
for (Requirement req : r.requirements) { if (r.requirements != null) {
//Special clone method, as Requirement is a special GDE, hidden from the project tree. rclone.requirements = new ArrayList<Requirement>();
rclone.requirements.add((Requirement) req.clone(clone)); for (Requirement req : r.requirements) {
} //Special clone method, as Requirement is a special GDE, hidden from the project tree.
} rclone.requirements.add((Requirement) req.clone(clone));
clone.replies.add(rclone); }
} }
} clone.replies.add(rclone);
return clone; }
} }
return clone;
@Override }
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (switch_to_npc == oldOne) { @Override
oldOne.removeBacklink(this); public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
switch_to_npc = (NPC) newOne; if (switch_to_npc == oldOne) {
if (newOne != null) newOne.addBacklink(this); oldOne.removeBacklink(this);
} else { switch_to_npc = (NPC) newOne;
if (replies != null) { if (newOne != null) newOne.addBacklink(this);
for (Reply r : replies) { } else {
if (r.next_phrase == oldOne) { if (replies != null) {
oldOne.removeBacklink(this); for (Reply r : replies) {
r.next_phrase = (Dialogue) newOne; if (r.next_phrase == oldOne) {
if (newOne != null) newOne.addBacklink(this); oldOne.removeBacklink(this);
} r.next_phrase = (Dialogue) newOne;
if (r.requirements != null) { if (newOne != null) newOne.addBacklink(this);
for (Requirement req : r.requirements) { }
req.elementChanged(oldOne, newOne); if (r.requirements != null) {
} for (Requirement req : r.requirements) {
} req.elementChanged(oldOne, newOne);
} }
} }
if (rewards != null) { }
for (Reward r : rewards) { }
if (r.reward_obj == oldOne) { if (rewards != null) {
oldOne.removeBacklink(this); for (Reward r : rewards) {
r.reward_obj = newOne; if (r.reward_obj == oldOne) {
if (newOne != null) newOne.addBacklink(this); oldOne.removeBacklink(this);
} r.reward_obj = newOne;
if (oldOne instanceof QuestStage) { if (newOne != null) newOne.addBacklink(this);
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 (oldOne instanceof QuestStage) {
if (newOne != null) newOne.addBacklink((GameDataElement) this); 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() { @SuppressWarnings({ "rawtypes", "unchecked" })
Map dialogueJson = new LinkedHashMap(); @Override
dialogueJson.put("id", this.id); public Map toJson() {
if (this.message != null) dialogueJson.put("message", this.message); Map dialogueJson = new LinkedHashMap();
if (this.switch_to_npc != null) { dialogueJson.put("id", this.id);
dialogueJson.put("switchToNPC", this.switch_to_npc.id); if (this.message != null) dialogueJson.put("message", this.message);
} else if (this.switch_to_npc_id != null) { if (this.switch_to_npc != null) {
dialogueJson.put("switchToNPC", this.switch_to_npc_id); dialogueJson.put("switchToNPC", this.switch_to_npc.id);
} } else if (this.switch_to_npc_id != null) {
if (this.replies != null) { dialogueJson.put("switchToNPC", this.switch_to_npc_id);
List repliesJson = new ArrayList(); }
dialogueJson.put("replies", repliesJson); if (this.replies != null) {
for (Reply reply : this.replies) { List repliesJson = new ArrayList();
Map replyJson = new LinkedHashMap(); dialogueJson.put("replies", repliesJson);
repliesJson.add(replyJson); for (Reply reply : this.replies){
if (reply.text != null) replyJson.put("text", reply.text); Map replyJson = new LinkedHashMap();
if (reply.next_phrase != null) { repliesJson.add(replyJson);
replyJson.put("nextPhraseID", reply.next_phrase.id); if (reply.text != null) replyJson.put("text", reply.text);
} else if (reply.next_phrase_id != null) { if (reply.next_phrase != null) {
replyJson.put("nextPhraseID", reply.next_phrase_id); replyJson.put("nextPhraseID", reply.next_phrase.id);
} } else if (reply.next_phrase_id != null) {
if (reply.requirements != null) { replyJson.put("nextPhraseID", reply.next_phrase_id);
List requirementsJson = new ArrayList(); }
replyJson.put("requires", requirementsJson); if (reply.requirements != null) {
for (Requirement requirement : reply.requirements) { List requirementsJson = new ArrayList();
Map requirementJson = new LinkedHashMap(); replyJson.put("requires", requirementsJson);
requirementsJson.add(requirementJson); for (Requirement requirement : reply.requirements) {
if (requirement.type != null) requirementJson.put("requireType", requirement.type.toString()); Map requirementJson = new LinkedHashMap();
if (requirement.required_obj != null) { requirementsJson.add(requirementJson);
requirementJson.put("requireID", requirement.required_obj.id); if (requirement.type != null) requirementJson.put("requireType", requirement.type.toString());
} else if (requirement.required_obj_id != null) { if (requirement.required_obj != null) {
requirementJson.put("requireID", requirement.required_obj_id); requirementJson.put("requireID", requirement.required_obj.id);
} } else if (requirement.required_obj_id != null) {
if (requirement.required_value != null) { requirementJson.put("requireID", requirement.required_obj_id);
requirementJson.put("value", requirement.required_value); }
} if (requirement.required_value != null) {
if (requirement.negated != null) requirementJson.put("negate", requirement.negated); requirementJson.put("value", requirement.required_value);
} }
} if (requirement.negated != null) requirementJson.put("negate", requirement.negated);
} }
} }
if (this.rewards != null) { }
List rewardsJson = new ArrayList(); }
dialogueJson.put("rewards", rewardsJson); if (this.rewards != null) {
for (Reward reward : this.rewards) { List rewardsJson = new ArrayList();
Map rewardJson = new LinkedHashMap(); dialogueJson.put("rewards", rewardsJson);
rewardsJson.add(rewardJson); for (Reward reward : this.rewards) {
if (reward.type != null) rewardJson.put("rewardType", reward.type.toString()); Map rewardJson = new LinkedHashMap();
if (reward.reward_obj != null) { rewardsJson.add(rewardJson);
rewardJson.put("rewardID", reward.reward_obj.id); if (reward.type != null) rewardJson.put("rewardType", reward.type.toString());
} else if (reward.reward_obj_id != null) { if (reward.reward_obj != null) {
rewardJson.put("rewardID", reward.reward_obj_id); rewardJson.put("rewardID", reward.reward_obj.id);
} } else if (reward.reward_obj_id != null) {
if (reward.reward_value != null) rewardJson.put("value", reward.reward_value); rewardJson.put("rewardID", reward.reward_obj_id);
if (reward.map != null) { }
rewardJson.put("mapName", reward.map.id); if (reward.reward_value != null) rewardJson.put("value", reward.reward_value);
} else if (reward.map_name != null) rewardJson.put("mapName", reward.map_name); if (reward.map != null) {
} rewardJson.put("mapName", reward.map.id);
} } else if (reward.map_name != null) rewardJson.put("mapName", reward.map_name);
return dialogueJson; }
} }
return dialogueJson;
@Override }
public String getProjectFilename() {
return "conversationlist_" + getProject().name + ".json"; @Override
} public String getProjectFilename() {
return "conversationlist_"+getProject().name+".json";
} }
}

View File

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

View File

@@ -1,236 +1,253 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import org.json.simple.JSONArray;
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.*; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONArray;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.*;
public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implements ProjectTreeNode, Serializable { public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = 5486008219704443733L; private static final long serialVersionUID = 5486008219704443733L;
public GameDataSet parent;
public String name;
public GameDataCategory(GameDataSet parent, String name) {
super();
this.parent = parent;
this.name = name;
}
public GameDataSet parent; @Override
public String name; public TreeNode getChildAt(int childIndex) {
return get(childIndex);
}
public GameDataCategory(GameDataSet parent, String name) { @Override
super(); public int getChildCount() {
this.parent = parent; return size();
this.name = name; }
}
@Override @Override
public TreeNode getChildAt(int childIndex) { public TreeNode getParent() {
return get(childIndex); return parent;
} }
@Override @Override
public int getChildCount() { public int getIndex(TreeNode node) {
return size(); return indexOf(node);
} }
@Override @Override
public TreeNode getParent() { public boolean getAllowsChildren() {
return parent; return true;
} }
@Override @Override
public int getIndex(TreeNode node) { public boolean isLeaf() {
return indexOf(node); return false;
} }
@Override @Override
public boolean getAllowsChildren() { public Enumeration<E> children() {
return true; return Collections.enumeration(this);
} }
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (E node : this) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+this.name;
}
@Override @Override
public boolean isLeaf() { public boolean equals(Object o) {
return false; return (o == this);
} }
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getJsonOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return parent.getDataSet();
}
@Override @Override
public Enumeration<E> children() { public Type getDataType() {
return Collections.enumeration(this); return parent.getDataType();
} }
@SuppressWarnings("rawtypes")
public void save(File jsonFile) {
if (getDataType() != GameSource.Type.created && getDataType() != GameSource.Type.altered) {
Notification.addError("Error while trying to write json file "+jsonFile.getAbsolutePath()+" : Game Source type "+getDataType().toString()+" should not be saved.");
return;
}
List<Map> dataToSave = new ArrayList<Map>();
for (E element : this) {
if (element.jsonFile.equals(jsonFile)) {
dataToSave.add(element.toJson());
}
}
if (dataToSave.isEmpty() && jsonFile.exists()) {
if (jsonFile.delete()) {
Notification.addSuccess("File "+jsonFile.getAbsolutePath()+" deleted.");
} else {
Notification.addError("Error deleting file "+jsonFile.getAbsolutePath());
}
return;
}
StringWriter writer = new JsonPrettyWriter();
try {
JSONArray.writeJSONString(dataToSave, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(jsonFile);
w.write(toWrite);
w.close();
for (E element : this) {
element.state = GameDataElement.State.saved;
}
Notification.addSuccess("Json file "+jsonFile.getAbsolutePath()+" saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file "+jsonFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
}
}
@Override public List<SaveEvent> attemptSave(boolean checkImpactedCategory, String fileName) {
public void childrenAdded(List<ProjectTreeNode> path) { List<SaveEvent> events = new ArrayList<SaveEvent>();
path.add(0, this); GameDataCategory<? extends JSONElement> impactedCategory = null;
parent.childrenAdded(path); String impactedFileName = fileName;
} Map<String, Integer> containedIds = new LinkedHashMap<String, Integer>();
for (JSONElement node : this) {
@Override if (node.getDataType() == GameSource.Type.created && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
public void childrenChanged(List<ProjectTreeNode> path) { if (getProject().alteredContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
path.add(0, this); events.add(new SaveEvent(SaveEvent.Type.moveToAltered, node, true, "Element ID matches one already present in the altered game content. Change this ID before saving."));
parent.childrenChanged(path); } else {
} events.add(new SaveEvent(SaveEvent.Type.moveToAltered, node));
impactedFileName = getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id).jsonFile.getName();
@Override impactedCategory = getProject().alteredContent.gameData.getCategory(node.getClass());
public void childrenRemoved(List<ProjectTreeNode> path) { }
if (path.size() == 1 && this.getChildCount() == 1) { } else if (this.getDataType() == GameSource.Type.altered && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) == null) {
childrenRemoved(new ArrayList<ProjectTreeNode>()); if (getProject().createdContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
} else { events.add(new SaveEvent(SaveEvent.Type.moveToCreated, node, true, "Element ID matches one already present in the created game content. Change this ID before saving."));
path.add(0, this); } else {
parent.childrenRemoved(path); events.add(new SaveEvent(SaveEvent.Type.moveToCreated, node));
} impactedCategory = getProject().createdContent.gameData.getCategory(node.getClass());
} impactedFileName = node.getProjectFilename();
}
@Override } else if (node.needsSaving()) {
public void notifyCreated() { events.add(new SaveEvent(SaveEvent.Type.alsoSave, node));
childrenAdded(new ArrayList<ProjectTreeNode>()); }
for (E node : this) { if (containedIds.containsKey(node.id)) {
node.notifyCreated(); containedIds.put(node.id, containedIds.get(node.id) + 1);
} } else {
} containedIds.put(node.id, 1);
}
@Override }
public String getDesc() { for (String key : containedIds.keySet()) {
return (needsSaving() ? "*" : "") + this.name; if (containedIds.get(key) > 1) {
} E node = null;
for (E n : this) {
@Override if (key.equals(n.id)) {
public boolean equals(Object o) { node = n;
return (o == this); break;
} }
}
@Override events.add(new SaveEvent(SaveEvent.Type.alsoSave, node, true, "There are "+containedIds.get(node.id)+" elements with this ID in this category. Change the conflicting IDs before saving."));
public Project getProject() { }
return parent.getProject(); }
} if (checkImpactedCategory && impactedCategory != null) {
events.addAll(impactedCategory.attemptSave(false, impactedFileName));
@Override }
public Image getIcon() { return events;
return getOpenIcon(); }
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getJsonOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return parent.getDataSet();
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@SuppressWarnings("rawtypes")
public void save(File jsonFile) {
if (getDataType() != GameSource.Type.created && getDataType() != GameSource.Type.altered) {
Notification.addError("Error while trying to write json file " + jsonFile.getAbsolutePath() + " : Game Source type " + getDataType().toString() + " should not be saved.");
return;
}
List<Map> dataToSave = new ArrayList<Map>();
for (E element : this) {
if (element.jsonFile.equals(jsonFile)) {
dataToSave.add(element.toJson());
}
}
if (dataToSave.isEmpty() && jsonFile.exists()) {
if (jsonFile.delete()) {
Notification.addSuccess("File " + jsonFile.getAbsolutePath() + " deleted.");
} else {
Notification.addError("Error deleting file " + jsonFile.getAbsolutePath());
}
return;
}
String toWrite = FileUtils.toJsonString(dataToSave);
if(FileUtils.writeStringToFile(toWrite, jsonFile, "JSON file '"+jsonFile.getAbsolutePath()+"'")){
for (E element : this) {
element.state = GameDataElement.State.saved;
}
}
}
public List<SaveEvent> attemptSave(boolean checkImpactedCategory, String fileName) {
List<SaveEvent> events = new ArrayList<SaveEvent>();
GameDataCategory<? extends JSONElement> impactedCategory = null;
String impactedFileName = fileName;
Map<String, Integer> containedIds = new LinkedHashMap<String, Integer>();
for (JSONElement node : this) {
if (node.getDataType() == GameSource.Type.created && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
if (getProject().alteredContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
events.add(new SaveEvent(SaveEvent.Type.moveToAltered, node, true, "Element ID matches one already present in the altered game content. Change this ID before saving."));
} else {
events.add(new SaveEvent(SaveEvent.Type.moveToAltered, node));
impactedFileName = getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id).jsonFile.getName();
impactedCategory = getProject().alteredContent.gameData.getCategory(node.getClass());
}
} else if (this.getDataType() == GameSource.Type.altered && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) == null) {
if (getProject().createdContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
events.add(new SaveEvent(SaveEvent.Type.moveToCreated, node, true, "Element ID matches one already present in the created game content. Change this ID before saving."));
} else {
events.add(new SaveEvent(SaveEvent.Type.moveToCreated, node));
impactedCategory = getProject().createdContent.gameData.getCategory(node.getClass());
impactedFileName = node.getProjectFilename();
}
} else if (node.needsSaving()) {
events.add(new SaveEvent(SaveEvent.Type.alsoSave, node));
}
if (containedIds.containsKey(node.id)) {
containedIds.put(node.id, containedIds.get(node.id) + 1);
} else {
containedIds.put(node.id, 1);
}
}
for (String key : containedIds.keySet()) {
if (containedIds.get(key) > 1) {
E node = null;
for (E n : this) {
if (key.equals(n.id)) {
node = n;
break;
}
}
events.add(new SaveEvent(SaveEvent.Type.alsoSave, node, true,
"There are " + containedIds.get(node.id) + " elements with this ID in this category. Change the conflicting IDs before saving."));
}
}
if (checkImpactedCategory && impactedCategory != null) {
events.addAll(impactedCategory.attemptSave(false, impactedFileName));
}
return events;
}
public boolean remove(E o) {
int index = getProject().getNodeIndex(o);
boolean result = super.remove(o);
getProject().fireElementRemoved(o, index);
return result;
}
@Override
public boolean needsSaving() {
for (E node : this) {
if (node.needsSaving()) return true;
}
return false;
}
public boolean remove(E o) {
int index = getProject().getNodeIndex(o);
boolean result = super.remove(o);
getProject().fireElementRemoved(o, index);
return result;
}
@Override
public boolean needsSaving() {
for (E node : this) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,5 +1,14 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
@@ -9,479 +18,456 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SavedSlotCollection; import com.gpl.rpg.atcontentstudio.model.SavedSlotCollection;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class GameDataSet implements ProjectTreeNode, Serializable { public class GameDataSet implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = -8558067213826970968L; private static final long serialVersionUID = -8558067213826970968L;
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res"+File.separator+"raw"+File.separator;
public static final String DEFAULT_REL_PATH_IN_PROJECT = "json"+File.separator;
public static final String GAME_AC_ARRAY_NAME = "loadresource_actorconditions";
public static final String GAME_DIALOGUES_ARRAY_NAME = "loadresource_conversationlists";
public static final String GAME_DROPLISTS_ARRAY_NAME = "loadresource_droplists";
public static final String GAME_ITEMS_ARRAY_NAME = "loadresource_items";
public static final String GAME_ITEMCAT_ARRAY_NAME = "loadresource_itemcategories";
public static final String GAME_NPC_ARRAY_NAME = "loadresource_monsters";
public static final String GAME_QUESTS_ARRAY_NAME = "loadresource_quests";
public static final String DEBUG_SUFFIX = "_debug";
public static final String RESOURCE_PREFIX = "@raw/";
public static final String FILENAME_SUFFIX = ".json";
public File baseFolder;
public GameDataCategory<ActorCondition> actorConditions;
public GameDataCategory<Dialogue> dialogues;
public GameDataCategory<Droplist> droplists;
public GameDataCategory<Item> items;
public GameDataCategory<ItemCategory> itemCategories;
public GameDataCategory<NPC> npcs;
public GameDataCategory<Quest> quests;
public GameSource parent;
public SavedSlotCollection v;
public GameDataSet(GameSource source) {
this.parent = source;
v = new SavedSlotCollection();
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res" + File.separator + "raw" + File.separator; if (parent.type.equals(GameSource.Type.altered) || parent.type.equals(GameSource.Type.created)) {
public static final String DEFAULT_REL_PATH_IN_PROJECT = "json" + File.separator; this.baseFolder = new File(parent.baseFolder, GameDataSet.DEFAULT_REL_PATH_IN_PROJECT);
if (!baseFolder.exists()) this.baseFolder.mkdirs();
} else if (parent.type.equals(GameSource.Type.source)) {
this.baseFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
}
actorConditions = new GameDataCategory<ActorCondition>(this, ActorCondition.getStaticDesc());
dialogues = new GameDataCategory<Dialogue>(this, Dialogue.getStaticDesc());
droplists = new GameDataCategory<Droplist>(this, Droplist.getStaticDesc());
items = new GameDataCategory<Item>(this, Item.getStaticDesc());
itemCategories = new GameDataCategory<ItemCategory>(this, ItemCategory.getStaticDesc());
npcs = new GameDataCategory<NPC>(this, NPC.getStaticDesc());
quests = new GameDataCategory<Quest>(this, Quest.getStaticDesc());
v.add(actorConditions);
v.add(dialogues);
v.add(droplists);
v.add(items);
v.add(itemCategories);
v.add(npcs);
v.add(quests);
//Start parsing to populate categories' content.
if (parent.type == GameSource.Type.source && (parent.parent.sourceSetToUse == ResourceSet.debugData || parent.parent.sourceSetToUse == ResourceSet.gameData)) {
String suffix = (parent.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : "";
if (parent.referencedSourceFiles.get(GAME_AC_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_AC_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
ActorCondition.fromJson(f, actorConditions);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_DIALOGUES_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_DIALOGUES_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Dialogue.fromJson(f, dialogues);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_DROPLISTS_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_DROPLISTS_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Droplist.fromJson(f, droplists);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_ITEMS_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_ITEMS_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Item.fromJson(f, items);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_ITEMCAT_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_ITEMCAT_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
ItemCategory.fromJson(f, itemCategories);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_NPC_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_NPC_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
NPC.fromJson(f, npcs);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_QUESTS_ARRAY_NAME+suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_QUESTS_ARRAY_NAME+suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
Quest.fromJson(f, quests);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
} else if (parent.type != GameSource.Type.referenced) {
for (File f : baseFolder.listFiles()) {
if (f.getName().startsWith("actorconditions_")) {
ActorCondition.fromJson(f, actorConditions);
} else if (f.getName().startsWith("conversationlist_")) {
Dialogue.fromJson(f, dialogues);
} else if (f.getName().startsWith("droplists_")) {
Droplist.fromJson(f, droplists);
} else if (f.getName().startsWith("itemlist_")) {
Item.fromJson(f, items);
} else if (f.getName().startsWith("itemcategories_")) {
ItemCategory.fromJson(f, itemCategories);
} else if (f.getName().startsWith("monsterlist_")) {
NPC.fromJson(f, npcs);
} else if (f.getName().startsWith("questlist")) {
Quest.fromJson(f, quests);
}
}
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements();
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return v.getNonEmptyElementAt(arg0);
}
@Override
public int getChildCount() {
return v.getNonEmptySize();
}
@Override
public int getIndex(TreeNode arg0) {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+"JSON data";
}
public static final String GAME_AC_ARRAY_NAME = "loadresource_actorconditions"; public void refreshTransients() {
public static final String GAME_DIALOGUES_ARRAY_NAME = "loadresource_conversationlists";
public static final String GAME_DROPLISTS_ARRAY_NAME = "loadresource_droplists"; }
public static final String GAME_ITEMS_ARRAY_NAME = "loadresource_items";
public static final String GAME_ITEMCAT_ARRAY_NAME = "loadresource_itemcategories"; public ActorCondition getActorCondition(String id) {
public static final String GAME_NPC_ARRAY_NAME = "loadresource_monsters"; if (actorConditions == null) return null;
public static final String GAME_QUESTS_ARRAY_NAME = "loadresource_quests"; for (ActorCondition gde : actorConditions) {
public static final String DEBUG_SUFFIX = "_debug"; if (id.equals(gde.id)){
public static final String RESOURCE_PREFIX = "@raw/"; return gde;
public static final String FILENAME_SUFFIX = ".json"; }
}
return null;
}
public Dialogue getDialogue(String id) {
if (dialogues == null) return null;
for (Dialogue gde : dialogues) {
if (id.equals(gde.id)){
return gde;
}
}
return null;
}
public Droplist getDroplist(String id) {
if (droplists == null) return null;
for (Droplist gde : droplists) {
if (id.equals(gde.id)){
return gde;
}
}
return null;
}
public Item getItem(String id) {
if (items == null) return null;
for (Item gde : items) {
if (id.equals(gde.id)){
return gde;
}
}
return null;
}
public ItemCategory getItemCategory(String id) {
if (itemCategories == null) return null;
for (ItemCategory gde : itemCategories) {
if (id.equals(gde.id)){
return gde;
}
}
return null;
}
public NPC getNPC(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equals(gde.id)){
return gde;
}
}
return null;
}
public NPC getNPCIgnoreCase(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equalsIgnoreCase(gde.id)){
return gde;
}
}
return null;
}
public Quest getQuest(String id) {
if (quests == null) return null;
for (Quest gde : quests) {
if (id.equals(gde.id)){
return gde;
}
}
return null;
}
@Override
public Project getProject() {
return parent.getProject();
}
public File baseFolder; @Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getJsonOpenIcon();
}
public GameDataCategory<ActorCondition> actorConditions; public void addElement(JSONElement node) {
public GameDataCategory<Dialogue> dialogues; ProjectTreeNode higherEmptyParent = this;
public GameDataCategory<Droplist> droplists; while (higherEmptyParent != null) {
public GameDataCategory<Item> items; if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
public GameDataCategory<ItemCategory> itemCategories; else break;
public GameDataCategory<NPC> npcs; }
public GameDataCategory<Quest> quests; if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
if (node instanceof ActorCondition) {
if (actorConditions.isEmpty() && higherEmptyParent == null) higherEmptyParent = actorConditions;
actorConditions.add((ActorCondition) node);
node.parent = actorConditions;
} else if (node instanceof Dialogue) {
if (dialogues.isEmpty() && higherEmptyParent == null) higherEmptyParent = dialogues;
dialogues.add((Dialogue) node);
node.parent = dialogues;
} else if (node instanceof Droplist) {
if (droplists.isEmpty() && higherEmptyParent == null) higherEmptyParent = droplists;
droplists.add((Droplist) node);
node.parent = droplists;
} else if (node instanceof Item) {
if (items.isEmpty() && higherEmptyParent == null) higherEmptyParent = items;
items.add((Item) node);
node.parent = items;
} else if (node instanceof ItemCategory) {
if (itemCategories.isEmpty() && higherEmptyParent == null) higherEmptyParent = itemCategories;
itemCategories.add((ItemCategory) node);
node.parent = itemCategories;
} else if (node instanceof NPC) {
if (npcs.isEmpty() && higherEmptyParent == null) higherEmptyParent = npcs;
npcs.add((NPC) node);
node.parent = npcs;
} else if (node instanceof Quest) {
if (quests.isEmpty() && higherEmptyParent == null) higherEmptyParent = quests;
quests.add((Quest) node);
node.parent = quests;
} else {
Notification.addError("Cannot add "+node.getDesc()+". Unknown data type.");
return;
}
if (node.jsonFile != null && parent.type == GameSource.Type.altered) {
//Altered node.
node.jsonFile = new File(this.baseFolder, node.jsonFile.getName());
} else {
//Created node.
node.jsonFile = new File(this.baseFolder, node.getProjectFilename());
}
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
public GameSource parent; @Override
public SavedSlotCollection v; public GameDataSet getDataSet() {
return this;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return v.isEmpty();
}
public GameDataSet(GameSource source) { public JSONElement getGameDataElement(Class<? extends JSONElement> gdeClass, String id) {
if (gdeClass == ActorCondition.class) {
return getActorCondition(id);
}
if (gdeClass == Dialogue.class) {
return getDialogue(id);
}
if (gdeClass == Droplist.class) {
return getDroplist(id);
}
if (gdeClass == ItemCategory.class) {
return getItemCategory(id);
}
if (gdeClass == Item.class) {
return getItem(id);
}
if (gdeClass == NPC.class) {
return getNPC(id);
}
if (gdeClass == Quest.class) {
return getQuest(id);
}
return null;
}
this.parent = source; public GameDataCategory<? extends JSONElement> getCategory(Class<? extends JSONElement> gdeClass) {
v = new SavedSlotCollection(); if (gdeClass == ActorCondition.class) {
return actorConditions;
if (parent.type.equals(GameSource.Type.altered) || parent.type.equals(GameSource.Type.created)) { }
this.baseFolder = new File(parent.baseFolder, GameDataSet.DEFAULT_REL_PATH_IN_PROJECT); if (gdeClass == Dialogue.class) {
if (!baseFolder.exists()) this.baseFolder.mkdirs(); return dialogues;
} else if (parent.type.equals(GameSource.Type.source)) { }
this.baseFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE); if (gdeClass == Droplist.class) {
} return droplists;
}
actorConditions = new GameDataCategory<ActorCondition>(this, ActorCondition.getStaticDesc()); if (gdeClass == ItemCategory.class) {
dialogues = new GameDataCategory<Dialogue>(this, Dialogue.getStaticDesc()); return itemCategories;
droplists = new GameDataCategory<Droplist>(this, Droplist.getStaticDesc()); }
items = new GameDataCategory<Item>(this, Item.getStaticDesc()); if (gdeClass == Item.class) {
itemCategories = new GameDataCategory<ItemCategory>(this, ItemCategory.getStaticDesc()); return items;
npcs = new GameDataCategory<NPC>(this, NPC.getStaticDesc()); }
quests = new GameDataCategory<Quest>(this, Quest.getStaticDesc()); if (gdeClass == NPC.class) {
return npcs;
v.add(actorConditions); }
v.add(dialogues); if (gdeClass == Quest.class) {
v.add(droplists); return quests;
v.add(items); }
v.add(itemCategories); return null;
v.add(npcs); }
v.add(quests);
@Override
//Start parsing to populate categories' content. public boolean needsSaving() {
if (parent.type == GameSource.Type.source && (parent.parent.sourceSetToUse == ResourceSet.debugData || parent.parent.sourceSetToUse == ResourceSet.gameData)) { for (ProjectTreeNode node : v.getNonEmptyIterable()) {
String suffix = (parent.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : ""; if (node.needsSaving()) return true;
}
if (parent.referencedSourceFiles.get(GAME_AC_ARRAY_NAME + suffix) != null) { return false;
for (String resource : parent.referencedSourceFiles.get(GAME_AC_ARRAY_NAME + suffix)) { }
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
ActorCondition.fromJson(f, actorConditions);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_DIALOGUES_ARRAY_NAME + suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_DIALOGUES_ARRAY_NAME + suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
Dialogue.fromJson(f, dialogues);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_DROPLISTS_ARRAY_NAME + suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_DROPLISTS_ARRAY_NAME + suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
Droplist.fromJson(f, droplists);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_ITEMS_ARRAY_NAME + suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_ITEMS_ARRAY_NAME + suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
Item.fromJson(f, items);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_ITEMCAT_ARRAY_NAME + suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_ITEMCAT_ARRAY_NAME + suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
ItemCategory.fromJson(f, itemCategories);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_NPC_ARRAY_NAME + suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_NPC_ARRAY_NAME + suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
NPC.fromJson(f, npcs);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
if (parent.referencedSourceFiles.get(GAME_QUESTS_ARRAY_NAME + suffix) != null) {
for (String resource : parent.referencedSourceFiles.get(GAME_QUESTS_ARRAY_NAME + suffix)) {
File f = new File(baseFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX);
if (f.exists()) {
Quest.fromJson(f, quests);
} else {
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name);
}
}
}
} else if (parent.type != GameSource.Type.referenced) {
for (File f : baseFolder.listFiles()) {
if (f.getName().startsWith("actorconditions_")) {
ActorCondition.fromJson(f, actorConditions);
} else if (f.getName().startsWith("conversationlist_")) {
Dialogue.fromJson(f, dialogues);
} else if (f.getName().startsWith("droplists_")) {
Droplist.fromJson(f, droplists);
} else if (f.getName().startsWith("itemlist_")) {
Item.fromJson(f, items);
} else if (f.getName().startsWith("itemcategories_")) {
ItemCategory.fromJson(f, itemCategories);
} else if (f.getName().startsWith("monsterlist_")) {
NPC.fromJson(f, npcs);
} else if (f.getName().startsWith("questlist")) {
Quest.fromJson(f, quests);
}
}
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements();
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return v.getNonEmptyElementAt(arg0);
}
@Override
public int getChildCount() {
return v.getNonEmptySize();
}
@Override
public int getIndex(TreeNode arg0) {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + "JSON data";
}
public void refreshTransients() {
}
public ActorCondition getActorCondition(String id) {
if (actorConditions == null) return null;
for (ActorCondition gde : actorConditions) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
public Dialogue getDialogue(String id) {
if (dialogues == null) return null;
for (Dialogue gde : dialogues) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
public Droplist getDroplist(String id) {
if (droplists == null) return null;
for (Droplist gde : droplists) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
public Item getItem(String id) {
if (items == null) return null;
for (Item gde : items) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
public ItemCategory getItemCategory(String id) {
if (itemCategories == null) return null;
for (ItemCategory gde : itemCategories) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
public NPC getNPC(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
public NPC getNPCIgnoreCase(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equalsIgnoreCase(gde.id)) {
return gde;
}
}
return null;
}
public Quest getQuest(String id) {
if (quests == null) return null;
for (Quest gde : quests) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getJsonClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getJsonOpenIcon();
}
public void addElement(JSONElement node) {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode) higherEmptyParent.getParent()).isEmpty())
higherEmptyParent = (ProjectTreeNode) higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
if (node instanceof ActorCondition) {
if (actorConditions.isEmpty() && higherEmptyParent == null) higherEmptyParent = actorConditions;
actorConditions.add((ActorCondition) node);
node.parent = actorConditions;
} else if (node instanceof Dialogue) {
if (dialogues.isEmpty() && higherEmptyParent == null) higherEmptyParent = dialogues;
dialogues.add((Dialogue) node);
node.parent = dialogues;
} else if (node instanceof Droplist) {
if (droplists.isEmpty() && higherEmptyParent == null) higherEmptyParent = droplists;
droplists.add((Droplist) node);
node.parent = droplists;
} else if (node instanceof Item) {
if (items.isEmpty() && higherEmptyParent == null) higherEmptyParent = items;
items.add((Item) node);
node.parent = items;
} else if (node instanceof ItemCategory) {
if (itemCategories.isEmpty() && higherEmptyParent == null) higherEmptyParent = itemCategories;
itemCategories.add((ItemCategory) node);
node.parent = itemCategories;
} else if (node instanceof NPC) {
if (npcs.isEmpty() && higherEmptyParent == null) higherEmptyParent = npcs;
npcs.add((NPC) node);
node.parent = npcs;
} else if (node instanceof Quest) {
if (quests.isEmpty() && higherEmptyParent == null) higherEmptyParent = quests;
quests.add((Quest) node);
node.parent = quests;
} else {
Notification.addError("Cannot add " + node.getDesc() + ". Unknown data type.");
return;
}
if (node.jsonFile != null && parent.type == GameSource.Type.altered) {
//Altered node.
node.jsonFile = new File(this.baseFolder, node.jsonFile.getName());
} else {
//Created node.
node.jsonFile = new File(this.baseFolder, node.getProjectFilename());
}
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
@Override
public GameDataSet getDataSet() {
return this;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return v.isEmpty();
}
public JSONElement getGameDataElement(Class<? extends JSONElement> gdeClass, String id) {
if (gdeClass == ActorCondition.class) {
return getActorCondition(id);
}
if (gdeClass == Dialogue.class) {
return getDialogue(id);
}
if (gdeClass == Droplist.class) {
return getDroplist(id);
}
if (gdeClass == ItemCategory.class) {
return getItemCategory(id);
}
if (gdeClass == Item.class) {
return getItem(id);
}
if (gdeClass == NPC.class) {
return getNPC(id);
}
if (gdeClass == Quest.class) {
return getQuest(id);
}
return null;
}
public GameDataCategory<? extends JSONElement> getCategory(Class<? extends JSONElement> gdeClass) {
if (gdeClass == ActorCondition.class) {
return actorConditions;
}
if (gdeClass == Dialogue.class) {
return dialogues;
}
if (gdeClass == Droplist.class) {
return droplists;
}
if (gdeClass == ItemCategory.class) {
return itemCategories;
}
if (gdeClass == Item.class) {
return items;
}
if (gdeClass == NPC.class) {
return npcs;
}
if (gdeClass == Quest.class) {
return quests;
}
return null;
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
if (node.needsSaving()) return true;
}
return false;
}
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -1,62 +1,64 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.json.simple.parser.JSONParser;
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 org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static com.gpl.rpg.atcontentstudio.model.gamedata.Common.*; import static com.gpl.rpg.atcontentstudio.model.gamedata.Common.*;
public class NPC extends JSONElement { public class NPC extends JSONElement {
private static final long serialVersionUID = 1093728879485491933L; private static final long serialVersionUID = 1093728879485491933L;
//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 String icon_id = null; public String icon_id = null;
//Available from parsed state //Available from parsed state
public Integer max_hp = null; public Integer max_hp = null;
public Integer max_ap = null; public Integer max_ap = null;
public Integer move_cost = null; public Integer move_cost = null;
public Integer unique = null; public Integer unique = null;
public MonsterClass monster_class = null; public MonsterClass monster_class = null;
public MovementType movement_type = null; public MovementType movement_type = null;
public Integer attack_damage_max = null; public Integer attack_damage_max = null;
public Integer attack_damage_min = null; public Integer attack_damage_min = null;
public String spawngroup_id = null; public String spawngroup_id = null;
public String faction_id = null; public String faction_id = null;
public String dialogue_id = null; public String dialogue_id = null;
public String droplist_id = null; public String droplist_id = null;
public Integer attack_cost = null; public Integer attack_cost = null;
public Integer attack_chance = null; public Integer attack_chance = null;
public Integer critical_skill = null; public Integer critical_skill = null;
public Double critical_multiplier = null; public Double critical_multiplier = null;
public Integer block_chance = null; public Integer block_chance = null;
public Integer damage_resistance = null; public Integer damage_resistance = null;
public HitEffect hit_effect = null; public HitEffect hit_effect = null;
public HitReceivedEffect hit_received_effect = null; public HitReceivedEffect hit_received_effect = null;
public DeathEffect death_effect = null; public DeathEffect death_effect = null;
//Available from linked state //Available from linked state
public Dialogue dialogue = null; public Dialogue dialogue = null;
public Droplist droplist = null; public Droplist droplist = null;
public enum MonsterClass { public enum MonsterClass {
humanoid, humanoid,
insect, insect,
demon, demon,
construct, construct,
animal, animal,
@@ -64,296 +66,501 @@ public class NPC extends JSONElement {
undead, undead,
reptile, reptile,
ghost ghost
} }
public enum MovementType { public enum MovementType {
none, none,
helpOthers, helpOthers,
protectSpawn, protectSpawn,
wholeMap wholeMap
} }
@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 "NPCs"; return "NPCs";
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<NPC> category) { public static void fromJson(File jsonFile, GameDataCategory<NPC> 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 npcs = (List) parser.parse(reader); List npcs = (List) parser.parse(reader);
for (Object obj : npcs) { for (Object obj : npcs) {
Map npcJson = (Map) obj; Map npcJson = (Map)obj;
NPC npc = fromJson(npcJson); NPC npc = fromJson(npcJson);
npc.jsonFile = jsonFile; npc.jsonFile = jsonFile;
npc.parent = category; npc.parent = category;
if (npc.getDataType() == GameSource.Type.created || npc.getDataType() == GameSource.Type.altered) { if (npc.getDataType() == GameSource.Type.created || npc.getDataType() == GameSource.Type.altered) {
npc.writable = true; npc.writable = true;
} }
category.add(npc); category.add(npc);
} }
} 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 NPC fromJson(String jsonString) throws ParseException { public static NPC fromJson(String jsonString) throws ParseException {
Map npcJson = (Map) new JSONParser().parse(jsonString); Map npcJson = (Map) new JSONParser().parse(jsonString);
NPC npc = fromJson(npcJson); NPC npc = fromJson(npcJson);
npc.parse(npcJson); npc.parse(npcJson);
return npc; return npc;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static NPC fromJson(Map npcJson) { public static NPC fromJson(Map npcJson) {
NPC npc = new NPC(); NPC npc = new NPC();
npc.icon_id = (String) npcJson.get("iconID"); npc.icon_id = (String) npcJson.get("iconID");
npc.id = (String) npcJson.get("id"); npc.id = (String) npcJson.get("id");
npc.name = (String) npcJson.get("name"); npc.name = (String) npcJson.get("name");
return npc; return npc;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public void parse(Map npcJson) { public void parse(Map npcJson) {
this.max_hp = JSONElement.getInteger((Number) npcJson.get("maxHP")); this.max_hp = JSONElement.getInteger((Number) npcJson.get("maxHP"));
this.max_ap = JSONElement.getInteger((Number) npcJson.get("maxAP")); this.max_ap = JSONElement.getInteger((Number) npcJson.get("maxAP"));
this.move_cost = JSONElement.getInteger((Number) npcJson.get("moveCost")); this.move_cost = JSONElement.getInteger((Number) npcJson.get("moveCost"));
this.unique = JSONElement.getInteger((Number) npcJson.get("unique")); this.unique = JSONElement.getInteger((Number) npcJson.get("unique"));
if (npcJson.get("monsterClass") != null) if (npcJson.get("monsterClass") != null) this.monster_class = MonsterClass.valueOf((String) npcJson.get("monsterClass"));
this.monster_class = MonsterClass.valueOf((String) npcJson.get("monsterClass")); if (npcJson.get("movementAggressionType") != null) this.movement_type = MovementType.valueOf((String) npcJson.get("movementAggressionType"));
if (npcJson.get("movementAggressionType") != null) if (npcJson.get("attackDamage") != null) {
this.movement_type = MovementType.valueOf((String) npcJson.get("movementAggressionType")); this.attack_damage_min = JSONElement.getInteger((Number) (((Map)npcJson.get("attackDamage")).get("min")));
if (npcJson.get("attackDamage") != null) { this.attack_damage_max = JSONElement.getInteger((Number) (((Map)npcJson.get("attackDamage")).get("max")));
this.attack_damage_min = JSONElement.getInteger((Number) (((Map) npcJson.get("attackDamage")).get("min"))); }
this.attack_damage_max = JSONElement.getInteger((Number) (((Map) npcJson.get("attackDamage")).get("max"))); this.spawngroup_id = (String) npcJson.get("spawnGroup");
} this.faction_id = (String) npcJson.get("faction");
this.spawngroup_id = (String) npcJson.get("spawnGroup"); this.dialogue_id = (String) npcJson.get("phraseID");
this.faction_id = (String) npcJson.get("faction"); this.droplist_id = (String) npcJson.get("droplistID");
this.dialogue_id = (String) npcJson.get("phraseID"); this.attack_cost = JSONElement.getInteger((Number) npcJson.get("attackCost"));
this.droplist_id = (String) npcJson.get("droplistID"); this.attack_chance = JSONElement.getInteger((Number) npcJson.get("attackChance"));
this.attack_cost = JSONElement.getInteger((Number) npcJson.get("attackCost")); this.critical_skill = JSONElement.getInteger((Number) npcJson.get("criticalSkill"));
this.attack_chance = JSONElement.getInteger((Number) npcJson.get("attackChance")); //TODO correct game data, to unify format.
this.critical_skill = JSONElement.getInteger((Number) npcJson.get("criticalSkill"));
//TODO correct game data, to unify format.
// this.critical_multiplier = JSONElement.getDouble((Number) npcJson.get("criticalMultiplier")); // this.critical_multiplier = JSONElement.getDouble((Number) npcJson.get("criticalMultiplier"));
if (npcJson.get("criticalMultiplier") != null) if (npcJson.get("criticalMultiplier") != null) this.critical_multiplier = JSONElement.getDouble(Double.parseDouble(npcJson.get("criticalMultiplier").toString()));
this.critical_multiplier = JSONElement.getDouble(Double.parseDouble(npcJson.get("criticalMultiplier").toString()));
this.block_chance = JSONElement.getInteger((Number) npcJson.get("blockChance")); this.block_chance = JSONElement.getInteger((Number) npcJson.get("blockChance"));
this.damage_resistance = JSONElement.getInteger((Number) npcJson.get("damageResistance")); this.damage_resistance = JSONElement.getInteger((Number) npcJson.get("damageResistance"));
Map hitEffect = (Map) npcJson.get("hitEffect"); Map hitEffect = (Map) npcJson.get("hitEffect");
if (hitEffect != null) { if (hitEffect != null) {
this.hit_effect = parseHitEffect(hitEffect); this.hit_effect = new HitEffect();
} if (hitEffect.get("increaseCurrentHP") != null) {
this.hit_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentHP")).get("max")));
this.hit_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentHP")).get("min")));
}
if (hitEffect.get("increaseCurrentAP") != null) {
this.hit_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentAP")).get("max")));
this.hit_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentAP")).get("min")));
}
List conditionsSourceJson = (List) hitEffect.get("conditionsSource");
this.hit_effect.conditions_source = parseTimedConditionEffects(conditionsSourceJson);
List conditionsTargetJson = (List) hitEffect.get("conditionsTarget");
this.hit_effect.conditions_target = parseTimedConditionEffects(conditionsTargetJson);
}
Map hitReceivedEffect = (Map) npcJson.get("hitReceivedEffect"); Map hitReceivedEffect = (Map) npcJson.get("hitReceivedEffect");
if (hitReceivedEffect != null) { if (hitReceivedEffect != null) {
this.hit_received_effect = parseHitReceivedEffect(hitReceivedEffect); this.hit_received_effect = parseHitReceivedEffect(hitReceivedEffect);
} }
Map deathEffect = (Map) npcJson.get("deathEffect"); Map deathEffect = (Map) npcJson.get("deathEffect");
if (deathEffect != null) { if (deathEffect != null) {
this.death_effect = parseDeathEffect(deathEffect); this.death_effect = new HitEffect();
} if (deathEffect.get("increaseCurrentHP") != null) {
} this.death_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentHP")).get("max")));
this.death_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentHP")).get("min")));
}
if (deathEffect.get("increaseCurrentAP") != null) {
this.death_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentAP")).get("max")));
this.death_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentAP")).get("min")));
}
List conditionsSourceJson = (List) deathEffect.get("conditionsSource");
this.death_effect.conditions_source = parseTimedConditionEffects(conditionsSourceJson);
}
@Override }
public void link() {
if (shouldSkipParseOrLink()) {
return;
}
ensureParseIfNeeded();
Project proj = getProject();
if (proj == null) {
Notification.addError("Error linking item " + id + ". No parent project found.");
return;
}
linkIcon(proj, this.icon_id, this);
if (this.dialogue_id != null) this.dialogue = proj.getDialogue(this.dialogue_id);
if (this.dialogue != null) this.dialogue.addBacklink(this);
if (this.droplist_id != null) this.droplist = proj.getDroplist(this.droplist_id); @Override
if (this.droplist != null) this.droplist.addBacklink(this); public void link() {
if (shouldSkipParseOrLink()) {
return;
}
ensureParseIfNeeded();
Project proj = getProject();
if (proj == null) {
Notification.addError("Error linking item "+id+". No parent project found.");
return;
}
if (this.icon_id != null) {
String spritesheetId = this.icon_id.split(":")[0];
proj.getSpritesheet(spritesheetId).addBacklink(this);
}
linkEffects(this.hit_effect, proj, this); if (this.dialogue_id != null) this.dialogue = proj.getDialogue(this.dialogue_id);
linkEffects(this.hit_received_effect, proj, this); if (this.dialogue != null) this.dialogue.addBacklink(this);
linkEffects(this.death_effect, proj, this);
this.state = State.linked;
}
@Override if (this.droplist_id != null) this.droplist = proj.getDroplist(this.droplist_id);
public Image getIcon() { if (this.droplist != null) this.droplist.addBacklink(this);
return getProject().getIcon(icon_id);
}
public Image getImage() { if (this.hit_effect != null) {
return getProject().getImage(icon_id); linkConditions(this.hit_effect.conditions_source, proj, this);
} linkConditions(this.hit_effect.conditions_target, proj, this);
}
if (this.hit_received_effect != null) {
linkConditions(this.hit_received_effect.conditions_source, proj, this);
linkConditions(this.hit_received_effect.conditions_target, proj, this);
}
if (this.death_effect != null) {
linkConditions(this.death_effect.conditions_source, proj, this);
}
this.state = State.linked;
}
@Override @Override
public GameDataElement clone() { public Image getIcon() {
NPC clone = new NPC(); return getProject().getIcon(icon_id);
clone.jsonFile = this.jsonFile; }
clone.state = this.state;
clone.id = this.id; public Image getImage() {
clone.name = this.name; return getProject().getImage(icon_id);
clone.icon_id = this.icon_id; }
clone.attack_chance = this.attack_chance;
clone.attack_cost = this.attack_cost; @Override
clone.attack_damage_min = this.attack_damage_min; public GameDataElement clone() {
clone.attack_damage_max = this.attack_damage_max; NPC clone = new NPC();
clone.block_chance = this.block_chance; clone.jsonFile = this.jsonFile;
clone.critical_multiplier = this.critical_multiplier; clone.state = this.state;
clone.critical_skill = this.critical_skill; clone.id = this.id;
clone.damage_resistance = this.damage_resistance; clone.name = this.name;
clone.dialogue = this.dialogue; clone.icon_id = this.icon_id;
if (clone.dialogue != null) { clone.attack_chance = this.attack_chance;
clone.dialogue.addBacklink(clone); clone.attack_cost = this.attack_cost;
} clone.attack_damage_min = this.attack_damage_min;
clone.dialogue_id = this.dialogue_id; clone.attack_damage_max = this.attack_damage_max;
clone.droplist = this.droplist; clone.block_chance = this.block_chance;
if (clone.droplist != null) { clone.critical_multiplier = this.critical_multiplier;
clone.droplist.addBacklink(clone); clone.critical_skill = this.critical_skill;
} clone.damage_resistance = this.damage_resistance;
clone.droplist_id = this.droplist_id; clone.dialogue = this.dialogue;
clone.faction_id = this.faction_id; if (clone.dialogue != null) {
if (this.hit_effect != null) { clone.dialogue.addBacklink(clone);
clone.hit_effect = new HitEffect(); }
copyHitEffectValues(clone.hit_effect, this.hit_effect, clone); clone.dialogue_id = this.dialogue_id;
} clone.droplist = this.droplist;
if (this.hit_received_effect != null) { if (clone.droplist != null) {
clone.droplist.addBacklink(clone);
}
clone.droplist_id = this.droplist_id;
clone.faction_id = this.faction_id;
if (this.hit_effect != null) {
clone.hit_effect = new HitEffect();
copyHitEffectValues(clone.hit_effect, this.hit_effect, clone);
}
if (this.hit_received_effect != null) {
clone.hit_received_effect = new HitReceivedEffect(); clone.hit_received_effect = new HitReceivedEffect();
copyHitReceivedEffectValues(clone.hit_received_effect, this.hit_received_effect, clone); copyHitReceivedEffectValues(clone.hit_received_effect, this.hit_received_effect, clone);
} }
if (this.death_effect != null) { if (this.death_effect != null) {
clone.death_effect = new DeathEffect(); clone.death_effect = new DeathEffect();
copyDeathEffectValues(clone.death_effect, this.death_effect, clone); copyDeathEffectValues(clone.death_effect, this.death_effect, clone);
} }
clone.max_ap = this.max_ap; clone.max_ap = this.max_ap;
clone.max_hp = this.max_hp; clone.max_hp = this.max_hp;
clone.monster_class = this.monster_class; clone.monster_class = this.monster_class;
clone.move_cost = this.move_cost; clone.move_cost = this.move_cost;
clone.movement_type = this.movement_type; clone.movement_type = this.movement_type;
clone.spawngroup_id = this.spawngroup_id; clone.spawngroup_id = this.spawngroup_id;
clone.unique = this.unique; clone.unique = this.unique;
return clone; return clone;
} }
@Override @Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (dialogue == oldOne) { if (dialogue == oldOne) {
oldOne.removeBacklink(this); oldOne.removeBacklink(this);
this.dialogue = (Dialogue) newOne; this.dialogue = (Dialogue) newOne;
if (newOne != null) newOne.addBacklink(this); if (newOne != null) newOne.addBacklink(this);
} else { } else {
if (this.droplist == oldOne) { if (this.droplist == oldOne) {
oldOne.removeBacklink(this); oldOne.removeBacklink(this);
this.droplist = (Droplist) newOne; this.droplist = (Droplist) newOne;
if (newOne != null) newOne.addBacklink(this); if (newOne != null) newOne.addBacklink(this);
} else { } else {
if (this.hit_effect != null) { if (this.hit_effect != null && this.hit_effect.conditions_source != null) {
actorConditionElementChanged(this.hit_effect.conditions_source, oldOne, newOne, this); for (TimedConditionEffect tce : this.hit_effect.conditions_source) {
actorConditionElementChanged(this.hit_effect.conditions_target, oldOne, newOne, this); if (tce.condition == oldOne) {
} oldOne.removeBacklink(this);
} tce.condition = (ActorCondition) newOne;
} if (newOne != null) newOne.addBacklink(this);
} }
}
}
if (this.hit_effect != null && this.hit_effect.conditions_target != null) {
for (TimedConditionEffect tce : this.hit_effect.conditions_target) {
if (tce.condition == oldOne) {
oldOne.removeBacklink(this);
tce.condition = (ActorCondition) newOne;
if (newOne != null) newOne.addBacklink(this);
}
}
}
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public Map toJson() { public Map toJson() {
Map npcJson = new LinkedHashMap(); Map npcJson = new LinkedHashMap();
npcJson.put("id", this.id); npcJson.put("id", this.id);
if (this.name != null) npcJson.put("name", this.name); if (this.name != null) npcJson.put("name", this.name);
writeIconToMap(npcJson, this.icon_id); if (this.icon_id != null) npcJson.put("iconID", this.icon_id);
if (this.max_hp != null) npcJson.put("maxHP", this.max_hp); if (this.max_hp != null) npcJson.put("maxHP", this.max_hp);
if (this.max_ap != null) npcJson.put("maxAP", this.max_ap); if (this.max_ap != null) npcJson.put("maxAP", this.max_ap);
if (this.move_cost != null) npcJson.put("moveCost", this.move_cost); if (this.move_cost != null) npcJson.put("moveCost", this.move_cost);
if (this.unique != null) npcJson.put("unique", this.unique); if (this.unique != null) npcJson.put("unique", this.unique);
if (this.monster_class != null) npcJson.put("monsterClass", this.monster_class.toString()); if (this.monster_class != null) npcJson.put("monsterClass", this.monster_class.toString());
if (this.movement_type != null) npcJson.put("movementAggressionType", this.movement_type.toString()); if (this.movement_type != null) npcJson.put("movementAggressionType", this.movement_type.toString());
writeMinMaxToMap(npcJson, "attackDamage", this.attack_damage_min, attack_damage_max, 0); if (this.attack_damage_min != null || this.attack_damage_max != null) {
if (this.spawngroup_id != null) npcJson.put("spawnGroup", this.spawngroup_id); Map adJson = new LinkedHashMap();
if (this.faction_id != null) npcJson.put("faction", this.faction_id); npcJson.put("attackDamage", adJson);
if (this.dialogue != null) { if (this.attack_damage_min != null) adJson.put("min", this.attack_damage_min);
npcJson.put("phraseID", this.dialogue.id); else adJson.put("min", 0);
} else if (this.dialogue_id != null) { if (this.attack_damage_max != null) adJson.put("max", this.attack_damage_max);
npcJson.put("phraseID", this.dialogue_id); else adJson.put("max", 0);
} }
if (this.droplist != null) { if (this.spawngroup_id != null) npcJson.put("spawnGroup", this.spawngroup_id);
npcJson.put("droplistID", this.droplist.id); if (this.faction_id != null) npcJson.put("faction", this.faction_id);
} else if (this.droplist_id != null) { if (this.dialogue != null) {
npcJson.put("droplistID", this.droplist_id); npcJson.put("phraseID", this.dialogue.id);
} } else if (this.dialogue_id != null) {
if (this.attack_cost != null) npcJson.put("attackCost", this.attack_cost); npcJson.put("phraseID", this.dialogue_id);
if (this.attack_chance != null) npcJson.put("attackChance", this.attack_chance); }
if (this.critical_skill != null) npcJson.put("criticalSkill", this.critical_skill); if (this.droplist != null) {
if (this.critical_multiplier != null) npcJson.put("criticalMultiplier", this.critical_multiplier); npcJson.put("droplistID", this.droplist.id);
if (this.block_chance != null) npcJson.put("blockChance", this.block_chance); } else if (this.droplist_id != null) {
if (this.damage_resistance != null) npcJson.put("damageResistance", this.damage_resistance); npcJson.put("droplistID", this.droplist_id);
writeHitEffectToMap(npcJson, this.hit_effect, "hitEffect"); }
writeHitReceivedEffectToMap(npcJson, this.hit_received_effect, "hitReceivedEffect"); if (this.attack_cost != null) npcJson.put("attackCost", this.attack_cost);
writeDeathEffectToMap(npcJson, this.death_effect, "deathEffect"); if (this.attack_chance != null) npcJson.put("attackChance", this.attack_chance);
return npcJson; if (this.critical_skill != null) npcJson.put("criticalSkill", this.critical_skill);
} if (this.critical_multiplier != null) npcJson.put("criticalMultiplier", this.critical_multiplier);
if (this.block_chance != null) npcJson.put("blockChance", this.block_chance);
if (this.damage_resistance != null) npcJson.put("damageResistance", this.damage_resistance);
if (this.hit_effect != null) {
Map hitEffectJson = new LinkedHashMap();
npcJson.put("hitEffect", hitEffectJson);
if (this.hit_effect.hp_boost_min != null || this.hit_effect.hp_boost_max != null) {
Map hpJson = new LinkedHashMap();
hitEffectJson.put("increaseCurrentHP", hpJson);
if (this.hit_effect.hp_boost_min != null) hpJson.put("min", this.hit_effect.hp_boost_min);
else hpJson.put("min", 0);
if (this.hit_effect.hp_boost_max != null) hpJson.put("max", this.hit_effect.hp_boost_max);
else hpJson.put("max", 0);
}
if (this.hit_effect.ap_boost_min != null || this.hit_effect.ap_boost_max != null) {
Map apJson = new LinkedHashMap();
hitEffectJson.put("increaseCurrentAP", apJson);
if (this.hit_effect.ap_boost_min != null) apJson.put("min", this.hit_effect.ap_boost_min);
else apJson.put("min", 0);
if (this.hit_effect.ap_boost_max != null) apJson.put("max", this.hit_effect.ap_boost_max);
else apJson.put("max", 0);
}
if (this.hit_effect.conditions_source != null) {
List conditionsSourceJson = new ArrayList();
hitEffectJson.put("conditionsSource", conditionsSourceJson);
for (TimedConditionEffect condition : this.hit_effect.conditions_source) {
Map conditionJson = new LinkedHashMap();
conditionsSourceJson.add(conditionJson);
if (condition.condition != null) {
conditionJson.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
conditionJson.put("condition", condition.condition_id);
}
if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude);
if (condition.duration != null) conditionJson.put("duration", condition.duration);
if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
if (this.hit_effect.conditions_target != null) {
List conditionsTargetJson = new ArrayList();
hitEffectJson.put("conditionsTarget", conditionsTargetJson);
for (TimedConditionEffect condition : this.hit_effect.conditions_target) {
Map conditionJson = new LinkedHashMap();
conditionsTargetJson.add(conditionJson);
if (condition.condition != null) {
conditionJson.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
conditionJson.put("condition", condition.condition_id);
}
if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude);
if (condition.duration != null) conditionJson.put("duration", condition.duration);
if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
}
if (this.hit_received_effect != null) {
Map hitReceivedEffectJson = new LinkedHashMap();
npcJson.put("hitReceivedEffect", hitReceivedEffectJson);
if (this.hit_received_effect.hp_boost_min != null || this.hit_received_effect.hp_boost_max != null) {
Map hpJson = new LinkedHashMap();
hitReceivedEffectJson.put("increaseCurrentHP", hpJson);
if (this.hit_received_effect.hp_boost_min != null) hpJson.put("min", this.hit_received_effect.hp_boost_min);
else hpJson.put("min", 0);
if (this.hit_received_effect.hp_boost_max != null) hpJson.put("max", this.hit_received_effect.hp_boost_max);
else hpJson.put("max", 0);
}
if (this.hit_received_effect.ap_boost_min != null || this.hit_received_effect.ap_boost_max != null) {
Map apJson = new LinkedHashMap();
hitReceivedEffectJson.put("increaseCurrentAP", apJson);
if (this.hit_received_effect.ap_boost_min != null) apJson.put("min", this.hit_received_effect.ap_boost_min);
else apJson.put("min", 0);
if (this.hit_received_effect.ap_boost_max != null) apJson.put("max", this.hit_received_effect.ap_boost_max);
else apJson.put("max", 0);
}
if (this.hit_received_effect.hp_boost_min_target != null || this.hit_received_effect.hp_boost_max_target != null) {
Map hpJson = new LinkedHashMap();
hitReceivedEffectJson.put("increaseAttackerCurrentHP", hpJson);
if (this.hit_received_effect.hp_boost_min_target != null) hpJson.put("min", this.hit_received_effect.hp_boost_min_target);
else hpJson.put("min", 0);
if (this.hit_received_effect.hp_boost_max_target != null) hpJson.put("max", this.hit_received_effect.hp_boost_max_target);
else hpJson.put("max", 0);
}
if (this.hit_received_effect.ap_boost_min_target != null || this.hit_received_effect.ap_boost_max_target != null) {
Map apJson = new LinkedHashMap();
hitReceivedEffectJson.put("increaseAttackerCurrentAP", apJson);
if (this.hit_received_effect.ap_boost_min_target != null) apJson.put("min", this.hit_received_effect.ap_boost_min_target);
else apJson.put("min", 0);
if (this.hit_received_effect.ap_boost_max_target != null) apJson.put("max", this.hit_received_effect.ap_boost_max_target);
else apJson.put("max", 0);
}
if (this.hit_received_effect.conditions_source != null) {
List conditionsSourceJson = new ArrayList();
hitReceivedEffectJson.put("conditionsSource", conditionsSourceJson);
for (TimedConditionEffect condition : this.hit_received_effect.conditions_source) {
Map conditionJson = new LinkedHashMap();
conditionsSourceJson.add(conditionJson);
if (condition.condition != null) {
conditionJson.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
conditionJson.put("condition", condition.condition_id);
}
if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude);
if (condition.duration != null) conditionJson.put("duration", condition.duration);
if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
if (this.hit_received_effect.conditions_target != null) {
List conditionsTargetJson = new ArrayList();
hitReceivedEffectJson.put("conditionsTarget", conditionsTargetJson);
for (TimedConditionEffect condition : this.hit_received_effect.conditions_target) {
Map conditionJson = new LinkedHashMap();
conditionsTargetJson.add(conditionJson);
if (condition.condition != null) {
conditionJson.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
conditionJson.put("condition", condition.condition_id);
}
if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude);
if (condition.duration != null) conditionJson.put("duration", condition.duration);
if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
}
if (this.death_effect != null) {
Map deathEffectJson = new LinkedHashMap();
npcJson.put("deathEffect", deathEffectJson);
if (this.death_effect.hp_boost_min != null || this.death_effect.hp_boost_max != null) {
Map hpJson = new LinkedHashMap();
deathEffectJson.put("increaseCurrentHP", hpJson);
if (this.death_effect.hp_boost_min != null) hpJson.put("min", this.death_effect.hp_boost_min);
else hpJson.put("min", 0);
if (this.death_effect.hp_boost_max != null) hpJson.put("max", this.death_effect.hp_boost_max);
else hpJson.put("max", 0);
}
if (this.death_effect.ap_boost_min != null || this.death_effect.ap_boost_max != null) {
Map apJson = new LinkedHashMap();
deathEffectJson.put("increaseCurrentAP", apJson);
if (this.death_effect.ap_boost_min != null) apJson.put("min", this.death_effect.ap_boost_min);
else apJson.put("min", 0);
if (this.death_effect.ap_boost_max != null) apJson.put("max", this.death_effect.ap_boost_max);
else apJson.put("max", 0);
}
if (this.death_effect.conditions_source != null) {
List conditionsSourceJson = new ArrayList();
deathEffectJson.put("conditionsSource", conditionsSourceJson);
for (TimedConditionEffect condition : this.death_effect.conditions_source) {
Map conditionJson = new LinkedHashMap();
conditionsSourceJson.add(conditionJson);
if (condition.condition != null) {
conditionJson.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
conditionJson.put("condition", condition.condition_id);
}
if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude);
if (condition.duration != null) conditionJson.put("duration", condition.duration);
if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
}
return npcJson;
}
@Override @Override
public String getProjectFilename() { public String getProjectFilename() {
return "monsterlist_" + getProject().name + ".json"; return "monsterlist_"+getProject().name+".json";
} }
public int getMonsterExperience() { public int getMonsterExperience() {
double EXP_FACTOR_DAMAGERESISTANCE = 9; double EXP_FACTOR_DAMAGERESISTANCE = 9;
double EXP_FACTOR_SCALING = 0.7; double EXP_FACTOR_SCALING = 0.7;
double attacksPerTurn = Math.floor((double) (max_ap != null ? max_ap : 10.0) / (double) (attack_cost != null ? attack_cost : 10.0)); double attacksPerTurn = Math.floor((double)(max_ap != null ? max_ap : 10.0) / (double)(attack_cost != null ? attack_cost : 10.0));
double avgDamagePotential = 0; double avgDamagePotential = 0;
if (attack_damage_min != null || attack_damage_max != null) { if (attack_damage_min != null || attack_damage_max != null) {
avgDamagePotential = ((double) (attack_damage_min != null ? attack_damage_min : 0) + (double) (attack_damage_max != null ? attack_damage_max : 0)) / 2.0; avgDamagePotential = ((double)(attack_damage_min != null ? attack_damage_min : 0) + (double)(attack_damage_max != null ? attack_damage_max : 0)) / 2.0;
} }
double avgCrit = 0; double avgCrit = 0;
if (critical_skill != null && critical_multiplier != null) { if (critical_skill != null && critical_multiplier != null) {
avgCrit = (double) (critical_skill / 100.0) * critical_multiplier; avgCrit = (double)(critical_skill / 100.0) * critical_multiplier;
} }
double avgAttackHP = attacksPerTurn * ((double) (attack_chance != null ? attack_chance : 0) / 100.0) * avgDamagePotential * (1 + avgCrit); double avgAttackHP = attacksPerTurn * ((double)(attack_chance != null ? attack_chance : 0) / 100.0) * avgDamagePotential * (1 + avgCrit);
double avgDefenseHP = ((max_hp != null ? max_hp : 1) * (1 + ((double) (block_chance != null ? block_chance : 0) / 100.0))) + double avgDefenseHP = ((max_hp != null ? max_hp : 1) * (1 + ((double)(block_chance != null ? block_chance : 0) / 100.0))) + ( EXP_FACTOR_DAMAGERESISTANCE * (damage_resistance != null ? damage_resistance : 0));
(EXP_FACTOR_DAMAGERESISTANCE * (damage_resistance != null ? damage_resistance : 0)); double attackConditionBonus = 0;
double attackConditionBonus = 0; if (hit_effect != null && hit_effect.conditions_target != null && hit_effect.conditions_target.size() > 0) {
if (hit_effect != null && hit_effect.conditions_target != null && hit_effect.conditions_target.size() > 0) { attackConditionBonus = 50;
attackConditionBonus = 50; }
} double experience = (((avgAttackHP * 3) + avgDefenseHP) * EXP_FACTOR_SCALING) + attackConditionBonus;
double experience = (((avgAttackHP * 3) + avgDefenseHP) * EXP_FACTOR_SCALING) + attackConditionBonus;
return new Double(Math.ceil(experience)).intValue(); return new Double(Math.ceil(experience)).intValue();
} };
} }

View File

@@ -1,190 +1,191 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import com.gpl.rpg.atcontentstudio.Notification; import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import java.io.File;
import com.gpl.rpg.atcontentstudio.model.GameSource; import java.io.FileNotFoundException;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import java.io.FileReader;
import org.json.simple.parser.JSONParser; import java.io.IOException;
import org.json.simple.parser.ParseException; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.awt.*; import java.util.List;
import java.io.File; import java.util.Map;
import java.io.FileNotFoundException;
import java.io.FileReader; import org.json.simple.parser.JSONParser;
import java.io.IOException; import org.json.simple.parser.ParseException;
import java.util.ArrayList;
import java.util.LinkedHashMap; import com.gpl.rpg.atcontentstudio.Notification;
import java.util.List; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import java.util.Map; import com.gpl.rpg.atcontentstudio.model.GameSource;
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
//public String id = null; inherited. //Available from init state
public String name = null; //public String id = null; inherited.
public String name = null;
//Available in parsed state
public Integer visible_in_log = null; //Available in parsed state
public List<QuestStage> stages = null; public Integer visible_in_log = null;
public List<QuestStage> stages = null;
@Override
public String getDesc() { @Override
return (needsSaving() ? "*" : "") + name + " (" + id + ")"; public String getDesc() {
} return (needsSaving() ? "*" : "")+name+" ("+id+")";
}
public static String getStaticDesc() {
return "Quests"; public static String getStaticDesc() {
} return "Quests";
}
@SuppressWarnings("rawtypes")
public static void fromJson(File jsonFile, GameDataCategory<Quest> category) { @SuppressWarnings("rawtypes")
JSONParser parser = new JSONParser(); public static void fromJson(File jsonFile, GameDataCategory<Quest> category) {
FileReader reader = null; JSONParser parser = new JSONParser();
try { FileReader reader = null;
reader = new FileReader(jsonFile); try {
List quests = (List) parser.parse(reader); reader = new FileReader(jsonFile);
for (Object obj : quests) { List quests = (List) parser.parse(reader);
Map questJson = (Map) obj; for (Object obj : quests) {
Quest quest = fromJson(questJson); Map questJson = (Map)obj;
quest.jsonFile = jsonFile; Quest quest = fromJson(questJson);
quest.parent = category; quest.jsonFile = jsonFile;
if (quest.getDataType() == GameSource.Type.created || quest.getDataType() == GameSource.Type.altered) { quest.parent = category;
quest.writable = true; if (quest.getDataType() == GameSource.Type.created || quest.getDataType() == GameSource.Type.altered) {
} quest.writable = true;
category.add(quest); }
} category.add(quest);
} 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 Quest fromJson(String jsonString) throws ParseException { @SuppressWarnings("rawtypes")
Map questJson = (Map) new JSONParser().parse(jsonString); public static Quest fromJson(String jsonString) throws ParseException {
Quest quest = fromJson(questJson); Map questJson = (Map) new JSONParser().parse(jsonString);
quest.parse(questJson); Quest quest = fromJson(questJson);
return quest; quest.parse(questJson);
} return quest;
}
@SuppressWarnings("rawtypes")
public static Quest fromJson(Map questJson) { @SuppressWarnings("rawtypes")
Quest quest = new Quest(); public static Quest fromJson(Map questJson) {
quest.id = (String) questJson.get("id"); Quest quest = new Quest();
quest.name = (String) questJson.get("name"); quest.id = (String) questJson.get("id");
//Quests have to be parsed to have their stages initialized. quest.name = (String) questJson.get("name");
quest.parse(questJson); //Quests have to be parsed to have their stages initialized.
return quest; quest.parse(questJson);
} return quest;
}
@SuppressWarnings("rawtypes")
@Override @SuppressWarnings("rawtypes")
public void parse(Map questJson) { @Override
this.visible_in_log = JSONElement.getInteger((Number) questJson.get("showInLog")); public void parse(Map questJson) {
List questStagesJson = (List) questJson.get("stages"); this.visible_in_log = JSONElement.getInteger((Number) questJson.get("showInLog"));
this.stages = new ArrayList<QuestStage>(); List questStagesJson = (List) questJson.get("stages");
if (questStagesJson != null && !questStagesJson.isEmpty()) { this.stages = new ArrayList<QuestStage>();
for (Object questStageJsonObj : questStagesJson) { if (questStagesJson != null && !questStagesJson.isEmpty()) {
Map questStageJson = (Map) questStageJsonObj; for (Object questStageJsonObj : questStagesJson) {
QuestStage questStage = new QuestStage(this); Map questStageJson = (Map)questStageJsonObj;
questStage.parse(questStageJson); QuestStage questStage = new QuestStage(this);
this.stages.add(questStage); questStage.parse(questStageJson);
} this.stages.add(questStage);
} }
this.state = State.parsed; }
} this.state = State.parsed;
}
@Override
public void link() { @Override
if (shouldSkipParseOrLink()) { public void link() {
return; if (shouldSkipParseOrLink()) {
} return;
ensureParseIfNeeded(); }
ensureParseIfNeeded();
for (QuestStage stage : stages) {
stage.link(); for (QuestStage stage : stages) {
} stage.link();
//Nothing to link to :D }
this.state = State.linked; //Nothing to link to :D
} this.state = State.linked;
}
@Override
public Image getIcon() { @Override
return DefaultIcons.getQuestIcon(); public Image getIcon() {
} return DefaultIcons.getQuestIcon();
}
public Image getImage() {
return DefaultIcons.getQuestImage(); public Image getImage() {
} return DefaultIcons.getQuestImage();
}
@Override
public GameDataElement clone() { @Override
Quest clone = new Quest(); public GameDataElement clone() {
clone.jsonFile = this.jsonFile; Quest clone = new Quest();
clone.state = this.state; clone.jsonFile = this.jsonFile;
clone.id = this.id; clone.state = this.state;
clone.name = this.name; clone.id = this.id;
clone.visible_in_log = this.visible_in_log; clone.name = this.name;
if (this.stages != null) { clone.visible_in_log = this.visible_in_log;
clone.stages = new ArrayList<QuestStage>(); if (this.stages != null) {
for (QuestStage stage : this.stages) { clone.stages = new ArrayList<QuestStage>();
clone.stages.add((QuestStage) stage.clone(clone)); for (QuestStage stage : this.stages){
} clone.stages.add((QuestStage) stage.clone(clone));
} }
return clone; }
} return clone;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { @Override
//Nothing to link to. public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} //Nothing to link to.
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override @SuppressWarnings({ "rawtypes", "unchecked" })
public Map toJson() { @Override
Map questJson = new LinkedHashMap(); public Map toJson() {
questJson.put("id", this.id); Map questJson = new LinkedHashMap();
if (this.name != null) questJson.put("name", this.name); questJson.put("id", this.id);
if (this.visible_in_log != null) questJson.put("showInLog", this.visible_in_log); if (this.name != null) questJson.put("name", this.name);
if (this.stages != null) { if (this.visible_in_log != null) questJson.put("showInLog", this.visible_in_log);
List stagesJson = new ArrayList(); if (this.stages != null) {
questJson.put("stages", stagesJson); List stagesJson = new ArrayList();
for (QuestStage stage : this.stages) { questJson.put("stages", stagesJson);
stagesJson.add(stage.toJson()); for (QuestStage stage : this.stages) {
} stagesJson.add(stage.toJson());
} }
return questJson; }
} return questJson;
}
@Override
public String getProjectFilename() { @Override
return "questlist_" + getProject().name + ".json"; public String getProjectFilename() {
} return "questlist_"+getProject().name+".json";
}
public QuestStage getStage(Integer stageId) {
for (QuestStage stage : stages) { public QuestStage getStage(Integer stageId) {
if (stage.progress.equals(stageId)) { for (QuestStage stage : stages) {
return stage; if (stage.progress.equals(stageId)) {
} return stage;
} }
return null; }
} return null;
}
}
}

View File

@@ -1,96 +1,96 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image;
import java.util.LinkedHashMap;
import java.util.Map;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
import java.util.LinkedHashMap;
import java.util.Map;
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;
clone.log_text = log_text != null ? new String(log_text) : null; clone.log_text = log_text != null ? new String(log_text) : null;
clone.exp_reward = exp_reward != null ? new Integer(exp_reward) : null; clone.exp_reward = exp_reward != null ? new Integer(exp_reward) : null;
clone.finishes_quest = finishes_quest != null ? new Integer(finishes_quest) : null; clone.finishes_quest = finishes_quest != null ? new Integer(finishes_quest) : null;
clone.id = this.id; clone.id = this.id;
return clone; return clone;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public void parse(Map jsonObj) { public void parse(Map jsonObj) {
progress = JSONElement.getInteger((Number) jsonObj.get("progress")); progress = JSONElement.getInteger((Number) jsonObj.get("progress"));
this.id = ((Quest) parent).id + ":" + progress; this.id = ((Quest)parent).id+":"+progress;
log_text = (String) jsonObj.get("logText"); log_text = (String) jsonObj.get("logText");
exp_reward = JSONElement.getInteger((Number) jsonObj.get("rewardExperience")); exp_reward = JSONElement.getInteger((Number) jsonObj.get("rewardExperience"));
finishes_quest = JSONElement.getInteger((Number) jsonObj.get("finishesQuest")); finishes_quest = JSONElement.getInteger((Number) jsonObj.get("finishesQuest"));
state = State.parsed; state = State.parsed;
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public Map toJson() { public Map toJson() {
Map stageJson = new LinkedHashMap(); Map stageJson = new LinkedHashMap();
if (progress != null) stageJson.put("progress", progress); if (progress != null) stageJson.put("progress", progress);
if (log_text != null) stageJson.put("logText", log_text); if (log_text != null) stageJson.put("logText", log_text);
if (exp_reward != null) stageJson.put("rewardExperience", exp_reward); if (exp_reward != null) stageJson.put("rewardExperience", exp_reward);
if (finishes_quest != null) stageJson.put("finishesQuest", finishes_quest); if (finishes_quest != null) stageJson.put("finishesQuest", finishes_quest);
return stageJson; return stageJson;
} }
@Override @Override
public String getDesc() { public String getDesc() {
return progress + " - " + (exp_reward != null ? "[" + exp_reward + "XP]" : "") + ((finishes_quest != null) && (finishes_quest == 1) ? "[END]" : "") + log_text; return progress+" - "+(exp_reward != null ? "["+exp_reward+"XP]" : "")+((finishes_quest != null) && (finishes_quest == 1) ? "[END]" : "")+log_text;
} }
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { if (shouldSkipParseOrLink()) {
return; return;
} }
ensureParseIfNeeded(); ensureParseIfNeeded();
//Nothing to link to :D //Nothing to link to :D
this.state = State.linked; this.state = State.linked;
} }
@Override @Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
// Nothing to link to. // Nothing to link to.
} }
@Override @Override
public String getProjectFilename() { public String getProjectFilename() {
return ((Quest) parent).getProjectFilename(); return ((Quest)parent).getProjectFilename();
} }
@Override @Override
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

@@ -1,230 +1,268 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
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 com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
public class Requirement extends JSONElement { public class Requirement extends JSONElement {
private static final long serialVersionUID = 7295593297142310955L; private static final long serialVersionUID = 7295593297142310955L;
private static Map<RequirementType, List<RequirementType>> COMPATIBLE_TYPES = new LinkedHashMap<RequirementType, List<RequirementType>>();
static {
List<RequirementType> questTypes = new ArrayList<RequirementType>();
questTypes.add(RequirementType.questProgress);
questTypes.add(RequirementType.questLatestProgress);
COMPATIBLE_TYPES.put(RequirementType.questProgress, questTypes);
COMPATIBLE_TYPES.put(RequirementType.questLatestProgress, questTypes);
List<RequirementType> countedItemTypes = new ArrayList<RequirementType>();
countedItemTypes.add(RequirementType.inventoryRemove);
countedItemTypes.add(RequirementType.inventoryKeep);
countedItemTypes.add(RequirementType.usedItem);
countedItemTypes.add(RequirementType.wear);
countedItemTypes.add(RequirementType.wearRemove);
COMPATIBLE_TYPES.put(RequirementType.inventoryRemove, countedItemTypes);
COMPATIBLE_TYPES.put(RequirementType.inventoryKeep, countedItemTypes);
COMPATIBLE_TYPES.put(RequirementType.usedItem, countedItemTypes);
COMPATIBLE_TYPES.put(RequirementType.wear, countedItemTypes);
COMPATIBLE_TYPES.put(RequirementType.wearRemove, countedItemTypes);
}
//Available from parsed state
public RequirementType type = null;
public String required_obj_id = null;
public Integer required_value = null;
public Boolean negated = null;
//Available from linked state
public GameDataElement required_obj = null;
public enum RequirementType {
questProgress,
questLatestProgress,
inventoryRemove,
inventoryKeep,
wear,
skillLevel,
killedMonster,
timerElapsed,
usedItem,
spentGold,
consumedBonemeals,
hasActorCondition,
factionScore,
random,
factionScoreEquals,
wearRemove,
date,
dateEquals,
time,
timeEquals
}
public enum SkillID {
weaponChance
,weaponDmg
,barter
,dodge
,barkSkin
,moreCriticals
,betterCriticals
,speed // Raises max ap
,coinfinder
,moreExp
,cleave // +10ap on kill
,eater // +1hp per kill
,fortitude // +N hp per levelup
,evasion // increase successful flee chance & reduce chance of monster attack
,regeneration // +N hp per round
,lowerExploss
,magicfinder
,resistanceMental // lowers chance to get negative active conditions by monsters (Mental like Dazed)
,resistancePhysical // lowers chance to get negative active conditions by monsters (Physical Capacity like Minor fatigue)
,resistanceBlood // lowers chance to get negative active conditions by monsters (Blood Disorder like Weak Poison)
,shadowBless
,sporeImmunity
,crit1 // lowers atk ability
,crit2 // lowers def ability ,rejuvenation // Reduces magnitudes of conditions
,rejuvenation // Reduces magnitudes of conditions
,taunt // Causes AP loss of attackers that miss
,concussion // AC loss for monsters with (AC-BC)>N
,weaponProficiencyDagger
,weaponProficiency1hsword
,weaponProficiency2hsword
,weaponProficiencyAxe
,weaponProficiencyBlunt
,weaponProficiencyUnarmed
,weaponProficiencyPole
,armorProficiencyShield
,armorProficiencyUnarmored
,armorProficiencyLight
,armorProficiencyHeavy
,fightstyleDualWield
,fightstyle2hand
,fightstyleWeaponShield
,specializationDualWield
,specialization2hand
,specializationWeaponShield
}
@Override
public String getDesc() {
String obj_id = "";
if (required_obj_id != null)
{
obj_id = required_obj_id;
if (type != null && type == RequirementType.random){
obj_id = " Chance " + obj_id + (required_obj_id.contains("/") ? "" : "%");
}
else {
obj_id += ":";
}
}
return ((negated != null && negated) ? "NOT " : "")
+(type == null ? "" : type.toString()+":")
+obj_id
+(required_value == null ? "" : required_value.toString());
}
private static Map<RequirementType, List<RequirementType>> COMPATIBLE_TYPES = new LinkedHashMap<RequirementType, List<RequirementType>>(); @Override
public void parse() {
throw new Error("Thou shalt not reach this method.");
}
static { @SuppressWarnings("rawtypes")
List<RequirementType> questTypes = new ArrayList<RequirementType>(); @Override
questTypes.add(RequirementType.questProgress); public Map toJson() {
questTypes.add(RequirementType.questLatestProgress); throw new Error("Thou shalt not reach this method.");
COMPATIBLE_TYPES.put(RequirementType.questProgress, questTypes); }
COMPATIBLE_TYPES.put(RequirementType.questLatestProgress, questTypes);
@SuppressWarnings("rawtypes")
@Override
public void parse(Map jsonObj) {
throw new Error("Thou shalt not reach this method.");
}
List<RequirementType> countedItemTypes = new ArrayList<RequirementType>(); @Override
countedItemTypes.add(RequirementType.inventoryRemove); public void link() {
countedItemTypes.add(RequirementType.inventoryKeep); if (this.state == State.created || this.state == State.modified || this.state == State.saved) {
countedItemTypes.add(RequirementType.usedItem); //This type of state is unrelated to parsing/linking.
countedItemTypes.add(RequirementType.wear); return;
countedItemTypes.add(RequirementType.wearRemove); }
COMPATIBLE_TYPES.put(RequirementType.inventoryRemove, countedItemTypes); if (this.state == State.init) {
COMPATIBLE_TYPES.put(RequirementType.inventoryKeep, countedItemTypes); //Not parsed yet.
COMPATIBLE_TYPES.put(RequirementType.usedItem, countedItemTypes); this.parse();
COMPATIBLE_TYPES.put(RequirementType.wear, countedItemTypes); } else if (this.state == State.linked) {
COMPATIBLE_TYPES.put(RequirementType.wearRemove, countedItemTypes); //Already linked.
} return;
}
//Available from parsed state Project proj = getProject();
public RequirementType type = null; if (proj == null) {
public String required_obj_id = null; Notification.addError("Error linking requirement "+getDesc()+". No parent project found.");
public Integer required_value = null; return;
public Boolean negated = null; }
switch (type) {
//Available from linked state case hasActorCondition:
public GameDataElement required_obj = null; this.required_obj = proj.getActorCondition(required_obj_id);
break;
public enum RequirementType { case inventoryKeep:
questProgress, case inventoryRemove:
questLatestProgress, case usedItem:
inventoryRemove, case wear:
inventoryKeep, case wearRemove:
wear, this.required_obj = proj.getItem(required_obj_id);
skillLevel, break;
killedMonster, case killedMonster:
timerElapsed, this.required_obj = proj.getNPC(required_obj_id);
usedItem, break;
spentGold, case questLatestProgress:
consumedBonemeals, case questProgress:
hasActorCondition, this.required_obj = proj.getQuest(required_obj_id);
factionScore, if (this.required_obj != null && this.required_value != null) {
random, QuestStage stage = ((Quest)this.required_obj).getStage(this.required_value);
factionScoreEquals, if (stage != null) {
wearRemove, stage.addBacklink((GameDataElement) this.parent);
date, }
dateEquals, }
time, break;
timeEquals case consumedBonemeals:
} case skillLevel:
case spentGold:
public enum SkillID { case timerElapsed:
weaponChance, weaponDmg, barter, dodge, barkSkin, moreCriticals, betterCriticals, speed // Raises max ap case factionScore:
, coinfinder, moreExp, cleave // +10ap on kill case factionScoreEquals:
, eater // +1hp per kill case random:
, fortitude // +N hp per levelup case date:
, evasion // increase successful flee chance & reduce chance of monster attack case dateEquals:
, regeneration // +N hp per round case time:
, lowerExploss, magicfinder, resistanceMental // lowers chance to get negative active conditions by monsters (Mental like Dazed) case timeEquals:
, resistancePhysical // lowers chance to get negative active conditions by monsters (Physical Capacity like Minor fatigue) break;
, resistanceBlood // lowers chance to get negative active conditions by monsters (Blood Disorder like Weak Poison) }
, shadowBless, sporeImmunity, crit1 // lowers atk ability if (this.required_obj != null) this.required_obj.addBacklink((GameDataElement) this.parent);
, crit2 // lowers def ability ,rejuvenation // Reduces magnitudes of conditions this.state = State.linked;
, rejuvenation // Reduces magnitudes of conditions }
, taunt // Causes AP loss of attackers that miss
, concussion // AC loss for monsters with (AC-BC)>N @Override
, weaponProficiencyDagger, weaponProficiency1hsword, weaponProficiency2hsword, weaponProficiencyAxe, weaponProficiencyBlunt, weaponProficiencyUnarmed, weaponProficiencyPole, armorProficiencyShield, armorProficiencyUnarmored, armorProficiencyLight, armorProficiencyHeavy, fightstyleDualWield, fightstyle2hand, fightstyleWeaponShield, specializationDualWield, specialization2hand, specializationWeaponShield public GameDataElement clone() {
} return clone(null);
}
@Override
public String getDesc() { public GameDataElement clone(GameDataElement parent) {
String obj_id = ""; Requirement clone = new Requirement();
if (required_obj_id != null) { clone.parent = parent;
obj_id = required_obj_id; clone.jsonFile = this.jsonFile;
if (type != null && type == RequirementType.random) { clone.state = this.state;
obj_id = " Chance " + obj_id + (required_obj_id.contains("/") ? "" : "%"); clone.required_obj_id = this.required_obj_id;
} else { clone.required_value = this.required_value;
obj_id += ":"; clone.negated = this.negated;
} clone.required_obj = this.required_obj;
} clone.type = this.type;
if (clone.required_obj != null && parent != null) {
return ((negated != null && negated) ? "NOT " : "") clone.required_obj.addBacklink(parent);
+ (type == null ? "" : type.toString() + ":") }
+ obj_id return clone;
+ (required_value == null ? "" : required_value.toString()); }
}
@Override
@Override public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
public void parse() { if (this.required_obj == oldOne) {
throw new Error("Thou shalt not reach this method."); oldOne.removeBacklink((GameDataElement) this.parent);
} this.required_obj = newOne;
if (newOne != null) newOne.addBacklink((GameDataElement) this.parent);
@SuppressWarnings("rawtypes") }
@Override if (oldOne instanceof QuestStage) {
public Map toJson() { if (this.required_obj != null && this.required_obj.equals(oldOne.parent) && this.required_value != null && this.required_value.equals(((QuestStage) oldOne).progress)) {
throw new Error("Thou shalt not reach this method."); oldOne.removeBacklink((GameDataElement) this.parent);
} if (newOne != null) newOne.addBacklink((GameDataElement) this.parent);
}
@SuppressWarnings("rawtypes") }
@Override }
public void parse(Map jsonObj) { @Override
throw new Error("Thou shalt not reach this method."); public String getProjectFilename() {
} throw new Error("Thou shalt not reach this method.");
}
@Override
public void link() { public void changeType(RequirementType destType) {
if (shouldSkipParseOrLink()) { if (COMPATIBLE_TYPES.get(type) == null || !COMPATIBLE_TYPES.get(type).contains(destType)) {
return; required_obj = null;
} required_obj_id = null;
ensureParseIfNeeded(); required_value = null;
Project proj = getProject(); }
if (proj == null) {
Notification.addError("Error linking requirement " + getDesc() + ". No parent project found."); if(destType==RequirementType.random)
return; {
} required_obj_id = "50/100";
switch (type) { }
case hasActorCondition:
this.required_obj = proj.getActorCondition(required_obj_id); type = destType;
break; }
case inventoryKeep:
case inventoryRemove:
case usedItem:
case wear:
case wearRemove:
this.required_obj = proj.getItem(required_obj_id);
break;
case killedMonster:
this.required_obj = proj.getNPC(required_obj_id);
break;
case questLatestProgress:
case questProgress:
this.required_obj = proj.getQuest(required_obj_id);
if (this.required_obj != null && this.required_value != null) {
QuestStage stage = ((Quest) this.required_obj).getStage(this.required_value);
if (stage != null) {
stage.addBacklink((GameDataElement) this.parent);
}
}
break;
case consumedBonemeals:
case skillLevel:
case spentGold:
case timerElapsed:
case factionScore:
case factionScoreEquals:
case random:
case date:
case dateEquals:
case time:
case timeEquals:
break;
}
if (this.required_obj != null) this.required_obj.addBacklink((GameDataElement) this.parent);
this.state = State.linked;
}
@Override
public GameDataElement clone() {
return clone(null);
}
public GameDataElement clone(GameDataElement parent) {
Requirement clone = new Requirement();
clone.parent = parent;
clone.jsonFile = this.jsonFile;
clone.state = this.state;
clone.required_obj_id = this.required_obj_id;
clone.required_value = this.required_value;
clone.negated = this.negated;
clone.required_obj = this.required_obj;
clone.type = this.type;
if (clone.required_obj != null && parent != null) {
clone.required_obj.addBacklink(parent);
}
return clone;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (this.required_obj == oldOne) {
oldOne.removeBacklink((GameDataElement) this.parent);
this.required_obj = newOne;
if (newOne != null) newOne.addBacklink((GameDataElement) this.parent);
}
if (oldOne instanceof QuestStage) {
if (this.required_obj != null && this.required_obj.equals(oldOne.parent) && this.required_value != null && this.required_value.equals(((QuestStage) oldOne).progress)) {
oldOne.removeBacklink((GameDataElement) this.parent);
if (newOne != null) newOne.addBacklink((GameDataElement) this.parent);
}
}
}
@Override
public String getProjectFilename() {
throw new Error("Thou shalt not reach this method.");
}
public void changeType(RequirementType destType) {
if (COMPATIBLE_TYPES.get(type) == null || !COMPATIBLE_TYPES.get(type).contains(destType)) {
required_obj = null;
required_obj_id = null;
required_value = null;
}
if (destType == RequirementType.random) {
required_obj_id = "50/100";
}
type = destType;
}
} }

View File

@@ -1,46 +1,45 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist; import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
public class ContainerArea extends MapObject { public class ContainerArea extends MapObject {
public Droplist droplist = null; public Droplist droplist = null;
public ContainerArea(tiled.core.MapObject obj) { public ContainerArea(tiled.core.MapObject obj) {}
}
@Override
@Override public void link() {
public void link() { droplist = parentMap.getProject().getDroplist(name);
droplist = parentMap.getProject().getDroplist(name); if (droplist != null) {
if (droplist != null) { droplist.addBacklink(parentMap);
droplist.addBacklink(parentMap); }
} }
}
@Override
@Override public Image getIcon() {
public Image getIcon() { if (droplist != null) return DefaultIcons.getContainerIcon();
if (droplist != null) return DefaultIcons.getContainerIcon(); else return DefaultIcons.getNullifyIcon();
else return DefaultIcons.getNullifyIcon(); }
}
@Override
@Override public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { if (oldOne == droplist) {
if (oldOne == droplist) { oldOne.removeBacklink(parentMap);
oldOne.removeBacklink(parentMap); droplist = (Droplist) newOne;
droplist = (Droplist) newOne; if (newOne != null) newOne.addBacklink(parentMap);
if (newOne != null) newOne.addBacklink(parentMap); }
} }
}
@Override
@Override public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) { if (droplist != null) {
if (droplist != null) { tmxObject.setName(droplist.id);
tmxObject.setName(droplist.id); }
} }
}
} }

View File

@@ -1,117 +1,116 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue; import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement; import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
public class KeyArea extends MapObject { public class KeyArea extends MapObject {
public String dialogue_id; public String dialogue_id = null;
public Dialogue dialogue = null; public Dialogue dialogue = null;
public Requirement requirement; public Requirement requirement = null;
public boolean oldSchoolRequirement; public boolean oldSchoolRequirement = true;
public KeyArea(tiled.core.MapObject obj) {
dialogue_id = obj.getProperties().getProperty("phrase");
String requireType = obj.getProperties().getProperty("requireType");
String requireId = obj.getProperties().getProperty("requireId");
String requireValue = obj.getProperties().getProperty("requireValue");
String requireNegation = obj.getProperties().getProperty("requireNegation");
oldSchoolRequirement = false;
if (requireType == null) {
String[] fields = obj.getName().split(":");
if (fields.length == 2) {
requireType = Requirement.RequirementType.questProgress.toString();
requireValue = fields[1];
requireId = fields[0];
oldSchoolRequirement = true;
} else if (fields.length == 3) {
requireValue = fields[2];
requireType = fields[0];
requireId = fields[1];
oldSchoolRequirement = true;
}
}
requirement = new Requirement();
if (requireType != null) requirement.type = Requirement.RequirementType.valueOf(requireType);
requirement.required_obj_id = requireId;
if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue);
if (requireNegation != null) requirement.negated = Boolean.parseBoolean(requireNegation);
requirement.state = GameDataElement.State.parsed;
}
@Override
public void link() {
if (dialogue_id != null) dialogue = parentMap.getProject().getDialogue(dialogue_id);
if (dialogue != null) {
dialogue.addBacklink(parentMap);
}
requirement.parent = parentMap;
requirement.link();
}
@Override
public Image getIcon() {
if (dialogue != null && requirement != null) return DefaultIcons.getKeyIcon();
return DefaultIcons.getNullifyIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
if (newOne != null) newOne.addBacklink(parentMap);
}
requirement.elementChanged(oldOne, newOne);
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (dialogue != null) {
tmxObject.getProperties().setProperty("phrase", dialogue.id);
} else if (dialogue_id != null) {
tmxObject.getProperties().setProperty("phrase", dialogue_id);
}
if (requirement != null) {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
tmxObject.setName(requirement.required_obj_id+":"+((requirement.required_value == null) ? "" : Integer.toString(requirement.required_value)));
} else {
if (requirement.type != null) {
tmxObject.getProperties().setProperty("requireType", requirement.type.toString());
}
if (requirement.required_obj != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id);
} else if (requirement.required_obj_id != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id);
}
if (requirement.required_value != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString());
}
if (requirement.negated != null) {
tmxObject.getProperties().setProperty("requireNegation", Boolean.toString(requirement.negated));
}
}
}
}
public KeyArea(tiled.core.MapObject obj) { public void updateNameFromRequirementChange() {
dialogue_id = obj.getProperties().getProperty("phrase"); if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
String requireType = obj.getProperties().getProperty("requireType"); name = (requirement.negated != null && requirement.negated) ? "NOT " : "" + requirement.required_obj_id+":"+((requirement.required_value == null) ? "" : Integer.toString(requirement.required_value));
String requireId = obj.getProperties().getProperty("requireId"); } else if (oldSchoolRequirement) {
String requireValue = obj.getProperties().getProperty("requireValue"); int i = 0;
String requireNegation = obj.getProperties().getProperty("requireNegation"); String futureName = requirement.type.toString() + "#" + Integer.toString(i);
oldSchoolRequirement = false; while (parentMap.getMapObject(futureName) != null) {
if (requireType == null) { i++;
String[] fields = obj.getName().split(":"); futureName = requirement.type.toString() + "#" + Integer.toString(i);
if (fields.length == 2) { }
requireType = Requirement.RequirementType.questProgress.toString(); this.name = futureName;
requireValue = fields[1]; }
requireId = fields[0]; }
oldSchoolRequirement = true;
} else if (fields.length == 3) {
requireValue = fields[2];
requireType = fields[0];
requireId = fields[1];
oldSchoolRequirement = true;
}
}
requirement = new Requirement();
if (requireType != null) requirement.type = Requirement.RequirementType.valueOf(requireType);
requirement.required_obj_id = requireId;
if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue);
if (requireNegation != null) requirement.negated = Boolean.parseBoolean(requireNegation);
requirement.state = GameDataElement.State.parsed;
}
@Override
public void link() {
if (dialogue_id != null) dialogue = parentMap.getProject().getDialogue(dialogue_id);
if (dialogue != null) {
dialogue.addBacklink(parentMap);
}
requirement.parent = parentMap;
requirement.link();
}
@Override
public Image getIcon() {
if (dialogue != null && requirement != null) return DefaultIcons.getKeyIcon();
return DefaultIcons.getNullifyIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
if (newOne != null) newOne.addBacklink(parentMap);
}
requirement.elementChanged(oldOne, newOne);
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (dialogue != null) {
tmxObject.getProperties().setProperty("phrase", dialogue.id);
} else if (dialogue_id != null) {
tmxObject.getProperties().setProperty("phrase", dialogue_id);
}
if (requirement != null) {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
tmxObject.setName(requirement.required_obj_id + ":" + ((requirement.required_value == null) ? "" : Integer.toString(requirement.required_value)));
} else {
if (requirement.type != null) {
tmxObject.getProperties().setProperty("requireType", requirement.type.toString());
}
if (requirement.required_obj != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id);
} else if (requirement.required_obj_id != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id);
}
if (requirement.required_value != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString());
}
if (requirement.negated != null) {
tmxObject.getProperties().setProperty("requireNegation", Boolean.toString(requirement.negated));
}
}
}
}
public void updateNameFromRequirementChange() {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
name = (requirement.negated != null && requirement.negated) ? "NOT " : "" + requirement.required_obj_id + ":" + ((requirement.required_value == null) ? "" : Integer.toString(
requirement.required_value));
} else if (oldSchoolRequirement) {
int i = 0;
String futureName = requirement.type.toString() + "#" + Integer.toString(i);
while (parentMap.getMapObject(futureName) != null) {
i++;
futureName = requirement.type.toString() + "#" + Integer.toString(i);
}
this.name = futureName;
}
}
} }

View File

@@ -1,57 +1,58 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
public class MapChange extends MapObject { public class MapChange extends MapObject {
public String map_id; public String map_id = null;
public TMXMap map = null; public TMXMap map = null;
public String place_id; public String place_id = null;
public MapChange(tiled.core.MapObject obj) {
this.map_id = obj.getProperties().getProperty("map");
this.place_id = obj.getProperties().getProperty("place");
}
public MapChange(tiled.core.MapObject obj) { @Override
this.map_id = obj.getProperties().getProperty("map"); public void link() {
this.place_id = obj.getProperties().getProperty("place"); if (map_id != null) this.map = parentMap.getProject().getMap(map_id);
} if (map != null) {
map.addBacklink(parentMap);
@Override }
public void link() { //TODO reinstate this if data validation system ever exist.
if (map_id != null) this.map = parentMap.getProject().getMap(map_id);
if (map != null) {
map.addBacklink(parentMap);
}
//TODO reinstate this if data validation system ever exist.
// else Notification.addWarn("Incomplete mapchange area \""+name+"\" in map \""+parentMap.id+"\". This is OK if it's an arrival only (no exit through this point)."); // else Notification.addWarn("Incomplete mapchange area \""+name+"\" in map \""+parentMap.id+"\". This is OK if it's an arrival only (no exit through this point).");
} }
@Override @Override
public Image getIcon() { public Image getIcon() {
if (name != null) return DefaultIcons.getTiledIconIcon(); if (name != null) return DefaultIcons.getTiledIconIcon();
else return DefaultIcons.getNullifyIcon(); else return DefaultIcons.getNullifyIcon();
} }
@Override @Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (oldOne == map) { if (oldOne == map) {
oldOne.removeBacklink(parentMap); oldOne.removeBacklink(parentMap);
map = (TMXMap) newOne; map = (TMXMap) newOne;
if (newOne != null) newOne.addBacklink(parentMap); if (newOne != null) newOne.addBacklink(parentMap);
} }
} }
@Override @Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) { public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (map != null) { if (map != null) {
tmxObject.getProperties().setProperty("map", map.id); tmxObject.getProperties().setProperty("map", map.id);
} else if (map_id != null) { } else if (map_id != null) {
tmxObject.getProperties().setProperty("map", map_id); tmxObject.getProperties().setProperty("map", map_id);
} }
if (place_id != null) { if (place_id != null) {
tmxObject.getProperties().setProperty("place", place_id); tmxObject.getProperties().setProperty("place", place_id);
} }
} }
} }

View File

@@ -1,171 +1,171 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
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 java.awt.*;
public abstract class MapObject { public abstract class MapObject {
public int x, y, w, h; public int x, y, w, h;
public String name; public String name;
public TMXMap parentMap;
public Types type;
protected static enum Types {
mapchange,
spawn,
rest,
key,
replace,
script,
container,
sign
}
public static MapObject buildObject(tiled.core.MapObject obj, TMXMap parentMap) {
MapObject result = null;
if (obj.getType() != null && !obj.getType().equals("") && Types.valueOf(obj.getType()) != null) {
switch (Types.valueOf(obj.getType())) {
case key:
result = new KeyArea(obj);
result.type = Types.key;
break;
case mapchange:
result = new MapChange(obj);
result.type = Types.mapchange;
break;
case replace:
result = new ReplaceArea(obj);
result.type = Types.replace;
break;
case rest:
result = new RestArea(obj);
result.type = Types.rest;
break;
case script:
result = new ScriptArea(obj);
result.type = Types.script;
break;
case sign:
result = new SignArea(obj);
result.type = Types.sign;
break;
case spawn:
result = new SpawnArea(obj);
result.type = Types.spawn;
break;
case container:
result = new ContainerArea(obj);
result.type = Types.container;
break;
}
} else {
Notification.addWarn("Unknown map object type: "+obj.getType()+"with name "+obj.getName()+" in map "+parentMap.id);
}
if (result != null) {
result.x = obj.getX();
result.y = obj.getY();
result.w = obj.getWidth();
result.h = obj.getHeight();
result.name = obj.getName();
result.parentMap = parentMap;
}
return result;
}
public abstract void link();
public TMXMap parentMap; public abstract Image getIcon();
public Types type; public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne);
protected static enum Types { public tiled.core.MapObject toTmxObject() {
mapchange, tiled.core.MapObject tmxObject = new tiled.core.MapObject(x, y, w, h);
spawn, tmxObject.setName(name);
rest, tmxObject.setType(type.toString());
key, savePropertiesInTmxObject(tmxObject);
replace, return tmxObject;
script, }
container,
sign public abstract void savePropertiesInTmxObject(tiled.core.MapObject tmxObject);
}
public static MapObject newMapchange(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Mapchange");
MapObject result = new MapChange(obj);
result.type = Types.mapchange;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newSpawnArea(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Spawnarea");
MapObject result = new SpawnArea(obj);
result.type = Types.spawn;
initObj(result, obj, parentMap);
return result;
}
public static MapObject buildObject(tiled.core.MapObject obj, TMXMap parentMap) { public static MapObject newRest(tiled.core.MapObject obj, TMXMap parentMap) {
MapObject result = null; if (obj.getName() == null) obj.setName("Rest");
if (obj.getType() != null && !obj.getType().equals("") && Types.valueOf(obj.getType()) != null) { MapObject result = new RestArea(obj);
switch (Types.valueOf(obj.getType())) { result.type = Types.rest;
case key: initObj(result, obj, parentMap);
result = new KeyArea(obj); return result;
result.type = Types.key; }
break;
case mapchange:
result = new MapChange(obj);
result.type = Types.mapchange;
break;
case replace:
result = new ReplaceArea(obj);
result.type = Types.replace;
break;
case rest:
result = new RestArea(obj);
result.type = Types.rest;
break;
case script:
result = new ScriptArea(obj);
result.type = Types.script;
break;
case sign:
result = new SignArea(obj);
result.type = Types.sign;
break;
case spawn:
result = new SpawnArea(obj);
result.type = Types.spawn;
break;
case container:
result = new ContainerArea(obj);
result.type = Types.container;
break;
}
} else {
Notification.addWarn("Unknown map object type: " + obj.getType() + "with name " + obj.getName() + " in map " + parentMap.id);
}
if (result != null) {
result.x = obj.getX();
result.y = obj.getY();
result.w = obj.getWidth();
result.h = obj.getHeight();
result.name = obj.getName();
result.parentMap = parentMap;
}
return result;
}
public abstract void link(); public static MapObject newKey(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Key");
MapObject result = new KeyArea(obj);
result.type = Types.key;
initObj(result, obj, parentMap);
return result;
}
public abstract Image getIcon(); public static MapObject newReplace(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Replace");
MapObject result = new ReplaceArea(obj);
result.type = Types.replace;
initObj(result, obj, parentMap);
return result;
}
public abstract void elementChanged(GameDataElement oldOne, GameDataElement newOne); public static MapObject newScript(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Script");
public tiled.core.MapObject toTmxObject() { MapObject result = new ScriptArea(obj);
tiled.core.MapObject tmxObject = new tiled.core.MapObject(x, y, w, h); result.type = Types.script;
tmxObject.setName(name); initObj(result, obj, parentMap);
tmxObject.setType(type.toString()); return result;
savePropertiesInTmxObject(tmxObject); }
return tmxObject;
}
public abstract void savePropertiesInTmxObject(tiled.core.MapObject tmxObject);
public static MapObject newMapchange(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Mapchange");
MapObject result = new MapChange(obj);
result.type = Types.mapchange;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newSpawnArea(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Spawnarea");
MapObject result = new SpawnArea(obj);
result.type = Types.spawn;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newRest(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Rest");
MapObject result = new RestArea(obj);
result.type = Types.rest;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newKey(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Key");
MapObject result = new KeyArea(obj);
result.type = Types.key;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newReplace(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Replace");
MapObject result = new ReplaceArea(obj);
result.type = Types.replace;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newScript(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Script");
MapObject result = new ScriptArea(obj);
result.type = Types.script;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newContainer(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Container");
MapObject result = new ContainerArea(obj);
result.type = Types.container;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newSign(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Sign");
MapObject result = new SignArea(obj);
result.type = Types.sign;
initObj(result, obj, parentMap);
return result;
}
private static MapObject initObj(MapObject result, tiled.core.MapObject obj, TMXMap parentMap) {
result.x = obj.getX();
result.y = obj.getY();
result.w = obj.getWidth();
result.h = obj.getHeight();
result.name = obj.getName();
result.parentMap = parentMap;
return result;
}
public static MapObject newContainer(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Container");
MapObject result = new ContainerArea(obj);
result.type = Types.container;
initObj(result, obj, parentMap);
return result;
}
public static MapObject newSign(tiled.core.MapObject obj, TMXMap parentMap) {
if (obj.getName() == null) obj.setName("Sign");
MapObject result = new SignArea(obj);
result.type = Types.sign;
initObj(result, obj, parentMap);
return result;
}
private static MapObject initObj(MapObject result, tiled.core.MapObject obj, TMXMap parentMap) {
result.x = obj.getX();
result.y = obj.getY();
result.w = obj.getWidth();
result.h = obj.getHeight();
result.name = obj.getName();
result.parentMap = parentMap;
return result;
}
} }

View File

@@ -1,60 +1,60 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
public class MapObjectGroup { public class MapObjectGroup {
public tiled.core.ObjectGroup tmxGroup;
public TMXMap parentMap;
public String name;
public boolean visible;
public List<MapObject> mapObjects = new ArrayList<MapObject>();
public Boolean active;
public MapObjectGroup(tiled.core.ObjectGroup layer, TMXMap map) {
this.tmxGroup = layer;
this.name = layer.getName();
this.visible = layer.isVisible();
this.parentMap = map;
if (layer.getProperties().get("active") != null) {
active = new Boolean(((String) layer.getProperties().get("active")));
} else {
active = true;
}
for (tiled.core.MapObject obj : layer.getObjectsList()) {
mapObjects.add(MapObject.buildObject(obj, map));
}
}
public tiled.core.ObjectGroup tmxGroup; public void link() {
public TMXMap parentMap; for (MapObject obj : mapObjects) {
public String name; obj.link();
public boolean visible; }
public List<MapObject> mapObjects = new ArrayList<MapObject>(); }
public Boolean active;
public MapObjectGroup(tiled.core.ObjectGroup layer, TMXMap map) { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
this.tmxGroup = layer; for (MapObject object : mapObjects) {
this.name = layer.getName(); object.elementChanged(oldOne, newOne);
this.visible = layer.isVisible(); }
this.parentMap = map; }
if (layer.getProperties().get("active") != null) {
active = new Boolean(((String) layer.getProperties().get("active")));
} else {
active = true;
}
for (tiled.core.MapObject obj : layer.getObjectsList()) {
mapObjects.add(MapObject.buildObject(obj, map));
}
}
public void link() { public void pushBackToTiledProperties() {
for (MapObject obj : mapObjects) { if (tmxGroup != null) {
obj.link(); tmxGroup.clear();
} } else {
} tmxGroup = new tiled.core.ObjectGroup();
}
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { tmxGroup.setVisible(visible);
for (MapObject object : mapObjects) { tmxGroup.setName(name);
object.elementChanged(oldOne, newOne); if (!active) {
} tmxGroup.getProperties().put("active", Boolean.toString(active));
} }
for (MapObject object : mapObjects) {
public void pushBackToTiledProperties() { tmxGroup.addObject(object.toTmxObject());
if (tmxGroup != null) { }
tmxGroup.clear(); }
} else {
tmxGroup = new tiled.core.ObjectGroup();
}
tmxGroup.setVisible(visible);
tmxGroup.setName(name);
if (!active) {
tmxGroup.getProperties().put("active", Boolean.toString(active));
}
for (MapObject object : mapObjects) {
tmxGroup.addObject(object.toTmxObject());
}
}
} }

View File

@@ -1,134 +1,149 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement; import com.gpl.rpg.atcontentstudio.model.gamedata.Requirement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class ReplaceArea extends MapObject { public class ReplaceArea extends MapObject {
public Requirement requirement; public Requirement requirement = null;
public boolean oldSchoolRequirement = false; public boolean oldSchoolRequirement = false;
public List<ReplaceArea.Replacement> replacements = null;
public List<ReplaceArea.Replacement> replacements = null; public ReplaceArea(tiled.core.MapObject obj) {
String requireType = obj.getProperties().getProperty("requireType");
public ReplaceArea(tiled.core.MapObject obj) { String requireId = obj.getProperties().getProperty("requireId");
String requireType = obj.getProperties().getProperty("requireType"); String requireValue = obj.getProperties().getProperty("requireValue");
String requireId = obj.getProperties().getProperty("requireId"); String requireNegation = obj.getProperties().getProperty("requireNegation");
String requireValue = obj.getProperties().getProperty("requireValue"); if (requireType == null) {
String requireNegation = obj.getProperties().getProperty("requireNegation"); String[] fields = obj.getName().split(":");
if (requireType == null) { if (fields.length == 2) {
String[] fields = obj.getName().split(":"); requireType = Requirement.RequirementType.questProgress.toString();
if (fields.length == 2) { requireValue = fields[1];
requireType = Requirement.RequirementType.questProgress.toString(); requireId = fields[0];
requireValue = fields[1]; oldSchoolRequirement = true;
requireId = fields[0]; } /*else if (fields.length == 3) {
oldSchoolRequirement = true;
} /*else if (fields.length == 3) {
requireValue = fields[2]; requireValue = fields[2];
requireType = fields[0]; requireType = fields[0];
requireId = fields[1]; requireId = fields[1];
}*/ }*/
} }
requirement = new Requirement(); requirement = new Requirement();
if (requireType != null) requirement.type = Requirement.RequirementType.valueOf(requireType); if (requireType != null) requirement.type = Requirement.RequirementType.valueOf(requireType);
requirement.required_obj_id = requireId; requirement.required_obj_id = requireId;
if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue); if (requireValue != null) requirement.required_value = Integer.parseInt(requireValue);
if (requireNegation != null) requirement.negated = Boolean.parseBoolean(requireNegation); if (requireNegation != null) requirement.negated = Boolean.parseBoolean(requireNegation);
requirement.state = GameDataElement.State.parsed; requirement.state = GameDataElement.State.parsed;
for (Object s : obj.getProperties().keySet()) {
if (!TMXMap.isPaintedLayerName(s.toString())) continue;
if (replacements == null) replacements = new ArrayList<ReplaceArea.Replacement>();
replacements.add(new Replacement(s.toString(), obj.getProperties().getProperty(s.toString())));
}
}
@Override
public void link() {
requirement.parent = parentMap;
requirement.link();
}
@Override
public Image getIcon() {
return DefaultIcons.getReplaceIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
requirement.elementChanged(oldOne, newOne);
}
public ReplaceArea.Replacement addReplacement(String source, String target) {
Replacement repl = new Replacement(source, target);
addReplacement(repl);
return repl;
}
public ReplaceArea.Replacement createReplacement(String source, String target) {
return new Replacement(source, target);
}
public void addReplacement(ReplaceArea.Replacement repl) {
if (replacements == null) replacements = new ArrayList<ReplaceArea.Replacement>();
replacements.add(repl);
}
// public void removeReplacement(String source, String target) {
// replacedLayers.remove(source);
// }
public void removeReplacement(Replacement repl) {
replacements.remove(repl);
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (replacements != null) {
for(Replacement r : replacements)
tmxObject.getProperties().setProperty(r.sourceLayer, r.targetLayer);
}
if (requirement != null) {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
tmxObject.setName(requirement.required_obj_id+":"+((requirement.required_value == null) ? "" : Integer.toString(requirement.required_value)));
} else {
if (requirement.type != null) {
tmxObject.getProperties().setProperty("requireType", requirement.type.toString());
}
if (requirement.required_obj != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id);
} else if (requirement.required_obj_id != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id);
}
if (requirement.required_value != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString());
}
if (requirement.negated != null) {
tmxObject.getProperties().setProperty("requireNegation", Boolean.toString(requirement.negated));
}
}
}
}
for (Object s : obj.getProperties().keySet()) { //Don't use yet !
if (!TMXMap.isPaintedLayerName(s.toString())) continue; public void updateNameFromRequirementChange() {
if (replacements == null) replacements = new ArrayList<ReplaceArea.Replacement>(); if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
replacements.add(new Replacement(s.toString(), obj.getProperties().getProperty(s.toString()))); name = (requirement.negated != null && requirement.negated) ? "NOT " : "" + requirement.required_obj_id+":"+((requirement.required_value == null) ? "" : Integer.toString(requirement.required_value));
} } else if (oldSchoolRequirement) {
int i = 0;
String futureName = requirement.type.toString() + "#" + Integer.toString(i);
while (parentMap.getMapObject(futureName) != null) {
i++;
futureName = requirement.type.toString() + "#" + Integer.toString(i);
}
this.name = futureName;
}
}
public class Replacement {
public String sourceLayer, targetLayer;
public Replacement(String source, String target) {
this.sourceLayer = source;
this.targetLayer = target;
}
}
} public boolean hasReplacementFor(String name) {
if (name == null) return false;
@Override for (Replacement repl : replacements) {
public void link() { if (name.equalsIgnoreCase(repl.sourceLayer)) return true;
requirement.parent = parentMap; }
requirement.link(); return false;
} }
@Override
public Image getIcon() {
return DefaultIcons.getReplaceIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
requirement.elementChanged(oldOne, newOne);
}
public ReplaceArea.Replacement createReplacement(String source, String target) {
Replacement repl = new Replacement(source, target);
return repl;
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (replacements != null) {
for (Replacement r : replacements)
tmxObject.getProperties().setProperty(r.sourceLayer, r.targetLayer);
}
if (requirement != null) {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
tmxObject.setName(requirement.required_obj_id + ":" + ((requirement.required_value == null) ? "" : Integer.toString(requirement.required_value)));
} else {
if (requirement.type != null) {
tmxObject.getProperties().setProperty("requireType", requirement.type.toString());
}
if (requirement.required_obj != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj.id);
} else if (requirement.required_obj_id != null) {
tmxObject.getProperties().setProperty("requireId", requirement.required_obj_id);
}
if (requirement.required_value != null) {
tmxObject.getProperties().setProperty("requireValue", requirement.required_value.toString());
}
if (requirement.negated != null) {
tmxObject.getProperties().setProperty("requireNegation", Boolean.toString(requirement.negated));
}
}
}
}
//Don't use yet !
public void updateNameFromRequirementChange() {
if (oldSchoolRequirement && Requirement.RequirementType.questProgress.equals(requirement.type) && (requirement.negated == null || !requirement.negated)) {
name = (requirement.negated != null && requirement.negated) ? "NOT " : "" + requirement.required_obj_id + ":" + ((requirement.required_value == null) ? "" : Integer.toString(
requirement.required_value));
} else if (oldSchoolRequirement) {
int i = 0;
String futureName = requirement.type.toString() + "#" + Integer.toString(i);
while (parentMap.getMapObject(futureName) != null) {
i++;
futureName = requirement.type.toString() + "#" + Integer.toString(i);
}
this.name = futureName;
}
}
public class Replacement {
public String sourceLayer, targetLayer;
public Replacement(String source, String target) {
this.sourceLayer = source;
this.targetLayer = target;
}
}
public boolean hasReplacementFor(String name) {
if (name == null) return false;
for (Replacement repl : replacements) {
if (name.equalsIgnoreCase(repl.sourceLayer)) return true;
}
return false;
}
} }

View File

@@ -1,33 +1,31 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
public class RestArea extends MapObject { public class RestArea extends MapObject {
public RestArea(tiled.core.MapObject obj) { public RestArea(tiled.core.MapObject obj) {}
}
@Override
public void link() {
}
@Override
public Image getIcon() {
return DefaultIcons.getRestIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
}
@Override
public void link() {}
@Override
public Image getIcon() {
return DefaultIcons.getRestIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
}
} }

View File

@@ -1,61 +1,61 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue; import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
public class ScriptArea extends MapObject { public class ScriptArea extends MapObject {
public Dialogue dialogue = null;
public EvaluationTrigger trigger_type = null;
public enum EvaluationTrigger {
enter,
step,
round,
always
}
public Dialogue dialogue = null; public ScriptArea(tiled.core.MapObject obj) {
public EvaluationTrigger trigger_type = null; String triggerTypeId = obj.getProperties().getProperty("when");
if (triggerTypeId != null) {
public enum EvaluationTrigger { trigger_type = EvaluationTrigger.valueOf(triggerTypeId);
enter, }
step, }
round,
always @Override
} public void link() {
if (name != null) dialogue = parentMap.getProject().getDialogue(name);
public ScriptArea(tiled.core.MapObject obj) { if (dialogue != null) {
String triggerTypeId = obj.getProperties().getProperty("when"); dialogue.addBacklink(parentMap);
if (triggerTypeId != null) { }
trigger_type = EvaluationTrigger.valueOf(triggerTypeId); }
}
} @Override
public Image getIcon() {
@Override if (dialogue != null) return DefaultIcons.getScriptIcon();
public void link() { else return DefaultIcons.getNullifyIcon();
if (name != null) dialogue = parentMap.getProject().getDialogue(name); }
if (dialogue != null) {
dialogue.addBacklink(parentMap); @Override
} public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
@Override dialogue = (Dialogue) newOne;
public Image getIcon() { if (newOne != null) newOne.addBacklink(parentMap);
if (dialogue != null) return DefaultIcons.getScriptIcon(); }
else return DefaultIcons.getNullifyIcon(); }
}
@Override
@Override public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { if (dialogue != null) {
if (oldOne == dialogue) { tmxObject.setName(dialogue.id);
oldOne.removeBacklink(parentMap); }
dialogue = (Dialogue) newOne; if (trigger_type != null) {
if (newOne != null) newOne.addBacklink(parentMap); tmxObject.getProperties().setProperty("when", trigger_type.toString());
} }
} }
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (dialogue != null) {
tmxObject.setName(dialogue.id);
}
if (trigger_type != null) {
tmxObject.getProperties().setProperty("when", trigger_type.toString());
}
}
} }

View File

@@ -1,47 +1,47 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue; import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
public class SignArea extends MapObject { public class SignArea extends MapObject {
public Dialogue dialogue = null; public Dialogue dialogue = null;
public SignArea(tiled.core.MapObject obj) { public SignArea(tiled.core.MapObject obj) {
} }
@Override
public void link() {
if (name != null) dialogue = parentMap.getProject().getDialogue(name);
if (dialogue != null) {
dialogue.addBacklink(parentMap);
}
}
@Override
public Image getIcon() {
if (dialogue != null) return DefaultIcons.getSignIcon();
else return DefaultIcons.getNullifyIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
if (newOne != null) newOne.addBacklink(parentMap);
}
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (dialogue != null) {
tmxObject.setName(dialogue.id);
}
}
@Override
public void link() {
if (name != null) dialogue = parentMap.getProject().getDialogue(name);
if (dialogue != null) {
dialogue.addBacklink(parentMap);
}
}
@Override
public Image getIcon() {
if (dialogue != null) return DefaultIcons.getSignIcon();
else return DefaultIcons.getNullifyIcon();
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
if (newOne != null) newOne.addBacklink(parentMap);
}
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (dialogue != null) {
tmxObject.setName(dialogue.id);
}
}
} }

View File

@@ -1,95 +1,95 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC; import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class SpawnArea extends MapObject { public class SpawnArea extends MapObject {
public int quantity = 1; public int quantity = 1;
public int respawnSpeed = 10; public int respawnSpeed = 10;
public boolean active = true; public boolean active = true;
public boolean ignoreAreas = false; public boolean ignoreAreas = false;
public String spawngroup_id; public String spawngroup_id;
public List<NPC> spawnGroup = new ArrayList<NPC>(); public List<NPC> spawnGroup = new ArrayList<NPC>();
public SpawnArea(tiled.core.MapObject obj) {
if (obj.getProperties().getProperty("quantity") != null) {
this.quantity = Integer.parseInt(obj.getProperties().getProperty("quantity"));
}
if (obj.getProperties().getProperty("respawnspeed") != null) {
this.respawnSpeed = Integer.parseInt(obj.getProperties().getProperty("respawnspeed"));
}
if (obj.getProperties().getProperty("active") != null) {
this.active = Boolean.parseBoolean(obj.getProperties().getProperty("active"));
}
if (obj.getProperties().getProperty("ignoreAreas") != null) {
this.ignoreAreas = Boolean.parseBoolean(obj.getProperties().getProperty("ignoreAreas"));
}
if (obj.getProperties().getProperty("spawngroup") != null) {
this.spawngroup_id = obj.getProperties().getProperty("spawngroup");
} else if (obj.getName() != null ){
this.spawngroup_id = obj.getName();
}
}
public SpawnArea(tiled.core.MapObject obj) { @Override
if (obj.getProperties().getProperty("quantity") != null) { public void link() {
this.quantity = Integer.parseInt(obj.getProperties().getProperty("quantity")); if (spawngroup_id != null) {
} spawnGroup = parentMap.getProject().getSpawnGroup(spawngroup_id);
if (obj.getProperties().getProperty("respawnspeed") != null) { } else {
this.respawnSpeed = Integer.parseInt(obj.getProperties().getProperty("respawnspeed")); spawnGroup = new ArrayList<NPC>();
} }
if (obj.getProperties().getProperty("active") != null) { if (spawnGroup != null) {
this.active = Boolean.parseBoolean(obj.getProperties().getProperty("active")); for (NPC npc : spawnGroup) {
} npc.addBacklink(parentMap);
if (obj.getProperties().getProperty("ignoreAreas") != null) { }
this.ignoreAreas = Boolean.parseBoolean(obj.getProperties().getProperty("ignoreAreas")); }
} }
if (obj.getProperties().getProperty("spawngroup") != null) {
this.spawngroup_id = obj.getProperties().getProperty("spawngroup"); @Override
} else if (obj.getName() != null) { public Image getIcon() {
this.spawngroup_id = obj.getName(); if (spawnGroup != null && !spawnGroup.isEmpty()) {
} return spawnGroup.get(0).getIcon();
} }
return DefaultIcons.getNullifyIcon();
@Override }
public void link() {
if (spawngroup_id != null) { @Override
spawnGroup = parentMap.getProject().getSpawnGroup(spawngroup_id); public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
} else { int replacedIndex = -1;
spawnGroup = new ArrayList<NPC>(); for (NPC npc : spawnGroup) {
} if (npc == oldOne) {
if (spawnGroup != null) { replacedIndex = spawnGroup.indexOf(npc);
for (NPC npc : spawnGroup) { }
npc.addBacklink(parentMap); }
} if (replacedIndex >= 0) {
} oldOne.removeBacklink(parentMap);
} spawnGroup.set(replacedIndex, (NPC) newOne);
if (newOne != null) newOne.addBacklink(parentMap);
@Override }
public Image getIcon() { }
if (spawnGroup != null && !spawnGroup.isEmpty()) {
return spawnGroup.get(0).getIcon(); @Override
} public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
return DefaultIcons.getNullifyIcon(); if (spawngroup_id != null) {
} tmxObject.getProperties().setProperty("spawngroup", spawngroup_id);
}
@Override if (quantity != 1) {
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { tmxObject.getProperties().setProperty("quantity", Integer.toString(quantity));
int replacedIndex = -1; }
for (NPC npc : spawnGroup) { if (respawnSpeed != 10) {
if (npc == oldOne) { tmxObject.getProperties().setProperty("respawnspeed", Integer.toString(respawnSpeed));
replacedIndex = spawnGroup.indexOf(npc); }
} if (!this.active) {
} tmxObject.getProperties().setProperty("active", Boolean.toString(active));
if (replacedIndex >= 0) { }
oldOne.removeBacklink(parentMap); if (this.ignoreAreas) {
spawnGroup.set(replacedIndex, (NPC) newOne); tmxObject.getProperties().setProperty("ignoreAreas", Boolean.toString(ignoreAreas));
if (newOne != null) newOne.addBacklink(parentMap); }
} }
}
@Override
public void savePropertiesInTmxObject(tiled.core.MapObject tmxObject) {
if (spawngroup_id != null) {
tmxObject.getProperties().setProperty("spawngroup", spawngroup_id);
}
if (quantity != 1) {
tmxObject.getProperties().setProperty("quantity", Integer.toString(quantity));
}
if (respawnSpeed != 10) {
tmxObject.getProperties().setProperty("respawnspeed", Integer.toString(respawnSpeed));
}
if (!this.active) {
tmxObject.getProperties().setProperty("active", Boolean.toString(active));
}
if (this.ignoreAreas) {
tmxObject.getProperties().setProperty("ignoreAreas", Boolean.toString(ignoreAreas));
}
}
} }

View File

@@ -1,476 +1,478 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.tree.TreeNode;
import tiled.io.TMXMapReader;
import tiled.io.TMXMapWriter;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.*; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC; import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import tiled.io.TMXMapReader;
import tiled.io.TMXMapWriter;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class TMXMap extends GameDataElement { public class TMXMap extends GameDataElement {
private static final long serialVersionUID = 1609502879500898837L; private static final long serialVersionUID = 1609502879500898837L;
public static final String GROUND_LAYER_NAME = "Ground";
public static final String OBJECTS_LAYER_NAME = "Objects";
public static final String ABOVE_LAYER_NAME = "Above";
public static final String TOP_LAYER_NAME = "Top";
public static final String WALKABLE_LAYER_NAME = "Walkable";
public enum ColorFilter {
none,
black20,
black40,
black60,
black80,
invert,
bw,
redtint,
greentint,
bluetint
}
public File tmxFile = null;
public tiled.core.Map tmxMap = null;
public Set<Spritesheet> usedSpritesheets = null;
public List<MapObjectGroup> groups = null;
public ProjectTreeNode parent;
public Integer outside = null;
public ColorFilter colorFilter = null;
public static final String GROUND_LAYER_NAME = "Ground"; public boolean changedOnDisk = false;
public static final String OBJECTS_LAYER_NAME = "Objects"; public int dismissNextChangeNotif = 0;
public static final String ABOVE_LAYER_NAME = "Above";
public static final String TOP_LAYER_NAME = "Top";
public static final String WALKABLE_LAYER_NAME = "Walkable";
public enum ColorFilter { public TMXMap(TMXMapSet parent, File f) {
none, this.parent = parent;
black20, this.tmxFile = f;
black40, String name = f.getName();
black60, id = name.substring(0, name.length() - 4);
black80, }
invert,
bw, public void parse() {
redtint, if (this.state == GameDataElement.State.init) {
greentint, if (tmxMap != null) return;
bluetint usedSpritesheets = new HashSet<Spritesheet>();
} try {
tmxMap = new TMXMapReader().readMap(tmxFile.getAbsolutePath(), this);
if (tmxMap.getProperties().get("outdoors") != null) {
outside = new Integer(((String) tmxMap.getProperties().get("outdoors")));
}
if (tmxMap.getProperties().get("colorfilter") != null) {
colorFilter = ColorFilter.valueOf(((String) tmxMap.getProperties().get("colorfilter")));
}
} catch (FileNotFoundException e) {
Notification.addError("Impossible to load TMX map file "+tmxFile.getAbsolutePath());
} catch (Exception e) {
Notification.addError("Error while loading TMX map file "+tmxFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
}
for (tiled.core.MapLayer layer : tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) {
if (groups == null) {
groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
groups.add(group);
}
}
for (Spritesheet s : usedSpritesheets) {
s.addBacklink(this);
}
state = State.parsed;
}
}
public void create() {
if (tmxMap != null) return;
tmxMap = new tiled.core.Map(30, 30);
}
public TMXMap clone() {
TMXMap clone = new TMXMap((TMXMapSet) this.parent, this.tmxFile);
try {
clone.usedSpritesheets = new HashSet<Spritesheet>();
clone.tmxMap = new TMXMapReader().readMap(new StringReader(this.toXml()), clone);
if (clone.tmxMap.getProperties().get("outdoors") != null) {
clone.outside = new Integer(((String) clone.tmxMap.getProperties().get("outdoors")));
}
if (clone.tmxMap.getProperties().get("colorfilter") != null) {
clone.colorFilter = ColorFilter.valueOf(((String) tmxMap.getProperties().get("colorfilter")));
}
for (tiled.core.MapLayer layer : clone.tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) {
if (clone.groups == null) {
clone.groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
group.link();
clone.groups.add(group);
}
}
for (Spritesheet s : usedSpritesheets) {
s.addBacklink(clone);
}
} catch (Exception e) {
Notification.addError("Error while cloning map "+this.id+" : "+e.getMessage());
e.printStackTrace();
}
return clone;
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
public File tmxFile; @Override
public tiled.core.Map tmxMap = null; public boolean getAllowsChildren() {
public Set<Spritesheet> usedSpritesheets = null; return false;
public List<MapObjectGroup> groups = null; }
public ProjectTreeNode parent; @Override
public Integer outside = null; public TreeNode getChildAt(int arg0) {
public ColorFilter colorFilter = null; return null;
}
public boolean changedOnDisk = false; @Override
public int dismissNextChangeNotif = 0; public int getChildCount() {
return 0;
}
public TMXMap(TMXMapSet parent, File f) { @Override
this.parent = parent; public int getIndex(TreeNode arg0) {
this.tmxFile = f; return 0;
String name = f.getName(); }
id = name.substring(0, name.length() - 4);
}
public void parse() { @Override
if (this.state == GameDataElement.State.init) { public TreeNode getParent() {
if (tmxMap != null) return; return parent;
usedSpritesheets = new HashSet<Spritesheet>(); }
try {
tmxMap = new TMXMapReader().readMap(tmxFile.getAbsolutePath(), this);
if (tmxMap.getProperties().get("outdoors") != null) {
outside = new Integer(((String) tmxMap.getProperties().get("outdoors")));
}
if (tmxMap.getProperties().get("colorfilter") != null) {
colorFilter = ColorFilter.valueOf(((String) tmxMap.getProperties().get("colorfilter")));
}
} catch (FileNotFoundException e) {
Notification.addError("Impossible to load TMX map file " + tmxFile.getAbsolutePath());
} catch (Exception e) {
Notification.addError("Error while loading TMX map file " + tmxFile.getAbsolutePath() + ": " + e.getMessage());
e.printStackTrace();
}
for (tiled.core.MapLayer layer : tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) {
if (groups == null) {
groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
groups.add(group);
}
}
for (Spritesheet s : usedSpritesheets) {
s.addBacklink(this);
}
state = State.parsed;
}
}
public void create() { @Override
if (tmxMap != null) return; public boolean isLeaf() {
tmxMap = new tiled.core.Map(30, 30); return true;
} }
public TMXMap clone() { @Override
TMXMap clone = new TMXMap((TMXMapSet) this.parent, this.tmxFile); public void childrenAdded(List<ProjectTreeNode> path) {
try { path.add(0,this);
clone.usedSpritesheets = new HashSet<Spritesheet>(); parent.childrenAdded(path);
clone.tmxMap = new TMXMapReader().readMap(new StringReader(this.toXml()), clone); }
if (clone.tmxMap.getProperties().get("outdoors") != null) {
clone.outside = new Integer(((String) clone.tmxMap.getProperties().get("outdoors")));
}
if (clone.tmxMap.getProperties().get("colorfilter") != null) {
clone.colorFilter = ColorFilter.valueOf(((String) tmxMap.getProperties().get("colorfilter")));
}
for (tiled.core.MapLayer layer : clone.tmxMap.getLayers()) {
if (layer instanceof tiled.core.ObjectGroup) {
if (clone.groups == null) {
clone.groups = new ArrayList<MapObjectGroup>();
}
MapObjectGroup group = new MapObjectGroup((tiled.core.ObjectGroup) layer, this);
group.link();
clone.groups.add(group);
}
}
for (Spritesheet s : usedSpritesheets) {
s.addBacklink(clone);
}
} catch (Exception e) {
Notification.addError("Error while cloning map " + this.id + " : " + e.getMessage());
e.printStackTrace();
}
return clone; @Override
} public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenChanged(path);
}
@Override @Override
public Enumeration<ProjectTreeNode> children() { public void childrenRemoved(List<ProjectTreeNode> path) {
return null; path.add(0,this);
} parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+id;
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override @Override
public boolean getAllowsChildren() { public Image getIcon() {
return false; return DefaultIcons.getTiledIconIcon();
} }
@Override
public Image getLeafIcon() {
return DefaultIcons.getTiledIconIcon();
}
@Override
public Image getClosedIcon() {return null;}
@Override
public Image getOpenIcon() {return null;}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override public String toXml() {
public TreeNode getChildAt(int arg0) { if (outside != null && outside == 1) {
return null; tmxMap.getProperties().put("outdoors", Integer.toString(outside));
} } else {
tmxMap.getProperties().remove("outdoors");
}
if (colorFilter != null) {
tmxMap.getProperties().put("colorfilter", colorFilter.toString());
} else {
tmxMap.getProperties().remove("colorfilter");
}
for (MapObjectGroup group : groups) {
group.pushBackToTiledProperties();
if (!tmxMap.containsLayer(group.tmxGroup)) {
tmxMap.addLayer(group.tmxGroup);
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
TMXMapWriter writer = new TMXMapWriter();
writer.settings.layerCompressionMethod = TMXMapWriter.Settings.LAYER_COMPRESSION_METHOD_ZLIB;
if (getDataType() == GameSource.Type.source) {
writer.writeMap(tmxMap, baos, tmxFile.getAbsolutePath());
} else {
writer.writeMap(tmxMap, baos, ((TMXMapSet)this.parent).mapFolder.getAbsolutePath()+File.separator+"placeholder.tmx");
}
} catch (Exception e) {
Notification.addError("Error while converting map "+getDesc()+" to XML: "+e.getMessage());
e.printStackTrace();
}
return baos.toString();
}
@Override
public boolean isEmpty() {
return false;
}
@Override public void save() {
public int getChildCount() { if (writable) {
return 0; String xml = toXml();
} try {
//TODO: check in fileutils, to test the workspace's filesystem once at startup, and figure out how many of these can occur, instead of hard-coded '2'
dismissNextChangeNotif += 2;
FileWriter w = new FileWriter(tmxFile);
w.write(xml);
w.close();
this.state = State.saved;
changedOnDisk = false;
Notification.addSuccess("TMX file "+tmxFile.getAbsolutePath()+" saved.");
} catch (IOException e) {
Notification.addError("Error while writing TMX file "+tmxFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
}
}
}
@Override
public List<SaveEvent> attemptSave() {
//TODO check cases where map should be moved from altered/created to created/altered....
save();
return null;
}
@Override public void delete() {
public int getIndex(TreeNode arg0) { if (writable) {
return 0; if (tmxFile.exists()) {
} if (tmxFile.delete()) {
Notification.addSuccess("TMX file "+tmxFile.getAbsolutePath()+" deleted.");
} else {
Notification.addError("Error while deleting TMX file "+tmxFile.getAbsolutePath());
}
}
((TMXMapSet)parent).tmxMaps.remove(this);
//TODO clear blacklinks ?
}
}
@Override @Override
public TreeNode getParent() { public void link() {
return parent; if (this.state == GameDataElement.State.init) {
} parse();
}
if (this.state == GameDataElement.State.parsed) {
if (groups != null) {
for (MapObjectGroup group : groups) {
group.link();
}
}
}
}
@Override @Override
public boolean isLeaf() { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
return true; for (MapObjectGroup group : groups) {
} group.elementChanged(oldOne, newOne);
}
}
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public String getProjectFilename() {
path.add(0, this); return tmxFile.getName();
parent.childrenAdded(path); }
}
@Override public void addLayer(tiled.core.MapLayer layer) {
public void childrenChanged(List<ProjectTreeNode> path) { tmxMap.addLayer(layer);
path.add(0, this); if (layer instanceof tiled.core.ObjectGroup) {
parent.childrenChanged(path); groups.add(new MapObjectGroup((tiled.core.ObjectGroup) layer, this));
} }
}
@Override public void removeLayer(tiled.core.MapLayer layer) {
public void childrenRemoved(List<ProjectTreeNode> path) { tmxMap.removeLayer(tmxMap.getLayerIndex(layer));
path.add(0, this); if (layer instanceof tiled.core.ObjectGroup) {
parent.childrenRemoved(path); MapObjectGroup toRemove = null;
} for (MapObjectGroup group : groups) {
if (group.tmxGroup == layer) {
toRemove = group;
}
}
if (toRemove != null) {
groups.remove(toRemove);
}
}
}
@Override public MapObjectGroup getGroup(tiled.core.ObjectGroup selectedLayer) {
public void notifyCreated() { for (MapObjectGroup group : groups) {
childrenAdded(new ArrayList<ProjectTreeNode>()); if (group.tmxGroup == selectedLayer) {
} return group;
}
@Override }
public String getDesc() { return null;
return (needsSaving() ? "*" : "") + id; }
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return DefaultIcons.getTiledIconIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getTiledIconIcon();
}
@Override
public Image getClosedIcon() {
return null;
}
@Override
public Image getOpenIcon() {
return null;
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
public String toXml() {
if (outside != null && outside == 1) {
tmxMap.getProperties().put("outdoors", Integer.toString(outside));
} else {
tmxMap.getProperties().remove("outdoors");
}
if (colorFilter != null) {
tmxMap.getProperties().put("colorfilter", colorFilter.toString());
} else {
tmxMap.getProperties().remove("colorfilter");
}
for (MapObjectGroup group : groups) {
group.pushBackToTiledProperties();
if (!tmxMap.containsLayer(group.tmxGroup)) {
tmxMap.addLayer(group.tmxGroup);
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
TMXMapWriter writer = new TMXMapWriter();
writer.settings.layerCompressionMethod = TMXMapWriter.Settings.LAYER_COMPRESSION_METHOD_ZLIB;
if (getDataType() == GameSource.Type.source) {
writer.writeMap(tmxMap, baos, tmxFile.getAbsolutePath());
} else {
writer.writeMap(tmxMap, baos, ((TMXMapSet) this.parent).mapFolder.getAbsolutePath() + File.separator + "placeholder.tmx");
}
} catch (Exception e) {
Notification.addError("Error while converting map " + getDesc() + " to XML: " + e.getMessage());
e.printStackTrace();
}
return baos.toString();
}
@Override
public boolean isEmpty() {
return false;
}
public void save() {
if (writable) {
String xml = toXml();
try {
//TODO: check in fileutils, to test the workspace's filesystem once at startup, and figure out how many of these can occur, instead of hard-coded '2'
dismissNextChangeNotif += 2;
FileWriter w = new FileWriter(tmxFile);
w.write(xml);
w.close();
this.state = State.saved;
changedOnDisk = false;
Notification.addSuccess("TMX file " + tmxFile.getAbsolutePath() + " saved.");
} catch (IOException e) {
Notification.addError("Error while writing TMX file " + tmxFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
}
}
}
@Override
public List<SaveEvent> attemptSave() {
//TODO check cases where map should be moved from altered/created to created/altered....
save();
return null;
}
public void delete() {
if (writable) {
if (tmxFile.exists()) {
if (tmxFile.delete()) {
Notification.addSuccess("TMX file " + tmxFile.getAbsolutePath() + " deleted.");
} else {
Notification.addError("Error while deleting TMX file " + tmxFile.getAbsolutePath());
}
}
((TMXMapSet) parent).tmxMaps.remove(this);
//TODO clear blacklinks ?
}
}
@Override
public void link() {
if (this.state == GameDataElement.State.init) {
parse();
}
if (this.state == GameDataElement.State.parsed) {
if (groups != null) {
for (MapObjectGroup group : groups) {
group.link();
}
}
}
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
for (MapObjectGroup group : groups) {
group.elementChanged(oldOne, newOne);
}
}
@Override
public String getProjectFilename() {
return tmxFile.getName();
}
public void addLayer(tiled.core.MapLayer layer) {
tmxMap.addLayer(layer);
if (layer instanceof tiled.core.ObjectGroup) {
groups.add(new MapObjectGroup((tiled.core.ObjectGroup) layer, this));
}
}
public void removeLayer(tiled.core.MapLayer layer) {
tmxMap.removeLayer(tmxMap.getLayerIndex(layer));
if (layer instanceof tiled.core.ObjectGroup) {
MapObjectGroup toRemove = null;
for (MapObjectGroup group : groups) {
if (group.tmxGroup == layer) {
toRemove = group;
}
}
if (toRemove != null) {
groups.remove(toRemove);
}
}
}
public MapObjectGroup getGroup(tiled.core.ObjectGroup selectedLayer) {
for (MapObjectGroup group : groups) {
if (group.tmxGroup == selectedLayer) {
return group;
}
}
return null;
}
public List<String> getMapchangesNames() {
List<String> result = new ArrayList<String>();
result.add(null);
for (MapObjectGroup group : groups) {
for (MapObject obj : group.mapObjects) {
if (obj.type == MapObject.Types.mapchange) {
result.add(obj.name);
}
}
}
return result;
}
public MapObject getMapObject(String name) {
MapObject result = null;
for (MapObjectGroup group : groups) {
for (MapObject obj : group.mapObjects) {
if (obj.name.equals(name)) {
result = obj;
break;
}
}
}
return result;
}
public static boolean isPaintedLayerName(String name) {
return GROUND_LAYER_NAME.equalsIgnoreCase(name) ||
OBJECTS_LAYER_NAME.equalsIgnoreCase(name) ||
ABOVE_LAYER_NAME.equalsIgnoreCase(name) ||
TOP_LAYER_NAME.equalsIgnoreCase(name) ||
WALKABLE_LAYER_NAME.equalsIgnoreCase(name);
}
public void reload() {
tmxMap = null;
for (Spritesheet s : usedSpritesheets) {
s.elementChanged(this, null);
}
usedSpritesheets.clear();
for (MapObjectGroup g : groups) {
for (MapObject o : g.mapObjects) {
if (o instanceof ContainerArea) {
if (((ContainerArea) o).droplist != null) ((ContainerArea) o).droplist.elementChanged(this, null);
} else if (o instanceof KeyArea) {
if (((KeyArea) o).dialogue != null) ((KeyArea) o).dialogue.elementChanged(this, null);
if (((KeyArea) o).requirement != null && ((KeyArea) o).requirement.required_obj != null)
((KeyArea) o).requirement.required_obj.elementChanged(this, null);
} else if (o instanceof MapChange) {
if (((MapChange) o).map != null) ((MapChange) o).map.elementChanged(this, null);
} else if (o instanceof ReplaceArea) {
if (((ReplaceArea) o).requirement != null && ((ReplaceArea) o).requirement.required_obj != null)
((ReplaceArea) o).requirement.required_obj.elementChanged(this, null);
} else if (o instanceof RestArea) {
} else if (o instanceof ScriptArea) {
if (((ScriptArea) o).dialogue != null) ((ScriptArea) o).dialogue.elementChanged(this, null);
} else if (o instanceof SignArea) {
if (((SignArea) o).dialogue != null) ((SignArea) o).dialogue.elementChanged(this, null);
} else if (o instanceof SpawnArea) {
if (((SpawnArea) o).spawnGroup != null) {
for (NPC n : ((SpawnArea) o).spawnGroup) {
n.elementChanged(this, null);
}
}
}
}
}
groups.clear();
outside = null;
colorFilter = null;
state = GameDataElement.State.init;
this.link();
changedOnDisk = false;
for (MapChangedOnDiskListener l : listeners) {
l.mapReloaded();
}
}
public void mapChangedOnDisk() {
if (dismissNextChangeNotif > 0) {
dismissNextChangeNotif--;
} else {
changedOnDisk = true;
for (MapChangedOnDiskListener l : listeners) {
l.mapChanged();
}
}
}
public interface MapChangedOnDiskListener {
public void mapChanged();
public void mapReloaded();
}
private List<MapChangedOnDiskListener> listeners = new CopyOnWriteArrayList<TMXMap.MapChangedOnDiskListener>();
public void addMapChangedOnDiskListener(MapChangedOnDiskListener l) {
listeners.add(l);
}
public void removeMapChangedOnDiskListener(MapChangedOnDiskListener l) {
listeners.remove(l);
}
public List<String> getMapchangesNames() {
List<String> result = new ArrayList<String>();
result.add(null);
for (MapObjectGroup group : groups) {
for (MapObject obj : group.mapObjects) {
if (obj.type == MapObject.Types.mapchange) {
result.add(obj.name);
}
}
}
return result;
}
public MapObject getMapObject(String name) {
MapObject result = null;
for (MapObjectGroup group : groups) {
for (MapObject obj : group.mapObjects) {
if (obj.name.equals(name)) {
result = obj;
break;
}
}
}
return result;
}
public static boolean isPaintedLayerName(String name) {
return GROUND_LAYER_NAME.equalsIgnoreCase(name) ||
OBJECTS_LAYER_NAME.equalsIgnoreCase(name) ||
ABOVE_LAYER_NAME.equalsIgnoreCase(name) ||
TOP_LAYER_NAME.equalsIgnoreCase(name) ||
WALKABLE_LAYER_NAME.equalsIgnoreCase(name);
}
public void reload() {
tmxMap = null;
for (Spritesheet s : usedSpritesheets) {
s.elementChanged(this, null);
}
usedSpritesheets.clear();
for (MapObjectGroup g : groups) {
for (MapObject o : g.mapObjects) {
if (o instanceof ContainerArea) {
if (((ContainerArea)o).droplist != null) ((ContainerArea)o).droplist.elementChanged(this, null);
} else if (o instanceof KeyArea) {
if (((KeyArea)o).dialogue != null) ((KeyArea)o).dialogue.elementChanged(this, null);
if (((KeyArea)o).requirement != null && ((KeyArea)o).requirement.required_obj != null) ((KeyArea)o).requirement.required_obj.elementChanged(this, null);
} else if (o instanceof MapChange) {
if (((MapChange)o).map != null) ((MapChange)o).map.elementChanged(this, null);
} else if (o instanceof ReplaceArea) {
if (((ReplaceArea)o).requirement != null && ((ReplaceArea)o).requirement.required_obj != null) ((ReplaceArea)o).requirement.required_obj.elementChanged(this, null);
} else if (o instanceof RestArea) {
} else if (o instanceof ScriptArea) {
if (((ScriptArea)o).dialogue != null) ((ScriptArea)o).dialogue.elementChanged(this, null);
} else if (o instanceof SignArea) {
if (((SignArea)o).dialogue != null) ((SignArea)o).dialogue.elementChanged(this, null);
} else if (o instanceof SpawnArea) {
if (((SpawnArea)o).spawnGroup != null) {
for (NPC n : ((SpawnArea)o).spawnGroup) {
n.elementChanged(this, null);
}
}
}
}
}
groups.clear();
outside = null;
colorFilter = null;
state = GameDataElement.State.init;
this.link();
changedOnDisk = false;
for (MapChangedOnDiskListener l : listeners) {
l.mapReloaded();
}
}
public void mapChangedOnDisk() {
if (dismissNextChangeNotif > 0) {
dismissNextChangeNotif--;
} else {
changedOnDisk = true;
for (MapChangedOnDiskListener l : listeners) {
l.mapChanged();
}
}
}
public interface MapChangedOnDiskListener {
public void mapChanged();
public void mapReloaded();
}
private List<MapChangedOnDiskListener> listeners = new CopyOnWriteArrayList<TMXMap.MapChangedOnDiskListener>();
public void addMapChangedOnDiskListener(MapChangedOnDiskListener l) {
listeners.add(l);
}
public void removeMapChangedOnDiskListener(MapChangedOnDiskListener l) {
listeners.remove(l);
}
} }

View File

@@ -1,5 +1,24 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
@@ -10,272 +29,246 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils; import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class TMXMapSet implements ProjectTreeNode { public class TMXMapSet implements ProjectTreeNode {
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res" + File.separator + "xml" + File.separator; public static final String DEFAULT_REL_PATH_IN_SOURCE = "res"+File.separator+"xml"+File.separator;
public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps" + File.separator; public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps"+File.separator;
public static final String DEFAULT_REL_PATH_TO_DRAWABLE = ".." + File.separator + "drawable" + File.separator; public static final String DEFAULT_REL_PATH_TO_DRAWABLE = ".."+File.separator+"drawable"+File.separator;
public static final String GAME_MAPS_ARRAY_NAME = "loadresource_maps"; public static final String GAME_MAPS_ARRAY_NAME = "loadresource_maps";
public static final String DEBUG_SUFFIX = "_debug"; public static final String DEBUG_SUFFIX = "_debug";
public static final String RESOURCE_PREFIX = "@xml/"; public static final String RESOURCE_PREFIX = "@xml/";
public static final String FILENAME_SUFFIX = ".tmx"; public static final String FILENAME_SUFFIX = ".tmx";
public File mapFolder = null;
public List<TMXMap> tmxMaps;
public ProjectTreeNode parent;
public TMXMapSet(GameSource source) {
this.parent = source;
if (source.type == GameSource.Type.source) {
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
}
else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
if (!this.mapFolder.exists()) {
this.mapFolder.mkdirs();
}
FileUtils.makeSymlink(getProject().baseContent.gameSprites.drawableFolder, new File(mapFolder.getAbsolutePath()+File.separator+DEFAULT_REL_PATH_TO_DRAWABLE));
}
this.tmxMaps = new ArrayList<TMXMap>();
if (source.type == GameSource.Type.source && (source.parent.sourceSetToUse == ResourceSet.debugData || source.parent.sourceSetToUse == ResourceSet.gameData)) {
String suffix = (source.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : "";
if (source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME+suffix) != null) {
for (String resource : source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME+suffix)) {
File f = new File(mapFolder, resource.replaceAll(RESOURCE_PREFIX, "")+FILENAME_SUFFIX);
if (f.exists()) {
TMXMap map = new TMXMap(this, f);
tmxMaps.add(map);
} else {
Notification.addWarn("Unable to locate resource "+resource+" in the game source for project "+getProject().name);
}
}
}
} else if (this.mapFolder != null) {
for (File f : this.mapFolder.listFiles()) {
if (f.getName().endsWith(".tmx") || f.getName().endsWith(".TMX")) {
TMXMap map = new TMXMap(this, f);
if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
map.writable = true;
}
tmxMaps.add(map);
}
}
}
Collections.sort(tmxMaps, new Comparator<TMXMap>() {
@Override
public int compare(TMXMap o1, TMXMap o2) {
return o1.id.compareTo(o2.id);
}
});
if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
final Path folderPath = Paths.get(mapFolder.getAbsolutePath());
Thread watcher = new Thread("Map folder watcher for "+getProject().name+"/"+source.type) {
public void run() {
WatchService watchService;
public File mapFolder = null; while(getProject().open) {
public List<TMXMap> tmxMaps; try {
watchService = FileSystems.getDefault().newWatchService();
/*WatchKey watchKey = */folderPath.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
WatchKey wk;
validService: while(getProject().open) {
wk = watchService.poll(10, TimeUnit.SECONDS);
if (wk != null) {
for (WatchEvent<?> event : wk.pollEvents()) {
Path changed = (Path) event.context();
String name = changed.getFileName().toString();
String id = name.substring(0, name.length() - 4);
TMXMap map = getMap(id);
if (map != null) {
map.mapChangedOnDisk();
}
}
if(!wk.reset()) {
watchService.close();
break validService;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
};
watcher.start();
}
}
@Override
public Enumeration<TMXMap> children() {
return Collections.enumeration(tmxMaps);
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return tmxMaps.get(arg0);
}
@Override
public int getChildCount() {
return tmxMaps.size();
}
@Override
public int getIndex(TreeNode arg0) {
return tmxMaps.indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (TMXMap map : tmxMaps) {
map.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+"TMX Maps";
}
@Override
public Project getProject() {
return parent.getProject();
}
public ProjectTreeNode parent; @Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getTmxClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getTmxClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getTmxOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return tmxMaps.isEmpty();
}
public TMXMapSet(GameSource source) { public TMXMap getMap(String id) {
this.parent = source; if (tmxMaps == null) return null;
if (source.type == GameSource.Type.source) { for (TMXMap map : tmxMaps) {
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE); if (id.equals(map.id)){
} else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) { return map;
this.mapFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT); }
if (!this.mapFolder.exists()) { }
this.mapFolder.mkdirs(); return null;
} }
FileUtils.makeSymlink(getProject().baseContent.gameSprites.drawableFolder, new File(mapFolder.getAbsolutePath() + File.separator + DEFAULT_REL_PATH_TO_DRAWABLE));
}
this.tmxMaps = new ArrayList<TMXMap>();
if (source.type == GameSource.Type.source && (source.parent.sourceSetToUse == ResourceSet.debugData || source.parent.sourceSetToUse == ResourceSet.gameData)) { public void addMap(TMXMap node) {
String suffix = (source.parent.sourceSetToUse == ResourceSet.debugData) ? DEBUG_SUFFIX : ""; ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME + suffix) != null) { if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
for (String resource : source.referencedSourceFiles.get(GAME_MAPS_ARRAY_NAME + suffix)) { else break;
File f = new File(mapFolder, resource.replaceAll(RESOURCE_PREFIX, "") + FILENAME_SUFFIX); }
if (f.exists()) { if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
TMXMap map = new TMXMap(this, f); tmxMaps.add(node);
tmxMaps.add(map); if (node.tmxFile != null) {
} else { //Altered node.
Notification.addWarn("Unable to locate resource " + resource + " in the game source for project " + getProject().name); node.tmxFile = new File(this.mapFolder, node.tmxFile.getName());
} } else {
} //Created node.
} node.tmxFile = new File(this.mapFolder, node.id+".tmx");
}
} else if (this.mapFolder != null) { node.parent = this;
for (File f : this.mapFolder.listFiles()) { if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
if (f.getName().endsWith(".tmx") || f.getName().endsWith(".TMX")) { else node.notifyCreated();
TMXMap map = new TMXMap(this, f); }
if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
map.writable = true;
}
tmxMaps.add(map);
}
}
}
Collections.sort(tmxMaps, new Comparator<TMXMap>() {
@Override
public int compare(TMXMap o1, TMXMap o2) {
return o1.id.compareTo(o2.id);
}
});
if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
final Path folderPath = Paths.get(mapFolder.getAbsolutePath());
Thread watcher = new Thread("Map folder watcher for " + getProject().name + "/" + source.type) {
public void run() {
WatchService watchService;
while (getProject().open) {
try {
watchService = FileSystems.getDefault().newWatchService();
/*WatchKey watchKey = */
folderPath.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
WatchKey wk;
validService:
while (getProject().open) {
wk = watchService.poll(10, TimeUnit.SECONDS);
if (wk != null) {
for (WatchEvent<?> event : wk.pollEvents()) {
Path changed = (Path) event.context();
String name = changed.getFileName().toString();
String id = name.substring(0, name.length() - 4);
TMXMap map = getMap(id);
if (map != null) {
map.mapChangedOnDisk();
}
}
if (!wk.reset()) {
watchService.close();
break validService;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
watcher.start();
}
}
@Override
public Enumeration<TMXMap> children() {
return Collections.enumeration(tmxMaps);
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return tmxMaps.get(arg0);
}
@Override
public int getChildCount() {
return tmxMaps.size();
}
@Override
public int getIndex(TreeNode arg0) {
return tmxMaps.indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (TMXMap map : tmxMaps) {
map.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + "TMX Maps";
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getTmxClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getTmxClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getTmxOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return tmxMaps.isEmpty();
}
public TMXMap getMap(String id) {
if (tmxMaps == null) return null;
for (TMXMap map : tmxMaps) {
if (id.equals(map.id)) {
return map;
}
}
return null;
}
public void addMap(TMXMap node) {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode) higherEmptyParent.getParent()).isEmpty())
higherEmptyParent = (ProjectTreeNode) higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
tmxMaps.add(node);
if (node.tmxFile != null) {
//Altered node.
node.tmxFile = new File(this.mapFolder, node.tmxFile.getName());
} else {
//Created node.
node.tmxFile = new File(this.mapFolder, node.id + ".tmx");
}
node.parent = this;
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
public TMXMap get(int index) {
return tmxMaps.get(index);
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : tmxMaps) {
if (node.needsSaving()) return true;
}
return false;
}
public TMXMap get(int index) {
return tmxMaps.get(index);
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : tmxMaps) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,5 +1,40 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.gpl.rpg.atcontentstudio.model.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.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
@@ -7,272 +42,250 @@ import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.*;
public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeNode { public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeNode {
private static final long serialVersionUID = 4590409256594556179L; private static final long serialVersionUID = 4590409256594556179L;
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res/xml/worldmap.xml"; public static final String DEFAULT_REL_PATH_IN_SOURCE = "res/xml/worldmap.xml";
public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps" + File.separator + "worldmap.xml"; public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps"+File.separator+"worldmap.xml";
public File worldmapFile;
public GameSource parent;
public Map<String, Map<String, Point>> segments = new LinkedHashMap<String, Map<String,Point>>();
public File worldmapFile; public Worldmap(GameSource gameSource) {
public GameSource parent; this.parent = gameSource;
if (getDataType() == Type.source) {
worldmapFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
} else {
worldmapFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
}
if (worldmapFile.exists()) {
loadFromFile(worldmapFile);
}
if (getDataType() == Type.source) {
for (WorldmapSegment segment : this) {
segment.writable = false;
}
} else {
for (WorldmapSegment segment : this) {
segment.writable = true;
}
}
}
public Map<String, Map<String, Point>> segments = new LinkedHashMap<String, Map<String, Point>>(); private void loadFromFile(File file) {
if (!file.exists()) return;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc;
try {
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(file));
insrc.setSystemId("http://worldmap/");
insrc.setEncoding("UTF-8");
doc = builder.parse(insrc);
Element root = (Element) doc.getElementsByTagName("worldmap").item(0);
if (root != null) {
NodeList segmentsList = root.getElementsByTagName("segment");
if (segmentsList != null) {
for (int i = 0; i < segmentsList.getLength(); i++) {
Element segmentNode = (Element) segmentsList.item(i);
String name = segmentNode.getAttribute("id");
add(new WorldmapSegment(this, name, segmentNode));
}
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Worldmap(GameSource gameSource) { @Override
this.parent = gameSource; public Enumeration<WorldmapSegment> children() {
if (getDataType() == Type.source) { return Collections.enumeration(this);
worldmapFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_SOURCE); }
} else {
worldmapFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
}
if (worldmapFile.exists()) {
loadFromFile(worldmapFile);
}
if (getDataType() == Type.source) {
for (WorldmapSegment segment : this) {
segment.writable = false;
}
} else {
for (WorldmapSegment segment : this) {
segment.writable = true;
}
}
}
private void loadFromFile(File file) { @Override
if (!file.exists()) return; public boolean getAllowsChildren() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); return true;
Document doc; }
try {
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(file));
insrc.setSystemId("http://worldmap/");
insrc.setEncoding("UTF-8");
doc = builder.parse(insrc);
Element root = (Element) doc.getElementsByTagName("worldmap").item(0); @Override
if (root != null) { public TreeNode getChildAt(int arg0) {
NodeList segmentsList = root.getElementsByTagName("segment"); return get(arg0);
if (segmentsList != null) { }
for (int i = 0; i < segmentsList.getLength(); i++) {
Element segmentNode = (Element) segmentsList.item(i);
String name = segmentNode.getAttribute("id");
add(new WorldmapSegment(this, name, segmentNode));
}
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override @Override
public Enumeration<WorldmapSegment> children() { public int getChildCount() {
return Collections.enumeration(this); return size();
} }
@Override @Override
public boolean getAllowsChildren() { public int getIndex(TreeNode arg0) {
return true; return indexOf(arg0);
} }
@Override @Override
public TreeNode getChildAt(int arg0) { public TreeNode getParent() {
return get(arg0); return parent;
} }
@Override @Override
public int getChildCount() { public boolean isLeaf() {
return size(); return false;
} }
@Override @Override
public int getIndex(TreeNode arg0) { public void childrenAdded(List<ProjectTreeNode> path) {
return indexOf(arg0); path.add(0,this);
} parent.childrenAdded(path);
}
@Override @Override
public TreeNode getParent() { public void childrenChanged(List<ProjectTreeNode> path) {
return parent; path.add(0,this);
} parent.childrenChanged(path);
}
@Override @Override
public boolean isLeaf() { public void childrenRemoved(List<ProjectTreeNode> path) {
return false; if (path.size() == 1 && this.getChildCount() == 1) {
} childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public String getDesc() {
path.add(0, this); return (needsSaving() ? "*" : "")+"Worldmap";
parent.childrenAdded(path); }
} @Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public Image getIcon() {
path.add(0, this); return DefaultIcons.getMapClosedIcon();
parent.childrenChanged(path); }
} @Override
public Image getLeafIcon() {
return null;
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getMapClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getMapOpenIcon();
}
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public GameDataSet getDataSet() {
if (path.size() == 1 && this.getChildCount() == 1) { return null;
childrenRemoved(new ArrayList<ProjectTreeNode>()); }
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override @Override
public String getDesc() { public Type getDataType() {
return (needsSaving() ? "*" : "") + "Worldmap"; return parent.getDataType();
} }
@Override public void save() {
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>()); try {
} Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
doc.setXmlVersion("1.0");
Element root = doc.createElement("worldmap");
doc.appendChild(root);
@Override for (WorldmapSegment segment : this) {
public Project getProject() { root.appendChild(segment.toXmlElement(doc));
return parent.getProject(); segment.state = GameDataElement.State.saved;
} }
@Override saveDocToFile(doc, worldmapFile);
public Image getIcon() { } catch (ParserConfigurationException e) {
return DefaultIcons.getMapClosedIcon(); // TODO Auto-generated catch block
} e.printStackTrace();
}
}
@Override public WorldmapSegment getWorldmapSegment(String id) {
public Image getLeafIcon() { for (WorldmapSegment s : this) {
return null; if (s.id.equals(id)) {
} return s;
}
}
return null;
}
@Override public void addSegment(WorldmapSegment node) {
public Image getClosedIcon() { ProjectTreeNode higherEmptyParent = this;
return DefaultIcons.getMapClosedIcon(); while (higherEmptyParent != null) {
} if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
add(node);
node.parent = this;
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
@Override
public Image getOpenIcon() { public static void saveDocToFile(Document doc, File f) {
return DefaultIcons.getMapOpenIcon(); try {
} Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(new FileOutputStream(f));
@Override Source input = new DOMSource(doc);
public GameDataSet getDataSet() { transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
return null; transformer.setOutputProperty(OutputKeys.INDENT, "yes");
} transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output);
@Override } catch (TransformerConfigurationException e) {
public Type getDataType() { // TODO Auto-generated catch block
return parent.getDataType(); e.printStackTrace();
} } catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
public void save() { e.printStackTrace();
} catch (FileNotFoundException e) {
try { // TODO Auto-generated catch block
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); e.printStackTrace();
doc.setXmlVersion("1.0"); } catch (TransformerException e) {
Element root = doc.createElement("worldmap"); // TODO Auto-generated catch block
doc.appendChild(root); e.printStackTrace();
}
for (WorldmapSegment segment : this) { }
root.appendChild(segment.toXmlElement(doc));
segment.state = GameDataElement.State.saved;
}
saveDocToFile(doc, worldmapFile);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public WorldmapSegment getWorldmapSegment(String id) {
for (WorldmapSegment s : this) {
if (s.id.equals(id)) {
return s;
}
}
return null;
}
public void addSegment(WorldmapSegment node) {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode) higherEmptyParent.getParent()).isEmpty())
higherEmptyParent = (ProjectTreeNode) higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
add(node);
node.parent = this;
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
public static void saveDocToFile(Document doc, File f) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(new FileOutputStream(f));
Source input = new DOMSource(doc);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : this) {
if (node.needsSaving()) return true;
}
return false;
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : this) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,233 +1,240 @@
package com.gpl.rpg.atcontentstudio.model.maps; package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.awt.Point;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
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;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class WorldmapSegment extends GameDataElement { public class WorldmapSegment extends GameDataElement {
private static final long serialVersionUID = 2658610076889592723L; private static final long serialVersionUID = 2658610076889592723L;
public static final String TEMP_LABEL_KEY = "ATCS_INTERNAL_TEMPORARY_KEY_FOR_LABEL";
public int segmentX;
public int segmentY;
public Map<String, Point> mapLocations = new LinkedHashMap<String, Point>();
public Map<String, List<String>> labelledMaps = new LinkedHashMap<String, List<String>>();
public Map<String, NamedArea> labels = new LinkedHashMap<String, NamedArea>();
public Element xmlNode;
public WorldmapSegment(Worldmap parent, String name, Element xmlNode) {
this.parent = parent;
this.id = name;
this.xmlNode = xmlNode;
}
@Override
public GameDataSet getDataSet() {
return parent.getDataSet();
}
public static final String TEMP_LABEL_KEY = "ATCS_INTERNAL_TEMPORARY_KEY_FOR_LABEL"; @Override
public String getDesc() {
return (needsSaving() ? "*" : "")+id;
}
public int segmentX; @Override
public int segmentY; public void parse() {
public Map<String, Point> mapLocations = new LinkedHashMap<String, Point>(); segmentX = Integer.parseInt(xmlNode.getAttribute("x"));
public Map<String, List<String>> labelledMaps = new LinkedHashMap<String, List<String>>(); segmentY = Integer.parseInt(xmlNode.getAttribute("y"));
public Map<String, NamedArea> labels = new LinkedHashMap<String, NamedArea>(); NodeList mapsList = xmlNode.getElementsByTagName("map");
public Element xmlNode; for (int j = 0; j < mapsList.getLength(); j++) {
Element mapNode = (Element) mapsList.item(j);
mapLocations.put(mapNode.getAttribute("id"), new Point(Integer.parseInt(mapNode.getAttribute("x")) - segmentX, Integer.parseInt(mapNode.getAttribute("y")) - segmentY));
String area;
if ((area = mapNode.getAttribute("area")) != null && !"".equals(area)) {
if (labelledMaps.get(area) == null) {
labelledMaps.put(area, new ArrayList<String>());
}
labelledMaps.get(area).add(mapNode.getAttribute("id"));
}
}
NodeList namedAreasNodeList = xmlNode.getElementsByTagName("namedarea");
for (int j = 0; j < namedAreasNodeList.getLength(); j++) {
Element namedAreaNode = (Element) namedAreasNodeList.item(j);
labels.put(namedAreaNode.getAttribute("id"), new NamedArea(namedAreaNode.getAttribute("id"), namedAreaNode.getAttribute("name"), namedAreaNode.getAttribute("type")));
}
this.state = State.parsed;
}
public WorldmapSegment(Worldmap parent, String name, Element xmlNode) { @Override
this.parent = parent; public void link() {
this.id = name; if (this.state == State.init) {
this.xmlNode = xmlNode; this.parse();
} } else if (this.state == State.linked) {
return;
}
for (String mapName : mapLocations.keySet()) {
if (getProject().getMap(mapName) != null) {
getProject().getMap(mapName).addBacklink(this);
}
}
}
@Override @Override
public GameDataSet getDataSet() { public WorldmapSegment clone() {
return parent.getDataSet(); WorldmapSegment clone = new WorldmapSegment((Worldmap)parent, id, (Element) xmlNode.cloneNode(true));
}
return clone;
}
@Override @Override
public String getDesc() { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
return (needsSaving() ? "*" : "") + id; boolean modified = false;
} if (newOne == null && writable) {
//A referenced map may have been deleted.
if (mapLocations.containsKey(oldOne.id)) {
mapLocations.remove(oldOne.id);
modified = true;
}
List<String> deprecatedLabels = new ArrayList<String>();
for (String label : labelledMaps.keySet()) {
if (labelledMaps.get(label).contains(oldOne.id)) {
labelledMaps.get(label).remove(oldOne.id);
modified = true;
if (labelledMaps.get(label).isEmpty()) {
deprecatedLabels.add(label);
}
}
}
for (String label : deprecatedLabels) {
labelledMaps.remove(label);
labels.remove(label);
}
}
oldOne.removeBacklink(this);
if(newOne != null) newOne.addBacklink(this);
if (modified) {
this.state = GameDataElement.State.modified;
childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(this);
}
}
@Override @Override
public void parse() { public String getProjectFilename() {
segmentX = Integer.parseInt(xmlNode.getAttribute("x")); return "worldmap.xml";
segmentY = Integer.parseInt(xmlNode.getAttribute("y")); }
NodeList mapsList = xmlNode.getElementsByTagName("map");
for (int j = 0; j < mapsList.getLength(); j++) {
Element mapNode = (Element) mapsList.item(j);
mapLocations.put(mapNode.getAttribute("id"), new Point(Integer.parseInt(mapNode.getAttribute("x")) - segmentX, Integer.parseInt(mapNode.getAttribute("y")) - segmentY));
String area;
if ((area = mapNode.getAttribute("area")) != null && !"".equals(area)) {
if (labelledMaps.get(area) == null) {
labelledMaps.put(area, new ArrayList<String>());
}
labelledMaps.get(area).add(mapNode.getAttribute("id"));
}
}
NodeList namedAreasNodeList = xmlNode.getElementsByTagName("namedarea");
for (int j = 0; j < namedAreasNodeList.getLength(); j++) {
Element namedAreaNode = (Element) namedAreasNodeList.item(j);
labels.put(namedAreaNode.getAttribute("id"), new NamedArea(namedAreaNode.getAttribute("id"), namedAreaNode.getAttribute("name"), namedAreaNode.getAttribute("type")));
}
this.state = State.parsed;
}
@Override @Override
public void link() { public void save() {
if (this.state == State.init) { ((Worldmap)parent).save();
this.parse(); }
} else if (this.state == State.linked) {
return; public String toXml() {
} Document doc;
for (String mapName : mapLocations.keySet()) { try {
if (getProject().getMap(mapName) != null) { doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
getProject().getMap(mapName).addBacklink(this); doc.setXmlVersion("1.0");
} Element root = doc.createElement("worldmap");
} doc.appendChild(root);
} root.appendChild(this.toXmlElement(doc));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result output = new StreamResult(baos);
Source input = new DOMSource(doc);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output);
return baos.toString();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
public Element toXmlElement(Document doc) {
Element element = doc.createElement("segment");
element.setAttribute("id", id);
element.setAttribute("x", Integer.toString(segmentX));
element.setAttribute("y", Integer.toString(segmentY));
for (String s : mapLocations.keySet()) {
Element map = doc.createElement("map");
map.setAttribute("id", s);
map.setAttribute("x", Integer.toString(mapLocations.get(s).x + segmentX));
map.setAttribute("y", Integer.toString(mapLocations.get(s).y + segmentY));
for (String label : labelledMaps.keySet()) {
if (TEMP_LABEL_KEY.equals(label)) continue;
if (labelledMaps.get(label).contains(s)) {
map.setAttribute("area", label);
}
}
element.appendChild(map);
}
for (String key : labels.keySet()) {
if (TEMP_LABEL_KEY.equals(key)) continue;
NamedArea area = labels.get(key);
Element namedArea = doc.createElement("namedarea");
namedArea.setAttribute("id", area.id);
namedArea.setAttribute("name", area.name);
namedArea.setAttribute("type", area.type);
element.appendChild(namedArea);
}
return element;
}
@Override @Override
public WorldmapSegment clone() { public List<SaveEvent> attemptSave() {
WorldmapSegment clone = new WorldmapSegment((Worldmap) parent, id, (Element) xmlNode.cloneNode(true)); // TODO Auto-generated method stub
save();
return clone; return null;
} }
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
boolean modified = false;
if (newOne == null && writable) {
//A referenced map may have been deleted.
if (mapLocations.containsKey(oldOne.id)) {
mapLocations.remove(oldOne.id);
modified = true;
}
List<String> deprecatedLabels = new ArrayList<String>();
for (String label : labelledMaps.keySet()) {
if (labelledMaps.get(label).contains(oldOne.id)) {
labelledMaps.get(label).remove(oldOne.id);
modified = true;
if (labelledMaps.get(label).isEmpty()) {
deprecatedLabels.add(label);
}
}
}
for (String label : deprecatedLabels) {
labelledMaps.remove(label);
labels.remove(label);
}
}
oldOne.removeBacklink(this);
if (newOne != null) newOne.addBacklink(this);
if (modified) {
this.state = GameDataElement.State.modified;
childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(this);
}
}
@Override
public String getProjectFilename() {
return "worldmap.xml";
}
@Override
public void save() {
((Worldmap) parent).save();
}
public String toXml() {
Document doc;
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
doc.setXmlVersion("1.0");
Element root = doc.createElement("worldmap");
doc.appendChild(root);
root.appendChild(this.toXmlElement(doc));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result output = new StreamResult(baos);
Source input = new DOMSource(doc);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output);
return baos.toString();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
public Element toXmlElement(Document doc) {
Element element = doc.createElement("segment");
element.setAttribute("id", id);
element.setAttribute("x", Integer.toString(segmentX));
element.setAttribute("y", Integer.toString(segmentY));
for (String s : mapLocations.keySet()) {
Element map = doc.createElement("map");
map.setAttribute("id", s);
map.setAttribute("x", Integer.toString(mapLocations.get(s).x + segmentX));
map.setAttribute("y", Integer.toString(mapLocations.get(s).y + segmentY));
for (String label : labelledMaps.keySet()) {
if (TEMP_LABEL_KEY.equals(label)) continue;
if (labelledMaps.get(label).contains(s)) {
map.setAttribute("area", label);
}
}
element.appendChild(map);
}
for (String key : labels.keySet()) {
if (TEMP_LABEL_KEY.equals(key)) continue;
NamedArea area = labels.get(key);
Element namedArea = doc.createElement("namedarea");
namedArea.setAttribute("id", area.id);
namedArea.setAttribute("name", area.name);
namedArea.setAttribute("type", area.type);
element.appendChild(namedArea);
}
return element;
}
@Override
public List<SaveEvent> attemptSave() {
// TODO Auto-generated method stub
save();
return null;
}
public static class NamedArea {
public String id;
public String name;
public String type;
public NamedArea(String id, String name, String type) {
this.id = id;
this.name = name;
this.type = type;
}
}
@Override
public Image getIcon() {
return DefaultIcons.getUIMapIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getUIMapIcon();
}
public static class NamedArea {
public String id;
public String name;
public String type;
public NamedArea(String id, String name, String type) {
this.id = id;
this.name = name;
this.type = type;
}
}
@Override
public Image getIcon() {
return DefaultIcons.getUIMapIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getUIMapIcon();
}
} }

View File

@@ -0,0 +1,177 @@
package com.gpl.rpg.atcontentstudio.model.saves;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.andorstrainer.io.SavedGameIO;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class SavedGame extends GameDataElement {
private static final long serialVersionUID = -6443495534761084990L;
public File savedFile;
transient public com.gpl.rpg.andorstrainer.model.SavedGame loadedSave = null;
transient public SavedGamesSet parent;
public SavedGame(SavedGamesSet parent, File f) throws IOException {
savedFile = f;
refreshTransients(parent);
}
public void refreshTransients(SavedGamesSet parent) throws IOException {
this.parent = parent;
this.loadedSave = SavedGameIO.loadFile(savedFile);
if (this.loadedSave == null) {
throw new IOException("Unable to load save: "+savedFile.getAbsolutePath());
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public TreeNode getChildAt(int arg0) {
return null;
}
@Override
public int getChildCount() {
return 0;
}
@Override
public int getIndex(TreeNode arg0) {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+loadedSave.displayInfo;
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return DefaultIcons.getHeroIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getHeroIcon();
}
@Override
public Image getClosedIcon() {return null;}
@Override
public Image getOpenIcon() {return null;}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void parse() {
// TODO Auto-generated method stub
}
@Override
public void link() {
// TODO Auto-generated method stub
}
@Override
public GameDataElement clone() {
// TODO Auto-generated method stub
return null;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
// TODO Auto-generated method stub
}
@Override
public String getProjectFilename() {
// TODO Auto-generated method stub
return null;
}
@Override
public void save() {
// TODO Auto-generated method stub
}
@Override
public List<SaveEvent> attemptSave() {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -0,0 +1,180 @@
package com.gpl.rpg.atcontentstudio.model.saves;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class SavedGamesSet implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = -6565834239789184087L;
public Vector<SavedGame> saves; //For simulations.
public Project parent;
public SavedGamesSet(Project parent) {
this.parent = parent;
saves = new Vector<SavedGame>();
}
public void refreshTransients() {
for (SavedGame save : saves) {
try {
save.refreshTransients(this);
} catch (IOException e) {
Notification.addError(e.getMessage());
}
}
}
public void addSave(File f) {
try {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
SavedGame node = new SavedGame(this, f);
saves.add(node);
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
} catch (IOException e) {
Notification.addError(e.getMessage());
}
}
public SavedGame getSave(File f) {
for (SavedGame save : saves) {
if (save.savedFile.equals(f)) return save;
}
return null;
}
@Override
public Enumeration<? extends ProjectTreeNode> children() {
return saves.elements();
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return saves.elementAt(arg0);
}
@Override
public int getChildCount() {
return saves.size();
}
@Override
public int getIndex(TreeNode arg0) {
return saves.indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (SavedGame s : saves) {
s.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+"Saved games";
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getSavClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getSavClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getSavOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return saves.isEmpty();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : saves) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -1,5 +1,14 @@
package com.gpl.rpg.atcontentstudio.model.sprites; package com.gpl.rpg.atcontentstudio.model.sprites;
import java.awt.Image;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
@@ -7,169 +16,147 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
public class SpriteSheetSet implements ProjectTreeNode { public class SpriteSheetSet implements ProjectTreeNode {
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res" + File.separator + "drawable" + File.separator; public static final String DEFAULT_REL_PATH_IN_SOURCE = "res"+File.separator+"drawable"+File.separator;
public static final String DEFAULT_REL_PATH_IN_PROJECT = "spritesheets" + File.separator; public static final String DEFAULT_REL_PATH_IN_PROJECT = "spritesheets"+File.separator;
public File drawableFolder = null;
public transient List<Spritesheet> spritesheets;
public File drawableFolder = null; public GameSource parent;
public SpriteSheetSet(GameSource source) {
this.parent = source;
if (source.type == GameSource.Type.source) this.drawableFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) {
this.drawableFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
if (!this.drawableFolder.exists()) {
this.drawableFolder.mkdirs();
}
}
spritesheets = new ArrayList<Spritesheet>();
if (this.drawableFolder != null) {
for (File f : this.drawableFolder.listFiles()) {
if (f.getName().endsWith(".png") || f.getName().endsWith(".PNG")) {
spritesheets.add(new Spritesheet(this, f));
}
}
}
}
@Override
public Enumeration<Spritesheet> children() {
return Collections.enumeration(spritesheets);
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return spritesheets.get(arg0);
}
@Override
public int getChildCount() {
return spritesheets.size();
}
@Override
public int getIndex(TreeNode arg0) {
return spritesheets.indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (Spritesheet s : spritesheets) {
s.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+"Spritesheets";
}
public transient List<Spritesheet> spritesheets; @Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getSpriteClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getSpriteClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getSpriteOpenIcon();
}
public GameSource parent; @Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return spritesheets.isEmpty();
}
public SpriteSheetSet(GameSource source) { public Spritesheet getSpritesheet(String id) {
this.parent = source; if (spritesheets == null) return null;
if (source.type == GameSource.Type.source) for (Spritesheet sheet : spritesheets) {
this.drawableFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_SOURCE); if (id.equals(sheet.id)){
else if (source.type == GameSource.Type.created | source.type == GameSource.Type.altered) { return sheet;
this.drawableFolder = new File(source.baseFolder, DEFAULT_REL_PATH_IN_PROJECT); }
if (!this.drawableFolder.exists()) { }
this.drawableFolder.mkdirs(); return null;
} }
}
spritesheets = new ArrayList<Spritesheet>(); @Override
if (this.drawableFolder != null) { public boolean needsSaving() {
for (File f : this.drawableFolder.listFiles()) { for (ProjectTreeNode node : spritesheets) {
if (f.getName().endsWith(".png") || f.getName().endsWith(".PNG")) { if (node.needsSaving()) return true;
spritesheets.add(new Spritesheet(this, f)); }
} return false;
} }
}
spritesheets.sort(Comparator.comparing(s -> s.id));
}
@Override
public Enumeration<Spritesheet> children() {
return Collections.enumeration(spritesheets);
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return spritesheets.get(arg0);
}
@Override
public int getChildCount() {
return spritesheets.size();
}
@Override
public int getIndex(TreeNode arg0) {
return spritesheets.indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (Spritesheet s : spritesheets) {
s.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + "Spritesheets";
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getSpriteClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getSpriteClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getSpriteOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return spritesheets.isEmpty();
}
public Spritesheet getSpritesheet(String id) {
if (spritesheets == null) return null;
for (Spritesheet sheet : spritesheets) {
if (id.equals(sheet.id)) {
return sheet;
}
}
return null;
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : spritesheets) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,5 +1,19 @@
package com.gpl.rpg.atcontentstudio.model.sprites; package com.gpl.rpg.atcontentstudio.model.sprites;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
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;
@@ -9,281 +23,250 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import javax.imageio.ImageIO;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;
public class Spritesheet extends GameDataElement { public class Spritesheet extends GameDataElement {
private static final long serialVersionUID = -5981708088278528586L;
public SpriteSheetSet parent;
public File spritesheetFile;
public int spriteWidth = 32;
public int spriteHeight = 32;
public String id;
public Category category = Category.none;
public boolean animated = false;
private static final long serialVersionUID = -5981708088278528586L; public enum Category {
none,
monster,
item,
actorcondition
};
//Lazy initialization.
public BufferedImage spritesheet = null;
public Map<Integer, BufferedImage> cache_full_size = new LinkedHashMap<Integer, BufferedImage>();
public Map<Integer, Image> cache_icon = new LinkedHashMap<Integer, Image>();
public Spritesheet(SpriteSheetSet parent, File f) {
this.spritesheetFile = f;
this.id = f.getName().substring(0, f.getName().lastIndexOf("."));
this.parent = parent;
String cat = getProject().getSpritesheetsProperty("atcs.spritesheet."+this.id+".category");
if (cat != null) {
this.category = Category.valueOf(cat);
}
String sizex = getProject().getSpritesheetsProperty("atcs.spritesheet."+this.id+".sizex");
if (sizex != null) {
this.spriteWidth = Integer.parseInt(sizex);
}
String sizey = getProject().getSpritesheetsProperty("atcs.spritesheet."+this.id+".sizey");
if (sizey != null) {
this.spriteHeight = Integer.parseInt(sizey);
}
String anim = getProject().getSpritesheetsProperty("atcs.spritesheet."+this.id+".animate");
if (anim != null) {
this.animated = Boolean.parseBoolean(anim);
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public TreeNode getChildAt(int arg0) {
return null;
}
@Override
public int getChildCount() {
return 0;
}
@Override
public int getIndex(TreeNode arg0) {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+spritesheetFile.getName();
}
public SpriteSheetSet parent; @Override
public File spritesheetFile; public Project getProject() {
public int spriteWidth = 32; return parent.getProject();
public int spriteHeight = 32; }
public String id;
public Category category = Category.none; public int getSpriteCount() {
public boolean animated = false; if (spritesheet == null) {
try {
spritesheet = ImageIO.read(spritesheetFile);
} catch (IOException e) {
Notification.addError("Error loading image "+spritesheetFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
return 0;
}
}
return (int) (Math.ceil(((double)spritesheet.getWidth()) / ((double)spriteWidth)) * Math.ceil(((double)spritesheet.getHeight()) / ((double)spriteHeight)));
}
public BufferedImage getImage(int index) {
if (spritesheet == null) {
try {
spritesheet = ImageIO.read(spritesheetFile);
} catch (IOException e) {
Notification.addError("Error loading image "+spritesheetFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
return null;
}
}
if (cache_full_size.get(index) != null) {
return cache_full_size.get(index);
}
BufferedImage result = new BufferedImage(spriteWidth, spriteHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = result.getGraphics();
int sx1, sy1;
sx1 = (index * spriteWidth) % spritesheet.getWidth();
sy1 = spriteHeight * ((index * spriteWidth) / spritesheet.getWidth());
if (sx1 + spriteWidth > spritesheet.getWidth() || sy1 + spriteHeight > spritesheet.getHeight()) {
g.finalize();
return null;
}
g.drawImage(spritesheet, 0, 0, spriteWidth, spriteHeight, sx1, sy1, sx1 + spriteWidth, sy1 + spriteHeight, null);
result.flush();
g.finalize();
cache_full_size.put(index, result);
return result;
}
public Image getIcon(int index) {
if (cache_icon.get(index) != null) {
return cache_icon.get(index);
}
Image result = getImage(index);
if (result == null) return null;
result = result.getScaledInstance((int)(16*ATContentStudio.SCALING), (int)(16*ATContentStudio.SCALING), Image.SCALE_SMOOTH);
cache_icon.put(index, result);
return result;
}
public void clearCache() {
cache_full_size.clear();
cache_icon.clear();
}
public enum Category { @Override
none, public Image getIcon() {
monster, return getIcon(0);
item, }
actorcondition @Override
} public Image getLeafIcon() {
return getIcon();
//Lazy initialization. }
public BufferedImage spritesheet = null; @Override
public Map<Integer, BufferedImage> cache_full_size = new LinkedHashMap<Integer, BufferedImage>(); public Image getClosedIcon() {return null;}
public Map<Integer, Image> cache_icon = new LinkedHashMap<Integer, Image>(); @Override
public Image getOpenIcon() {return null;}
public Spritesheet(SpriteSheetSet parent, File f) {
this.spritesheetFile = f;
this.id = f.getName().substring(0, f.getName().lastIndexOf("."));
this.parent = parent;
String cat = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".category");
if (cat != null) {
this.category = Category.valueOf(cat);
}
String sizex = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizex");
if (sizex != null) {
this.spriteWidth = Integer.parseInt(sizex);
}
String sizey = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizey");
if (sizey != null) {
this.spriteHeight = Integer.parseInt(sizey);
}
String anim = getProject().getSpritesheetsProperty("atcs.spritesheet." + this.id + ".animate");
if (anim != null) {
this.animated = Boolean.parseBoolean(anim);
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public TreeNode getChildAt(int arg0) {
return null;
}
@Override
public int getChildCount() {
return 0;
}
@Override
public int getIndex(TreeNode arg0) {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + spritesheetFile.getName();
}
@Override
public Project getProject() {
return parent.getProject();
}
public int getSpriteCount() {
if (spritesheet == null) {
try {
spritesheet = ImageIO.read(spritesheetFile);
} catch (IOException e) {
Notification.addError("Error loading image " + spritesheetFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
return 0;
}
}
return (int) (Math.ceil(((double) spritesheet.getWidth()) / ((double) spriteWidth)) * Math.ceil(((double) spritesheet.getHeight()) / ((double) spriteHeight)));
}
public BufferedImage getImage(int index) {
if (spritesheet == null) {
try {
spritesheet = ImageIO.read(spritesheetFile);
} catch (IOException e) {
Notification.addError("Error loading image " + spritesheetFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
return null;
}
}
if (cache_full_size.get(index) != null) {
return cache_full_size.get(index);
}
BufferedImage result = new BufferedImage(spriteWidth, spriteHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = result.getGraphics();
int sx1, sy1;
sx1 = (index * spriteWidth) % spritesheet.getWidth();
sy1 = spriteHeight * ((index * spriteWidth) / spritesheet.getWidth());
if (sx1 + spriteWidth > spritesheet.getWidth() || sy1 + spriteHeight > spritesheet.getHeight()) {
g.finalize();
return null;
}
g.drawImage(spritesheet, 0, 0, spriteWidth, spriteHeight, sx1, sy1, sx1 + spriteWidth, sy1 + spriteHeight, null);
result.flush();
g.finalize();
cache_full_size.put(index, result);
return result;
}
public Image getIcon(int index) {
if (cache_icon.get(index) != null) {
return cache_icon.get(index);
}
Image result = getImage(index);
if (result == null) return null;
result = result.getScaledInstance((int) (16 * ATContentStudio.SCALING), (int) (16 * ATContentStudio.SCALING), Image.SCALE_SMOOTH);
cache_icon.put(index, result);
return result;
}
public void clearCache() {
cache_full_size.clear();
cache_icon.clear();
}
@Override @Override
public Image getIcon() { public GameDataSet getDataSet() {
return getIcon(0); return null;
} }
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void parse() {
if(this.state == GameDataElement.State.init){
this.state = GameDataElement.State.parsed;
}
}
@Override @Override
public Image getLeafIcon() { public void link() {
return getIcon(); if (this.state == GameDataElement.State.init) {
} this.parse();
}
if(this.state == GameDataElement.State.parsed) {
this.state = GameDataElement.State.linked;
}
}
@Override @Override
public Image getClosedIcon() { public GameDataElement clone() {
return null; Spritesheet clone = new Spritesheet((SpriteSheetSet) getParent(), new File(spritesheetFile.getAbsolutePath()));
} clone.id = this.id;
clone.animated = this.animated;
clone.category = this.category;
clone.spriteWidth = this.spriteWidth;
clone.spriteHeight = this.spriteHeight;
return clone;
}
@Override @Override
public Image getOpenIcon() { public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
return null; //nothing linked.
} }
@Override
public String getProjectFilename() {
return spritesheetFile.getName();
}
@Override @Override
public GameDataSet getDataSet() { public void save() {
return null; if (this.category != null) getProject().setSpritesheetsProperty("atcs.spritesheet."+this.id+".category", this.category.toString());
} if (this.spriteWidth != 32) getProject().setSpritesheetsProperty("atcs.spritesheet."+this.id+".sizex", Integer.toString(this.spriteWidth));
if (this.spriteHeight != 32) getProject().setSpritesheetsProperty("atcs.spritesheet."+this.id+".sizey", Integer.toString(this.spriteHeight));
@Override if (this.animated)getProject().setSpritesheetsProperty("atcs.spritesheet."+this.id+".animate", Boolean.toString(this.animated));
public Type getDataType() { getProject().save();
return parent.getDataType();
} this.state = GameDataElement.State.saved;
}
@Override
public boolean isEmpty() { @Override
return false; public List<SaveEvent> attemptSave() {
} save();
return null;
@Override }
public void parse() {
if (this.state == GameDataElement.State.init) {
this.state = GameDataElement.State.parsed;
}
}
@Override
public void link() {
if (this.state == GameDataElement.State.init) {
this.parse();
}
if (this.state == GameDataElement.State.parsed) {
this.state = GameDataElement.State.linked;
}
}
@Override
public GameDataElement clone() {
Spritesheet clone = new Spritesheet((SpriteSheetSet) getParent(), new File(spritesheetFile.getAbsolutePath()));
clone.id = this.id;
clone.animated = this.animated;
clone.category = this.category;
clone.spriteWidth = this.spriteWidth;
clone.spriteHeight = this.spriteHeight;
return clone;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
//nothing linked.
}
@Override
public String getProjectFilename() {
return spritesheetFile.getName();
}
@Override
public void save() {
if (this.category != null)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".category", this.category.toString());
if (this.spriteWidth != 32)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizex", Integer.toString(this.spriteWidth));
if (this.spriteHeight != 32)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".sizey", Integer.toString(this.spriteHeight));
if (this.animated)
getProject().setSpritesheetsProperty("atcs.spritesheet." + this.id + ".animate", Boolean.toString(this.animated));
getProject().save();
this.state = GameDataElement.State.saved;
}
@Override
public List<SaveEvent> attemptSave() {
save();
return null;
}
} }

View File

@@ -1,6 +1,11 @@
package com.gpl.rpg.atcontentstudio.model.tools.i18n; package com.gpl.rpg.atcontentstudio.model.tools.i18n;
import java.io.*; import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
@@ -9,76 +14,76 @@ import java.util.Map;
public class PoPotWriter { public class PoPotWriter {
Map<String, List<String>> stringsResources = new LinkedHashMap<String, List<String>>(); Map<String, List<String>> stringsResources = new LinkedHashMap<String, List<String>>();
Map<String, String> translations = new LinkedHashMap<String, String>(); Map<String, String> translations = new LinkedHashMap<String, String>();
File f; File f;
public static void writePoFile(Map<String, List<String>> stringsResources, Map<String, String> translations, File destination) { public static void writePoFile(Map<String, List<String>> stringsResources, Map<String, String> translations, File destination) {
try { try {
Writer fw = new OutputStreamWriter(new FileOutputStream(destination), StandardCharsets.UTF_8); Writer fw = new OutputStreamWriter(new FileOutputStream(destination), StandardCharsets.UTF_8);
if (translations.get("") != null) { if (translations.get("") != null) {
fw.write(translations.get("")); fw.write(translations.get(""));
writeEndOfEntry(fw); writeEndOfEntry(fw);
} }
if (translations.get("translator-credits") != null) { if (translations.get("translator-credits") != null) {
List<String> refs = new LinkedList<String>(); List<String> refs = new LinkedList<String>();
refs.add("[none]"); refs.add("[none]");
writeReferences(fw, refs); writeReferences(fw, refs);
writeMsgId(fw, "translator-credits"); writeMsgId(fw, "translator-credits");
writeMsgStr(fw, translations.get("translator-credits")); writeMsgStr(fw, translations.get("translator-credits"));
writeEndOfEntry(fw); writeEndOfEntry(fw);
} }
for (String msg : stringsResources.keySet()) { for (String msg : stringsResources.keySet()) {
writeReferences(fw, stringsResources.get(msg)); writeReferences(fw, stringsResources.get(msg));
writeMsgId(fw, msg); writeMsgId(fw, msg);
writeMsgStr(fw, translations.get(msg)); writeMsgStr(fw, translations.get(msg));
writeEndOfEntry(fw); writeEndOfEntry(fw);
} }
fw.flush(); fw.flush();
fw.close(); fw.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void writePotFile(Map<String, List<String>> stringsResources, File destination) { public static void writePotFile(Map<String, List<String>> stringsResources, File destination) {
try { try {
FileWriter fw = new FileWriter(destination); FileWriter fw = new FileWriter(destination);
for (String msg : stringsResources.keySet()) { for (String msg : stringsResources.keySet()) {
writeReferences(fw, stringsResources.get(msg)); writeReferences(fw, stringsResources.get(msg));
writeMsgId(fw, msg); writeMsgId(fw, msg);
writeMsgStr(fw, ""); writeMsgStr(fw, "");
writeEndOfEntry(fw); writeEndOfEntry(fw);
} }
fw.flush(); fw.flush();
fw.close(); fw.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private static void writeReferences(Writer w, List<String> references) throws IOException { private static void writeReferences(Writer w, List<String> references) throws IOException {
for (String ref : references) { for (String ref : references) {
w.write("#: "); w.write("#: ");
w.write(ref); w.write(ref);
w.write("\n"); w.write("\n");
} }
} }
private static void writeMsgId(Writer w, String msg) throws IOException { private static void writeMsgId(Writer w, String msg) throws IOException {
w.write("msgid \""); w.write("msgid \"");
w.write(msg); w.write(msg);
w.write("\"\n"); w.write("\"\n");
} }
private static void writeMsgStr(Writer w, String translation) throws IOException { private static void writeMsgStr(Writer w, String translation) throws IOException {
w.write("msgstr \""); w.write("msgstr \"");
w.write(translation == null ? "" : translation); w.write(translation == null ? "" : translation);
w.write("\"\n"); w.write("\"\n");
} }
private static void writeEndOfEntry(Writer w) throws IOException { private static void writeEndOfEntry(Writer w) throws IOException {
w.write("\n"); w.write("\n");
} }
} }

View File

@@ -1,304 +1,310 @@
package com.gpl.rpg.atcontentstudio.model.tools.i18n; package com.gpl.rpg.atcontentstudio.model.tools.i18n;
import java.io.File;
import java.io.FileFilter;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.swing.JOptionPane;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import net.launchpad.tobal.poparser.POEntry; import net.launchpad.tobal.poparser.POEntry;
import net.launchpad.tobal.poparser.POFile; import net.launchpad.tobal.poparser.POFile;
import net.launchpad.tobal.poparser.POParser; import net.launchpad.tobal.poparser.POParser;
import javax.swing.*;
import java.io.File;
import java.io.FileFilter;
import java.util.*;
/** /**
*
* @author Kevin * @author Kevin
* <p> *
* To use this, paste the following script in the beanshell console of ATCS. * To use this, paste the following script in the beanshell console of ATCS.
* Don't forget to change the project number to suit your needs. * Don't forget to change the project number to suit your needs.
* <p> *
* <code> import com.gpl.rpg.atcontentstudio.model.Workspace;
import com.gpl.rpg.atcontentstudio.model.tools.i18n.PotGenerator;
import com.gpl.rpg.atcontentstudio.model.tools.i18n.PotComparator;
proj = Workspace.activeWorkspace.projects.get(7);
PotGenerator.generatePotFileForProject(proj);
comp = new PotComparator(proj);
comp.compare();
comp.updatePoFiles(proj);
*
*
* *
* import com.gpl.rpg.atcontentstudio.model.Workspace;
* import com.gpl.rpg.atcontentstudio.model.tools.i18n.PotGenerator;
* import com.gpl.rpg.atcontentstudio.model.tools.i18n.PotComparator;
*
* proj = Workspace.activeWorkspace.projects.get(7);
* PotGenerator.generatePotFileForProject(proj);
* comp = new PotComparator(proj);
* comp.compare();
* comp.updatePoFiles(proj);
* </code>
*/ */
public class PotComparator { public class PotComparator {
Map<String, List<String>> stringsResourcesNew = new LinkedHashMap<String, List<String>>(); Map<String, List<String>> stringsResourcesNew = new LinkedHashMap<String, List<String>>();
Map<String, String> resourcesStringsNew = new LinkedHashMap<String, String>(); Map<String, String> resourcesStringsNew = new LinkedHashMap<String, String>();
Map<String, List<String>> stringsResourcesOld = new LinkedHashMap<String, List<String>>();
Map<String, String> resourcesStringsOld = new LinkedHashMap<String, String>();
Map<String, List<String>> stringsResourcesOld = new LinkedHashMap<String, List<String>>(); Map<String, String> msgIdToReplace = new LinkedHashMap<String, String>();
Map<String, String> resourcesStringsOld = new LinkedHashMap<String, String>(); List<String> msgIdToReview = new LinkedList<String>();
List<String> msgIdOutdated = new LinkedList<String>();
public PotComparator(Project proj) {
POParser parser = new POParser();
Map<String, String> msgIdToReplace = new LinkedHashMap<String, String>(); POFile newPot = parser.parseFile(new File(proj.alteredContent.baseFolder.getAbsolutePath()+File.separator+"english.pot"));
List<String> msgIdToReview = new LinkedList<String>(); if (newPot == null) {
List<String> msgIdOutdated = new LinkedList<String>(); System.err.println("Cannot locate new english.pot file at "+proj.alteredContent.baseFolder.getAbsolutePath()+File.separator);
}
extractFromPoFile(newPot, stringsResourcesNew, resourcesStringsNew);
POFile oldPot = parser.parseFile(new File(proj.baseContent.baseFolder.getAbsolutePath()+File.separator+"assets"+File.separator+"translation"+File.separator+"english.pot"));
if (oldPot == null) {
System.err.println("Cannot locate old english.pot file at "+proj.baseContent.baseFolder.getAbsolutePath()+File.separator+"assets"+File.separator+"translations"+File.separator);
}
extractFromPoFile(oldPot, stringsResourcesOld, resourcesStringsOld);
}
private void extractFromPoFile(POFile po, Map<String, List<String>> stringsResources, Map<String, String> resourcesStrings) {
for (POEntry entry : po.getEntryArray()) {
Vector<String> resources = entry.getStringsByType(POEntry.StringType.REFERENCE);
Vector<String> msgids = entry.getStringsByType(POEntry.StringType.MSGID);
if (resources == null || resources.size() == 0 || msgids == null || msgids.size() == 0) continue;
String msgid = msgids.get(0);
if (msgids.size() > 1) {
for (int i = 1; i < msgids.size(); i++) {
msgid += msgids.get(i);
}
}
if (msgid.contains("\\n")) {
msgid = msgid.replaceAll("\\\\n", "\\\\n\"\n\"");
msgid = "\"\n\""+msgid;
}
for (String resLine : resources) {
String[] resArray = resLine.split(" ");
for (String res : resArray) {
resourcesStrings.put(res, msgid);
if (stringsResources.get(msgid) == null) {
stringsResources.put(msgid, new LinkedList<String>());
}
stringsResources.get(msgid).add(res);
}
}
}
}
public void compare() {
for (String oldRes : resourcesStringsOld.keySet()) {
String newString = resourcesStringsNew.get(oldRes);
String oldString = resourcesStringsOld.get(oldRes);
if (newString != null) {
if (!newString.equals(oldString)) {
List<String> allOldResources = stringsResourcesOld.get(oldString);
List<String> allNewResources = stringsResourcesNew.get(oldString);
StringBuffer sb = new StringBuffer();
sb.append("---------------------------------------------\n");
sb.append("--- TYPO CHECK ------------------------------\n");
sb.append("---------------------------------------------\n");
sb.append("String at: "+oldRes+"\n");
if (allOldResources.size() > 1) {
sb.append("Also present at:\n");
for (String res : allOldResources) {
if (!res.equals(oldRes)) {
sb.append("- "+res+"\n");
}
}
}
if (allNewResources != null) {
sb.append("Still present at: \n");
for (String res : allNewResources) {
sb.append("- "+res+"\n");
}
}
sb.append("Was : \""+oldString+"\"\n");
sb.append("Now : \""+newString+"\"\n");
System.out.println(sb.toString());
showTypoDialog(oldString, newString, sb.toString());
}
} else {
List<String> allOldResources = stringsResourcesOld.get(oldString);
List<String> allNewResources = stringsResourcesNew.get(oldString);
if (allOldResources.size() >= 1) {
System.out.println("---------------------------------------------");
System.out.println("--- REMOVED RESOURCE ------------------------");
System.out.println("---------------------------------------------");
System.out.println("String at: "+oldRes);
if (allOldResources.size() > 1) {
System.out.println("And also at:");
for (String res : allOldResources) {
if (!res.equals(oldRes)) {
System.out.println("- "+res);
}
}
}
System.out.println("Was: \""+oldString+"\"");
if (allNewResources == null) {
System.out.println("Absent from new.");
} else {
System.out.println("Still present at: ");
for (String res : allNewResources) {
System.out.println("- "+res);
}
}
}
}
}
removedStrings: for (String oldString : stringsResourcesOld.keySet()) {
if (stringsResourcesNew.get(oldString) == null) {
List<String> allOldResources = stringsResourcesOld.get(oldString);
if (allOldResources.size() >= 1) {
if (allOldResources.size() > 0) {
for (String res : allOldResources) {
String newString = resourcesStringsNew.get(res);
if (newString != null) {
continue removedStrings;
}
}
}
System.out.println("---------------------------------------------");
System.out.println("--- REMOVED STRING --------------------------");
System.out.println("---------------------------------------------");
System.out.println("String: \""+oldString+"\"");
if (allOldResources.size() > 0) {
System.out.println("Was at:");
for (String res : allOldResources) {
System.out.println("- "+res);
}
}
System.out.println("This string is absent from the new file, and its attached resources are missing too.");
}
}
}
}
private void showTypoDialog(String oldMsg, String newMsg, String checkReport) {
String typo = "Typo";
String review = "Review";
String outdated = "Outdated";
String none = "None";
Object[] options = new Object[] {typo, review, outdated, none};
int result = JOptionPane.showOptionDialog(null, checkReport, "Choose action", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, typo);
if (result < 0 || result >= options.length) {
System.out.println("No decision");
return;
}
public PotComparator(Project proj) { System.out.println("Decision: "+options[result]);
POParser parser = new POParser();
if (options[result] != none) {
POFile newPot = parser.parseFile(new File(proj.alteredContent.baseFolder.getAbsolutePath() + File.separator + "english.pot")); msgIdToReplace.put(oldMsg, newMsg);
if (newPot == null) { if (options[result] == review) {
System.err.println("Cannot locate new english.pot file at " + proj.alteredContent.baseFolder.getAbsolutePath() + File.separator); msgIdToReview.add(newMsg);
} } else if (options[result] == outdated) {
extractFromPoFile(newPot, stringsResourcesNew, resourcesStringsNew); msgIdOutdated.add(newMsg);
}
POFile oldPot = parser.parseFile(new File(proj.baseContent.baseFolder.getAbsolutePath() + File.separator + "assets" + File.separator + "translation" + File.separator + "english.pot")); }
if (oldPot == null) {
System.err.println("Cannot locate old english.pot file at " + proj.baseContent.baseFolder.getAbsolutePath() + File.separator + "assets" + File.separator + "translations" + File.separator); }
}
extractFromPoFile(oldPot, stringsResourcesOld, resourcesStringsOld);
} public void updatePoFiles(Project proj) {
File poFolder = new File(proj.baseContent.baseFolder.getAbsolutePath()+File.separator+"assets"+File.separator+"translation");
File[] poFiles = poFolder.listFiles(new FileFilter() {
private void extractFromPoFile(POFile po, Map<String, List<String>> stringsResources, Map<String, String> resourcesStrings) { @Override
for (POEntry entry : po.getEntryArray()) { public boolean accept(File arg0) {
Vector<String> resources = entry.getStringsByType(POEntry.StringType.REFERENCE); return arg0.isFile() && arg0.getName().endsWith(".po");
Vector<String> msgids = entry.getStringsByType(POEntry.StringType.MSGID); }
if (resources == null || resources.size() == 0 || msgids == null || msgids.size() == 0) continue; });
String msgid = msgids.get(0);
if (msgids.size() > 1) { for (File f : poFiles) {
for (int i = 1; i < msgids.size(); i++) { updatePoFile(proj, f);
msgid += msgids.get(i); }
} }
}
if (msgid.contains("\\n")) { private void updatePoFile(Project proj, File f) {
msgid = msgid.replaceAll("\\\\n", "\\\\n\"\n\""); POParser parser = new POParser();
msgid = "\"\n\"" + msgid; POFile poFile = parser.parseFile(f);
}
for (String resLine : resources) { Map<String, String> translations = new LinkedHashMap<String, String>();
String[] resArray = resLine.split(" ");
for (String res : resArray) { //Collect existing translations
resourcesStrings.put(res, msgid); if (poFile.getHeader() != null) {
if (stringsResources.get(msgid) == null) { Vector<String> msgstrs = poFile.getHeader().getStringsByType(POEntry.StringType.HEADER);
stringsResources.put(msgid, new LinkedList<String>()); String header = "";
} if (!msgstrs.isEmpty()) {
stringsResources.get(msgid).add(res); if (msgstrs.size() == 1) {
} header = msgstrs.get(0);
} } else {
} for (String msgstr : msgstrs) {
} header += msgstr;
header += "\n";
public void compare() { }
for (String oldRes : resourcesStringsOld.keySet()) { }
String newString = resourcesStringsNew.get(oldRes); }
String oldString = resourcesStringsOld.get(oldRes); translations.put("", header);
if (newString != null) { }
if (!newString.equals(oldString)) {
List<String> allOldResources = stringsResourcesOld.get(oldString); for (POEntry entry : poFile.getEntryArray()) {
List<String> allNewResources = stringsResourcesNew.get(oldString); Vector<String> msgids = entry.getStringsByType(POEntry.StringType.MSGID);
StringBuffer sb = new StringBuffer(); Vector<String> msgstrs = entry.getStringsByType(POEntry.StringType.MSGSTR);
sb.append("---------------------------------------------\n"); if (msgids == null || msgids.size() == 0) continue;
sb.append("--- TYPO CHECK ------------------------------\n"); String msgid = msgids.get(0);
sb.append("---------------------------------------------\n"); if (msgids.size() > 1) {
sb.append("String at: " + oldRes + "\n"); for (int i = 1; i < msgids.size(); i++) {
if (allOldResources.size() > 1) { msgid += msgids.get(i);
sb.append("Also present at:\n"); }
for (String res : allOldResources) { }
if (!res.equals(oldRes)) { if (msgid.contains("\\n")) {
sb.append("- " + res + "\n"); msgid = msgid.replaceAll("\\\\n", "\\\\n\"\n\"");
} msgid = "\"\n\""+msgid;
} }
} String translation = "";
if (allNewResources != null) { if (!msgstrs.isEmpty()) {
sb.append("Still present at: \n"); if (msgstrs.size() == 1) {
for (String res : allNewResources) { translation = msgstrs.get(0);
sb.append("- " + res + "\n"); } else {
} for (String msgstr : msgstrs) {
} translation += msgstr;
sb.append("Was : \"" + oldString + "\"\n"); }
sb.append("Now : \"" + newString + "\"\n"); }
System.out.println(sb.toString()); if (translation.contains("\\n")) {
showTypoDialog(oldString, newString, sb.toString()); translation = translation.replaceAll("\\\\n", "\\\\n\"\n\"");
} translation = "\"\n\""+translation;
} else { }
List<String> allOldResources = stringsResourcesOld.get(oldString); }
List<String> allNewResources = stringsResourcesNew.get(oldString); translations.put(msgid, translation);
if (allOldResources.size() >= 1) { }
System.out.println("---------------------------------------------");
System.out.println("--- REMOVED RESOURCE ------------------------"); //Patch data
System.out.println("---------------------------------------------"); for (String oldId : msgIdToReplace.keySet()) {
System.out.println("String at: " + oldRes); String newId = msgIdToReplace.get(oldId);
if (allOldResources.size() > 1) { if (translations.containsKey(oldId)) {
System.out.println("And also at:"); String trans = translations.get(oldId);
for (String res : allOldResources) { translations.remove(oldId);
if (!res.equals(oldRes)) { translations.put(newId, trans);
System.out.println("- " + res); }
} }
}
} for (String msgid : msgIdToReview) {
System.out.println("Was: \"" + oldString + "\""); if (translations.containsKey(msgid)) {
if (allNewResources == null) { String trans = translations.get(msgid);
System.out.println("Absent from new."); if (trans != null && trans.length() >= 1) translations.put(msgid, "[REVIEW]"+trans);
} else { }
System.out.println("Still present at: "); }
for (String res : allNewResources) {
System.out.println("- " + res);
}
}
}
}
}
removedStrings:
for (String oldString : stringsResourcesOld.keySet()) {
if (stringsResourcesNew.get(oldString) == null) {
List<String> allOldResources = stringsResourcesOld.get(oldString);
if (allOldResources.size() >= 1) {
if (allOldResources.size() > 0) {
for (String res : allOldResources) {
String newString = resourcesStringsNew.get(res);
if (newString != null) {
continue removedStrings;
}
}
}
System.out.println("---------------------------------------------");
System.out.println("--- REMOVED STRING --------------------------");
System.out.println("---------------------------------------------");
System.out.println("String: \"" + oldString + "\"");
if (allOldResources.size() > 0) {
System.out.println("Was at:");
for (String res : allOldResources) {
System.out.println("- " + res);
}
}
System.out.println("This string is absent from the new file, and its attached resources are missing too.");
}
}
}
}
private void showTypoDialog(String oldMsg, String newMsg, String checkReport) {
String typo = "Typo";
String review = "Review";
String outdated = "Outdated";
String none = "None";
Object[] options = new Object[]{typo, review, outdated, none};
int result = JOptionPane.showOptionDialog(null, checkReport, "Choose action", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, typo);
if (result < 0 || result >= options.length) {
System.out.println("No decision");
return;
}
System.out.println("Decision: " + options[result]);
if (options[result] != none) {
msgIdToReplace.put(oldMsg, newMsg);
if (options[result] == review) {
msgIdToReview.add(newMsg);
} else if (options[result] == outdated) {
msgIdOutdated.add(newMsg);
}
}
}
public void updatePoFiles(Project proj) {
File poFolder = new File(proj.baseContent.baseFolder.getAbsolutePath() + File.separator + "assets" + File.separator + "translation");
File[] poFiles = poFolder.listFiles(new FileFilter() {
@Override
public boolean accept(File arg0) {
return arg0.isFile() && arg0.getName().endsWith(".po");
}
});
for (File f : poFiles) {
updatePoFile(proj, f);
}
}
private void updatePoFile(Project proj, File f) {
POParser parser = new POParser();
POFile poFile = parser.parseFile(f);
Map<String, String> translations = new LinkedHashMap<String, String>();
//Collect existing translations
if (poFile.getHeader() != null) {
Vector<String> msgstrs = poFile.getHeader().getStringsByType(POEntry.StringType.HEADER);
String header = "";
if (!msgstrs.isEmpty()) {
if (msgstrs.size() == 1) {
header = msgstrs.get(0);
} else {
for (String msgstr : msgstrs) {
header += msgstr;
header += "\n";
}
}
}
translations.put("", header);
}
for (POEntry entry : poFile.getEntryArray()) {
Vector<String> msgids = entry.getStringsByType(POEntry.StringType.MSGID);
Vector<String> msgstrs = entry.getStringsByType(POEntry.StringType.MSGSTR);
if (msgids == null || msgids.size() == 0) continue;
String msgid = msgids.get(0);
if (msgids.size() > 1) {
for (int i = 1; i < msgids.size(); i++) {
msgid += msgids.get(i);
}
}
if (msgid.contains("\\n")) {
msgid = msgid.replaceAll("\\\\n", "\\\\n\"\n\"");
msgid = "\"\n\"" + msgid;
}
String translation = "";
if (!msgstrs.isEmpty()) {
if (msgstrs.size() == 1) {
translation = msgstrs.get(0);
} else {
for (String msgstr : msgstrs) {
translation += msgstr;
}
}
if (translation.contains("\\n")) {
translation = translation.replaceAll("\\\\n", "\\\\n\"\n\"");
translation = "\"\n\"" + translation;
}
}
translations.put(msgid, translation);
}
//Patch data
for (String oldId : msgIdToReplace.keySet()) {
String newId = msgIdToReplace.get(oldId);
if (translations.containsKey(oldId)) {
String trans = translations.get(oldId);
translations.remove(oldId);
translations.put(newId, trans);
}
}
for (String msgid : msgIdToReview) {
if (translations.containsKey(msgid)) {
String trans = translations.get(msgid);
if (trans != null && trans.length() >= 1) translations.put(msgid, "[REVIEW]" + trans);
}
}
for (String msgid : msgIdOutdated) {
if (translations.containsKey(msgid)) {
String trans = translations.get(msgid);
if (trans != null && trans.length() >= 1) translations.put(msgid, "[OUTDATED]" + trans);
}
}
PoPotWriter.writePoFile(stringsResourcesNew, translations, new File(proj.alteredContent.baseFolder.getAbsolutePath() + File.separator + f.getName()));
}
for (String msgid : msgIdOutdated) {
if (translations.containsKey(msgid)) {
String trans = translations.get(msgid);
if (trans != null && trans.length() >= 1) translations.put(msgid, "[OUTDATED]"+trans);
}
}
PoPotWriter.writePoFile(stringsResourcesNew, translations, new File(proj.alteredContent.baseFolder.getAbsolutePath()+File.separator+f.getName()));
}
} }

View File

@@ -1,94 +1,101 @@
package com.gpl.rpg.atcontentstudio.model.tools.i18n; package com.gpl.rpg.atcontentstudio.model.tools.i18n;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import java.io.File; import java.io.File;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.model.gamedata.ItemCategory;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.gamedata.Quest;
import com.gpl.rpg.atcontentstudio.model.gamedata.QuestStage;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
public class PotGenerator { public class PotGenerator {
public static void generatePotFileForProject(Project proj) { public static void generatePotFileForProject(Project proj) {
Map<String, List<String>> stringsResources = new LinkedHashMap<String, List<String>>(); Map<String, List<String>> stringsResources = new LinkedHashMap<String, List<String>>();
Map<String, String> resourcesStrings = new LinkedHashMap<String, String>(); Map<String, String> resourcesStrings = new LinkedHashMap<String, String>();
GameSource gsrc = proj.baseContent; GameSource gsrc = proj.baseContent;
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"); pushString(stringsResources, resourcesStrings, ac.description, getPotContextComment(ac)+":description");
} }
for (Dialogue d : gsrc.gameData.dialogues) { for (Dialogue d : gsrc.gameData.dialogues ) {
pushString(stringsResources, resourcesStrings, d.message, getPotContextComment(d)); pushString(stringsResources, resourcesStrings, d.message, getPotContextComment(d));
if (d.replies == null) continue; if (d.replies == null) continue;
for (Dialogue.Reply r : d.replies) { for (Dialogue.Reply r : d.replies) {
if (r.text != null && !r.text.equals(Dialogue.Reply.GO_NEXT_TEXT)) { if (r.text != null && !r.text.equals(Dialogue.Reply.GO_NEXT_TEXT) ) {
pushString(stringsResources, resourcesStrings, r.text, getPotContextComment(d) + ":" + d.replies.indexOf(r)); pushString(stringsResources, resourcesStrings, r.text, getPotContextComment(d)+":"+d.replies.indexOf(r));
} }
} }
} }
for (ItemCategory ic : gsrc.gameData.itemCategories) { for (ItemCategory ic : gsrc.gameData.itemCategories) {
pushString(stringsResources, resourcesStrings, ic.name, getPotContextComment(ic)); pushString(stringsResources, resourcesStrings, ic.name, getPotContextComment(ic));
} }
for (Item i : gsrc.gameData.items) { for (Item i : gsrc.gameData.items) {
pushString(stringsResources, resourcesStrings, i.name, getPotContextComment(i)); pushString(stringsResources, resourcesStrings, i.name, getPotContextComment(i));
pushString(stringsResources, resourcesStrings, i.description, getPotContextComment(i) + ":description"); pushString(stringsResources, resourcesStrings, i.description, getPotContextComment(i)+":description");
} }
for (NPC npc : gsrc.gameData.npcs) { for (NPC npc : gsrc.gameData.npcs ) {
pushString(stringsResources, resourcesStrings, npc.name, getPotContextComment(npc)); pushString(stringsResources, resourcesStrings, npc.name, getPotContextComment(npc));
} }
for (Quest q : gsrc.gameData.quests) { for (Quest q : gsrc.gameData.quests) {
if (q.visible_in_log != null && q.visible_in_log != 0) { if (q.visible_in_log != null && q.visible_in_log != 0) {
pushString(stringsResources, resourcesStrings, q.name, getPotContextComment(q)); pushString(stringsResources, resourcesStrings, q.name, getPotContextComment(q));
for (QuestStage qs : q.stages) { for (QuestStage qs : q.stages) {
pushString(stringsResources, resourcesStrings, qs.log_text, getPotContextComment(q) + ":" + Integer.toString(qs.progress)); pushString(stringsResources, resourcesStrings, qs.log_text, getPotContextComment(q)+":"+Integer.toString(qs.progress));
} }
} }
} }
for (WorldmapSegment ws : gsrc.worldmap) { for (WorldmapSegment ws : gsrc.worldmap) {
for (WorldmapSegment.NamedArea area : ws.labels.values()) { for (WorldmapSegment.NamedArea area : ws.labels.values()) {
pushString(stringsResources, resourcesStrings, area.name, gsrc.worldmap.worldmapFile.getName() + ":" + ws.id + ":" + area.id); pushString(stringsResources, resourcesStrings, area.name, gsrc.worldmap.worldmapFile.getName()+":"+ws.id+":"+area.id);
} }
} }
File f = new File(proj.alteredContent.baseFolder, "english.pot"); File f = new File(proj.alteredContent.baseFolder, "english.pot");
PoPotWriter.writePotFile(stringsResources, f); PoPotWriter.writePotFile(stringsResources, f);
} }
private static void pushString(Map<String, List<String>> stringsResources, Map<String, String> resourcesStrings, String translatableString, String resourceIdentifier) { private static void pushString (Map<String, List<String>> stringsResources, Map<String, String> resourcesStrings, String translatableString, String resourceIdentifier) {
if (translatableString == null) return; if (translatableString == null) return;
if (translatableString.length() == 0) return; if (translatableString.length() == 0) return;
if (translatableString.contains("\"")) { if (translatableString.contains("\"")) {
translatableString = translatableString.replaceAll("\"", "\\\\\""); translatableString = translatableString.replaceAll("\"", "\\\\\"");
} }
if (translatableString.contains("\n")) { if (translatableString.contains("\n")) {
translatableString = translatableString.replaceAll("\n", "\\\\n\"\n\""); translatableString = translatableString.replaceAll("\n", "\\\\n\"\n\"");
translatableString = "\"\n\"" + translatableString; translatableString = "\"\n\""+translatableString;
} }
resourcesStrings.put(resourceIdentifier, translatableString); resourcesStrings.put(resourceIdentifier, translatableString);
List<String> resourceIdentifiers = stringsResources.get(translatableString); List<String> resourceIdentifiers = stringsResources.get(translatableString);
if (resourceIdentifiers == null) { if (resourceIdentifiers == null) {
resourceIdentifiers = new LinkedList<String>(); resourceIdentifiers = new LinkedList<String>();
stringsResources.put(translatableString, resourceIdentifiers); stringsResources.put(translatableString, resourceIdentifiers);
} }
resourceIdentifiers.add(resourceIdentifier); resourceIdentifiers.add(resourceIdentifier);
} }
private static String getPotContextComment(JSONElement e) { private static String getPotContextComment(JSONElement e) {
return e.jsonFile.getName() + ":" + e.id; return e.jsonFile.getName()+":"+e.id;
} }
} }

View File

@@ -1,7 +1,30 @@
package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer; package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import org.json.simple.JSONArray;
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.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition; import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
@@ -15,347 +38,344 @@ import com.whoischarles.util.json.Minify;
import com.whoischarles.util.json.Minify.UnterminatedCommentException; import com.whoischarles.util.json.Minify.UnterminatedCommentException;
import com.whoischarles.util.json.Minify.UnterminatedRegExpLiteralException; import com.whoischarles.util.json.Minify.UnterminatedRegExpLiteralException;
import com.whoischarles.util.json.Minify.UnterminatedStringLiteralException; import com.whoischarles.util.json.Minify.UnterminatedStringLiteralException;
import org.json.simple.JSONArray;
import tiled.core.TileSet; import tiled.core.TileSet;
import tiled.io.TMXMapWriter; import tiled.io.TMXMapWriter;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import java.util.*;
/** /**
*
* @author Kevin * @author Kevin
* <p> *
* To use this, paste the following script in the beanshell console of ATCS. * To use this, paste the following script in the beanshell console of ATCS.
* Don't forget to change the project number to suit your needs. * Don't forget to change the project number to suit your needs.
* <p> *
* <code> import com.gpl.rpg.atcontentstudio.model.tools.resoptimizer.ResourcesCompactor;
* import com.gpl.rpg.atcontentstudio.model.tools.resoptimizer.ResourcesCompactor; import com.gpl.rpg.atcontentstudio.model.Workspace;
* import com.gpl.rpg.atcontentstudio.model.Workspace;
proj = Workspace.activeWorkspace.projects.get(0);
new ResourcesCompactor(proj).compactData();
* *
* proj = Workspace.activeWorkspace.projects.get(0);
* new ResourcesCompactor(proj).compactData();
* </code>
*/ */
public class ResourcesCompactor { public class ResourcesCompactor {
public static String DEFAULT_REL_PATH_IN_PROJECT = "compressed" + File.separator; public static String DEFAULT_REL_PATH_IN_PROJECT = "compressed"+File.separator;
private Project proj;
private File baseFolder;
private List<CompressedSpritesheet> compressedSpritesheets = new LinkedList<CompressedSpritesheet>();
private List<File> preservedSpritesheets = new LinkedList<File>();
private Map<SpritesheetId, SpritesheetId> spritesRelocationForObjects = new LinkedHashMap<SpritesheetId, SpritesheetId>();
private Integer currentSpritesheetIndexForObjects = 0;
private CompressedSpritesheet currentSpritesheetForObjects = null;
private Project proj; private Map<SpritesheetId, SpritesheetId> spritesRelocationForMaps = new LinkedHashMap<SpritesheetId, SpritesheetId>();
private File baseFolder; private Map<SpritesheetId, CompressedSpritesheet> spritesheetsBySidForMaps = new LinkedHashMap<SpritesheetId, CompressedSpritesheet>();
private List<CompressedSpritesheet> compressedSpritesheets = new LinkedList<CompressedSpritesheet>(); private Integer currentSpritesheetIndexForMaps = 0;
private List<File> preservedSpritesheets = new LinkedList<File>(); private CompressedSpritesheet currentSpritesheetForMaps = null;
public ResourcesCompactor(Project proj) {
this.proj = proj;
this.baseFolder = new File(proj.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
if (!baseFolder.exists()) baseFolder.mkdirs();
}
public void compactData() {
compactJsonData();
for(CompressedSpritesheet cs : compressedSpritesheets) {
cs.drawFile();
}
for (File preserved : preservedSpritesheets) {
FileUtils.copyFile(preserved, new File(baseFolder.getAbsolutePath()+File.separator+DEFAULT_DRAWABLE_REL_PATH+File.separator+preserved.getName()));
}
compactMaps();
}
public void compactJsonData() {
final List<File> filesCovered = new LinkedList<File>();
File folder = new File(baseFolder.getAbsolutePath()+File.separator+GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!folder.exists()) folder.mkdirs();
for (ActorCondition ac : proj.baseContent.gameData.actorConditions) {
if (filesCovered.contains(ac.jsonFile)) continue;
File currentFile = ac.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (ActorCondition acond : proj.baseContent.gameData.actorConditions) {
if (!acond.jsonFile.equals(currentFile)) continue;
Map json = acond.toJson();
json.put("iconID", convertObjectSprite(acond.icon_id).toStringID());
dataToSave.add(json);
}
File target = new File(folder, ac.jsonFile.getName());
writeJson(dataToSave, target);
}
for (Item it : proj.baseContent.gameData.items) {
if (filesCovered.contains(it.jsonFile)) continue;
File currentFile = it.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (Item item : proj.baseContent.gameData.items) {
if (!item.jsonFile.equals(currentFile)) continue;
Map json = item.toJson();
json.put("iconID", convertObjectSprite(item.icon_id).toStringID());
dataToSave.add(json);
}
File target = new File(folder, it.jsonFile.getName());
writeJson(dataToSave, target);
}
private Map<SpritesheetId, SpritesheetId> spritesRelocationForObjects = new LinkedHashMap<SpritesheetId, SpritesheetId>(); for (NPC np : proj.baseContent.gameData.npcs) {
private Integer currentSpritesheetIndexForObjects = 0; if (filesCovered.contains(np.jsonFile)) continue;
private CompressedSpritesheet currentSpritesheetForObjects = null; File currentFile = np.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (NPC npc : proj.baseContent.gameData.npcs) {
if (!npc.jsonFile.equals(currentFile)) continue;
Map json = npc.toJson();
if (proj.getImage(npc.icon_id).getWidth(null) == TILE_WIDTH_IN_PIXELS || proj.getImage(npc.icon_id).getHeight(null) == TILE_HEIGHT_IN_PIXELS) {
json.put("iconID", convertObjectSprite(npc.icon_id).toStringID());
}
dataToSave.add(json);
}
File target = new File(folder, np.jsonFile.getName());
writeJson(dataToSave, target);
}
File[] remainingFiles = proj.baseContent.gameData.baseFolder.listFiles(new FileFilter() {
@Override
public boolean accept(File arg0) {
return arg0.getName().endsWith(".json") && !filesCovered.contains(arg0);
}
});
for (File source : remainingFiles) {
File target = new File(folder, source.getName());
minifyJson(source, target);
}
}
private Map<SpritesheetId, SpritesheetId> spritesRelocationForMaps = new LinkedHashMap<SpritesheetId, SpritesheetId>(); private Minify jsonMinifier = new Minify();
private Map<SpritesheetId, CompressedSpritesheet> spritesheetsBySidForMaps = new LinkedHashMap<SpritesheetId, CompressedSpritesheet>();
private Integer currentSpritesheetIndexForMaps = 0; private void writeJson(List<Map> dataToSave, File target) {
private CompressedSpritesheet currentSpritesheetForMaps = null; StringWriter writer = new JsonPrettyWriter();
try {
JSONArray.writeJSONString(dataToSave, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(target);
w.write(jsonMinifier.minify(toWrite));
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public ResourcesCompactor(Project proj) { private void minifyJson(File source, File target) {
this.proj = proj; ByteArrayOutputStream baos = new ByteArrayOutputStream();
this.baseFolder = new File(proj.baseFolder, DEFAULT_REL_PATH_IN_PROJECT); try {
if (!baseFolder.exists()) baseFolder.mkdirs(); FileInputStream fis = new FileInputStream(source);
} jsonMinifier.minify(fis, baos);
FileWriter w = new FileWriter(target);
public void compactData() { w.write(baos.toString());
compactJsonData(); w.close();
for (CompressedSpritesheet cs : compressedSpritesheets) { } catch (IOException e) {
cs.drawFile(); e.printStackTrace();
} } catch (UnterminatedRegExpLiteralException e) {
for (File preserved : preservedSpritesheets) { e.printStackTrace();
FileUtils.copyFile(preserved, new File(baseFolder.getAbsolutePath() + File.separator + DEFAULT_DRAWABLE_REL_PATH + File.separator + preserved.getName())); } catch (UnterminatedCommentException e) {
} e.printStackTrace();
compactMaps(); } catch (UnterminatedStringLiteralException e) {
} e.printStackTrace();
}
public void compactJsonData() { }
final List<File> filesCovered = new LinkedList<File>(); private void compactMaps() {
for (TMXMap map : proj.baseContent.gameMaps.tmxMaps) {
File folder = new File(baseFolder.getAbsolutePath() + File.separator + GameDataSet.DEFAULT_REL_PATH_IN_SOURCE); TMXMap clone = map.clone();
if (!folder.exists()) folder.mkdirs(); for (GameDataElement gde : clone.getBacklinks()) {
gde.removeBacklink(clone);
for (ActorCondition ac : proj.baseContent.gameData.actorConditions) { }
if (filesCovered.contains(ac.jsonFile)) continue; clone.getBacklinks().clear();
File currentFile = ac.jsonFile; tiled.core.Map tmx = clone.tmxMap;
filesCovered.add(currentFile); compactMap(tmx, map.id);
List<Map> dataToSave = new ArrayList<Map>(); clone.tmxMap = null;
for (ActorCondition acond : proj.baseContent.gameData.actorConditions) { clone.groups.clear();
if (!acond.jsonFile.equals(currentFile)) continue; clone = null;
Map json = acond.toJson(); }
json.put("iconID", convertObjectSprite(acond.icon_id).toStringID()); }
dataToSave.add(json);
} private void compactMap(tiled.core.Map tmx, String name) {
File target = new File(folder, ac.jsonFile.getName()); File target = new File(baseFolder.getAbsolutePath()+File.separator+TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE+File.separator+name+".tmx");
writeJson(dataToSave, target); if (!target.getParentFile().exists()) target.getParentFile().mkdirs();
}
Map<tiled.core.Tile, SpritesheetId> localConvertions = new LinkedHashMap<tiled.core.Tile, SpritesheetId>();
for (Item it : proj.baseContent.gameData.items) { List<CompressedSpritesheet> usedSpritesheets = new LinkedList<CompressedSpritesheet>();
if (filesCovered.contains(it.jsonFile)) continue;
File currentFile = it.jsonFile; List<tiled.core.TileSet> toRemove = new LinkedList<TileSet>();
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>(); for (tiled.core.TileSet ts : tmx.getTileSets()) {
for (Item item : proj.baseContent.gameData.items) { if (!ts.getName().equalsIgnoreCase("map_dynamic_placeholders")) {
if (!item.jsonFile.equals(currentFile)) continue; toRemove.add(ts);
Map json = item.toJson(); }
json.put("iconID", convertObjectSprite(item.icon_id).toStringID()); }
dataToSave.add(json);
} for (tiled.core.TileLayer layer : tmx.getTileLayers()) {
File target = new File(folder, it.jsonFile.getName()); for (int x = 0; x < layer.getWidth(); x++) {
writeJson(dataToSave, target); for (int y = 0; y < layer.getHeight(); y++) {
} tiled.core.Tile tile = layer.getTileAt(x, y);
if (tile != null && !tile.getTileSet().getName().equalsIgnoreCase("map_dynamic_placeholders")) {
SpritesheetId sid = convertMapSprite(SpritesheetId.toStringID(tile.getTileSet().getName(), tile.getId()));
for (NPC np : proj.baseContent.gameData.npcs) { localConvertions.put(tile, sid);
if (filesCovered.contains(np.jsonFile)) continue; if (!usedSpritesheets.contains(spritesheetsBySidForMaps.get(sid))) {
File currentFile = np.jsonFile; usedSpritesheets.add(spritesheetsBySidForMaps.get(sid));
filesCovered.add(currentFile); }
List<Map> dataToSave = new ArrayList<Map>(); }
for (NPC npc : proj.baseContent.gameData.npcs) { }
if (!npc.jsonFile.equals(currentFile)) continue; }
Map json = npc.toJson(); }
if (proj.getImage(npc.icon_id).getWidth(null) == TILE_WIDTH_IN_PIXELS || proj.getImage(npc.icon_id).getHeight(null) == TILE_HEIGHT_IN_PIXELS) {
json.put("iconID", convertObjectSprite(npc.icon_id).toStringID()); Map<CompressedSpritesheet, tiled.core.TileSet> csToTs = new LinkedHashMap<CompressedSpritesheet, tiled.core.TileSet>();
} for (CompressedSpritesheet cs : usedSpritesheets) {
dataToSave.add(json); cs.drawFile();
} tiled.core.TileSet ts = new tiled.core.TileSet();
File target = new File(folder, np.jsonFile.getName()); csToTs.put(cs, ts);
writeJson(dataToSave, target); tiled.util.BasicTileCutter cutter = new tiled.util.BasicTileCutter(TILE_WIDTH_IN_PIXELS, TILE_HEIGHT_IN_PIXELS, 0, 0);
} try {
ts.importTileBitmap(cs.f.getAbsolutePath(), cutter);
File[] remainingFiles = proj.baseContent.gameData.baseFolder.listFiles(new FileFilter() { } catch (IOException e) {
@Override e.printStackTrace();
public boolean accept(File arg0) { }
return arg0.getName().endsWith(".json") && !filesCovered.contains(arg0); ts.setName(cs.prefix+Integer.toString(cs.index));
} //ts.setSource("../drawable/"+ts.getName()+TILESHEET_SUFFIX);
}); tmx.addTileset(ts);
}
for (File source : remainingFiles) {
File target = new File(folder, source.getName()); for (tiled.core.TileLayer layer : tmx.getTileLayers()) {
minifyJson(source, target); for (tiled.core.Tile tile : localConvertions.keySet()) {
} SpritesheetId sid = localConvertions.get(tile);
} layer.replaceTile(tile, csToTs.get(spritesheetsBySidForMaps.get(sid)).getTile(sid.offset));
}
private Minify jsonMinifier = new Minify(); }
private void writeJson(List<Map> dataToSave, File target) { for (tiled.core.TileSet ts : toRemove) {
String toWrite = FileUtils.toJsonString(dataToSave); tmx.removeTileset(ts);
toWrite = jsonMinifier.minify(toWrite); }
FileUtils.writeStringToFile(toWrite, target, null); ByteArrayOutputStream baos = new ByteArrayOutputStream();
try { TMXMapWriter writer = new TMXMapWriter();
FileWriter w = new FileWriter(target); writer.settings.layerCompressionMethod = TMXMapWriter.Settings.LAYER_COMPRESSION_METHOD_ZLIB;
w.write(toWrite); try {
w.close(); writer.writeMap(tmx, baos, target.getAbsolutePath());
} catch (IOException e) { String xml = baos.toString();
e.printStackTrace(); FileWriter w = new FileWriter(target);
} w.write(xml);
} w.close();
} catch (Exception e) {
private void minifyJson(File source, File target) { e.printStackTrace();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); }
try {
FileInputStream fis = new FileInputStream(source); }
jsonMinifier.minify(fis, baos);
FileWriter w = new FileWriter(target); private SpritesheetId convertObjectSprite(String originalSpriteId) {
w.write(baos.toString()); if (spritesRelocationForObjects.containsKey(SpritesheetId.getInstance(originalSpriteId))) {
w.close(); return spritesRelocationForObjects.get(SpritesheetId.getInstance(originalSpriteId));
} catch (IOException e) { } else if (currentSpritesheetForObjects == null || !currentSpritesheetForObjects.hasFreeSlot()) {
e.printStackTrace(); currentSpritesheetForObjects = new CompressedSpritesheet(TILESHEET_PREFIX_FOR_OBJECTS, currentSpritesheetIndexForObjects);
} catch (UnterminatedRegExpLiteralException e) { compressedSpritesheets.add(currentSpritesheetForObjects);
e.printStackTrace(); currentSpritesheetIndexForObjects++;
} catch (UnterminatedCommentException e) { }
e.printStackTrace(); SpritesheetId sid = currentSpritesheetForObjects.addSprite(originalSpriteId);
} catch (UnterminatedStringLiteralException e) { spritesRelocationForObjects.put(SpritesheetId.getInstance(originalSpriteId), sid);
e.printStackTrace(); return sid;
} }
}
private SpritesheetId convertMapSprite(String originalSpriteId) {
private void compactMaps() { if (spritesRelocationForMaps.containsKey(SpritesheetId.getInstance(originalSpriteId))) {
for (TMXMap map : proj.baseContent.gameMaps.tmxMaps) { return spritesRelocationForMaps.get(SpritesheetId.getInstance(originalSpriteId));
TMXMap clone = map.clone(); } else if (currentSpritesheetForMaps == null || !currentSpritesheetForMaps.hasFreeSlot()) {
for (GameDataElement gde : clone.getBacklinks()) { currentSpritesheetForMaps = new CompressedSpritesheet(TILESHEET_PREFIX_FOR_MAPS, currentSpritesheetIndexForMaps);
gde.removeBacklink(clone); compressedSpritesheets.add(currentSpritesheetForMaps);
} currentSpritesheetIndexForMaps++;
clone.getBacklinks().clear(); }
tiled.core.Map tmx = clone.tmxMap; SpritesheetId sid = currentSpritesheetForMaps.addSprite(originalSpriteId);
compactMap(tmx, map.id); spritesRelocationForMaps.put(SpritesheetId.getInstance(originalSpriteId), sid);
clone.tmxMap = null; spritesheetsBySidForMaps.put(sid, currentSpritesheetForMaps);
clone.groups.clear(); return sid;
} }
}
private void compactMap(tiled.core.Map tmx, String name) { private static final int TILESHEET_WIDTH_IN_SPRITES = 8;
File target = new File(baseFolder.getAbsolutePath() + File.separator + TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE + File.separator + name + ".tmx"); private static final int TILESHEET_HEIGHT_IN_SPRITES = 8;
if (!target.getParentFile().exists()) target.getParentFile().mkdirs(); private static final int TILE_WIDTH_IN_PIXELS = 32;
private static final int TILE_HEIGHT_IN_PIXELS = 32;
Map<tiled.core.Tile, SpritesheetId> localConvertions = new LinkedHashMap<tiled.core.Tile, SpritesheetId>();
List<CompressedSpritesheet> usedSpritesheets = new LinkedList<CompressedSpritesheet>(); private static final String TILESHEET_PREFIX_FOR_OBJECTS = "obj_";
private static final String TILESHEET_PREFIX_FOR_MAPS = "map_";
List<tiled.core.TileSet> toRemove = new LinkedList<TileSet>(); private static final String TILESHEET_SUFFIX = ".png";
for (tiled.core.TileSet ts : tmx.getTileSets()) { private static final String DEFAULT_DRAWABLE_REL_PATH = SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE;
if (!ts.getName().equalsIgnoreCase("map_dynamic_placeholders")) {
toRemove.add(ts); private class CompressedSpritesheet {
} String prefix;
} int index;
File f;
for (tiled.core.TileLayer layer : tmx.getTileLayers()) {
for (int x = 0; x < layer.getWidth(); x++) {
for (int y = 0; y < layer.getHeight(); y++) {
tiled.core.Tile tile = layer.getTileAt(x, y);
if (tile != null && !tile.getTileSet().getName().equalsIgnoreCase("map_dynamic_placeholders")) {
SpritesheetId sid = convertMapSprite(SpritesheetId.toStringID(tile.getTileSet().getName(), tile.getId()));
localConvertions.put(tile, sid);
if (!usedSpritesheets.contains(spritesheetsBySidForMaps.get(sid))) {
usedSpritesheets.add(spritesheetsBySidForMaps.get(sid));
}
}
}
}
}
Map<CompressedSpritesheet, tiled.core.TileSet> csToTs = new LinkedHashMap<CompressedSpritesheet, tiled.core.TileSet>();
for (CompressedSpritesheet cs : usedSpritesheets) {
cs.drawFile();
tiled.core.TileSet ts = new tiled.core.TileSet();
csToTs.put(cs, ts);
tiled.util.BasicTileCutter cutter = new tiled.util.BasicTileCutter(TILE_WIDTH_IN_PIXELS, TILE_HEIGHT_IN_PIXELS, 0, 0);
try {
ts.importTileBitmap(cs.f.getAbsolutePath(), cutter);
} catch (IOException e) {
e.printStackTrace();
}
ts.setName(cs.prefix + Integer.toString(cs.index));
//ts.setSource("../drawable/"+ts.getName()+TILESHEET_SUFFIX);
tmx.addTileset(ts);
}
for (tiled.core.TileLayer layer : tmx.getTileLayers()) {
for (tiled.core.Tile tile : localConvertions.keySet()) {
SpritesheetId sid = localConvertions.get(tile);
layer.replaceTile(tile, csToTs.get(spritesheetsBySidForMaps.get(sid)).getTile(sid.offset));
}
}
for (tiled.core.TileSet ts : toRemove) {
tmx.removeTileset(ts);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TMXMapWriter writer = new TMXMapWriter();
writer.settings.layerCompressionMethod = TMXMapWriter.Settings.LAYER_COMPRESSION_METHOD_ZLIB;
try {
writer.writeMap(tmx, baos, target.getAbsolutePath());
String xml = baos.toString();
FileWriter w = new FileWriter(target);
w.write(xml);
w.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private SpritesheetId convertObjectSprite(String originalSpriteId) {
if (spritesRelocationForObjects.containsKey(SpritesheetId.getInstance(originalSpriteId))) {
return spritesRelocationForObjects.get(SpritesheetId.getInstance(originalSpriteId));
} else if (currentSpritesheetForObjects == null || !currentSpritesheetForObjects.hasFreeSlot()) {
currentSpritesheetForObjects = new CompressedSpritesheet(TILESHEET_PREFIX_FOR_OBJECTS, currentSpritesheetIndexForObjects);
compressedSpritesheets.add(currentSpritesheetForObjects);
currentSpritesheetIndexForObjects++;
}
SpritesheetId sid = currentSpritesheetForObjects.addSprite(originalSpriteId);
spritesRelocationForObjects.put(SpritesheetId.getInstance(originalSpriteId), sid);
return sid;
}
private SpritesheetId convertMapSprite(String originalSpriteId) {
if (spritesRelocationForMaps.containsKey(SpritesheetId.getInstance(originalSpriteId))) {
return spritesRelocationForMaps.get(SpritesheetId.getInstance(originalSpriteId));
} else if (currentSpritesheetForMaps == null || !currentSpritesheetForMaps.hasFreeSlot()) {
currentSpritesheetForMaps = new CompressedSpritesheet(TILESHEET_PREFIX_FOR_MAPS, currentSpritesheetIndexForMaps);
compressedSpritesheets.add(currentSpritesheetForMaps);
currentSpritesheetIndexForMaps++;
}
SpritesheetId sid = currentSpritesheetForMaps.addSprite(originalSpriteId);
spritesRelocationForMaps.put(SpritesheetId.getInstance(originalSpriteId), sid);
spritesheetsBySidForMaps.put(sid, currentSpritesheetForMaps);
return sid;
}
private static final int TILESHEET_WIDTH_IN_SPRITES = 8;
private static final int TILESHEET_HEIGHT_IN_SPRITES = 8;
private static final int TILE_WIDTH_IN_PIXELS = 32;
private static final int TILE_HEIGHT_IN_PIXELS = 32;
private static final String TILESHEET_PREFIX_FOR_OBJECTS = "obj_";
private static final String TILESHEET_PREFIX_FOR_MAPS = "map_";
private static final String TILESHEET_SUFFIX = ".png";
private static final String DEFAULT_DRAWABLE_REL_PATH = SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE;
private class CompressedSpritesheet {
String prefix;
int index;
File f;
boolean mustDraw = true;
int nextFreeSlot = 0;
String[] originalSpritesId = new String[TILESHEET_WIDTH_IN_SPRITES * TILESHEET_HEIGHT_IN_SPRITES];
public CompressedSpritesheet(String prefix, int index) {
this.prefix = prefix;
this.index = index;
File folder = new File(ResourcesCompactor.this.baseFolder.getAbsolutePath() + File.separator + DEFAULT_DRAWABLE_REL_PATH);
if (!folder.exists()) folder.mkdirs();
this.f = new File(folder, prefix + Integer.toString(index) + TILESHEET_SUFFIX);
}
public boolean hasFreeSlot() {
return nextFreeSlot < TILESHEET_WIDTH_IN_SPRITES * TILESHEET_HEIGHT_IN_SPRITES;
}
public SpritesheetId addSprite(String spriteId) {
mustDraw = true;
originalSpritesId[nextFreeSlot] = spriteId;
nextFreeSlot++;
return SpritesheetId.getInstance(prefix + Integer.toString(index), nextFreeSlot - 1);
}
public void drawFile() {
if (!mustDraw) return;
BufferedImage img = new BufferedImage(TILESHEET_WIDTH_IN_SPRITES * TILE_WIDTH_IN_PIXELS, TILESHEET_HEIGHT_IN_SPRITES * TILE_HEIGHT_IN_PIXELS, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
Color transparent = new Color(0, 0, 0, 0);
g.setColor(transparent);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
for (int i = 0; i < nextFreeSlot; i++) {
g.drawImage(
proj.getImage(originalSpritesId[i]),
(i % TILESHEET_WIDTH_IN_SPRITES) * TILE_WIDTH_IN_PIXELS,
(i / TILESHEET_WIDTH_IN_SPRITES) * TILE_HEIGHT_IN_PIXELS,
TILE_WIDTH_IN_PIXELS,
TILE_HEIGHT_IN_PIXELS,
null);
}
try {
ImageIO.write(img, "png", f);
mustDraw = false;
} catch (IOException e) {
e.printStackTrace();
}
}
}
boolean mustDraw = true;
int nextFreeSlot = 0;
String[] originalSpritesId = new String[TILESHEET_WIDTH_IN_SPRITES * TILESHEET_HEIGHT_IN_SPRITES];
public CompressedSpritesheet(String prefix, int index) {
this.prefix = prefix;
this.index = index;
File folder = new File(ResourcesCompactor.this.baseFolder.getAbsolutePath()+File.separator+DEFAULT_DRAWABLE_REL_PATH);
if (!folder.exists()) folder.mkdirs();
this.f = new File(folder, prefix+Integer.toString(index)+TILESHEET_SUFFIX);
}
public boolean hasFreeSlot() {
return nextFreeSlot < TILESHEET_WIDTH_IN_SPRITES * TILESHEET_HEIGHT_IN_SPRITES;
}
public SpritesheetId addSprite(String spriteId) {
mustDraw = true;
originalSpritesId[nextFreeSlot] = spriteId;
nextFreeSlot++;
return SpritesheetId.getInstance(prefix+Integer.toString(index), nextFreeSlot - 1);
}
public void drawFile() {
if (!mustDraw) return;
BufferedImage img = new BufferedImage(TILESHEET_WIDTH_IN_SPRITES * TILE_WIDTH_IN_PIXELS, TILESHEET_HEIGHT_IN_SPRITES * TILE_HEIGHT_IN_PIXELS, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D)img.getGraphics();
Color transparent = new Color(0, 0, 0, 0);
g.setColor(transparent);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
for (int i = 0; i < nextFreeSlot; i++) {
g.drawImage(
proj.getImage(originalSpritesId[i]),
(i % TILESHEET_WIDTH_IN_SPRITES) * TILE_WIDTH_IN_PIXELS,
(i / TILESHEET_WIDTH_IN_SPRITES) * TILE_HEIGHT_IN_PIXELS,
TILE_WIDTH_IN_PIXELS,
TILE_HEIGHT_IN_PIXELS,
null);
}
try {
ImageIO.write(img, "png", f);
mustDraw = false;
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }

View File

@@ -4,35 +4,35 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
public class SpritesheetId { public class SpritesheetId {
static Map<String, SpritesheetId> instancesCache = new LinkedHashMap<String, SpritesheetId>(); static Map<String, SpritesheetId> instancesCache = new LinkedHashMap<String, SpritesheetId>();
String tileset; String tileset;
int offset; int offset;
static SpritesheetId getInstance(String id) { static SpritesheetId getInstance(String id) {
String[] values = id.split(":"); String[] values = id.split(":");
return getInstance(values[0], Integer.parseInt(values[1])); return getInstance(values[0], Integer.parseInt(values[1]));
} }
static SpritesheetId getInstance(String tilesetId, int offset) { static SpritesheetId getInstance(String tilesetId, int offset) {
if (!instancesCache.containsKey(toStringID(tilesetId, offset))) { if (!instancesCache.containsKey(toStringID(tilesetId, offset))) {
SpritesheetId instance = new SpritesheetId(tilesetId, offset); SpritesheetId instance = new SpritesheetId(tilesetId, offset);
instancesCache.put(instance.toStringID(), instance); instancesCache.put(instance.toStringID(), instance);
} }
return instancesCache.get(toStringID(tilesetId, offset)); return instancesCache.get(toStringID(tilesetId, offset));
} }
private SpritesheetId(String tileset, int offset) { private SpritesheetId(String tileset, int offset) {
this.tileset = tileset; this.tileset = tileset;
this.offset = offset; this.offset = offset;
} }
public String toStringID() { public String toStringID() {
return toStringID(tileset, offset); return toStringID(tileset, offset);
} }
static String toStringID(String tileset, int offset) { static String toStringID(String tileset, int offset) {
return tileset + ":" + Integer.toString(offset); return tileset+":"+Integer.toString(offset);
} }
} }

View File

@@ -1,249 +1,274 @@
package com.gpl.rpg.atcontentstudio.model.tools.writermode; package com.gpl.rpg.atcontentstudio.model.tools.writermode;
import com.gpl.rpg.atcontentstudio.Notification; import java.awt.Image;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import java.io.File;
import com.gpl.rpg.atcontentstudio.model.*; import java.io.FileNotFoundException;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import java.io.FileReader;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import java.io.FileWriter;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import java.io.IOException;
import com.gpl.rpg.atcontentstudio.utils.FileUtils; import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
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 javax.swing.tree.TreeNode; import com.gpl.rpg.atcontentstudio.Notification;
import java.awt.*; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import java.io.*; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import java.util.List; import com.gpl.rpg.atcontentstudio.model.GameSource;
import java.util.*; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class WriterModeDataSet implements ProjectTreeNode, Serializable { public class WriterModeDataSet implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = 5434504851883441971L; private static final long serialVersionUID = 5434504851883441971L;
public static final String DEFAULT_REL_PATH_IN_PROJECT = "writer.json"; public static final String DEFAULT_REL_PATH_IN_PROJECT = "writer.json";
public GameSource parent;
public File writerFile;
public List<WriterModeData> writerModeDataList = new ArrayList<WriterModeData>();
public WriterModeDataSet(GameSource gameSource) {
this.parent = gameSource;
writerFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
parse();
}
@Override
public TreeNode getChildAt(int childIndex) {
return writerModeDataList.get(childIndex);
}
public GameSource parent; @Override
public File writerFile; public int getChildCount() {
return writerModeDataList.size();
}
public List<WriterModeData> writerModeDataList = new ArrayList<WriterModeData>(); @Override
public TreeNode getParent() {
return parent;
}
public WriterModeDataSet(GameSource gameSource) { @Override
this.parent = gameSource; public int getIndex(TreeNode node) {
writerFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_PROJECT); return writerModeDataList.indexOf(node);
parse(); }
}
@Override @Override
public TreeNode getChildAt(int childIndex) { public boolean getAllowsChildren() {
return writerModeDataList.get(childIndex); return true;
} }
@Override @Override
public int getChildCount() { public boolean isLeaf() {
return writerModeDataList.size(); return false;
} }
@Override @SuppressWarnings("rawtypes")
public TreeNode getParent() { @Override
return parent; public Enumeration children() {
} return Collections.enumeration(writerModeDataList);
}
@Override @Override
public int getIndex(TreeNode node) { public void childrenAdded(List<ProjectTreeNode> path) {
return writerModeDataList.indexOf(node); path.add(0,this);
} parent.childrenAdded(path);
}
@Override @Override
public boolean getAllowsChildren() { public void childrenChanged(List<ProjectTreeNode> path) {
return true; path.add(0,this);
} parent.childrenChanged(path);
}
@Override @Override
public boolean isLeaf() { public void childrenRemoved(List<ProjectTreeNode> path) {
return false; path.add(0,this);
} parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@SuppressWarnings("rawtypes") @Override
@Override public String getDesc() {
public Enumeration children() { return (needsSaving() ? "*" : "")+"Dialogue sketches";
return Collections.enumeration(writerModeDataList); }
}
@Override @Override
public void childrenAdded(List<ProjectTreeNode> path) { public Project getProject() {
path.add(0, this); return parent.getProject();
parent.childrenAdded(path); }
}
@Override @Override
public void childrenChanged(List<ProjectTreeNode> path) { public GameDataSet getDataSet() {
path.add(0, this); return null;
parent.childrenChanged(path); }
}
@Override @Override
public void childrenRemoved(List<ProjectTreeNode> path) { public Image getIcon() {
path.add(0, this); return DefaultIcons.getStdClosedIcon();
parent.childrenRemoved(path); }
}
@Override @Override
public void notifyCreated() { public Image getOpenIcon() {
childrenAdded(new ArrayList<ProjectTreeNode>()); return DefaultIcons.getStdOpenIcon();
} }
@Override @Override
public String getDesc() { public Image getClosedIcon() {
return (needsSaving() ? "*" : "") + "Dialogue sketches"; return DefaultIcons.getStdClosedIcon();
} }
@Override @Override
public Project getProject() { public Image getLeafIcon() {
return parent.getProject(); return null;
} }
@Override @Override
public GameDataSet getDataSet() { public Type getDataType() {
return null; return parent.getDataType();
} }
@Override @Override
public Image getIcon() { public boolean isEmpty() {
return DefaultIcons.getStdClosedIcon(); return writerModeDataList.isEmpty();
} }
@SuppressWarnings("rawtypes")
public void save(File jsonFile) {
List<Map> dataToSave = new ArrayList<Map>();
for (WriterModeData data : writerModeDataList) {
if (data.jsonFile.equals(jsonFile)) {
dataToSave.add(data.toJson());
}
}
if (dataToSave.isEmpty() && writerFile.exists()) {
if (writerFile.delete()) {
Notification.addSuccess("File "+writerFile.getAbsolutePath()+" deleted.");
} else {
Notification.addError("Error deleting file "+writerFile.getAbsolutePath());
}
return;
}
StringWriter writer = new JsonPrettyWriter();
try {
JSONArray.writeJSONString(dataToSave, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(writerFile);
w.write(toWrite);
w.close();
for (WriterModeData element : writerModeDataList) {
element.state = GameDataElement.State.saved;
}
Notification.addSuccess("Json file "+writerFile.getAbsolutePath()+" saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file "+writerFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
}
}
public List<SaveEvent> attemptSave() {
List<SaveEvent> events = new ArrayList<SaveEvent>();
for (WriterModeData data : writerModeDataList) {
if (data.needsSaving()) {
events.add(new SaveEvent(SaveEvent.Type.alsoSave, data));
}
}
return events;
}
@SuppressWarnings("rawtypes")
public void parse() {
if (!writerFile.exists()) return;
JSONParser parser = new JSONParser();
FileReader reader = null;
try {
reader = new FileReader(writerFile);
List writerDataListJson = (List) parser.parse(reader);
for (Object obj : writerDataListJson) {
Map jsonObj = (Map)obj;
WriterModeData data = new WriterModeData(this, jsonObj);
data.writable = true;
writerModeDataList.add(data);
}
} catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file "+writerFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Notification.addError("Error while parsing JSON file "+writerFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
} catch (ParseException e) {
Notification.addError("Error while parsing JSON file "+writerFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override public WriterModeData getWriterSketch(String id) {
public Image getOpenIcon() { for (WriterModeData sketch : writerModeDataList) {
return DefaultIcons.getStdOpenIcon(); if (id.equals(sketch.id)){
} return sketch;
}
}
return null;
}
@Override public WriterModeData get(int index) {
public Image getClosedIcon() { return writerModeDataList.get(index);
return DefaultIcons.getStdClosedIcon(); }
}
@Override public void add(WriterModeData node) {
public Image getLeafIcon() { ProjectTreeNode higherEmptyParent = this;
return null; while (higherEmptyParent != null) {
} if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
writerModeDataList.add(node);
node.writable = true;
if (node.jsonFile == null) node.jsonFile = this.writerFile;
node.parent = this;
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
@Override @Override
public Type getDataType() { public boolean needsSaving() {
return parent.getDataType(); for (ProjectTreeNode node : writerModeDataList) {
} if (node.needsSaving()) return true;
}
@Override return false;
public boolean isEmpty() { }
return writerModeDataList.isEmpty();
}
@SuppressWarnings("rawtypes")
public void save(File jsonFile) {
List<Map> dataToSave = new ArrayList<Map>();
for (WriterModeData data : writerModeDataList) {
if (data.jsonFile.equals(jsonFile)) {
dataToSave.add(data.toJson());
}
}
if (dataToSave.isEmpty() && writerFile.exists()) {
if (writerFile.delete()) {
Notification.addSuccess("File " + writerFile.getAbsolutePath() + " deleted.");
} else {
Notification.addError("Error deleting file " + writerFile.getAbsolutePath());
}
return;
}
String toWrite = FileUtils.toJsonString(dataToSave);
if(FileUtils.writeStringToFile(toWrite, writerFile, "Json file " + writerFile.getAbsolutePath())) {
for (WriterModeData element : writerModeDataList) {
element.state = GameDataElement.State.saved;
}
}
}
public List<SaveEvent> attemptSave() {
List<SaveEvent> events = new ArrayList<SaveEvent>();
for (WriterModeData data : writerModeDataList) {
if (data.needsSaving()) {
events.add(new SaveEvent(SaveEvent.Type.alsoSave, data));
}
}
return events;
}
@SuppressWarnings("rawtypes")
public void parse() {
if (!writerFile.exists()) return;
JSONParser parser = new JSONParser();
FileReader reader = null;
try {
reader = new FileReader(writerFile);
List writerDataListJson = (List) parser.parse(reader);
for (Object obj : writerDataListJson) {
Map jsonObj = (Map) obj;
WriterModeData data = new WriterModeData(this, jsonObj);
data.writable = true;
writerModeDataList.add(data);
}
} catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file " + writerFile.getAbsolutePath() + ": " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Notification.addError("Error while parsing JSON file " + writerFile.getAbsolutePath() + ": " + e.getMessage());
e.printStackTrace();
} catch (ParseException e) {
Notification.addError("Error while parsing JSON file " + writerFile.getAbsolutePath() + ": " + e.getMessage());
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public WriterModeData getWriterSketch(String id) {
for (WriterModeData sketch : writerModeDataList) {
if (id.equals(sketch.id)) {
return sketch;
}
}
return null;
}
public WriterModeData get(int index) {
return writerModeDataList.get(index);
}
public void add(WriterModeData node) {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode) higherEmptyParent.getParent()).isEmpty())
higherEmptyParent = (ProjectTreeNode) higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
writerModeDataList.add(node);
node.writable = true;
if (node.jsonFile == null) node.jsonFile = this.writerFile;
node.parent = this;
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : writerModeDataList) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,203 +1,180 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Scanner;
import javax.swing.ImageIcon;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.event.HyperlinkListener;
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;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.jidesoft.swing.JideTabbedPane; import com.jidesoft.swing.JideTabbedPane;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Scanner;
public class AboutEditor extends Editor { public class AboutEditor extends Editor {
private static final long serialVersionUID = 6230549148222457139L; private static final long serialVersionUID = 6230549148222457139L;
public static final String WELCOME_STRING = public static final String WELCOME_STRING =
"<html><head>" + "<html><head>" +
"<meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=UTF-8\\\" />" + "<meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=UTF-8\\\" />" +
"</head><body>" + "</head><body>" +
"<table><tr valign=\"top\">" + "<table><tr valign=\"top\">" +
"<td><img src=\"" + ATContentStudio.class.getResource("/com/gpl/rpg/atcontentstudio/img/atcs_border_banner.png") + "\"/></td>" + "<td><img src=\""+ATContentStudio.class.getResource("/com/gpl/rpg/atcontentstudio/img/atcs_border_banner.png")+"\"/></td>" +
"<td><font size=+1>Welcome to " + ATContentStudio.APP_NAME + " " + ATContentStudio.APP_VERSION + "</font><br/>" + "<td><font size=+1>Welcome to "+ATContentStudio.APP_NAME+" "+ATContentStudio.APP_VERSION+"</font><br/>" +
"<br/>" + "<br/>" +
"This is a content editor for Andor's Trail.<br/>" + "This is a content editor for Andor's Trail.<br/>" +
"<b>Right click on the left area or use the \"File\" menu to create a project.</b><br/>" + "<b>Right click on the left area or use the \"File\" menu to create a project.</b><br/>" +
"<br/>" + "<br/>" +
"Play <a href=\"https://play.google.com/store/apps/details?id=com.gpl.rpg.AndorsTrail\">Andor's Trail</a> for free on your Android device.<br/>" + "Play <a href=\"https://play.google.com/store/apps/details?id=com.gpl.rpg.AndorsTrail\">Andor's Trail</a> for free on your Android device.<br/>" +
"Visit <a href=\"https://andorstrail.com/\">the official forum</a> to give or receive help.<br/>" + "Visit <a href=\"https://andorstrail.com/\">the official forum</a> to give or receive help.<br/>" +
"Open the project's <a href=\"https://github.com/Zukero/andors-trail/\">GitHub project page</a> to check out the game's source code.<br/>" + "Open the project's <a href=\"https://github.com/Zukero/andors-trail/\">GitHub project page</a> to check out the game's source code.<br/>" +
"<br/>" + "<br/>" +
"For content creation help, make sure to use the following resources:<br/>" + "For content creation help, make sure to use the following resources:<br/>" +
"<a href=\"https://andorstrail.com/viewtopic.php?f=6&t=4560\">The contribution guide on the forums</a><br/>" + "<a href=\"https://andorstrail.com/viewtopic.php?f=6&t=4560\">The contribution guide on the forums</a><br/>" +
"<a href=\"https://andorstrail.com/wiki/doku.php?id=andors_trail_wiki:developer_section\">The developer section of the Andor's Trail wiki</a><br/>" + "<a href=\"https://andorstrail.com/wiki/doku.php?id=andors_trail_wiki:developer_section\">The developer section of the Andor's Trail wiki</a><br/>" +
"<a href=\"https://docs.google.com/document/d/1BwWD1tLgPcmA2bwudrVnOc6f2dkPLFCjWdn7tXlIp5g\">The design outline document on Google Drive/Docs</a><br/>" + "<a href=\"https://docs.google.com/document/d/1BwWD1tLgPcmA2bwudrVnOc6f2dkPLFCjWdn7tXlIp5g\">The design outline document on Google Drive/Docs</a><br/>" +
"<br/>" + "<br/>" +
"<font size=+1>Credits:</font><br/>" + "<font size=+1>Credits:</font><br/>" +
"<br/>" + "<br/>" +
"Author: <a href=\"https://andorstrail.com/memberlist.php?mode=viewprofile&u=2875\">Zukero</a><br/>" + "Author: <a href=\"https://andorstrail.com/memberlist.php?mode=viewprofile&u=2875\">Zukero</a><br/>" +
"Licence: <a href=\"http://www.gnu.org/licenses/gpl-3.0.html\">GPL v3</a><br/>" + "Licence: <a href=\"http://www.gnu.org/licenses/gpl-3.0.html\">GPL v3</a><br/>" +
"Sources are included in this package and on <a href=\"https://github.com/Zukero/ATCS\">GitHub</a>.<br/>" + "Sources are included in this package and on <a href=\"https://github.com/Zukero/ATCS\">GitHub</a>.<br/>" +
"<br/>" + "<br/>" +
"Contributors: <br/>" + "Contributors: <br/>" +
"Quentin Delvallet<br/>" + "Quentin Delvallet<br/>" +
"Žižkin<br/>" + "Žižkin<br/>" +
"Gonk<br/>" + "Gonk<br/>" +
"<a href=\"https://github.com/OMGeeky\">OMGeeky</a><br/>" + "<br/>" +
"<br/>" + "This project uses the following libraries:<br/>" +
"This project uses the following libraries:<br/>" + "<a href=\"http://code.google.com/p/json-simple/\">JSON.simple</a> by Yidong Fang & Chris Nokleberg.<br/>" +
"<a href=\"http://code.google.com/p/json-simple/\">JSON.simple</a> by Yidong Fang & Chris Nokleberg.<br/>" + "License: <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Apache License 2.0</a><br/>" +
"License: <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">Apache License 2.0</a><br/>" + "<br/>" +
"<br/>" + "<a href=\"http://fifesoft.com/rsyntaxtextarea/\">RSyntaxTextArea</a> by Robert Futrell.<br/>" +
"<a href=\"http://fifesoft.com/rsyntaxtextarea/\">RSyntaxTextArea</a> by Robert Futrell.<br/>" + "License: <a href=\"http://fifesoft.com/rsyntaxtextarea/RSyntaxTextArea.License.txt\">Modified BSD License (a.k.a. 3-Clause BSD)</a><br/>" +
"License: <a href=\"http://fifesoft.com/rsyntaxtextarea/RSyntaxTextArea.License.txt\">Modified BSD License (a.k.a. 3-Clause BSD)</a><br/>" + "<br/>" +
"<br/>" + "<a href=\"http://www.jidesoft.com/products/oss.htm\">JIDE Common Layer</a> by JIDE Software.<br/>" +
"<a href=\"http://www.jidesoft.com/products/oss.htm\">JIDE Common Layer</a> by JIDE Software.<br/>" + "License: <a href=\"http://openjdk.java.net/legal/gplv2+ce.html\">GPL v2 with classpath exception</a><br/>" +
"License: <a href=\"http://openjdk.java.net/legal/gplv2+ce.html\">GPL v2 with classpath exception</a><br/>" + "<br/>" +
"<br/>" + "A modified version of <a href=\"https://github.com/bjorn/tiled/tree/master/util/java/libtiled-java\">libtiled-java</a> by Adam Turk & Thorbjorn Lindeijer.<br/>" +
"A modified version of <a href=\"https://github.com/bjorn/tiled/tree/master/util/java/libtiled-java\">libtiled-java</a> by Adam Turk & Thorbjorn Lindeijer.<br/>" + "License: <a href=\"https://github.com/bjorn/tiled/blob/master/LICENSE.BSD\">Simplified BSD License (a.k.a 2-Clause BSD)</a><br/>" +
"License: <a href=\"https://github.com/bjorn/tiled/blob/master/LICENSE.BSD\">Simplified BSD License (a.k.a 2-Clause BSD)</a><br/>" + "Sources of the modified version are included in this package.<br/>" +
"Sources of the modified version are included in this package.<br/>" + "<br/>" +
"<br/>" + "<a href=\"http://prefuse.org/\">Prefuse</a> by the Berkeley Institue of Design.<br/>" +
"<a href=\"http://prefuse.org/\">Prefuse</a> by the Berkeley Institue of Design.<br/>" + "License: <a href=\"http://prefuse.org/license-prefuse.txt\">Modified BSD License (a.k.a 3-Clause BSD)</a><br/>" +
"License: <a href=\"http://prefuse.org/license-prefuse.txt\">Modified BSD License (a.k.a 3-Clause BSD)</a><br/>" + "<br/>" +
"<br/>" + "<a href=\"http://www.beanshell.org/\">BeanShell</a> by Pat Niemeyer.<br/>" +
"<a href=\"http://www.beanshell.org/\">BeanShell</a> by Pat Niemeyer.<br/>" + "License: <a href=\"http://www.beanshell.org/license.html\">LGPL v3</a><br/>" +
"License: <a href=\"http://www.beanshell.org/license.html\">LGPL v3</a><br/>" + "<br/>" +
"<br/>" + "A slightly modified version of <a href=\"https://github.com/zackehh/siphash-java\">SipHash for Java</a> by Isaac Whitfield.<br/>" +
"A slightly modified version of <a href=\"https://github.com/zackehh/siphash-java\">SipHash for Java</a> by Isaac Whitfield.<br/>" + "License: <a href=\"https://github.com/zackehh/siphash-java/blob/master/LICENSE\">MIT License</a><br/>" +
"License: <a href=\"https://github.com/zackehh/siphash-java/blob/master/LICENSE\">MIT License</a><br/>" + "<br/>" +
"<br/>" + "<a href=\"https://jsoup.org/\">jsoup</a> by Jonathan Hedley<br/>" +
"<a href=\"https://jsoup.org/\">jsoup</a> by Jonathan Hedley<br/>" + "License: <a href=\"https://jsoup.org/license\">MIT License</a><br/>" +
"License: <a href=\"https://jsoup.org/license\">MIT License</a><br/>" + "<br/>" +
"<br/>" + "A slightly modified version of <a href=\"https://launchpad.net/po-parser\">General PO Parser</a> by Bal<61>zs T<>th<br/>" +
"A slightly modified version of <a href=\"https://launchpad.net/po-parser\">General PO Parser</a> by Bal<61>zs T<>th<br/>" + "License: <a href=\"http://www.gnu.org/licenses/gpl-3.0.html\">GPL v3</a><br/>" +
"License: <a href=\"http://www.gnu.org/licenses/gpl-3.0.html\">GPL v3</a><br/>" + "<br/>" +
"<br/>" + "A slightly modified version of <a href=\"www.whoischarles.com\">Minify.java</a> by Charles Bihis<br/>" +
"A slightly modified version of <a href=\"www.whoischarles.com\">Minify.java</a> by Charles Bihis<br/>" + "License: <a href=\"https://github.com/charlesbihis/minify#license\">Douglas Crockford variant of MIT License</a><br/>" +
"License: <a href=\"https://github.com/charlesbihis/minify#license\">Douglas Crockford variant of MIT License</a><br/>" + "<br/>" +
"<br/>" + "See the tabs below to find the full license text for each of these.<br/>" +
"See the tabs below to find the full license text for each of these.<br/>" + "<br/>" +
"<br/>" + "The Windows installer was created with:<br/>" +
"The Windows installer was created with:<br/>" + "<a href=\"http://nsis.sourceforge.net/Main_Page\">NSIS (Nullsoft Scriptable Install System) v2.46</a>" +
"<a href=\"http://nsis.sourceforge.net/Main_Page\">NSIS (Nullsoft Scriptable Install System) v2.46</a>" + "</td></tr></table>" +
"</td></tr></table>" + "</body></html>";
"</body></html>";
public static final AboutEditor instance = new AboutEditor();
public static final AboutEditor instance = new AboutEditor(); @SuppressWarnings("resource")
private AboutEditor() {
@SuppressWarnings("resource") this.name="About "+ATContentStudio.APP_NAME;
private AboutEditor() { this.icon = new ImageIcon(DefaultIcons.getMainIconIcon());
this.name = "About " + ATContentStudio.APP_NAME; this.target = new GameDataElement(){
this.icon = new ImageIcon(DefaultIcons.getMainIconIcon()); private static final long serialVersionUID = -227480102288529682L;
this.target = new GameDataElement() { @Override
private static final long serialVersionUID = -227480102288529682L; public GameDataSet getDataSet() {return null;}
@Override
@Override public String getDesc() {return null;}
public GameDataSet getDataSet() { @Override
return null; public void parse() {}
} @Override
public void link() {}
@Override @Override
public String getDesc() { public GameDataElement clone() {return null;}
return null; @Override
} public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {}
@Override
@Override public String getProjectFilename() {return null;}
public void parse() { @Override
} public void save() {}
@Override
@Override public List<SaveEvent> attemptSave() {return null;}
public void link() { };
}
setLayout(new BorderLayout());
@Override JideTabbedPane editorTabsHolder = new JideTabbedPane(JideTabbedPane.BOTTOM);
public GameDataElement clone() { editorTabsHolder.setTabShape(JideTabbedPane.SHAPE_FLAT);
return null; editorTabsHolder.setUseDefaultShowCloseButtonOnTab(false);
} editorTabsHolder.setShowCloseButtonOnTab(false);
add(editorTabsHolder, BorderLayout.CENTER);
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { editorTabsHolder.add("Welcome", getInfoPane(WELCOME_STRING, "text/html"));
} editorTabsHolder.add("JSON.simple License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.JSON.simple.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("RSyntaxTextArea License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/RSyntaxTextArea.License.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
@Override editorTabsHolder.add("JIDE Common Layer License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.JIDE.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
public String getProjectFilename() { editorTabsHolder.add("libtiled-java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.libtiled.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
return null; editorTabsHolder.add("prefuse License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/license-prefuse.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
} editorTabsHolder.add("BeanShell License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.LGPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("SipHash for Java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.siphash-zackehh.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
@Override editorTabsHolder.add("jsoup License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.jsoup.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
public void save() { editorTabsHolder.add("General PO Parser License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
} editorTabsHolder.add("Minify.java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.minify.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
@Override
public List<SaveEvent> attemptSave() { }
return null;
} private JPanel getInfoPane(String content, String mime) {
}; JEditorPane welcome = new JEditorPane();
welcome.setContentType(mime);
setLayout(new BorderLayout()); welcome.setText(content);
JideTabbedPane editorTabsHolder = new JideTabbedPane(JideTabbedPane.BOTTOM); welcome.setEditable(false);
editorTabsHolder.setTabShape(JideTabbedPane.SHAPE_FLAT); welcome.addHyperlinkListener(new HyperlinkListener() {
editorTabsHolder.setUseDefaultShowCloseButtonOnTab(false); @Override
editorTabsHolder.setShowCloseButtonOnTab(false); public void hyperlinkUpdate(HyperlinkEvent arg0) {
add(editorTabsHolder, BorderLayout.CENTER); arg0.getEventType();
if (arg0.getEventType() == EventType.ACTIVATED) {
editorTabsHolder.add("Welcome", getInfoPane(WELCOME_STRING, "text/html")); if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
editorTabsHolder.add("JSON.simple License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.JSON.simple.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); try {
editorTabsHolder.add("RSyntaxTextArea License", Desktop.getDesktop().browse(arg0.getURL().toURI());
getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/RSyntaxTextArea.License.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); } catch (IOException e) {
editorTabsHolder.add("JIDE Common Layer License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.JIDE.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); e.printStackTrace();
editorTabsHolder.add("libtiled-java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.libtiled.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); } catch (URISyntaxException e) {
editorTabsHolder.add("prefuse License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/license-prefuse.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); e.printStackTrace();
editorTabsHolder.add("BeanShell License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.LGPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); }
editorTabsHolder.add("SipHash for Java License", }
getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.siphash-zackehh.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); }
editorTabsHolder.add("jsoup License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.jsoup.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); }
editorTabsHolder.add("General PO Parser License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); });
editorTabsHolder.add("Minify.java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.minify.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); JPanel pane = new JPanel();
editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); pane.setLayout(new BorderLayout());
pane.add(new JScrollPane(welcome), BorderLayout.CENTER);
} return pane;
}
private JPanel getInfoPane(String content, String mime) {
JEditorPane welcome = new JEditorPane();
welcome.setContentType(mime); @Override
welcome.setText(content); public void targetUpdated() {}
welcome.setEditable(false);
welcome.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent arg0) {
arg0.getEventType();
if (arg0.getEventType() == EventType.ACTIVATED) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(arg0.getURL().toURI());
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
}
});
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.add(new JScrollPane(welcome), BorderLayout.CENTER);
return pane;
}
@Override
public void targetUpdated() {
}
} }

View File

@@ -1,17 +1,17 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.*; import javax.swing.JCheckBox;
public class BooleanBasedCheckBox extends JCheckBox { public class BooleanBasedCheckBox extends JCheckBox {
private static final long serialVersionUID = 3941646360487399554L; private static final long serialVersionUID = 3941646360487399554L;
public Boolean getBooleanValue() { public Boolean getBooleanValue() {
return isSelected() ? Boolean.TRUE : null; return isSelected() ? Boolean.TRUE : null;
} }
public void setBooleanValue(Boolean val) { public void setBooleanValue(Boolean val) {
setSelected(val != null && val); setSelected(val != null && val);
} }
} }

View File

@@ -1,155 +1,160 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.*; import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.*; public class CollapsiblePanel extends JPanel {
public class CollapsiblePanel extends JPanel { private static final long serialVersionUID = 319384990345722150L;
private static final long serialVersionUID = 319384990345722150L; String title;
TitledBorder border;
String title;
TitledBorder border;
public CollapsiblePanel(String title) { public CollapsiblePanel(String title) {
super(); super();
this.title = title; this.title = title;
border = BorderFactory.createTitledBorder(title); border = BorderFactory.createTitledBorder(title);
setBorder(border); setBorder(border);
BorderLayout borderLayout = new BorderLayout(); BorderLayout borderLayout = new BorderLayout();
setLayout(borderLayout); setLayout(borderLayout);
addMouseListener(mouseListener); addMouseListener(mouseListener);
} }
MouseListener mouseListener = new MouseAdapter() { MouseListener mouseListener = new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
toggleVisibility(); toggleVisibility();
} }
}; };
ComponentListener contentComponentListener = new ComponentAdapter() { ComponentListener contentComponentListener = new ComponentAdapter() {
@Override @Override
public void componentShown(ComponentEvent e) { public void componentShown(ComponentEvent e) {
updateBorderTitle(); updateBorderTitle();
} }
@Override
@Override public void componentHidden(ComponentEvent e) {
public void componentHidden(ComponentEvent e) { updateBorderTitle();
updateBorderTitle(); }
} };
};
public String getTitle() {
public String getTitle() { return title;
return title; }
}
public void setTitle(String title) { public void setTitle(String title) {
String oldTitle = this.title; String oldTitle = this.title;
this.title = title; this.title = title;
firePropertyChange("title", oldTitle, this.title); firePropertyChange("title", oldTitle, this.title);
updateBorderTitle(); updateBorderTitle();
} }
@Override @Override
public Component add(Component comp) { public Component add(Component comp) {
comp.addComponentListener(contentComponentListener); comp.addComponentListener(contentComponentListener);
Component r = super.add(comp); Component r = super.add(comp);
updateBorderTitle(); updateBorderTitle();
return r; return r;
} }
@Override @Override
public Component add(String name, Component comp) { public Component add(String name, Component comp) {
comp.addComponentListener(contentComponentListener); comp.addComponentListener(contentComponentListener);
Component r = super.add(name, comp); Component r = super.add(name, comp);
updateBorderTitle(); updateBorderTitle();
return r; return r;
} }
@Override @Override
public Component add(Component comp, int index) { public Component add(Component comp, int index) {
comp.addComponentListener(contentComponentListener); comp.addComponentListener(contentComponentListener);
Component r = super.add(comp, index); Component r = super.add(comp, index);
updateBorderTitle(); updateBorderTitle();
return r; return r;
} }
@Override @Override
public void add(Component comp, Object constraints) { public void add(Component comp, Object constraints) {
comp.addComponentListener(contentComponentListener); comp.addComponentListener(contentComponentListener);
super.add(comp, constraints); super.add(comp, constraints);
updateBorderTitle(); updateBorderTitle();
} }
@Override @Override
public void add(Component comp, Object constraints, int index) { public void add(Component comp, Object constraints, int index) {
comp.addComponentListener(contentComponentListener); comp.addComponentListener(contentComponentListener);
super.add(comp, constraints, index); super.add(comp, constraints, index);
updateBorderTitle(); updateBorderTitle();
} }
@Override @Override
public void remove(int index) { public void remove(int index) {
Component comp = getComponent(index); Component comp = getComponent(index);
comp.removeComponentListener(contentComponentListener); comp.removeComponentListener(contentComponentListener);
super.remove(index); super.remove(index);
} }
@Override @Override
public void remove(Component comp) { public void remove(Component comp) {
comp.removeComponentListener(contentComponentListener); comp.removeComponentListener(contentComponentListener);
super.remove(comp); super.remove(comp);
} }
@Override @Override
public void removeAll() { public void removeAll() {
for (Component c : getComponents()) { for (Component c : getComponents()) {
c.removeComponentListener(contentComponentListener); c.removeComponentListener(contentComponentListener);
} }
super.removeAll(); super.removeAll();
} }
protected void toggleVisibility() { protected void toggleVisibility() {
toggleVisibility(hasInvisibleComponent()); toggleVisibility(hasInvisibleComponent());
} }
protected void toggleVisibility(boolean visible) { protected void toggleVisibility(boolean visible) {
for (Component c : getComponents()) { for (Component c : getComponents()) {
c.setVisible(visible); c.setVisible(visible);
} }
updateBorderTitle(); updateBorderTitle();
} }
protected void updateBorderTitle() { protected void updateBorderTitle() {
String arrow = ""; String arrow = "";
if (getComponentCount() > 0) { if (getComponentCount() > 0) {
arrow = (hasInvisibleComponent() ? "[+] " : "[-] "); arrow = (hasInvisibleComponent()?"[+] ":"[-] ");
} }
border.setTitle(arrow + title); border.setTitle(arrow+title);
repaint(); repaint();
} }
protected final boolean hasInvisibleComponent() { protected final boolean hasInvisibleComponent() {
for (Component c : getComponents()) { for (Component c : getComponents()) {
if (!c.isVisible()) { if (!c.isVisible()) {
return true; return true;
} }
} }
return false; return false;
} }
public void collapse() { public void collapse() {
toggleVisibility(false); toggleVisibility(false);
} }
public void expand() { public void expand() {
toggleVisibility(true); toggleVisibility(true);
} }
public void setExpanded(boolean expand) { public void setExpanded(boolean expand) {
toggleVisibility(expand); toggleVisibility(expand);
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,177 +1,198 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import java.awt.BorderLayout;
import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.*;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor;
import com.gpl.rpg.atcontentstudio.ui.map.WorldMapEditor;
import com.gpl.rpg.atcontentstudio.ui.sprites.SpritesheetEditor;
import com.gpl.rpg.atcontentstudio.ui.tools.writermode.WriterModeEditor;
import com.jidesoft.swing.JideTabbedPane;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import javax.swing.Action;
import javax.swing.JPanel;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
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.JSONElement;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.gamedata.Quest;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.ActorConditionEditor;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.DialogueEditor;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.DroplistEditor;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.ItemCategoryEditor;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.ItemEditor;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.NPCEditor;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.QuestEditor;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor;
import com.gpl.rpg.atcontentstudio.ui.map.WorldMapEditor;
import com.gpl.rpg.atcontentstudio.ui.saves.SavedGameEditor;
import com.gpl.rpg.atcontentstudio.ui.sprites.SpritesheetEditor;
import com.gpl.rpg.atcontentstudio.ui.tools.writermode.WriterModeEditor;
import com.jidesoft.swing.JideTabbedPane;
public class EditorsArea extends JPanel { public class EditorsArea extends JPanel {
private static final long serialVersionUID = 8801849846876081538L; private static final long serialVersionUID = 8801849846876081538L;
private Map<Object, Editor> editors = new LinkedHashMap<Object, Editor>(); private Map<Object, Editor> editors = new LinkedHashMap<Object, Editor>();
private JideTabbedPane tabHolder; private JideTabbedPane tabHolder;
public EditorsArea() {
super();
setLayout(new BorderLayout());
tabHolder = new JideTabbedPane();
tabHolder.setTabPlacement(JideTabbedPane.TOP);
tabHolder.setTabShape(JideTabbedPane.SHAPE_FLAT);
tabHolder.setUseDefaultShowCloseButtonOnTab(false);
tabHolder.setShowCloseButtonOnTab(true);
tabHolder.setCloseAction(new Action() {
@Override
public void actionPerformed(ActionEvent e) {
closeEditor((Editor) e.getSource());
}
@Override
public void setEnabled(boolean b) {
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
}
@Override
public void putValue(String key, Object value) {
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public Object getValue(String key) {
return null;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
}
});
add(tabHolder, BorderLayout.CENTER);
}
public void openEditor(Editor e) {
if (!editors.containsKey(e.target) && !editors.containsValue(e)) {
editors.put(e.target, e);
tabHolder.addTab(e.name, e.icon, e);
tabHolder.setSelectedComponent(e);
}
}
public void closeEditor(Editor e) {
if (editors.containsValue(e)) {
tabHolder.remove(e);
editors.remove(e.target);
e.clearElementListeners();
}
}
public EditorsArea() { public void openEditor(JSONElement node) {
super(); if (editors.containsKey(node)) {
setLayout(new BorderLayout()); tabHolder.setSelectedComponent(editors.get(node));
tabHolder = new JideTabbedPane(); return;
tabHolder.setTabPlacement(JideTabbedPane.TOP); }
tabHolder.setTabShape(JideTabbedPane.SHAPE_FLAT); if (node instanceof Quest) {
tabHolder.setUseDefaultShowCloseButtonOnTab(false); openEditor(new QuestEditor((Quest)node));
tabHolder.setShowCloseButtonOnTab(true); } else if (node instanceof Dialogue) {
tabHolder.setCloseAction(new Action() { openEditor(new DialogueEditor((Dialogue) node));
@Override } else if (node instanceof Droplist) {
public void actionPerformed(ActionEvent e) { openEditor(new DroplistEditor((Droplist) node));
closeEditor((Editor) e.getSource()); } else if (node instanceof ActorCondition) {
} openEditor(new ActorConditionEditor((ActorCondition) node));
} else if (node instanceof ItemCategory) {
openEditor(new ItemCategoryEditor((ItemCategory) node));
} else if (node instanceof Item) {
openEditor(new ItemEditor((Item) node));
} else if (node instanceof NPC) {
openEditor(new NPCEditor((NPC) node));
}
}
public void openEditor(Spritesheet node) {
if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node));
return;
}
node.link();
openEditor(new SpritesheetEditor((Spritesheet) node));
}
@Override public void openEditor(TMXMap node) {
public void setEnabled(boolean b) { if (editors.containsKey(node)) {
} tabHolder.setSelectedComponent(editors.get(node));
return;
@Override }
public void removePropertyChangeListener(PropertyChangeListener listener) { node.link();
} openEditor(new TMXMapEditor(node));
}
@Override
public void putValue(String key, Object value) {
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public Object getValue(String key) {
return null;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
}
});
add(tabHolder, BorderLayout.CENTER);
}
public void openEditor(Editor e) {
if (!editors.containsKey(e.target) && !editors.containsValue(e)) {
editors.put(e.target, e);
tabHolder.addTab(e.name, e.icon, e);
tabHolder.setSelectedComponent(e);
}
}
public void closeEditor(Editor e) {
if (editors.containsValue(e)) {
tabHolder.remove(e);
editors.remove(e.target);
e.clearElementListeners();
}
}
public void openEditor(JSONElement node) {
if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node));
return;
}
if (node instanceof Quest) {
openEditor(new QuestEditor((Quest) node));
} else if (node instanceof Dialogue) {
openEditor(new DialogueEditor((Dialogue) node));
} else if (node instanceof Droplist) {
openEditor(new DroplistEditor((Droplist) node));
} else if (node instanceof ActorCondition) {
openEditor(new ActorConditionEditor((ActorCondition) node));
} else if (node instanceof ItemCategory) {
openEditor(new ItemCategoryEditor((ItemCategory) node));
} else if (node instanceof Item) {
openEditor(new ItemEditor((Item) node));
} else if (node instanceof NPC) {
openEditor(new NPCEditor((NPC) node));
}
}
public void openEditor(Spritesheet node) {
if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node));
return;
}
node.link();
openEditor(new SpritesheetEditor((Spritesheet) node));
}
public void openEditor(TMXMap node) {
if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node));
return;
}
node.link();
openEditor(new TMXMapEditor(node));
}
public void openEditor(WorldmapSegment node) { public void openEditor(SavedGame save) {
if (editors.containsKey(node)) { if (editors.containsKey(save)) {
tabHolder.setSelectedComponent(editors.get(node)); tabHolder.setSelectedComponent(editors.get(save));
return; return;
} }
node.link(); openEditor(new SavedGameEditor(save));
openEditor(new WorldMapEditor(node)); }
}
public void openEditor(WriterModeData node) {
if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node));
return;
}
node.link();
openEditor(new WriterModeEditor(node));
}
public void closeEditor(ProjectTreeNode node) { public void openEditor(WorldmapSegment node) {
if (editors.containsKey(node)) { if (editors.containsKey(node)) {
closeEditor(editors.get(node)); tabHolder.setSelectedComponent(editors.get(node));
} return;
} }
node.link();
openEditor(new WorldMapEditor(node));
}
public void openEditor(WriterModeData node) {
if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node));
return;
}
node.link();
openEditor(new WriterModeEditor(node));
}
public void closeEditor(ProjectTreeNode node) {
if (editors.containsKey(node)) {
closeEditor(editors.get(node));
}
}
public void editorTabChanged(Editor e) {
int index = tabHolder.indexOfComponent(e);
if (index >= 0) {
tabHolder.setTitleAt(index, e.name);
tabHolder.setIconAt(index, e.icon);
}
}
public void editorTabChanged(Editor e) { public void editorTabChanged(ProjectTreeNode node) {
int index = tabHolder.indexOfComponent(e); if (editors.get(node) != null) {
if (index >= 0) { editors.get(node).targetUpdated();
tabHolder.setTitleAt(index, e.name); editorTabChanged(editors.get(node));
tabHolder.setIconAt(index, e.icon); }
} }
}
public void showAbout() {
public void editorTabChanged(ProjectTreeNode node) { if (editors.containsKey(AboutEditor.instance)) {
if (editors.get(node) != null) { tabHolder.setSelectedComponent(AboutEditor.instance);
editors.get(node).targetUpdated(); return;
editorTabChanged(editors.get(node)); }
} openEditor(AboutEditor.instance);
} }
public void showAbout() {
if (editors.containsKey(AboutEditor.instance)) {
tabHolder.setSelectedComponent(AboutEditor.instance);
return;
}
openEditor(AboutEditor.instance);
}
} }

View File

@@ -1,5 +1,21 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
@@ -7,211 +23,204 @@ import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet; import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
public class ExportProjectWizard extends JDialog { public class ExportProjectWizard extends JDialog {
private static final long serialVersionUID = -8745083621008868612L; private static final long serialVersionUID = -8745083621008868612L;
JPanel pane;
JLabel errorLabel, fileSelectionLabel;
JRadioButton asZip, overSources;
JComboBox<String> target;
JButton browse;
JButton okButton, cancelButton;
Project proj;
public ExportProjectWizard(Project proj) {
super(ATContentStudio.frame);
setTitle("Export project for inclusion in-game");
this.proj = proj;
pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
errorLabel = new JLabel();
JPanel pane; pane.add(errorLabel, JideBoxLayout.FIX);
JLabel errorLabel, fileSelectionLabel; pane.add(new JLabel("Export this ATCS project..."), JideBoxLayout.FIX);
JRadioButton asZip, overSources;
JComboBox<String> target; ButtonGroup radioGroup = new ButtonGroup();
JButton browse;
JButton okButton, cancelButton; asZip = new JRadioButton("... as a Zip archive");
radioGroup.add(asZip);
overSources = new JRadioButton("... into a game source folder");
radioGroup.add(overSources);
overSources.setSelected(true);
Project proj; pane.add(asZip, JideBoxLayout.FIX);
pane.add(overSources, JideBoxLayout.FIX);
ActionListener updateListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateState();
}
};
asZip.addActionListener(updateListener);
overSources.addActionListener(updateListener);
target = new JComboBox<String>();
target.setEditable(true);
target.addActionListener(updateListener);
browse = new JButton("Browse");
browse.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = new JFileChooser(){
private static final long serialVersionUID = -3001082967957619011L;
@Override
public boolean accept(File f) {
if (asZip.isSelected()) {
if (f.isDirectory() || f.getName().endsWith(".zip") || f.getName().endsWith(".ZIP")) {
return super.accept(f);
} else {
return false;
}
} else {
return f.isDirectory();
}
}
};
jfc.setFileSelectionMode(asZip.isSelected() ? JFileChooser.FILES_AND_DIRECTORIES : JFileChooser.DIRECTORIES_ONLY);
jfc.setSelectedFile(new File(target.getSelectedItem() == null ? "" : target.getSelectedItem().toString()));
jfc.setMultiSelectionEnabled(false);
int result = jfc.showOpenDialog(ATContentStudio.frame);
if (result == JFileChooser.APPROVE_OPTION) {
File f = jfc.getSelectedFile();
if (asZip.isSelected() && !f.getAbsolutePath().substring(f.getAbsolutePath().length() - 4, f.getAbsolutePath().length()).equalsIgnoreCase(".zip")) {
f = new File(f.getAbsolutePath()+".zip");
}
target.setSelectedItem(f.getAbsolutePath());
updateState();
}
}
});
JPanel fileSelectionPane = new JPanel();
fileSelectionPane.setLayout(new JideBoxLayout(fileSelectionPane, JideBoxLayout.LINE_AXIS, 6));
fileSelectionLabel = new JLabel("Zip file: ");
fileSelectionPane.add(fileSelectionLabel, JideBoxLayout.FIX);
fileSelectionPane.add(target, JideBoxLayout.VARY);
fileSelectionPane.add(browse, JideBoxLayout.FIX);
pane.add(fileSelectionPane, JideBoxLayout.FIX);
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
cancelButton = new JButton("Cancel");
buttonPane.add(cancelButton, JideBoxLayout.FIX);
okButton = new JButton("Ok");
buttonPane.add(okButton, JideBoxLayout.FIX);
pane.add(new JPanel(), JideBoxLayout.VARY);
pane.add(buttonPane, JideBoxLayout.FIX);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ExportProjectWizard.this.setVisible(false);
ExportProjectWizard.this.dispose();
}
});
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (asZip.isSelected()) {
ExportProjectWizard.this.proj.exportProjectAsZipPackage(new File(target.getSelectedItem().toString()));
} else {
ExportProjectWizard.this.proj.exportProjectOverGameSource(new File(target.getSelectedItem().toString()));
}
ExportProjectWizard.this.setVisible(false);
ExportProjectWizard.this.dispose();
}
});
updateState();
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
setMinimumSize(new Dimension(500,150));
pack();
public ExportProjectWizard(Project proj) { Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
Dimension wdim = getSize();
super(ATContentStudio.frame); setLocation((sdim.width - wdim.width)/2, (sdim.height - wdim.height)/2);
setTitle("Export project for inclusion in-game"); }
this.proj = proj; private void updateState() {
if (asZip.isSelected()) {
pane = new JPanel(); fileSelectionLabel.setText("Zip file: ");
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6)); } else {
fileSelectionLabel.setText("Game source folder: ");
errorLabel = new JLabel(); }
pane.add(errorLabel, JideBoxLayout.FIX);
pane.add(new JLabel("Export this ATCS project..."), JideBoxLayout.FIX); File f = new File(target.getSelectedItem() == null ? "" : target.getSelectedItem().toString());
if (asZip.isSelected()) {
ButtonGroup radioGroup = new ButtonGroup(); if (target.getSelectedItem() == null || target.getSelectedItem().toString().length() <= 0) {
errorLabel.setText("<html><font color=\"#FF0000\">You must select where to save the zip file.</font></html>");
asZip = new JRadioButton("... as a Zip archive"); okButton.setEnabled(false);
radioGroup.add(asZip); } else if (f.isDirectory()) {
overSources = new JRadioButton("... into a game source folder"); errorLabel.setText("<html><font color=\"#FF0000\">The selected target is a directory. It should be a zip file.</font></html>");
radioGroup.add(overSources); okButton.setEnabled(false);
overSources.setSelected(true); } else if (!(f.getName().toLowerCase().endsWith(".zip"))) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected target is not a zip file. It should be a zip file.</font></html>");
pane.add(asZip, JideBoxLayout.FIX); okButton.setEnabled(false);
pane.add(overSources, JideBoxLayout.FIX); } else if (f.exists()) {
errorLabel.setText("<html><font color=\"#FF9000\">The selected target is an existing zip file. It will be overwritten.</font></html>");
ActionListener updateListener = new ActionListener() { okButton.setEnabled(true);
@Override } else {
public void actionPerformed(ActionEvent e) { errorLabel.setText("<html><font color=\"#00AA00\">Everything looks good !</font></html>");
updateState(); okButton.setEnabled(true);
} }
}; } else {
asZip.addActionListener(updateListener); if (target.getSelectedItem() == null || target.getSelectedItem().toString().length() <= 0) {
overSources.addActionListener(updateListener); errorLabel.setText("<html><font color=\"#FF0000\">You must select an AT source root folder.</font></html>");
okButton.setEnabled(false);
target = new JComboBox<String>(); } else if (!f.isDirectory() || !f.exists()) {
target.setEditable(true); errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source is not a folder. It should be an existing AT source root folder.</font></html>");
target.addActionListener(updateListener); okButton.setEnabled(false);
browse = new JButton("Browse"); } else {
browse.addActionListener(new ActionListener() { File res = new File(f, GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
@Override File drawable = new File(f, SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE);
public void actionPerformed(ActionEvent e) { File xml = new File(f, TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE);
JFileChooser jfc = new JFileChooser() { if (!res.exists()) {
private static final long serialVersionUID = -3001082967957619011L; errorLabel.setText("<html><font color=\"#FF9000\">The selected AT source root folder does not contain the \"res\" folder.</font></html>");
okButton.setEnabled(true);
@Override } else if (!drawable.exists()) {
public boolean accept(File f) { errorLabel.setText("<html><font color=\"#FF9000\">The selected AT source root folder does not contain the \"drawable\" folder.</font></html>");
if (asZip.isSelected()) { okButton.setEnabled(true);
if (f.isDirectory() || f.getName().endsWith(".zip") || f.getName().endsWith(".ZIP")) { } else if (!xml.exists()) {
return super.accept(f); errorLabel.setText("<html><font color=\"#FF9000\">The selected AT source root folder does not contain the \"xml\" folder.</font></html>");
} else { okButton.setEnabled(true);
return false; } else {
} errorLabel.setText("<html><font color=\"#00AA00\">Everything looks good !</font></html>");
} else { okButton.setEnabled(true);
return f.isDirectory(); }
} }
} }
}; revalidate();
jfc.setFileSelectionMode(asZip.isSelected() ? JFileChooser.FILES_AND_DIRECTORIES : JFileChooser.DIRECTORIES_ONLY); repaint();
jfc.setSelectedFile(new File(target.getSelectedItem() == null ? "" : target.getSelectedItem().toString()));
jfc.setMultiSelectionEnabled(false);
int result = jfc.showOpenDialog(ATContentStudio.frame);
if (result == JFileChooser.APPROVE_OPTION) {
File f = jfc.getSelectedFile();
if (asZip.isSelected() && !f.getAbsolutePath().substring(f.getAbsolutePath().length() - 4, f.getAbsolutePath().length()).equalsIgnoreCase(".zip")) {
f = new File(f.getAbsolutePath() + ".zip");
}
target.setSelectedItem(f.getAbsolutePath());
updateState();
}
}
});
JPanel fileSelectionPane = new JPanel();
fileSelectionPane.setLayout(new JideBoxLayout(fileSelectionPane, JideBoxLayout.LINE_AXIS, 6));
fileSelectionLabel = new JLabel("Zip file: ");
fileSelectionPane.add(fileSelectionLabel, JideBoxLayout.FIX);
fileSelectionPane.add(target, JideBoxLayout.VARY);
fileSelectionPane.add(browse, JideBoxLayout.FIX);
pane.add(fileSelectionPane, JideBoxLayout.FIX);
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
cancelButton = new JButton("Cancel");
buttonPane.add(cancelButton, JideBoxLayout.FIX);
okButton = new JButton("Ok");
buttonPane.add(okButton, JideBoxLayout.FIX);
pane.add(new JPanel(), JideBoxLayout.VARY);
pane.add(buttonPane, JideBoxLayout.FIX);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ExportProjectWizard.this.setVisible(false);
ExportProjectWizard.this.dispose();
}
});
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (asZip.isSelected()) {
ExportProjectWizard.this.proj.exportProjectAsZipPackage(new File(target.getSelectedItem().toString()));
} else {
ExportProjectWizard.this.proj.exportProjectOverGameSource(new File(target.getSelectedItem().toString()));
}
ExportProjectWizard.this.setVisible(false);
ExportProjectWizard.this.dispose();
}
});
updateState();
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
setMinimumSize(new Dimension(500, 150));
pack();
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
Dimension wdim = getSize();
setLocation((sdim.width - wdim.width) / 2, (sdim.height - wdim.height) / 2);
}
private void updateState() {
if (asZip.isSelected()) {
fileSelectionLabel.setText("Zip file: ");
} else {
fileSelectionLabel.setText("Game source folder: ");
}
File f = new File(target.getSelectedItem() == null ? "" : target.getSelectedItem().toString());
if (asZip.isSelected()) {
if (target.getSelectedItem() == null || target.getSelectedItem().toString().length() <= 0) {
errorLabel.setText("<html><font color=\"#FF0000\">You must select where to save the zip file.</font></html>");
okButton.setEnabled(false);
} else if (f.isDirectory()) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected target is a directory. It should be a zip file.</font></html>");
okButton.setEnabled(false);
} else if (!(f.getName().toLowerCase().endsWith(".zip"))) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected target is not a zip file. It should be a zip file.</font></html>");
okButton.setEnabled(false);
} else if (f.exists()) {
errorLabel.setText("<html><font color=\"#FF9000\">The selected target is an existing zip file. It will be overwritten.</font></html>");
okButton.setEnabled(true);
} else {
errorLabel.setText("<html><font color=\"#00AA00\">Everything looks good !</font></html>");
okButton.setEnabled(true);
}
} else {
if (target.getSelectedItem() == null || target.getSelectedItem().toString().length() <= 0) {
errorLabel.setText("<html><font color=\"#FF0000\">You must select an AT source root folder.</font></html>");
okButton.setEnabled(false);
} else if (!f.isDirectory() || !f.exists()) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source is not a folder. It should be an existing AT source root folder.</font></html>");
okButton.setEnabled(false);
} else {
File res = new File(f, GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
File drawable = new File(f, SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE);
File xml = new File(f, TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!res.exists()) {
errorLabel.setText("<html><font color=\"#FF9000\">The selected AT source root folder does not contain the \"res\" folder.</font></html>");
okButton.setEnabled(true);
} else if (!drawable.exists()) {
errorLabel.setText("<html><font color=\"#FF9000\">The selected AT source root folder does not contain the \"drawable\" folder.</font></html>");
okButton.setEnabled(true);
} else if (!xml.exists()) {
errorLabel.setText("<html><font color=\"#FF9000\">The selected AT source root folder does not contain the \"xml\" folder.</font></html>");
okButton.setEnabled(true);
} else {
errorLabel.setText("<html><font color=\"#00AA00\">Everything looks good !</font></html>");
okButton.setEnabled(true);
}
}
}
revalidate();
repaint();
}
}
} }

View File

@@ -1,9 +1,9 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.*; import javax.swing.JComponent;
public interface FieldUpdateListener { public interface FieldUpdateListener {
public void valueChanged(JComponent source, Object value); public void valueChanged(JComponent source, Object value);
} }

View File

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

View File

@@ -1,19 +1,19 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.*; import javax.swing.JCheckBox;
public class IntegerBasedCheckBox extends JCheckBox { public class IntegerBasedCheckBox extends JCheckBox {
private static final long serialVersionUID = 3941646360487399554L; private static final long serialVersionUID = 3941646360487399554L;
static final Integer one = 1; static final Integer one = 1;
public Integer getIntegerValue() { public Integer getIntegerValue() {
return isSelected() ? one : null; return isSelected() ? one : null;
} }
public void setIntegerValue(Integer val) { public void setIntegerValue(Integer val) {
setSelected(val != null && val.equals(one)); setSelected(val != null && val.equals(one));
} }
} }

View File

@@ -1,93 +1,96 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.*; import java.awt.Color;
import java.awt.*; import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import javax.swing.JComponent;
public class JMovingIdler extends JComponent { public class JMovingIdler extends JComponent {
private static final long serialVersionUID = -2980521421870322717L; private static final long serialVersionUID = -2980521421870322717L;
int position = 0; int position = 0;
boolean destroyed = false, running = false; boolean destroyed=false, running=false;
Thread moverThread = new Thread() { Thread moverThread = new Thread(){
public void run() { public void run() {
while (!destroyed) { while (!destroyed) {
boolean back = false; boolean back = false;
while (running) { while (running) {
if (back) { if (back) {
position = --position % 100; position = --position % 100;
if (position == 0) { if (position == 0) {
back = false; back = false;
} }
} else { } else {
position = ++position % 100; position = ++position % 100;
if (position == 99) { if (position == 99) {
back = true; back = true;
} }
} }
try { try {
sleep(10); sleep(10);
} catch (InterruptedException e) { } catch (InterruptedException e) {}
} JMovingIdler.this.revalidate();
JMovingIdler.this.revalidate(); JMovingIdler.this.repaint();
JMovingIdler.this.repaint(); }
} }
} }
} };
};
public void start() {
public void start() { if (!moverThread.isAlive()) {
if (!moverThread.isAlive()) { moverThread.start();
moverThread.start(); }
} running = true;
running = true; }
}
public void stop() {
public void stop() { running = false;
running = false; }
}
public void destroy() {
public void destroy() { destroyed = true;
destroyed = true; running = false;
running = false; try {
try { moverThread.join();
moverThread.join(); } catch (InterruptedException e) {}
} catch (InterruptedException e) { }
}
} protected void paintComponent(Graphics g) {
super.paintComponent(g);
protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g); int w = this.getWidth();
Graphics2D g2 = (Graphics2D) g; int h = this.getHeight();
int w = this.getWidth();
int h = this.getHeight(); g2.setColor(getBackground());
g2.fillRect(0,0,w,h);
g2.setColor(getBackground());
g2.fillRect(0, 0, w, h); int x = w * position / 100;
int x = w * position / 100; Paint p = new GradientPaint(x - (w/8), 0, getBackground(), x , 0, getForeground());
g2.setPaint(p);
Paint p = new GradientPaint(x - (w / 8), 0, getBackground(), x, 0, getForeground()); g2.fillRect(Math.max(0,x-(w/8)),0, Math.min(x, w), h);
g2.setPaint(p);
g2.fillRect(Math.max(0, x - (w / 8)), 0, Math.min(x, w), h);
p = new GradientPaint(x, 0, getForeground(), x + (w / 8), 0, getBackground());
g2.setPaint(p);
g2.fillRect(Math.max(0, x), 0, Math.min(x + (w / 8), w), h);
g2.setColor(Color.BLACK);
g2.drawLine(0, 0, 0, h);
g2.drawLine(0, 0, w, 0);
g2.drawLine(w, 0, w, h);
g2.drawLine(0, h, w, h);
}
@Override
public void setVisible(boolean aFlag) {
super.setVisible(aFlag);
if (!aFlag) destroy();
}
p = new GradientPaint(x, 0, getForeground(), x + (w/8), 0, getBackground());
g2.setPaint(p);
g2.fillRect(Math.max(0,x),0, Math.min(x+(w/8), w), h);
g2.setColor(Color.BLACK);
g2.drawLine(0,0,0,h);
g2.drawLine(0,0,w,0);
g2.drawLine(w,0,w,h);
g2.drawLine(0,h,w,h);
}
@Override
public void setVisible(boolean aFlag) {
super.setVisible(aFlag);
if (!aFlag) destroy();
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +0,0 @@
package com.gpl.rpg.atcontentstudio.ui;
import java.util.Collection;
public interface ListenerCollectionModel<E> extends ListenerListModel<E> {
public Collection<E> getElements();
@Override
default int getSize() {
Collection<E> elements = getElements();
if (elements == null) return 0;
return elements.size();
}
@Override
default E getElementAt(int index) {
for (E obj : getElements()) {
if (index == 0) return obj;
index--;
}
return null;
}
}

View File

@@ -1,67 +0,0 @@
package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.util.List;
public interface ListenerListModel<E> extends ListModel<E> {
List<ListDataListener> getListeners();
default void notifyListeners(ChangeType event, int index0, int index1) {
notifyListeners(this, event, index0, index1);
}
default void notifyListeners(Object source, ChangeType event, int index0, int index1) {
int eventCode;
switch (event) {
case CHANGED:
eventCode = ListDataEvent.CONTENTS_CHANGED;
break;
case ADDED:
eventCode = ListDataEvent.INTERVAL_ADDED;
break;
case REMOVED:
eventCode = ListDataEvent.INTERVAL_REMOVED;
break;
default:
throw new IllegalArgumentException();
}
for (ListDataListener l : getListeners()) {
ListDataEvent e = new ListDataEvent(source, eventCode, index0, index1);
switch (event) {
case CHANGED: {
l.contentsChanged(e);
break;
}
case ADDED: {
l.intervalAdded(e);
break;
}
case REMOVED: {
l.intervalRemoved(e);
break;
}
}
}
}
default void addListDataListener(ListDataListener l) {
getListeners().add(l);
}
default void removeListDataListener(ListDataListener l) {
getListeners().remove(l);
}
default void fireListChanged() {
notifyListeners(this, ChangeType.CHANGED, 0, getSize() - 1);
}
enum ChangeType {
CHANGED,
ADDED,
REMOVED,
}
}

View File

@@ -1,87 +1,105 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import java.awt.Color;
import com.gpl.rpg.atcontentstudio.Notification; import java.awt.Component;
import com.gpl.rpg.atcontentstudio.NotificationListener; import java.awt.Font;
import javax.swing.*;
import javax.swing.event.ListDataListener;
import java.awt.*;
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 java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.NotificationListener;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class NotificationsPane extends JList { public class NotificationsPane extends JList {
private static final long serialVersionUID = -1100364214372392608L; private static final long serialVersionUID = -1100364214372392608L;
public static final Map<Notification.Type, Icon> icons = new LinkedHashMap<Notification.Type, Icon>(Notification.Type.values().length); public static final Map<Notification.Type, Icon> icons = new LinkedHashMap<Notification.Type, Icon>(Notification.Type.values().length);
static { static {
icons.put(Notification.Type.SUCCESS, new ImageIcon(DefaultIcons.getStatusGreenIcon())); icons.put(Notification.Type.SUCCESS, new ImageIcon(DefaultIcons.getStatusGreenIcon()));
icons.put(Notification.Type.INFO, new ImageIcon(DefaultIcons.getStatusBlueIcon())); icons.put(Notification.Type.INFO, new ImageIcon(DefaultIcons.getStatusBlueIcon()));
icons.put(Notification.Type.WARN, new ImageIcon(DefaultIcons.getStatusOrangeIcon())); icons.put(Notification.Type.WARN, new ImageIcon(DefaultIcons.getStatusOrangeIcon()));
icons.put(Notification.Type.ERROR, new ImageIcon(DefaultIcons.getStatusRedIcon())); icons.put(Notification.Type.ERROR, new ImageIcon(DefaultIcons.getStatusRedIcon()));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public NotificationsPane() { public NotificationsPane() {
super(); super();
MyListModel model = new MyListModel(); MyListModel model = new MyListModel();
setModel(model); setModel(model);
setCellRenderer(new ListCellRenderer() { setCellRenderer(new ListCellRenderer(){
@Override @Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = new JLabel(); JLabel label = new JLabel();
Font f = label.getFont(); Font f = label.getFont();
label.setIcon(NotificationsPane.icons.get(((Notification) value).type)); label.setIcon(NotificationsPane.icons.get(((Notification)value).type));
label.setText(((Notification) value).text); label.setText(((Notification)value).text);
if (isSelected) { if (isSelected) {
// label.setBackground(Color.RED); // label.setBackground(Color.RED);
label.setBorder(BorderFactory.createLineBorder(Color.BLUE)); label.setBorder(BorderFactory.createLineBorder(Color.BLUE));
// label.setForeground(Color.WHITE); // label.setForeground(Color.WHITE);
} }
f = f.deriveFont(10f * ATContentStudio.SCALING); f = f.deriveFont(10f*ATContentStudio.SCALING);
label.setFont(f); label.setFont(f);
return label; return label;
} }
}); });
Notification.addNotificationListener(model); Notification.addNotificationListener(model);
} }
private class MyListModel implements ListenerListModel<Notification>, NotificationListener { private class MyListModel implements ListModel, NotificationListener {
@Override @Override
public Notification getElementAt(int index) { public Object getElementAt(int index) {
return Notification.notifs.get(index); return Notification.notifs.get(index);
} }
@Override @Override
public List<ListDataListener> getListeners() { public int getSize() {
return listeners; return Notification.notifs.size();
} }
@Override @Override
public int getSize() { public void onNewNotification(Notification n) {
return Notification.notifs.size(); for (ListDataListener l : listeners) {
} l.intervalAdded(new ListDataEvent(NotificationsPane.this, ListDataEvent.INTERVAL_ADDED, Notification.notifs.size() - 1 , Notification.notifs.size() - 1));
}
@Override NotificationsPane.this.ensureIndexIsVisible(Notification.notifs.indexOf(n));
public void onNewNotification(Notification n) { }
notifyListeners(NotificationsPane.this, ChangeType.ADDED, Notification.notifs.size() - 1, Notification.notifs.size() - 1);
NotificationsPane.this.ensureIndexIsVisible(Notification.notifs.indexOf(n)); @Override
} public void onListCleared(int i) {
for (ListDataListener l : listeners) {
@Override l.intervalRemoved(new ListDataEvent(NotificationsPane.this, ListDataEvent.INTERVAL_REMOVED, 0 , i));
public void onListCleared(int i) { }
notifyListeners(NotificationsPane.this, ChangeType.REMOVED, 0, i); }
}
private List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
private List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>(); @Override
} public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
} }

View File

@@ -1,93 +0,0 @@
package com.gpl.rpg.atcontentstudio.ui;
import javax.swing.event.ListDataListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public abstract class OrderedListenerListModel<S, E> implements ListenerCollectionModel<E> {
protected S source;
protected abstract List<E> getItems();
protected abstract void setItems(List<E> items);
public OrderedListenerListModel(S source) {
this.source = source;
}
@Override
public Collection<E> getElements() {
return getItems();
}
@Override
public E getElementAt(int index) {
if (index < 0 || index >= getSize()) return null;
return getItems().get(index);
}
public E setElementAt(int index, E value) {
if (index < 0 || index >= getSize()) return null;
return getItems().set(index, value);
}
public void addObject(E item) {
addItem(item);
}
public void addItem(E item) {
if (getItems() == null) {
setItems(new ArrayList<E>());
}
getItems().add(item);
int index = getItems().indexOf(item);
notifyListeners(ChangeType.ADDED, index, index);
}
public void removeObject(E item) {
removeItem(item);
}
public void removeItem(E item) {
int index = getItems().indexOf(item);
getItems().remove(item);
if (getSize() == 0) {
setItems(null);
}
notifyListeners(this, ChangeType.REMOVED, index, index);
}
public void moveUp(E item) {
moveUpOrDown(item, -1);
}
public void moveDown(E item) {
moveUpOrDown(item, 1);
}
private void moveUpOrDown(E item, int direction) {
int index = getItems().indexOf(item);
E exchanged = getElementAt(index + direction);
setElementAt(index, exchanged);
setElementAt(index + direction, item);
notifyListeners(this, ChangeType.CHANGED, index + direction, index);
}
public void objectChanged(E item) {
itemChanged(item);
}
public void itemChanged(E item) {
int index = getItems().indexOf(item);
notifyListeners(this, ChangeType.CHANGED, index, index);
}
private final List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
public List<ListDataListener> getListeners() {
return listeners;
}
}

Some files were not shown because too many files have changed in this diff Show More