Compare commits

...

69 Commits

Author SHA1 Message Date
OMGeeky
86b838f755 fix ordering of changed elements with optimized structure 2025-12-21 15:56:11 +01:00
Nut.andor
f66d016d08 fix spritesheet 2025-11-09 21:13:55 +01:00
Nut.andor
9ba45fe848 toList replaced by collect 2025-11-09 18:03:30 +01:00
Nut.andor
f14255ce1c new spritesheets 2025-11-09 16:36:40 +01:00
Nut.andor
c37b56988d sort problem 2025-10-26 02:49:44 +02:00
Nut.andor
9654da02c2 New requirement "skillIncrease" to check if a skill increase for n levels is possible 2025-10-26 02:49:44 +02:00
Nut.andor
d5c1ccebce Merge remote-tracking branch 'origin/master' 2025-10-04 02:13:01 +02:00
Nut.andor
0bf6b3f4d1 spriteFlipChance renamed to horizontalFlipChance to fit the engine 2025-10-04 01:22:11 +02:00
Nut
69c031d28e Merge pull request #16 from OMGeeky/fix-release-workflow
Fix release workflow
2025-10-03 16:30:13 +02:00
Nut.andor
6ec4cbf83d Merge branch 'pulls/1195352/15'
Miss effect added, add comments to start script
2025-10-03 15:56:10 +02:00
Nut.andor
5b2480920e Version 24 2025-10-03 15:53:37 +02:00
Nut.andor
e6f89b8802 Miss effect 2025-10-03 15:18:15 +02:00
Nut.andor
f2008de3e2 Merge branch 'pulls/1195352/13' 2025-10-03 15:15:35 +02:00
Nut.andor
0df961c8d3 forgotten parameter 2025-10-03 15:12:00 +02:00
Nut.andor
15b98eedcf Added field for Sprite Flip Chance 2025-10-03 14:59:04 +02:00
OMGeeky
8399ae60ee upload zip as soon as its ready and upload exe later 2025-10-02 17:40:00 +02:00
OMGeeky
1b643f4aa1 fix nsis arguments (from switching to linux) 2025-10-02 17:10:23 +02:00
OMGeeky
4293095e8e fix warning/error output in action 2025-10-02 17:09:08 +02:00
OMGeeky
5f2927e00c switch to linux runner (windows-latest is annoying me with undocumented breaking changes...) 2025-10-02 16:59:48 +02:00
OMGeeky
79eddde155 handle errors during nsis exe creation and only upload zip in those cases 2025-10-02 16:46:08 +02:00
Nut.andor
c94c5fb41b Pull Request #15: Miss effect 2025-10-02 16:39:45 +02:00
OMGeeky
be040a74bd change miss_effect to HitEffect instead of HitReceivedEffect
(the received effects might have been applied, but the game UI would not display them, so better not show them here too)
2025-10-02 15:57:21 +02:00
OMGeeky
31cbdcabab add clarification comment to package.sh 2025-09-23 20:43:08 +02:00
OMGeeky
7e5c8d05ab improve hints on who is getting what effect on hit / hit-received for npcs 2025-09-23 20:26:58 +02:00
OMGeeky
b2003bfc38 improve create pane content calls with overrides
also fixes a bug where the wrong one was used on accident
2025-09-23 20:10:30 +02:00
OMGeeky
3b99a94654 add comments to start script about min required java version; update nsi script to match standalone start script 2025-09-23 19:29:28 +02:00
OMGeeky
806f0b10e6 miss effect 2025-09-23 18:48:46 +02:00
OMGeeky
29241f18b8 improve EffectPane generics and usage & fix hitReceivedEffect 2025-09-23 18:48:46 +02:00
Nut.andor
7df75482eb Pull Request #13: Added field for Sprite Flip Chance 2025-09-08 14:40:23 +02:00
Raphi
f93d865da7 Add spriteFlipChance as attribute in NPC.java 2025-09-04 21:41:27 +02:00
Raphi
bad86eec93 Add Sprite Flip Chance Field to NPCEditor.java 2025-09-04 21:29:04 +02:00
Nut.andor
ef9a2a628d Pull Request #12: startup performance improvements 2025-09-03 20:51:55 +02:00
Nut.andor
9dfd217a27 Merge branch 'pulls/1195352/12'
Pull Request #12: startup performance improvements
2025-09-03 20:49:57 +02:00
Nut.andor
6f10e5b94a startup performance improvements 2025-09-02 20:55:35 +02:00
Nut.andor
7cbce8e4d7 Pull Request #12: startup performance improvements 2025-08-31 23:40:31 +02:00
OMGeeky
364bf8ee11 cleanup some duplicate code 2025-08-31 23:34:46 +02:00
OMGeeky
e2b0b0e81e remove not double linking 2025-08-31 23:33:52 +02:00
OMGeeky
703b723322 improve GameDataCategory lookup time
by changing it to something backed by a HashMap with
 the id as key things can be found without looping over every element.
 This reduced the startup time on my machine to about half of the original time
2025-08-31 23:33:52 +02:00
Nut.andor
297bff84db Merge branch 'pulls/1195352/11' 2025-08-31 12:58:17 +02:00
Nut.andor
67724f5124 Revert "decrease version to avoid swing issue"
This reverts commit 3ceee2e9e6.
2025-08-31 12:53:33 +02:00
Nut.andor
09d23c8cdf Jide oss update 2025-08-30 15:48:32 +02:00
Nut.andor
749e64e09e version 2025-08-14 21:53:30 +02:00
Nut.andor
998560a6ff Pull Request #11: Jide oss update 2025-08-06 23:20:38 +02:00
OMGeeky
2bf64c417f Merge branch 'master' into jide-oss-update 2025-08-06 23:20:37 +02:00
Nut.andor
120ed02a69 Merge branch 'pulls/1195352/10' workspace + project as json 2025-08-04 21:05:23 +02:00
Nut.andor
f308580deb Json project files 2025-08-04 20:47:39 +02:00
Nut.andor
fd41013ade Merge branch 'pulls/1195352/9' 2025-08-04 20:47:18 +02:00
Nut.andor
114e09597e Pull Request #10: Json project files 2025-08-04 13:39:00 +02:00
Nut.andor
3ceee2e9e6 decrease version to avoid swing issue 2025-07-17 20:49:36 +02:00
OMGeeky
83cc57515d Add .workspace.json and .project.json to .gitignore in createProject.bat 2025-07-17 20:36:56 +02:00
OMGeeky
06d4131582 Add toJsonString method for JsonSerializable objects 2025-07-17 20:33:56 +02:00
OMGeeky
60205d54de Remove AndorsTrainer references and related functionality 2025-07-17 20:33:56 +02:00
OMGeeky
f6fbb0f5a3 Remove unused SavedGame references and related functionality
it didn't really work for a long time anyway and was extremely outdated
2025-07-17 20:33:56 +02:00
OMGeeky
af48341439 fix json project & workspace file paths when migrating from binary 2025-07-17 20:33:56 +02:00
OMGeeky
7b7218ad4e Add error handling for update check timeouts and HTTP status exceptions 2025-07-17 19:45:29 +02:00
OMGeeky
1ddf1c5051 Add notification for error when opening SpritesheetEditor 2025-07-17 18:20:16 +02:00
OMGeeky
f9a9ab97de Sort spritesheets by ID in the Project-Tree 2025-07-17 18:19:31 +02:00
Nut.andor
b37d32b5c2 Deduplicating a lot of stuff 2025-07-16 21:22:01 +02:00
OMGeeky
3c5ed1d6f6 Merge branch 'dedup-1' into json-project-files 2025-07-15 12:54:32 +02:00
OMGeeky
bc3333bd0e improve some checks when switching look and feel 2025-07-15 12:51:49 +02:00
OMGeeky
e6d9d8fbda update jar to version 3.7.15
this should improve compatibility with newer jdk versions
2025-07-15 12:51:24 +02:00
Nut.andor
32ff1b57fa Pull Request #9: Deduplicating a lot of stuff 2025-07-13 02:28:01 +02:00
OMGeeky
4b2aa77cb6 refactor to keep compatibility with old java version (openjdk-11 tested) 2025-07-03 20:16:36 +02:00
OMGeeky
782d436681 Revert "remove saves (temporarily?) since they don't really work"
This reverts commit 7929ffe2a7.
2025-06-25 01:27:34 +02:00
OMGeeky
397d1ded8c make project file to json
same as with .workspace the .project file now saves as .project.json and falls back to .project
2025-06-25 01:24:41 +02:00
OMGeeky
aef6429dbc code style 2025-06-24 23:27:54 +02:00
OMGeeky
c43b8464a2 save .workspace as json
(under .workspace.json)

falls back on old .workspace implementation
2025-06-24 23:27:38 +02:00
OMGeeky
7929ffe2a7 remove saves (temporarily?) since they don't really work 2025-06-24 21:51:41 +02:00
OMGeeky
a3ffecfd23 improve json saving to file 2025-06-24 21:50:52 +02:00
46 changed files with 2290 additions and 2786 deletions

View File

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

View File

@@ -10,7 +10,6 @@
<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

@@ -10,5 +10,10 @@
<option name="BINARY_OPERATION_WRAP" value="5" /> <option name="BINARY_OPERATION_WRAP" value="5" />
<option name="SOFT_MARGINS" value="120" /> <option name="SOFT_MARGINS" value="120" />
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View File

@@ -61,6 +61,8 @@ 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

Binary file not shown.

Binary file not shown.

View File

@@ -67,22 +67,22 @@ Section install
FileWrite $9 '$\r$\n' FileWrite $9 '$\r$\n'
FileWrite $9 'set "ATCS_DIR=%~dp0"$\r$\n' FileWrite $9 'set "ATCS_DIR=%~dp0"$\r$\n'
FileWrite $9 'set "MAX_MEM=1024M"$\r$\n' FileWrite $9 'set "MAX_MEM=1024M"$\r$\n'
FileWrite $9 'set "CP=%ATCS_DIR%lib\*"$\r$\n' FileWrite $9 'REM required minimum java version is 11$\r$\n'
FileWrite $9 'set "JAVA=$R0"$\r$\n' FileWrite $9 'set "JAVA=$R0"$\r$\n'
FileWrite $9 'set "JAVA_OPTS="$\r$\n' FileWrite $9 'set "JAVA_OPTS=-DFONT_SCALE=1.0 -Dswing.aatext=true"$\r$\n'
FileWrite $9 'set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"$\r$\n' FileWrite $9 'set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"$\r$\n'
FileWrite $9 'set "MAIN_CLASS=com.gpl.rpg.atcontentstudio.ATContentStudio"$\r$\n'
FileWrite $9 '$\r$\n' FileWrite $9 '$\r$\n'
FileWrite $9 'if exist "%ENV_FILE%" ($\r$\n' FileWrite $9 'if exist "%ENV_FILE%" ($\r$\n'
FileWrite $9 ' call "%ENV_FILE%"$\r$\n' FileWrite $9 ' call "%ENV_FILE%"$\r$\n'
FileWrite $9 ') else ($\r$\n' FileWrite $9 ') else ($\r$\n'
FileWrite $9 ' echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"$\r$\n' FileWrite $9 ' echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM required minimum java version is 11$\r$\n'
FileWrite $9 ' echo REM set "JAVA=%JAVA%">>"%ENV_FILE%"$\r$\n' FileWrite $9 ' echo REM set "JAVA=%JAVA%">>"%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%"$\r$\n' FileWrite $9 ' echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%"$\r$\n'
FileWrite $9 ' echo.>>"%ENV_FILE%"$\r$\n' FileWrite $9 ' echo.>>"%ENV_FILE%"$\r$\n'
FileWrite $9 ')$\r$\n' FileWrite $9 ')$\r$\n'
FileWrite $9 '$\r$\n' FileWrite $9 '$\r$\n'
FileWrite $9 'start "" "%JAVA%" %JAVA_OPTS% -Xmx%MAX_MEM% -jar ATCS.jar$\r$\n' FileWrite $9 'start "" "%JAVA%" %JAVA_OPTS% -Xmx%MAX_MEM% -jar "%ATCS_DIR%\ATCS.jar"$\r$\n'
FileClose $9 FileClose $9
WriteUninstaller "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe"

View File

@@ -2,6 +2,7 @@
set "ATCS_DIR=%~dp0" set "ATCS_DIR=%~dp0"
set "MAX_MEM=1024M" set "MAX_MEM=1024M"
REM required minimum java version is 11
set "JAVA=java.exe" set "JAVA=java.exe"
set "JAVA_OPTS=-DFONT_SCALE=1.0 -Dswing.aatext=true" set "JAVA_OPTS=-DFONT_SCALE=1.0 -Dswing.aatext=true"
set "ENV_FILE=%ATCS_DIR%ATCS.env.bat" set "ENV_FILE=%ATCS_DIR%ATCS.env.bat"
@@ -10,6 +11,7 @@ if exist "%ENV_FILE%" (
call "%ENV_FILE%" call "%ENV_FILE%"
) else ( ) else (
echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%" echo REM set "MAX_MEM=%MAX_MEM%">"%ENV_FILE%"
echo REM required minimum java version is 11
echo REM set "JAVA=%JAVA%">>"%ENV_FILE%" echo REM set "JAVA=%JAVA%">>"%ENV_FILE%"
echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%" echo REM set "JAVA_OPTS=%JAVA_OPTS%">>"%ENV_FILE%"
echo.>>"%ENV_FILE%" echo.>>"%ENV_FILE%"

View File

@@ -1,9 +1,11 @@
#!/bin/bash #!/usr/bin/env bash
# get the directory of this script
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}'" echo "ATCS_DIR: '${ATCS_DIR}'"
MAX_MEM="512M" MAX_MEM="512M"
JAVA="java" JAVA="java" # minimum required version is Java 11
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"
@@ -13,7 +15,7 @@ if [ -f "${ENV_FILE}" ]; then
else else
{ {
echo "#MAX_MEM=\"${MAX_MEM}\"" echo "#MAX_MEM=\"${MAX_MEM}\""
echo "#JAVA=\"${JAVA}\"" echo "#JAVA=\"${JAVA}\" # minimum required version is Java 11"
echo "#JAVA_OPTS=\"${JAVA_OPTS}\"" echo "#JAVA_OPTS=\"${JAVA_OPTS}\""
echo "" echo ""
}>"${ENV_FILE}" }>"${ENV_FILE}"

View File

@@ -13,8 +13,8 @@ else
fi fi
# --- Configuration --- # --- Configuration ---
PACKAGING_DIR=$(dirname "$(readlink -f "$0" || greadlink -f "$0" || stat -f "$0")") PACKAGING_DIR=$(dirname "$(readlink -f "$0" || greadlink -f "$0" || stat -f "$0")") # Directory of this script
ATCS_SOURCE_DIR=$(dirname "${PACKAGING_DIR}") ATCS_SOURCE_DIR=$(dirname "${PACKAGING_DIR}") # Parent directory of this script, assumed to be ATCS source root
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"
@@ -31,7 +31,6 @@ EXTRA_SOURCE_DIRS=(
# --- Libraries to include --- # --- Libraries to include ---
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"

View File

@@ -1 +1 @@
v0.6.21 v0.6.24

View File

@@ -45,6 +45,7 @@ atcs.spritesheet.items_weapons.category=item
atcs.spritesheet.items_weapons_2.category=item atcs.spritesheet.items_weapons_2.category=item
atcs.spritesheet.items_weapons_3.category=item atcs.spritesheet.items_weapons_3.category=item
atcs.spritesheet.monsters_antison.category=monster
atcs.spritesheet.monsters_armor1.category=monster atcs.spritesheet.monsters_armor1.category=monster
atcs.spritesheet.monsters_arulirs.category=monster atcs.spritesheet.monsters_arulirs.category=monster
@@ -132,3 +133,6 @@ atcs.spritesheet.monsters_newb_3.sizey=64
atcs.spritesheet.monsters_newb_4.category=monster atcs.spritesheet.monsters_newb_4.category=monster
atcs.spritesheet.monsters_newb_4.sizex=32 atcs.spritesheet.monsters_newb_4.sizex=32
atcs.spritesheet.monsters_newb_4.sizey=64 atcs.spritesheet.monsters_newb_4.sizey=64
atcs.spritesheet.monsters_1x2.category=monster
atcs.spritesheet.monsters_1x2.sizex=32
atcs.spritesheet.monsters_1x2.sizey=64

View File

@@ -20,6 +20,10 @@ 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.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
@@ -61,22 +65,8 @@ public class ATContentStudio {
ConfigCache.init(); ConfigCache.init();
try { String laf = ConfigCache.getFavoriteLaFClassName();
String laf = ConfigCache.getFavoriteLaFClassName(); setLookAndFeel(laf);
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();
}
scaleUIFont();
// 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 this setting. // reset this setting.
@@ -112,7 +102,6 @@ public class ATContentStudio {
frame.setVisible(true); frame.setVisible(true);
frame.setDefaultCloseOperation(StudioFrame.DO_NOTHING_ON_CLOSE); frame.setDefaultCloseOperation(StudioFrame.DO_NOTHING_ON_CLOSE);
} }
}); });
for (File f : ConfigCache.getKnownWorkspaces()) { for (File f : ConfigCache.getKnownWorkspaces()) {
if (workspaceRoot.equals(f)) { if (workspaceRoot.equals(f)) {
@@ -130,6 +119,34 @@ public class ATContentStudio {
}); });
} }
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 {
UIManager.setLookAndFeel(laf);
} catch (ClassNotFoundException e) {
System.err.println("Failed to load system look and feel. ");
System.err.println("Installed look and feel classes: ");
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();
} catch (InstantiationException | UnsupportedLookAndFeelException | IllegalAccessException e) {
e.printStackTrace();
}
var newLaF = UIManager.getLookAndFeel();
System.out.println("Using look and feel: " + newLaF.getName() + " (" + newLaF.getClass().getName() + ")");
scaleUIFont();
}
private static void checkUpdate() { private static void checkUpdate() {
BufferedReader in = null; BufferedReader in = null;
try { try {
@@ -152,13 +169,13 @@ public class ATContentStudio {
style.append("font-weight:" + (font.isBold() ? "bold" : "normal") + ";"); style.append("font-weight:" + (font.isBold() ? "bold" : "normal") + ";");
style.append("font-size:" + font.getSize() + "pt;"); style.append("font-size:" + font.getSize() + "pt;");
style.append("background-color: rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() style.append("background-color: rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue()
+ ");"); + ");");
JEditorPane ep = new JEditorPane("text/html", JEditorPane ep = new JEditorPane("text/html",
"<html><body style=\"" + style + "\">" + "You are not running the latest ATCS version.<br/>" "<html><body style=\"" + style + "\">" + "You are not running the latest ATCS version.<br/>"
+ "You can get the latest version (" + lastLine + ") by clicking the link below.<br/>" + "You can get the latest version (" + lastLine + ") by clicking the link below.<br/>"
+ "<a href=\"" + DOWNLOAD_URL + "\">" + DOWNLOAD_URL + "</a><br/>" + "<br/>" + "<a href=\"" + DOWNLOAD_URL + "\">" + DOWNLOAD_URL + "</a><br/>" + "<br/>"
+ "</body></html>"); + "</body></html>");
ep.setEditable(false); ep.setEditable(false);
ep.setBorder(null); ep.setBorder(null);
@@ -183,8 +200,14 @@ public class ATContentStudio {
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
e.printStackTrace(); e.printStackTrace();
} catch (HttpTimeoutException e) {
System.out.println("Could not connect to url to check for updates (timeout): " + CHECK_UPDATE_URL);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); 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 { } finally {
try { try {
if (in != null) if (in != null)

View File

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

View File

@@ -1,5 +1,6 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
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;
@@ -24,7 +25,7 @@ import java.io.*;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
public class GameSource implements ProjectTreeNode, Serializable { public class GameSource implements ProjectTreeNode, Serializable, JsonSerializable {
private static final long serialVersionUID = -1512979360971918158L; private static final long serialVersionUID = -1512979360971918158L;
@@ -38,6 +39,22 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient WriterModeDataSet writerModeDataSet; public transient WriterModeDataSet writerModeDataSet;
private transient SavedSlotCollection v; private transient SavedSlotCollection v;
@Override
public Map toMap() {
Map map = new HashMap();
map.put("type", type.toString());
map.put("baseFolder", baseFolder.getPath());
return map;
}
@Override
public void fromMap(Map map) {
if(map==null)return;
type = Enum.valueOf(Type.class, (String)map.get("type"));
baseFolder = new File((String) map.get("baseFolder"));
}
public static enum Type { public static enum Type {
source, source,
referenced, referenced,
@@ -52,6 +69,10 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient Map<String, List<String>> referencedSourceFiles = null; public transient Map<String, List<String>> referencedSourceFiles = null;
public GameSource(Map json, Project parent) {
fromMap(json);
refreshTransients(parent);
}
public GameSource(File folder, Project parent) { public GameSource(File folder, Project parent) {
this.parent = parent; this.parent = parent;
this.baseFolder = folder; this.baseFolder = folder;

View File

@@ -1,19 +1,53 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import java.awt.*; 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 { public class Preferences implements Serializable, JsonSerializable {
private static final long serialVersionUID = 2455802658424031276L; private static final long serialVersionUID = 2455802658424031276L;
public Dimension windowSize = null; public Dimension windowSize = null;
public Map<String, Integer> splittersPositions = new HashMap<String, Integer>(); public Map<String, Integer> splittersPositions = new HashMap<>();
public Preferences() { 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,27 +2,29 @@ package com.gpl.rpg.atcontentstudio.model;
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; import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.*;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
public class Workspace implements ProjectTreeNode, Serializable { 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 final String WS_SETTINGS_FILE_JSON = ".workspace.json";
public static Workspace activeWorkspace; public static Workspace activeWorkspace;
@@ -38,6 +40,7 @@ public class Workspace implements ProjectTreeNode, Serializable {
public transient ProjectsTreeModel projectsTreeModel = null; public transient ProjectsTreeModel projectsTreeModel = null;
public Workspace(File workspaceRoot) { public Workspace(File workspaceRoot) {
boolean freshWorkspace = false;
baseFolder = workspaceRoot; baseFolder = workspaceRoot;
if (!workspaceRoot.exists()) { if (!workspaceRoot.exists()) {
try { try {
@@ -49,44 +52,105 @@ public class Workspace implements ProjectTreeNode, Serializable {
} }
} }
settings = new WorkspaceSettings(this); settings = new WorkspaceSettings(this);
settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE); settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE_JSON);
if (!settingsFile.exists()) { if (!settingsFile.exists()) {
try { try {
settingsFile.createNewFile(); settingsFile.createNewFile();
freshWorkspace = true;
} catch (IOException e) { } catch (IOException e) {
Notification.addError("Error creating workspace datafile: " Notification.addError("Error creating workspace datafile: "
+ e.getMessage()); + e.getMessage());
e.printStackTrace(); e.printStackTrace();
} }
Notification.addSuccess("New workspace created: "
+ workspaceRoot.getAbsolutePath());
} }
Notification.addSuccess("New workspace created: " if (freshWorkspace)
+ workspaceRoot.getAbsolutePath()); save();
save(); }
@Override
public Map toMap() {
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 fromMap(Map map) {
if(serialVersionUID != (long) map.get("serialVersionUID")){
throw new SerializationException("wrong seriaVersionUID");
}
preferences.fromMap((Map) map.get("preferences"));
projectsName = new HashSet<>((List<String>) map.getOrDefault("projectsName", new HashSet<String>()));
projectsOpenByName = (Map<String, Boolean>) map.getOrDefault("projectsOpenByName", new HashMap<String, Boolean>() );
List<String> knownMapSourcesFolders1 = (List<String>) map.getOrDefault("knownMapSourcesFolders", new ArrayList<String>());
knownMapSourcesFolders = new HashSet<>();
if (knownMapSourcesFolders1 != null){
int size = knownMapSourcesFolders1.size();
for (String path: knownMapSourcesFolders1) {
//TODO: catch invalid paths...?
knownMapSourcesFolders.add(new File(path));
}
}
} }
public static void setActive(File workspaceRoot) { public static void setActive(File workspaceRoot) {
Workspace w; Workspace w;
File f = new File(workspaceRoot, WS_SETTINGS_FILE); File f2 = new File(workspaceRoot, WS_SETTINGS_FILE_JSON);
if (!workspaceRoot.exists() || !f.exists()) { if (f2.exists()) {
w = new Workspace(workspaceRoot); w = loadWorkspaceFromJson(workspaceRoot, f2);
w.refreshTransients();
} else { } else {
w = (Workspace) SettingsSave.loadInstance(f, "Workspace"); Notification.addInfo("Could not find json workspace file. Checking for binary file");
if (w == null) { File f = new File(workspaceRoot, WS_SETTINGS_FILE);
if (!workspaceRoot.exists() || !f.exists()) {
w = new Workspace(workspaceRoot); w = new Workspace(workspaceRoot);
} else { } else {
w.refreshTransients(); 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; activeWorkspace = w;
} }
private static Workspace loadWorkspaceFromJson(File workspaceRoot, File settingsFile) {
Workspace w = w = new Workspace(workspaceRoot);
Map json = FileUtils.mapFromJsonFile(settingsFile);
if (json!= null) {
w.fromMap(json);
}
return w;
}
public static void saveActive() { public static void saveActive() {
activeWorkspace.save(); activeWorkspace.save();
} }
public void save() { public void save() {
settings.save(); settings.save();
SettingsSave.saveInstance(this, settingsFile, "Workspace"); FileUtils.writeStringToFile(FileUtils.toJsonString(this), settingsFile, "Workspace");
} }
@Override @Override
@@ -356,5 +420,4 @@ public class Workspace implements ProjectTreeNode, Serializable {
} }
return false; return false;
} }
} }

View File

@@ -1,8 +1,7 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import java.io.*; import java.io.*;
@@ -108,22 +107,8 @@ public class WorkspaceSettings {
} }
json.put(VERSION_KEY, SETTINGS_VERSION); json.put(VERSION_KEY, SETTINGS_VERSION);
StringWriter writer = new JsonPrettyWriter(); String toWrite = FileUtils.toJsonString(json);
try { FileUtils.writeStringToFile(toWrite, file, "Workspace settings");
JSONObject.writeJSONString(json, writer);
} catch (IOException e) {
//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() { public void resetDefault() {

View File

@@ -1,31 +1,115 @@
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.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.*; import com.gpl.rpg.atcontentstudio.model.*;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import org.json.simple.JSONArray; import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import java.awt.*; import java.awt.*;
import java.io.*; import java.io.File;
import java.util.List;
import java.util.*; import java.util.*;
import java.util.List;
public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implements ProjectTreeNode, Serializable { public class GameDataCategory<E extends JSONElement> implements ProjectTreeNode {
//region Data
private final ArrayList<String> keyList = new ArrayList<>();
private final HashMap<String, E> dataMap = new HashMap<>();
//endregion
private static final long serialVersionUID = 5486008219704443733L;
public GameDataSet parent; public GameDataSet parent;
public String name; public String name;
public GameDataCategory(GameDataSet parent, String name) { public GameDataCategory(GameDataSet parent, String name) {
super();
this.parent = parent; this.parent = parent;
this.name = name; this.name = name;
} }
//region Helpers
public E get(String key) {
return dataMap.get(key);
}
public E get(int index) {
String key = keyList.get(index);
return dataMap.get(key);
}
public E getIgnoreCase(String key) {
for (String k : keyList) {
if (k.equalsIgnoreCase(key)) {
return dataMap.get(k);
}
}
return null;
}
public E put(String key, E element) {
if (!dataMap.containsKey(key)) {
keyList.add(key);
}
return dataMap.put(key, element);
}
public void add(E quest) {
String key = quest.id;
put(key, quest);
}
public E remove(String key) {
if (dataMap.containsKey(key)) {
keyList.remove(key);
}
return dataMap.remove(key);
}
public E remove(int index) {
String key = keyList.get(index);
keyList.remove(index);
return dataMap.remove(key);
}
public boolean removeGeneric(JSONElement element){
return remove((E) element);
}
public boolean remove(E element) {
String key = element.id;
int index = getProject().getNodeIndex(element);
boolean result = false;
if (dataMap.containsKey(key)) {
keyList.remove(key);
dataMap.remove(key);
result = true;
}
getProject().fireElementRemoved(element, index);
return result;
}
public int size() {
return dataMap.size();
}
public int indexOf(String key) {
return keyList.indexOf(key);
}
public int indexOf(E element) {
String key = element.id;
return keyList.indexOf(key);
}
public ArrayList<E> toList() {
ArrayList<E> list = new ArrayList<>();
for (String key : keyList) {
list.add(dataMap.get(key));
}
return list;
}
//endregion
//region copied implementation of ProjectTreeNode
@Override @Override
public TreeNode getChildAt(int childIndex) { public TreeNode getChildAt(int childIndex) {
return get(childIndex); return get(childIndex);
@@ -43,7 +127,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
@Override @Override
public int getIndex(TreeNode node) { public int getIndex(TreeNode node) {
return indexOf(node); return indexOf((E) node);
} }
@Override @Override
@@ -58,7 +142,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
@Override @Override
public Enumeration<E> children() { public Enumeration<E> children() {
return Collections.enumeration(this); return Collections.enumeration(toList());
} }
@Override @Override
@@ -86,7 +170,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
@Override @Override
public void notifyCreated() { public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>()); childrenAdded(new ArrayList<ProjectTreeNode>());
for (E node : this) { for (E node : toList()) {
node.notifyCreated(); node.notifyCreated();
} }
} }
@@ -132,10 +216,15 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
} }
@Override @Override
public Type getDataType() { public GameSource.Type getDataType() {
return parent.getDataType(); return parent.getDataType();
} }
@Override
public boolean isEmpty() {
return dataMap.isEmpty();
}
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void save(File jsonFile) { public void save(File jsonFile) {
if (getDataType() != GameSource.Type.created && getDataType() != GameSource.Type.altered) { if (getDataType() != GameSource.Type.created && getDataType() != GameSource.Type.altered) {
@@ -143,7 +232,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return; return;
} }
List<Map> dataToSave = new ArrayList<Map>(); List<Map> dataToSave = new ArrayList<Map>();
for (E element : this) { for (E element : toList()) {
if (element.jsonFile.equals(jsonFile)) { if (element.jsonFile.equals(jsonFile)) {
dataToSave.add(element.toJson()); dataToSave.add(element.toJson());
} }
@@ -157,26 +246,13 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return; return;
} }
StringWriter writer = new JsonPrettyWriter();
try { String toWrite = FileUtils.toJsonString(dataToSave);
JSONArray.writeJSONString(dataToSave, writer); if(FileUtils.writeStringToFile(toWrite, jsonFile, "JSON file '"+jsonFile.getAbsolutePath()+"'")){
} catch (IOException e) { for (E element : dataMap.values()) {
//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; 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();
} }
} }
@@ -185,7 +261,8 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
GameDataCategory<? extends JSONElement> impactedCategory = null; GameDataCategory<? extends JSONElement> impactedCategory = null;
String impactedFileName = fileName; String impactedFileName = fileName;
Map<String, Integer> containedIds = new LinkedHashMap<String, Integer>(); Map<String, Integer> containedIds = new LinkedHashMap<String, Integer>();
for (JSONElement node : this) { ArrayList<E> list = toList();
for (JSONElement node : list) {
if (node.getDataType() == GameSource.Type.created && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) != null) { 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) { 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.")); 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."));
@@ -214,7 +291,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
for (String key : containedIds.keySet()) { for (String key : containedIds.keySet()) {
if (containedIds.get(key) > 1) { if (containedIds.get(key) > 1) {
E node = null; E node = null;
for (E n : this) { for (E n : list) {
if (key.equals(n.id)) { if (key.equals(n.id)) {
node = n; node = n;
break; break;
@@ -230,19 +307,15 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return events; return events;
} }
public boolean remove(E o) {
int index = getProject().getNodeIndex(o);
boolean result = super.remove(o);
getProject().fireElementRemoved(o, index);
return result;
}
@Override @Override
public boolean needsSaving() { public boolean needsSaving() {
for (E node : this) { for (E node : dataMap.values()) {
if (node.needsSaving()) return true; if (node.needsSaving()) return true;
} }
return false; return false;
} }
//endregion
} }

View File

@@ -13,9 +13,9 @@ import javax.swing.tree.TreeNode;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.File;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.*;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class GameDataSet implements ProjectTreeNode, Serializable { public class GameDataSet implements ProjectTreeNode, Serializable {
@@ -67,7 +67,7 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
items = new GameDataCategory<Item>(this, Item.getStaticDesc()); items = new GameDataCategory<Item>(this, Item.getStaticDesc());
itemCategories = new GameDataCategory<ItemCategory>(this, ItemCategory.getStaticDesc()); itemCategories = new GameDataCategory<ItemCategory>(this, ItemCategory.getStaticDesc());
npcs = new GameDataCategory<NPC>(this, NPC.getStaticDesc()); npcs = new GameDataCategory<NPC>(this, NPC.getStaticDesc());
quests = new GameDataCategory<Quest>(this, Quest.getStaticDesc()); quests = new GameDataCategory<>(this, Quest.getStaticDesc());
v.add(actorConditions); v.add(actorConditions);
v.add(dialogues); v.add(dialogues);
@@ -159,7 +159,9 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
} }
} else if (parent.type != GameSource.Type.referenced) { } else if (parent.type != GameSource.Type.referenced) {
for (File f : baseFolder.listFiles()) { List<File> files = new ArrayList<File>(Arrays.stream(baseFolder.listFiles()).collect(Collectors.toList()));
Collections.sort(files,Comparator.comparing(x->x.getName()));
for (File f : files) {
if (f.getName().startsWith("actorconditions_")) { if (f.getName().startsWith("actorconditions_")) {
ActorCondition.fromJson(f, actorConditions); ActorCondition.fromJson(f, actorConditions);
} else if (f.getName().startsWith("conversationlist_")) { } else if (f.getName().startsWith("conversationlist_")) {
@@ -256,82 +258,42 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
public ActorCondition getActorCondition(String id) { public ActorCondition getActorCondition(String id) {
if (actorConditions == null) return null; if (actorConditions == null) return null;
for (ActorCondition gde : actorConditions) { return actorConditions.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
public Dialogue getDialogue(String id) { public Dialogue getDialogue(String id) {
if (dialogues == null) return null; if (dialogues == null) return null;
for (Dialogue gde : dialogues) { return dialogues.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
public Droplist getDroplist(String id) { public Droplist getDroplist(String id) {
if (droplists == null) return null; if (droplists == null) return null;
for (Droplist gde : droplists) { return droplists.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
public Item getItem(String id) { public Item getItem(String id) {
if (items == null) return null; if (items == null) return null;
for (Item gde : items) { return items.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
public ItemCategory getItemCategory(String id) { public ItemCategory getItemCategory(String id) {
if (itemCategories == null) return null; if (itemCategories == null) return null;
for (ItemCategory gde : itemCategories) { return itemCategories.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
public NPC getNPC(String id) { public NPC getNPC(String id) {
if (npcs == null) return null; if (npcs == null) return null;
for (NPC gde : npcs) { return npcs.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
public NPC getNPCIgnoreCase(String id) { public NPC getNPCIgnoreCase(String id) {
if (npcs == null) return null; if (npcs == null) return null;
for (NPC gde : npcs) { return npcs.getIgnoreCase(id);
if (id.equalsIgnoreCase(gde.id)) {
return gde;
}
}
return null;
} }
public Quest getQuest(String id) { public Quest getQuest(String id) {
if (quests == null) return null; if (quests == null) return null;
for (Quest gde : quests) { return quests.get(id);
if (id.equals(gde.id)) {
return gde;
}
}
return null;
} }
@Override @Override

View File

@@ -36,6 +36,8 @@ public class Item extends JSONElement {
public String description = null; public String description = null;
public HitEffect hit_effect = null; public HitEffect hit_effect = null;
public HitReceivedEffect hit_received_effect = null; public HitReceivedEffect hit_received_effect = null;
public HitEffect miss_effect = null;
public HitReceivedEffect miss_received_effect = null;
public DeathEffect kill_effect = null; public DeathEffect kill_effect = null;
public EquipEffect equip_effect = null; public EquipEffect equip_effect = null;
@@ -193,6 +195,16 @@ public class Item extends JSONElement {
this.hit_received_effect = parseHitReceivedEffect(hitReceivedEffect); this.hit_received_effect = parseHitReceivedEffect(hitReceivedEffect);
} }
Map missEffect = (Map) itemJson.get("missEffect");
if (missEffect != null) {
this.miss_effect = parseHitEffect(missEffect);
}
Map missReceivedEffect = (Map) itemJson.get("missReceivedEffect");
if (missReceivedEffect != null) {
this.miss_received_effect = parseHitReceivedEffect(missReceivedEffect);
}
Map killEffect = (Map) itemJson.get("killEffect"); Map killEffect = (Map) itemJson.get("killEffect");
if (killEffect == null) { if (killEffect == null) {
killEffect = (Map) itemJson.get("useEffect"); killEffect = (Map) itemJson.get("useEffect");
@@ -225,6 +237,8 @@ public class Item extends JSONElement {
linkEffects(this.hit_effect, proj, this); linkEffects(this.hit_effect, proj, this);
linkEffects(this.hit_received_effect, proj, this); linkEffects(this.hit_received_effect, proj, this);
linkEffects(this.miss_effect, proj, this);
linkEffects(this.miss_received_effect, proj, this);
linkEffects(this.kill_effect, proj, this); linkEffects(this.kill_effect, proj, this);
this.state = State.linked; this.state = State.linked;
} }
@@ -294,6 +308,14 @@ public class Item extends JSONElement {
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.miss_effect != null) {
clone.miss_effect = new HitEffect();
copyHitEffectValues(clone.miss_effect, this.miss_effect, clone);
}
if (this.miss_received_effect != null) {
clone.miss_received_effect = new HitReceivedEffect();
copyHitReceivedEffectValues(clone.miss_received_effect, this.miss_received_effect, clone);
}
if (this.kill_effect != null) { if (this.kill_effect != null) {
clone.kill_effect = new DeathEffect(); clone.kill_effect = new DeathEffect();
copyDeathEffectValues(clone.kill_effect, this.kill_effect, clone); copyDeathEffectValues(clone.kill_effect, this.kill_effect, clone);
@@ -317,6 +339,18 @@ public class Item extends JSONElement {
actorConditionElementChanged(this.hit_effect.conditions_source, oldOne, newOne, this); actorConditionElementChanged(this.hit_effect.conditions_source, oldOne, newOne, this);
actorConditionElementChanged(this.hit_effect.conditions_target, oldOne, newOne, this); actorConditionElementChanged(this.hit_effect.conditions_target, oldOne, newOne, this);
} }
if (this.hit_received_effect != null) {
actorConditionElementChanged(this.hit_received_effect.conditions_source, oldOne, newOne, this);
actorConditionElementChanged(this.hit_received_effect.conditions_target, oldOne, newOne, this);
}
if (this.miss_effect != null) {
actorConditionElementChanged(this.miss_effect.conditions_source, oldOne, newOne, this);
actorConditionElementChanged(this.miss_effect.conditions_target, oldOne, newOne, this);
}
if (this.miss_received_effect != null) {
actorConditionElementChanged(this.miss_received_effect.conditions_source, oldOne, newOne, this);
actorConditionElementChanged(this.miss_received_effect.conditions_target, oldOne, newOne, this);
}
if (this.kill_effect != null) { if (this.kill_effect != null) {
actorConditionElementChanged(this.kill_effect.conditions_source, oldOne, newOne, this); actorConditionElementChanged(this.kill_effect.conditions_source, oldOne, newOne, this);
@@ -381,6 +415,8 @@ public class Item extends JSONElement {
} }
writeHitEffectToMap(itemJson, this.hit_effect, "hitEffect"); writeHitEffectToMap(itemJson, this.hit_effect, "hitEffect");
writeHitReceivedEffectToMap(itemJson, this.hit_received_effect, "hitReceivedEffect"); writeHitReceivedEffectToMap(itemJson, this.hit_received_effect, "hitReceivedEffect");
writeHitEffectToMap(itemJson, this.miss_effect, "missEffect");
writeHitReceivedEffectToMap(itemJson, this.miss_received_effect, "missReceivedEffect");
String key; String key;
if (this.category != null && this.category.action_type != null && this.category.action_type == ItemCategory.ActionType.equip) { if (this.category != null && this.category.action_type != null && this.category.action_type == ItemCategory.ActionType.equip) {

View File

@@ -4,6 +4,7 @@ import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@@ -73,16 +74,10 @@ public abstract class JSONElement extends GameDataElement {
public abstract Map toJson(); public abstract Map toJson();
public String toJsonString() { public String toJsonString() {
StringWriter writer = new JsonPrettyWriter(); Map json = this.toJson();
try { return FileUtils.toJsonString(json);
JSONObject.writeJSONString(this.toJson(), writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
return writer.toString();
} }
@Override @Override
public GameDataSet getDataSet() { public GameDataSet getDataSet() {
if (parent == null) { if (parent == null) {

View File

@@ -38,6 +38,7 @@ public class NPC extends JSONElement {
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 Integer horizontalFlipChance = 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;
@@ -155,6 +156,7 @@ public class NPC extends JSONElement {
} }
this.spawngroup_id = (String) npcJson.get("spawnGroup"); this.spawngroup_id = (String) npcJson.get("spawnGroup");
this.faction_id = (String) npcJson.get("faction"); this.faction_id = (String) npcJson.get("faction");
this.horizontalFlipChance = JSONElement.getInteger((Number) npcJson.get("horizontalFlipChance"));
this.dialogue_id = (String) npcJson.get("phraseID"); this.dialogue_id = (String) npcJson.get("phraseID");
this.droplist_id = (String) npcJson.get("droplistID"); this.droplist_id = (String) npcJson.get("droplistID");
this.attack_cost = JSONElement.getInteger((Number) npcJson.get("attackCost")); this.attack_cost = JSONElement.getInteger((Number) npcJson.get("attackCost"));
@@ -244,6 +246,7 @@ public class NPC extends JSONElement {
} }
clone.droplist_id = this.droplist_id; clone.droplist_id = this.droplist_id;
clone.faction_id = this.faction_id; clone.faction_id = this.faction_id;
clone.horizontalFlipChance = this.horizontalFlipChance;
if (this.hit_effect != null) { if (this.hit_effect != null) {
clone.hit_effect = new HitEffect(); clone.hit_effect = new HitEffect();
copyHitEffectValues(clone.hit_effect, this.hit_effect, clone); copyHitEffectValues(clone.hit_effect, this.hit_effect, clone);
@@ -302,6 +305,7 @@ public class NPC extends JSONElement {
writeMinMaxToMap(npcJson, "attackDamage", this.attack_damage_min, attack_damage_max, 0); writeMinMaxToMap(npcJson, "attackDamage", this.attack_damage_min, attack_damage_max, 0);
if (this.spawngroup_id != null) npcJson.put("spawnGroup", this.spawngroup_id); if (this.spawngroup_id != null) npcJson.put("spawnGroup", this.spawngroup_id);
if (this.faction_id != null) npcJson.put("faction", this.faction_id); if (this.faction_id != null) npcJson.put("faction", this.faction_id);
if (this.horizontalFlipChance != null) npcJson.put("horizontalFlipChance", this.horizontalFlipChance);
if (this.dialogue != null) { if (this.dialogue != null) {
npcJson.put("phraseID", this.dialogue.id); npcJson.put("phraseID", this.dialogue.id);
} else if (this.dialogue_id != null) { } else if (this.dialogue_id != null) {

View File

@@ -186,5 +186,4 @@ public class Quest extends JSONElement {
} }
return null; return null;
} }
} }

View File

@@ -64,7 +64,8 @@ public class Requirement extends JSONElement {
date, date,
dateEquals, dateEquals,
time, time,
timeEquals timeEquals,
skillIncrease
} }
public enum SkillID { public enum SkillID {
@@ -166,6 +167,7 @@ public class Requirement extends JSONElement {
case dateEquals: case dateEquals:
case time: case time:
case timeEquals: case timeEquals:
case skillIncrease:
break; break;
} }
if (this.required_obj != null) this.required_obj.addBacklink((GameDataElement) this.parent); if (this.required_obj != null) this.required_obj.addBacklink((GameDataElement) this.parent);

View File

@@ -1,185 +0,0 @@
package com.gpl.rpg.atcontentstudio.model.saves;
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;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
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

@@ -1,188 +0,0 @@
package com.gpl.rpg.atcontentstudio.model.saves;
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;
import javax.swing.tree.TreeNode;
import java.awt.*;
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;
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

@@ -10,9 +10,7 @@ import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List; import java.util.List;
public class SpriteSheetSet implements ProjectTreeNode { public class SpriteSheetSet implements ProjectTreeNode {
@@ -44,6 +42,7 @@ public class SpriteSheetSet implements ProjectTreeNode {
} }
} }
} }
spritesheets.sort(Comparator.comparing(s -> s.id));
} }
@Override @Override

View File

@@ -19,12 +19,12 @@ public class PotGenerator {
GameSource gsrc = proj.baseContent; GameSource gsrc = proj.baseContent;
for (ActorCondition ac : gsrc.gameData.actorConditions) { for (ActorCondition ac : gsrc.gameData.actorConditions.toList()) {
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.toList()) {
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) {
@@ -34,20 +34,20 @@ public class PotGenerator {
} }
} }
for (ItemCategory ic : gsrc.gameData.itemCategories) { for (ItemCategory ic : gsrc.gameData.itemCategories.toList()) {
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.toList()) {
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.toList()) {
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.toList()) {
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) {

View File

@@ -3,10 +3,7 @@ package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer;
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.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition; import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet; import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
@@ -81,12 +78,13 @@ public class ResourcesCompactor {
File folder = new File(baseFolder.getAbsolutePath() + File.separator + GameDataSet.DEFAULT_REL_PATH_IN_SOURCE); File folder = new File(baseFolder.getAbsolutePath() + File.separator + GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!folder.exists()) folder.mkdirs(); if (!folder.exists()) folder.mkdirs();
for (ActorCondition ac : proj.baseContent.gameData.actorConditions) { ArrayList<ActorCondition> actorConditions = proj.baseContent.gameData.actorConditions.toList();
for (ActorCondition ac : actorConditions) {
if (filesCovered.contains(ac.jsonFile)) continue; if (filesCovered.contains(ac.jsonFile)) continue;
File currentFile = ac.jsonFile; File currentFile = ac.jsonFile;
filesCovered.add(currentFile); filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>(); List<Map> dataToSave = new ArrayList<Map>();
for (ActorCondition acond : proj.baseContent.gameData.actorConditions) { for (ActorCondition acond : actorConditions) {
if (!acond.jsonFile.equals(currentFile)) continue; if (!acond.jsonFile.equals(currentFile)) continue;
Map json = acond.toJson(); Map json = acond.toJson();
json.put("iconID", convertObjectSprite(acond.icon_id).toStringID()); json.put("iconID", convertObjectSprite(acond.icon_id).toStringID());
@@ -96,12 +94,13 @@ public class ResourcesCompactor {
writeJson(dataToSave, target); writeJson(dataToSave, target);
} }
for (Item it : proj.baseContent.gameData.items) { ArrayList<Item> items = proj.baseContent.gameData.items.toList();
for (Item it : items) {
if (filesCovered.contains(it.jsonFile)) continue; if (filesCovered.contains(it.jsonFile)) continue;
File currentFile = it.jsonFile; File currentFile = it.jsonFile;
filesCovered.add(currentFile); filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>(); List<Map> dataToSave = new ArrayList<Map>();
for (Item item : proj.baseContent.gameData.items) { for (Item item : items) {
if (!item.jsonFile.equals(currentFile)) continue; if (!item.jsonFile.equals(currentFile)) continue;
Map json = item.toJson(); Map json = item.toJson();
json.put("iconID", convertObjectSprite(item.icon_id).toStringID()); json.put("iconID", convertObjectSprite(item.icon_id).toStringID());
@@ -112,12 +111,13 @@ public class ResourcesCompactor {
} }
for (NPC np : proj.baseContent.gameData.npcs) { ArrayList<NPC> npcs = proj.baseContent.gameData.npcs.toList();
for (NPC np : npcs) {
if (filesCovered.contains(np.jsonFile)) continue; if (filesCovered.contains(np.jsonFile)) continue;
File currentFile = np.jsonFile; File currentFile = np.jsonFile;
filesCovered.add(currentFile); filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>(); List<Map> dataToSave = new ArrayList<Map>();
for (NPC npc : proj.baseContent.gameData.npcs) { for (NPC npc : npcs) {
if (!npc.jsonFile.equals(currentFile)) continue; if (!npc.jsonFile.equals(currentFile)) continue;
Map json = npc.toJson(); 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) { if (proj.getImage(npc.icon_id).getWidth(null) == TILE_WIDTH_IN_PIXELS || proj.getImage(npc.icon_id).getHeight(null) == TILE_HEIGHT_IN_PIXELS) {
@@ -145,16 +145,12 @@ public class ResourcesCompactor {
private Minify jsonMinifier = new Minify(); private Minify jsonMinifier = new Minify();
private void writeJson(List<Map> dataToSave, File target) { private void writeJson(List<Map> dataToSave, File target) {
StringWriter writer = new JsonPrettyWriter(); String toWrite = FileUtils.toJsonString(dataToSave);
try { toWrite = jsonMinifier.minify(toWrite);
JSONArray.writeJSONString(dataToSave, writer); FileUtils.writeStringToFile(toWrite, target, null);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try { try {
FileWriter w = new FileWriter(target); FileWriter w = new FileWriter(target);
w.write(jsonMinifier.minify(toWrite)); w.write(toWrite);
w.close(); w.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -6,6 +6,7 @@ import com.gpl.rpg.atcontentstudio.model.*;
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 com.gpl.rpg.atcontentstudio.utils.FileUtils;
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;
@@ -155,24 +156,12 @@ public class WriterModeDataSet implements ProjectTreeNode, Serializable {
return; return;
} }
StringWriter writer = new JsonPrettyWriter();
try { String toWrite = FileUtils.toJsonString(dataToSave);
JSONArray.writeJSONString(dataToSave, writer); if(FileUtils.writeStringToFile(toWrite, writerFile, "Json file " + writerFile.getAbsolutePath())) {
} 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) { for (WriterModeData element : writerModeDataList) {
element.state = GameDataElement.State.saved; 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();
} }
} }

View File

@@ -4,13 +4,11 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.*; import com.gpl.rpg.atcontentstudio.model.gamedata.*;
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.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.*; import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.*;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor; import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor;
import com.gpl.rpg.atcontentstudio.ui.map.WorldMapEditor; 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.sprites.SpritesheetEditor;
import com.gpl.rpg.atcontentstudio.ui.tools.writermode.WriterModeEditor; import com.gpl.rpg.atcontentstudio.ui.tools.writermode.WriterModeEditor;
import com.jidesoft.swing.JideTabbedPane; import com.jidesoft.swing.JideTabbedPane;
@@ -129,15 +127,6 @@ public class EditorsArea extends JPanel {
} }
public void openEditor(SavedGame save) {
if (editors.containsKey(save)) {
tabHolder.setSelectedComponent(editors.get(save));
return;
}
openEditor(new SavedGameEditor(save));
}
public void openEditor(WorldmapSegment node) { public void openEditor(WorldmapSegment node) {
if (editors.containsKey(node)) { if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node)); tabHolder.setSelectedComponent(editors.get(node));

View File

@@ -1,6 +1,5 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import com.gpl.rpg.andorstrainer.AndorsTrainer;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.Workspace; import com.gpl.rpg.atcontentstudio.model.Workspace;
@@ -8,7 +7,6 @@ import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement; import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
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.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.jidesoft.swing.TreeSearchable; import com.jidesoft.swing.TreeSearchable;
@@ -36,12 +34,6 @@ public class ProjectsTree extends JPanel {
private JPopupMenu popupMenu; private JPopupMenu popupMenu;
private Thread konamiTimeout = null;
private boolean exit = false;
private int timeout = 200;
private Integer[] konamiBuffer = new Integer[]{null, null, null, null, null, null, null, null, null, null};
private boolean konamiCodeEntered = false;
public ProjectsTree() { public ProjectsTree() {
super(); super();
setLayout(new BorderLayout()); setLayout(new BorderLayout());
@@ -68,22 +60,6 @@ public class ProjectsTree extends JPanel {
if (projectsTree.getSelectionPath() != null) { if (projectsTree.getSelectionPath() != null) {
itemAction((ProjectTreeNode) projectsTree.getSelectionPath().getLastPathComponent()); itemAction((ProjectTreeNode) projectsTree.getSelectionPath().getLastPathComponent());
} }
} else {
if (konamiTimeout == null) {
startKonamiCount();
}
int i = 0;
while (i < konamiBuffer.length && konamiBuffer[i] != null) {
i++;
}
if (i < konamiBuffer.length) {
konamiBuffer[i] = e.getKeyCode();
if (!compareBuffers()) {
exit = true;
} else {
resetTimeout();
}
}
} }
} }
}); });
@@ -198,10 +174,6 @@ public class ProjectsTree extends JPanel {
addNextSeparator = true; addNextSeparator = true;
popupMenu.add(new JMenuItem(actions.createWorldmap)); popupMenu.add(new JMenuItem(actions.createWorldmap));
} }
if (actions.loadSave.isEnabled()) {
addNextSeparator = true;
popupMenu.add(new JMenuItem(actions.loadSave));
}
if (addNextSeparator) { if (addNextSeparator) {
popupMenu.add(new JSeparator()); popupMenu.add(new JSeparator());
addNextSeparator = false; addNextSeparator = false;
@@ -245,311 +217,6 @@ public class ProjectsTree extends JPanel {
popupMenu.add(new JSeparator()); popupMenu.add(new JSeparator());
addNextSeparator = false; addNextSeparator = false;
} }
if (konamiCodeEntered) {
JMenuItem openTrainer = new JMenuItem("Start Andor's Trainer...");
popupMenu.add(openTrainer);
popupMenu.addSeparator();
openTrainer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Thread() {
public void run() {
AndorsTrainer.startApp(false);
}
}.start();
}
});
}
// if (projectsTree.getSelectionPath() == null || projectsTree.getSelectionPath().getLastPathComponent() == null) {
// JMenuItem addProject = new JMenuItem("Create project...");
// popupMenu.add(addProject);
// addProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new ProjectCreationWizard().setVisible(true);
// }
// });
// popupMenu.addSeparator();
// } else if (projectsTree.getSelectionPaths().length > 1) {
// boolean deleteAll = false;
// final List<GameDataElement> elementsToDelete = new ArrayList<GameDataElement>();
// for (TreePath selected : projectsTree.getSelectionPaths()) {
// if (selected.getLastPathComponent() instanceof GameDataElement && ((GameDataElement)selected.getLastPathComponent()).writable) {
// elementsToDelete.add((GameDataElement) selected.getLastPathComponent());
// deleteAll = true;
// } else {
// deleteAll = false;
// break;
// }
// }
// if (deleteAll) {
// JMenuItem deleteItems = new JMenuItem("Delete all selected elements");
// popupMenu.add(deleteItems);
// deleteItems.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// final Map<GameDataCategory<JSONElement>, Set<File>> impactedCategories = new IdentityHashMap<GameDataCategory<JSONElement>, Set<File>>();
// for (GameDataElement element : elementsToDelete) {
// ATContentStudio.frame.closeEditor(element);
// element.childrenRemoved(new ArrayList<ProjectTreeNode>());
// if (element instanceof JSONElement) {
// @SuppressWarnings("unchecked")
// GameDataCategory<JSONElement> category = (GameDataCategory<JSONElement>) element.getParent();
// category.remove(element);
// if (impactedCategories.get(category) == null) {
// impactedCategories.put(category, new HashSet<File>());
// }
// impactedCategories.get(category).add(((JSONElement) element).jsonFile);
// } else if (element instanceof TMXMap) {
// TMXMapSet parent = (TMXMapSet) element.getParent();
// parent.tmxMaps.remove(element);
// }
// }
// new Thread() {
// @Override
// public void run() {
// final List<SaveEvent> events = new ArrayList<SaveEvent>();
// List<SaveEvent> catEvents = null;
// for (GameDataCategory<JSONElement> category : impactedCategories.keySet()) {
// for (File f : impactedCategories.get(category)) {
// catEvents = category.attemptSave(true, f.getName());
// if (catEvents.isEmpty()) {
// category.save(f);
// } else {
// events.addAll(catEvents);
// }
// }
// }
// if (!events.isEmpty()) {
// new SaveItemsWizard(events, null).setVisible(true);
// }
// }
// }.start();
// }
// });
// }
//
// popupMenu.addSeparator();
// } else {
// final ProjectTreeNode selected = (ProjectTreeNode) projectsTree.getSelectionPath().getLastPathComponent();
// if (selected instanceof Project) {
// JMenuItem closeProject = new JMenuItem("Close Project...");
// JMenuItem deleteProject = new JMenuItem("Delete Project...");
// popupMenu.add(closeProject);
// popupMenu.add(deleteProject);
// popupMenu.addSeparator();
// closeProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// Workspace.closeProject((Project) selected);
// }
// });
// deleteProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// int confirm = JOptionPane.showConfirmDialog(ProjectsTree.this, "Are you sure you wish to delete this project ?\nAll files created for it will be deleted too...", "Delete this project ?", JOptionPane.OK_CANCEL_OPTION);
// if (confirm == JOptionPane.OK_OPTION) {
// Workspace.deleteProject(((Project)projectsTree.getSelectionPath().getLastPathComponent()));
// }
// }
// });
// }
// if (selected instanceof ClosedProject) {
// JMenuItem openProject = new JMenuItem("Open Project...");
// JMenuItem deleteProject = new JMenuItem("Delete Project...");
// popupMenu.add(openProject);
// popupMenu.add(deleteProject);
// popupMenu.addSeparator();
// openProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// Workspace.openProject(((ClosedProject)selected));
// }
// });
// deleteProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// int confirm = JOptionPane.showConfirmDialog(ProjectsTree.this, "Are you sure you wish to delete this project ?\nAll files created for it will be deleted too...", "Delete this project ?", JOptionPane.OK_CANCEL_OPTION);
// if (confirm == JOptionPane.OK_OPTION) {
// Workspace.deleteProject(((ClosedProject)selected));
// }
// }
// });
// }
// if (selected.getProject() != null) {
// final Project proj = ((ProjectTreeNode)selected).getProject();
// JMenuItem createGDE = new JMenuItem("Create Game Data Element (JSON)");
// popupMenu.add(createGDE);
// createGDE.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new JSONCreationWizard(proj).setVisible(true);
// }
// });
// JMenuItem importJson = new JMenuItem("Import JSON data");
// popupMenu.add(importJson);
// importJson.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new JSONImportWizard(proj).setVisible(true);
// }
// });
// //TODO move somewhere else
// JMenu compareElementsMenu = new JMenu("Open comparator for...");
// JMenuItem compareItems = new JMenuItem("Items");
// compareElementsMenu.add(compareItems);
// compareItems.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.editors.openEditor(new ItemsTableView(selected.getProject()));
// }
// });
// JMenuItem compareNPCs = new JMenuItem("NPCs");
// compareElementsMenu.add(compareNPCs);
// compareNPCs.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.editors.openEditor(new NPCsTableView(selected.getProject()));
// }
// });
// popupMenu.add(compareElementsMenu);
//
// JMenuItem exportProjectPackage = new JMenuItem("Export project");
// exportProjectPackage.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// JFileChooser chooser = new JFileChooser() {
// private static final long serialVersionUID = 8039332384370636746L;
// public boolean accept(File f) {
// return f.isDirectory() || f.getName().endsWith(".zip") || f.getName().endsWith(".ZIP");
// }
// };
// chooser.setMultiSelectionEnabled(false);
// int result = chooser.showSaveDialog(ATContentStudio.frame);
// if (result == JFileChooser.APPROVE_OPTION) {
// selected.getProject().generateExportPackage(chooser.getSelectedFile());
// }
// }
// });
// popupMenu.add(exportProjectPackage);
// popupMenu.addSeparator();
// }
// if (selected instanceof GameDataElement) {
// final GameDataElement node = ((GameDataElement)selected);
// if (node.state == GameDataElement.State.modified){
// JMenuItem saveItem = new JMenuItem("Save this element");
// saveItem.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// node.save();
// ATContentStudio.frame.nodeChanged(node);
// }
// });
// popupMenu.add(saveItem);
// }
//
// JMenuItem deleteItem = null;
// if (node.getDataType() == GameSource.Type.created) {
// deleteItem = new JMenuItem("Delete this element");
// } else if (node.getDataType() == GameSource.Type.altered) {
// deleteItem = new JMenuItem("Revert to original");
// }
// if (deleteItem != null) {
// popupMenu.add(deleteItem);
// deleteItem.addActionListener(new ActionListener() {
// @SuppressWarnings("unchecked")
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.closeEditor(node);
// new Thread() {
// @Override
// public void run() {
// node.childrenRemoved(new ArrayList<ProjectTreeNode>());
// if (node.getParent() instanceof GameDataCategory<?>) {
// ((GameDataCategory<?>)node.getParent()).remove(node);
// List<SaveEvent> events = node.attemptSave();
// if (events == null || events.isEmpty()) {
// node.save();
// } else {
// new SaveItemsWizard(events, null).setVisible(true);
// }
// }
// }
// }.start();
// }
// });
// }
// popupMenu.addSeparator();
//
// }
// if (selected instanceof Project || selected instanceof SavedGamesSet) {
// JMenuItem addSave = new JMenuItem("Load saved game...");
// popupMenu.add(addSave);
// popupMenu.addSeparator();
// addSave.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// JFileChooser chooser = new JFileChooser("Select an Andor's Trail save file");
// if (chooser.showOpenDialog(ATContentStudio.frame) == JFileChooser.APPROVE_OPTION) {
// selected.getProject().addSave(chooser.getSelectedFile());
// selected.getProject().save();
// }
// }
// });
//
// }
// }
// if (konamiCodeEntered) {
// JMenuItem openTrainer = new JMenuItem("Start Andor's Trainer...");
// popupMenu.add(openTrainer);
// popupMenu.addSeparator();
// openTrainer.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new Thread() {
// public void run() {
// AndorsTrainer.startApp(false);
// }
// }.start();
// }
// });
// }
// JMenu changeLaF = new JMenu("Change Look and Feel");
// for (final LookAndFeelInfo i : UIManager.getInstalledLookAndFeels()) {
// final JMenuItem lafItem = new JMenuItem("Switch to "+i.getName());
// changeLaF.add(lafItem);
// lafItem.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// try {
// UIManager.setLookAndFeel(i.getClassName());
// SwingUtilities.updateComponentTreeUI(ATContentStudio.frame);
// ConfigCache.setFavoriteLaFClassName(i.getClassName());
// } catch (ClassNotFoundException e1) {
// e1.printStackTrace();
// } catch (InstantiationException e1) {
// e1.printStackTrace();
// } catch (IllegalAccessException e1) {
// e1.printStackTrace();
// } catch (UnsupportedLookAndFeelException e1) {
// e1.printStackTrace();
// }
// }
// });
// }
// popupMenu.add(changeLaF);
// popupMenu.addSeparator();
// JMenuItem showAbout = new JMenuItem("About...");
// popupMenu.add(showAbout);
// popupMenu.addSeparator();
// showAbout.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.showAbout();
// }
// });
} }
public void popupActivated(MouseEvent e) { public void popupActivated(MouseEvent e) {
@@ -584,10 +251,6 @@ public class ProjectsTree extends JPanel {
ATContentStudio.frame.openEditor((WriterModeData) node); ATContentStudio.frame.openEditor((WriterModeData) node);
} else if (node instanceof BookmarkEntry) { } else if (node instanceof BookmarkEntry) {
ATContentStudio.frame.openEditor(((BookmarkEntry) node).bookmarkedElement); ATContentStudio.frame.openEditor(((BookmarkEntry) node).bookmarkedElement);
} else if (node instanceof SavedGame) {
if (konamiCodeEntered) {
ATContentStudio.frame.openEditor((SavedGame) node);
}
} }
} }
@@ -704,65 +367,4 @@ public class ProjectsTree extends JPanel {
projectsTree.scrollPathToVisible(tp); projectsTree.scrollPathToVisible(tp);
} }
protected void startKonamiCount() {
resetTimeout();
exit = false;
konamiTimeout = new Thread() {
@Override
public void run() {
while (!exit && timeout > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
timeout -= 10;
}
konamiTimeout = null;
konamiBuffer = new Integer[]{null, null, null, null, null, null, null, null, null, null};
}
};
konamiTimeout.start();
}
protected void resetTimeout() {
timeout = 400;
}
protected boolean compareBuffers() {
if (konamiBuffer[0] == null) return true;
else if (konamiBuffer[0] != KeyEvent.VK_UP) return false;
if (konamiBuffer[1] == null) return true;
else if (konamiBuffer[1] != KeyEvent.VK_UP) return false;
if (konamiBuffer[2] == null) return true;
else if (konamiBuffer[2] != KeyEvent.VK_DOWN) return false;
if (konamiBuffer[3] == null) return true;
else if (konamiBuffer[3] != KeyEvent.VK_DOWN) return false;
if (konamiBuffer[4] == null) return true;
else if (konamiBuffer[4] != KeyEvent.VK_LEFT) return false;
if (konamiBuffer[5] == null) return true;
else if (konamiBuffer[5] != KeyEvent.VK_RIGHT) return false;
if (konamiBuffer[6] == null) return true;
else if (konamiBuffer[6] != KeyEvent.VK_LEFT) return false;
if (konamiBuffer[7] == null) return true;
else if (konamiBuffer[7] != KeyEvent.VK_RIGHT) return false;
if (konamiBuffer[8] == null) return true;
else if (konamiBuffer[8] != KeyEvent.VK_B) return false;
if (konamiBuffer[9] == null) return true;
else if (konamiBuffer[9] != KeyEvent.VK_A) return false;
konamiCodeEntered = true;
exit = true;
return true;
}
} }

View File

@@ -163,7 +163,7 @@ public class SaveItemsWizard extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Map<GameDataCategory<JSONElement>, Set<File>> jsonToSave = new IdentityHashMap<GameDataCategory<JSONElement>, Set<File>>(); Map<GameDataCategory<JSONElement>, Set<File>> jsonToSave = new IdentityHashMap<>();
for (SaveEvent event : movedToCreatedList) { for (SaveEvent event : movedToCreatedList) {
if (event.target instanceof JSONElement) { if (event.target instanceof JSONElement) {
if (!jsonToSave.containsKey(event.target.getParent())) { if (!jsonToSave.containsKey(event.target.getParent())) {

View File

@@ -8,7 +8,6 @@ import com.gpl.rpg.atcontentstudio.model.Workspace;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement; import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
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.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
@@ -127,7 +126,6 @@ public class StudioFrame extends JFrame {
projectMenu.add(new JMenuItem(actions.importJSON)); projectMenu.add(new JMenuItem(actions.importJSON));
projectMenu.add(new JMenuItem(actions.createMap)); projectMenu.add(new JMenuItem(actions.createMap));
projectMenu.add(new JMenuItem(actions.createWorldmap)); projectMenu.add(new JMenuItem(actions.createWorldmap));
projectMenu.add(new JMenuItem(actions.loadSave));
getJMenuBar().add(projectMenu); getJMenuBar().add(projectMenu);
JMenu toolsMenu = new JMenu("Tools"); JMenu toolsMenu = new JMenu("Tools");
@@ -147,20 +145,10 @@ public class StudioFrame extends JFrame {
lafItem.addActionListener(new ActionListener() { lafItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { String lookAndFeel = i.getClassName();
UIManager.setLookAndFeel(i.getClassName()); ATContentStudio.setLookAndFeel(lookAndFeel);
ATContentStudio.scaleUIFont(); SwingUtilities.updateComponentTreeUI(ATContentStudio.frame);
SwingUtilities.updateComponentTreeUI(ATContentStudio.frame); ConfigCache.setFavoriteLaFClassName(lookAndFeel);
ConfigCache.setFavoriteLaFClassName(i.getClassName());
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
} }
}); });
} }
@@ -204,10 +192,6 @@ public class StudioFrame extends JFrame {
} }
} }
public void openEditor(SavedGame save) {
editors.openEditor(save);
}
public void openEditor(WorldmapSegment node) { public void openEditor(WorldmapSegment node) {
editors.openEditor(node); editors.openEditor(node);
} }
@@ -237,5 +221,4 @@ public class StudioFrame extends JFrame {
editors.showAbout(); editors.showAbout();
} }
} }

View File

@@ -6,7 +6,6 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.Worldmap; import com.gpl.rpg.atcontentstudio.model.maps.Worldmap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment; import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGamesSet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet;
import com.gpl.rpg.atcontentstudio.ui.tools.BeanShellView; import com.gpl.rpg.atcontentstudio.ui.tools.BeanShellView;
@@ -122,7 +121,7 @@ public class WorkspaceActions {
if (element.getParent() instanceof GameDataCategory<?>) { if (element.getParent() instanceof GameDataCategory<?>) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
GameDataCategory<JSONElement> category = (GameDataCategory<JSONElement>) element.getParent(); GameDataCategory<JSONElement> category = (GameDataCategory<JSONElement>) element.getParent();
category.remove(element); category.remove((JSONElement) element);
if (impactedCategories.get(category) == null) { if (impactedCategories.get(category) == null) {
impactedCategories.put(category, new HashSet<File>()); impactedCategories.put(category, new HashSet<File>());
} }
@@ -190,7 +189,7 @@ public class WorkspaceActions {
node.childrenRemoved(new ArrayList<ProjectTreeNode>()); node.childrenRemoved(new ArrayList<ProjectTreeNode>());
if (node instanceof JSONElement) { if (node instanceof JSONElement) {
if (node.getParent() instanceof GameDataCategory<?>) { if (node.getParent() instanceof GameDataCategory<?>) {
((GameDataCategory<?>) node.getParent()).remove(node); ((GameDataCategory<?>) node.getParent()).removeGeneric((JSONElement) node);
List<SaveEvent> events = node.attemptSave(); List<SaveEvent> events = node.attemptSave();
if (events == null || events.isEmpty()) { if (events == null || events.isEmpty()) {
node.save(); node.save();
@@ -315,22 +314,6 @@ public class WorkspaceActions {
} }
}; };
public ATCSAction loadSave = new ATCSAction("Load saved game...", "Opens the saved game loading wizard") {
public void actionPerformed(ActionEvent e) {
if (!(selectedNode instanceof Project || selectedNode instanceof SavedGamesSet)) return;
JFileChooser chooser = new JFileChooser("Select an Andor's Trail save file");
if (chooser.showOpenDialog(ATContentStudio.frame) == JFileChooser.APPROVE_OPTION) {
selectedNode.getProject().addSave(chooser.getSelectedFile());
selectedNode.getProject().save();
}
}
public void selectionChanged(ProjectTreeNode selectedNode, TreePath[] selectedPaths) {
setEnabled(selectedNode instanceof Project || selectedNode instanceof SavedGamesSet);
}
};
public ATCSAction compareItems = new ATCSAction("Items comparator", "Opens an editor showing all the items of the project in a table") { public ATCSAction compareItems = new ATCSAction("Items comparator", "Opens an editor showing all the items of the project in a table") {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (selectedNode == null || selectedNode.getProject() == null) return; if (selectedNode == null || selectedNode.getProject() == null) return;
@@ -466,7 +449,6 @@ public class WorkspaceActions {
actions.add(createGDE); actions.add(createGDE);
actions.add(createMap); actions.add(createMap);
actions.add(importJSON); actions.add(importJSON);
actions.add(loadSave);
actions.add(compareItems); actions.add(compareItems);
actions.add(compareNPCs); actions.add(compareNPCs);
actions.add(exportProject); actions.add(exportProject);

View File

@@ -26,7 +26,7 @@ public class CommonEditor {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@Override @Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
JLabel label = (JLabel) c; JLabel label = (JLabel) c;
@@ -68,7 +68,7 @@ public class CommonEditor {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@Override @Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
JLabel label = (JLabel) c; JLabel label = (JLabel) c;
@@ -90,7 +90,7 @@ public class CommonEditor {
} }
} }
public static class HitRecievedEffectPane<EFFECT extends Common.HitReceivedEffect, LIST_MODEL_SOURCE, ELEMENT extends Common.TimedActorConditionEffect, MODEL extends OrderedListenerListModel<LIST_MODEL_SOURCE, ELEMENT>> extends HitEffectPane<EFFECT, LIST_MODEL_SOURCE, ELEMENT, MODEL> { public static class HitReceivedEffectPane<EFFECT extends Common.HitReceivedEffect> extends HitEffectPane<EFFECT> {
/// this should just be a convenience field, to access it, without casting. DO NOT SET WITHOUT ALSO SETTING THE FIELD IN THE SUPER-CLASS! /// this should just be a convenience field, to access it, without casting. DO NOT SET WITHOUT ALSO SETTING THE FIELD IN THE SUPER-CLASS!
EFFECT effect; EFFECT effect;
private JSpinner hitReceivedEffectHPMinTarget; private JSpinner hitReceivedEffectHPMinTarget;
@@ -98,13 +98,14 @@ public class CommonEditor {
private JSpinner hitReceivedEffectAPMinTarget; private JSpinner hitReceivedEffectAPMinTarget;
private JSpinner hitReceivedEffectAPMaxTarget; private JSpinner hitReceivedEffectAPMaxTarget;
public HitRecievedEffectPane(String title, Supplier<ELEMENT> sourceNewSupplier, Editor editor, String applyToHint, String applyToTargetHint) { public HitReceivedEffectPane(String title, Editor editor, String applyToHint, String applyToTargetHint) {
super(title, sourceNewSupplier, editor, applyToHint, applyToTargetHint); super(title, editor, applyToHint, applyToTargetHint);
} }
void createHitReceivedEffectPaneContent(FieldUpdateListener listener, boolean writable, EFFECT e, MODEL sourceConditionsModelInput, MODEL targetConditionsModelInput) { @Override
public void createPaneContent(FieldUpdateListener listener, boolean writable, EFFECT e) {
effect = e; effect = e;
createHitEffectPaneContent(listener, writable, e, sourceConditionsModelInput, targetConditionsModelInput); super.createPaneContent(listener, writable, e);
} }
@Override @Override
@@ -144,32 +145,35 @@ public class CommonEditor {
} }
} }
public static class HitEffectPane<EFFECT extends Common.HitEffect, LIST_MODEL_SOURCE, ELEMENT extends Common.TimedActorConditionEffect, MODEL extends OrderedListenerListModel<LIST_MODEL_SOURCE, ELEMENT>> extends DeathEffectPane<EFFECT, LIST_MODEL_SOURCE, ELEMENT, MODEL> { public static class HitEffectPane<EFFECT extends Common.HitEffect>
extends DeathEffectPane<EFFECT> {
/// this should just be a convenience field, to access it, without casting. DO NOT SET WITHOUT ALSO SETTING THE FIELD IN THE SUPER-CLASS! /// this should just be a convenience field, to access it, without casting. DO NOT SET WITHOUT ALSO SETTING THE FIELD IN THE SUPER-CLASS!
public EFFECT effect; public EFFECT effect;
protected final String applyToTargetHint; protected final String applyToTargetHint;
private JList hitTargetConditionsList; private JList<Common.TimedActorConditionEffect> hitTargetConditionsList;
private final ConditionEffectEditorPane<LIST_MODEL_SOURCE, ELEMENT, MODEL> hitTargetConditionPane; private final ConditionEffectEditorPane<Common.HitEffect, TargetTimedConditionsListModel> hitTargetConditionPane;
/* /*
* create a new HitEffectPane with the selections (probably passed in from last time) * create a new HitEffectPane with the selections (probably passed in from last time)
*/ */
public HitEffectPane(String title, Supplier<ELEMENT> sourceNewSupplier, Editor editor, String applyToHint, String applyToTargetHint) { public HitEffectPane(String title, Editor editor, String applyToHint, String applyToTargetHint) {
super(title, sourceNewSupplier, editor, applyToHint); super(title, editor, applyToHint);
hitTargetConditionPane = new ConditionEffectEditorPane<>(editor); hitTargetConditionPane = new ConditionEffectEditorPane<>(editor);
if (applyToTargetHint == null || applyToTargetHint == "") { if (applyToTargetHint == null || applyToTargetHint.isEmpty()) {
this.applyToTargetHint = ""; this.applyToTargetHint = "";
} else { } else {
this.applyToTargetHint = String.format(" (%s)", applyToTargetHint); this.applyToTargetHint = String.format(" (%s)", applyToTargetHint);
} }
} }
void createHitEffectPaneContent(FieldUpdateListener listener, boolean writable, EFFECT e, MODEL sourceConditionsModelInput, MODEL targetConditionsListModel) { @Override
public void createPaneContent(FieldUpdateListener listener, boolean writable, EFFECT e) {
effect = e; effect = e;
hitTargetConditionPane.conditionsModel = targetConditionsListModel; hitTargetConditionPane.conditionsModel = new TargetTimedConditionsListModel(e);
createDeathEffectPaneContent(listener, writable, e, sourceConditionsModelInput); super.createPaneContent(listener, writable, e);
} }
@Override @Override
@@ -178,8 +182,8 @@ public class CommonEditor {
String titleTarget = String.format("Actor Conditions applied to the target%s: ", applyToTargetHint); String titleTarget = String.format("Actor Conditions applied to the target%s: ", applyToTargetHint);
CommonEditor.TimedConditionsCellRenderer cellRendererTarget = new CommonEditor.TimedConditionsCellRenderer(); CommonEditor.TimedConditionsCellRenderer cellRendererTarget = new CommonEditor.TimedConditionsCellRenderer();
BasicLambdaWithArg<ELEMENT> selectedSetTarget = (value) -> hitTargetConditionPane.selectedCondition = value; BasicLambdaWithArg<Common.TimedActorConditionEffect> selectedSetTarget = (value) -> hitTargetConditionPane.selectedCondition = value;
BasicLambdaWithReturn<ELEMENT> selectedGetTarget = () -> hitTargetConditionPane.selectedCondition; BasicLambdaWithReturn<Common.TimedActorConditionEffect> selectedGetTarget = () -> hitTargetConditionPane.selectedCondition;
BasicLambda selectedResetTarget = () -> hitTargetConditionPane.selectedCondition = null; BasicLambda selectedResetTarget = () -> hitTargetConditionPane.selectedCondition = null;
BasicLambdaWithArg<JPanel> updatePaneTarget = (editorPane) -> hitTargetConditionPane.updateEffectTimedConditionEditorPane( BasicLambdaWithArg<JPanel> updatePaneTarget = (editorPane) -> hitTargetConditionPane.updateEffectTimedConditionEditorPane(
editorPane, hitTargetConditionPane.selectedCondition, listener); editorPane, hitTargetConditionPane.selectedCondition, listener);
@@ -212,8 +216,8 @@ public class CommonEditor {
} }
} }
public static class DeathEffectPane<EFFECT extends Common.DeathEffect, LIST_MODEL_SOURCE, ELEMENT extends Common.TimedActorConditionEffect, MODEL extends OrderedListenerListModel<LIST_MODEL_SOURCE, ELEMENT>> { public static class DeathEffectPane<EFFECT extends Common.DeathEffect> {
protected final Supplier<ELEMENT> conditionSupplier; protected final Supplier<Common.TimedActorConditionEffect> conditionSupplier;
protected final String title; protected final String title;
protected final String applyToHint; protected final String applyToHint;
@@ -224,28 +228,27 @@ public class CommonEditor {
private JSpinner effectHPMax; private JSpinner effectHPMax;
private JSpinner effectAPMin; private JSpinner effectAPMin;
private JSpinner effectAPMax; private JSpinner effectAPMax;
private JList<ELEMENT> sourceConditionsList; private JList<Common.TimedActorConditionEffect> sourceConditionsList;
private final ConditionEffectEditorPane<LIST_MODEL_SOURCE, ELEMENT, MODEL> sourceConditionPane; private final ConditionEffectEditorPane<Common.DeathEffect, SourceTimedConditionsListModel> sourceConditionPane;
/* /*
* create a new DeatchEffectPane with the selections (probably passed in from last time) * create a new DeatchEffectPane with the selections (probably passed in from last time)
*/ */
public DeathEffectPane(String title, Supplier<ELEMENT> conditionSupplier, Editor editor, String applyToHint) { public DeathEffectPane(String title, Editor editor, String applyToHint) {
this.title = title; this.title = title;
this.conditionSupplier = conditionSupplier; this.conditionSupplier = Common.TimedActorConditionEffect::new;
this.sourceConditionPane = new ConditionEffectEditorPane<>(editor); this.sourceConditionPane = new ConditionEffectEditorPane<>(editor);
if (applyToHint == null || applyToHint == "") { if (applyToHint == null || applyToHint.isEmpty()) {
this.applyToHint = ""; this.applyToHint = "";
} else { } else {
this.applyToHint = String.format(" (%s)", applyToHint); this.applyToHint = String.format(" (%s)", applyToHint);
} }
} }
public void createPaneContent(FieldUpdateListener listener, boolean writable, EFFECT e) {
void createDeathEffectPaneContent(FieldUpdateListener listener, boolean writable, EFFECT e, MODEL sourceConditionsModel) {
effect = e; effect = e;
sourceConditionPane.conditionsModel = sourceConditionsModel; sourceConditionPane.conditionsModel = new SourceTimedConditionsListModel(e);
effectPane = new CollapsiblePanel(title); effectPane = new CollapsiblePanel(title);
effectPane.setLayout(new JideBoxLayout(effectPane, JideBoxLayout.PAGE_AXIS)); effectPane.setLayout(new JideBoxLayout(effectPane, JideBoxLayout.PAGE_AXIS));
@@ -269,8 +272,8 @@ public class CommonEditor {
protected void addLists(FieldUpdateListener listener, boolean writable) { protected void addLists(FieldUpdateListener listener, boolean writable) {
String titleSource = String.format("Actor Conditions applied to the source%s: ", applyToHint); String titleSource = String.format("Actor Conditions applied to the source%s: ", applyToHint);
TimedConditionsCellRenderer cellRendererSource = new TimedConditionsCellRenderer(); TimedConditionsCellRenderer cellRendererSource = new TimedConditionsCellRenderer();
BasicLambdaWithArg<ELEMENT> selectedSetSource = (value) -> sourceConditionPane.selectedCondition = value; BasicLambdaWithArg<Common.TimedActorConditionEffect> selectedSetSource = (value) -> sourceConditionPane.selectedCondition = value;
BasicLambdaWithReturn<ELEMENT> selectedGetSource = () -> sourceConditionPane.selectedCondition; BasicLambdaWithReturn<Common.TimedActorConditionEffect> selectedGetSource = () -> sourceConditionPane.selectedCondition;
BasicLambda selectedResetSource = () -> sourceConditionPane.selectedCondition = null; BasicLambda selectedResetSource = () -> sourceConditionPane.selectedCondition = null;
BasicLambdaWithArg<JPanel> updatePaneSource = (editorPane) -> sourceConditionPane.updateEffectTimedConditionEditorPane( BasicLambdaWithArg<JPanel> updatePaneSource = (editorPane) -> sourceConditionPane.updateEffectTimedConditionEditorPane(
editorPane, sourceConditionPane.selectedCondition, listener); editorPane, sourceConditionPane.selectedCondition, listener);
@@ -309,9 +312,9 @@ public class CommonEditor {
} }
} }
static class ConditionEffectEditorPane<LIST_MODEL_SOURCE, ELEMENT extends Common.TimedActorConditionEffect, MODEL extends OrderedListenerListModel<LIST_MODEL_SOURCE, ELEMENT>> { static class ConditionEffectEditorPane<LIST_MODEL_SOURCE, MODEL extends OrderedListenerListModel<LIST_MODEL_SOURCE, Common.TimedActorConditionEffect> > {
private final Editor editor; private final Editor editor;
ELEMENT selectedCondition; Common.TimedActorConditionEffect selectedCondition;
MODEL conditionsModel; MODEL conditionsModel;
Editor.MyComboBox conditionBox; Editor.MyComboBox conditionBox;
@@ -328,7 +331,7 @@ public class CommonEditor {
this.editor = editor; this.editor = editor;
} }
public void updateEffectTimedConditionWidgets(ELEMENT condition) { public void updateEffectTimedConditionWidgets(Common.TimedActorConditionEffect condition) {
boolean writable = editor.target.writable; boolean writable = editor.target.writable;
boolean immunity = condition.isImmunity(); boolean immunity = condition.isImmunity();
@@ -352,7 +355,7 @@ public class CommonEditor {
conditionForever.setEnabled(!clear && writable); conditionForever.setEnabled(!clear && writable);
} }
public void updateEffectTimedConditionEditorPane(JPanel pane, ELEMENT condition, final FieldUpdateListener listener) { public void updateEffectTimedConditionEditorPane(JPanel pane, Common.TimedActorConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (conditionBox != null) { if (conditionBox != null) {
editor.removeElementListener(conditionBox); editor.removeElementListener(conditionBox);
@@ -495,7 +498,7 @@ public class CommonEditor {
} }
private void setDurationToDefaultIfNone() { private void setDurationToDefaultIfNone() {
if (selectedCondition.duration == null || selectedCondition.duration == ActorCondition.DURATION_NONE) { if (selectedCondition.duration == null || selectedCondition.duration.equals(ActorCondition.DURATION_NONE)) {
selectedCondition.duration = 1; selectedCondition.duration = 1;
} }
} }

View File

@@ -610,6 +610,17 @@ public class DialogueEditor extends JSONElementEditor {
requirementObjId = addTextField(pane, "Time type HHMMSS:", requirement.required_obj_id, writable, listener); requirementObjId = addTextField(pane, "Time type HHMMSS:", requirement.required_obj_id, writable, listener);
requirementValue = addIntegerField(pane, "Exact time value: ", requirement.required_value, true, writable, listener); requirementValue = addIntegerField(pane, "Exact time value: ", requirement.required_value, true, writable, listener);
break; break;
case skillIncrease:
skillId = null;
try {
skillId = requirement.required_obj_id == null ? null : Requirement.SkillID.valueOf(requirement.required_obj_id);
} catch (IllegalArgumentException e) {
}
requirementObj = null;
requirementSkill = addEnumValueBox(pane, "Skill ID:", Requirement.SkillID.values(), skillId, writable, listener);
requirementObjId = null;//addTextField(pane, "Skill ID:", requirement.required_obj_id, writable, listener);
requirementValue = addIntegerField(pane, "Level up: ", requirement.required_value, false, writable, listener);
break;
} }
requirementNegated = addBooleanBasedCheckBox(pane, "Negate this requirement.", requirement.negated, writable, listener); requirementNegated = addBooleanBasedCheckBox(pane, "Negate this requirement.", requirement.negated, writable, listener);
} }
@@ -843,7 +854,7 @@ public class DialogueEditor extends JSONElementEditor {
if (req.required_obj.getIcon() != null) { if (req.required_obj.getIcon() != null) {
label.setIcon(new ImageIcon(req.required_obj.getIcon())); label.setIcon(new ImageIcon(req.required_obj.getIcon()));
} }
} else if (req.type == Requirement.RequirementType.skillLevel) { } else if (req.type == Requirement.RequirementType.skillLevel || req.type == Requirement.RequirementType.skillIncrease) {
label.setIcon(new ImageIcon(DefaultIcons.getSkillIcon())); label.setIcon(new ImageIcon(DefaultIcons.getSkillIcon()));
} else if (req.type == Requirement.RequirementType.spentGold) { } else if (req.type == Requirement.RequirementType.spentGold) {
label.setIcon(new ImageIcon(DefaultIcons.getGoldIcon())); label.setIcon(new ImageIcon(DefaultIcons.getGoldIcon()));
@@ -1008,7 +1019,7 @@ public class DialogueEditor extends JSONElementEditor {
selectedRequirement.required_obj.removeBacklink(dialogue); selectedRequirement.required_obj.removeBacklink(dialogue);
selectedRequirement.required_obj = null; selectedRequirement.required_obj = null;
} }
if (selectedRequirement.type == Requirement.RequirementType.skillLevel) { if (selectedRequirement.type == Requirement.RequirementType.skillLevel || selectedRequirement.type == Requirement.RequirementType.skillIncrease) {
selectedRequirement.required_obj_id = value == null ? null : value.toString(); selectedRequirement.required_obj_id = value == null ? null : value.toString();
} }
requirementsListModel.itemChanged(selectedRequirement); requirementsListModel.itemChanged(selectedRequirement);

View File

@@ -76,9 +76,11 @@ public class ItemEditor extends JSONElementEditor {
private JRadioButton equipConditionImmunity; private JRadioButton equipConditionImmunity;
private JSpinner equipConditionMagnitude; private JSpinner equipConditionMagnitude;
private CommonEditor.HitEffectPane hitEffectPane = new CommonEditor.HitEffectPane("Effect on every hit: ", TimedActorConditionEffect::new, this, null, null); private final CommonEditor.HitEffectPane<HitEffect> hitEffectPane = new CommonEditor.HitEffectPane<>("Effect on every hit: ", this, null, "npc");
private CommonEditor.DeathEffectPane killEffectPane = new CommonEditor.DeathEffectPane(killLabel, TimedActorConditionEffect::new, this, null); private final CommonEditor.DeathEffectPane<DeathEffect> killEffectPane = new CommonEditor.DeathEffectPane<>(killLabel, this, null);
private CommonEditor.HitRecievedEffectPane hitReceivedEffectPane = new CommonEditor.HitRecievedEffectPane("Effect on every hit received: ", TimedActorConditionEffect::new, this, null, null); private final CommonEditor.HitReceivedEffectPane<HitReceivedEffect> hitReceivedEffectPane = new CommonEditor.HitReceivedEffectPane<>("Effect on every hit received: ", this, "player", "npc");
private final CommonEditor.HitEffectPane<HitEffect> missEffectPane = new CommonEditor.HitEffectPane<>("Effect on every miss: ", this, "player", "npc");
private final CommonEditor.HitReceivedEffectPane<HitReceivedEffect> missReceivedEffectPane = new CommonEditor.HitReceivedEffectPane<>("Effect on every miss received: ", this, "player", "npc");
public ItemEditor(Item item) { public ItemEditor(Item item) {
super(item, item.getDesc(), item.getIcon()); super(item, item.getDesc(), item.getIcon());
@@ -86,7 +88,6 @@ public class ItemEditor extends JSONElementEditor {
addEditorTab(json_view_id, getJSONView()); addEditorTab(json_view_id, getJSONView());
} }
@SuppressWarnings({"unchecked", "rawtypes"})
@Override @Override
public void insertFormViewDataField(JPanel pane) { public void insertFormViewDataField(JPanel pane) {
@@ -111,11 +112,7 @@ public class ItemEditor extends JSONElementEditor {
equipEffectPane = new CollapsiblePanel("Effect when equipped: "); equipEffectPane = new CollapsiblePanel("Effect when equipped: ");
equipEffectPane.setLayout(new JideBoxLayout(equipEffectPane, JideBoxLayout.PAGE_AXIS)); equipEffectPane.setLayout(new JideBoxLayout(equipEffectPane, JideBoxLayout.PAGE_AXIS));
if (item.equip_effect == null) { equipEffect = Objects.requireNonNullElseGet(item.equip_effect, Item.EquipEffect::new);
equipEffect = new Item.EquipEffect();
} else {
equipEffect = item.equip_effect;
}
equipDmgMin = addIntegerField(equipEffectPane, "Attack Damage min: ", equipEffect.damage_boost_min, true, item.writable, listener); equipDmgMin = addIntegerField(equipEffectPane, "Attack Damage min: ", equipEffect.damage_boost_min, true, item.writable, listener);
equipDmgMax = addIntegerField(equipEffectPane, "Attack Damage max: ", equipEffect.damage_boost_max, true, item.writable, listener); equipDmgMax = addIntegerField(equipEffectPane, "Attack Damage max: ", equipEffect.damage_boost_max, true, item.writable, listener);
equipSetDM = addIntegerField(equipEffectPane, "Damage modifier %: ", equipEffect.damage_modifier, 100, false, item.writable, listener); equipSetDM = addIntegerField(equipEffectPane, "Damage modifier %: ", equipEffect.damage_modifier, 100, false, item.writable, listener);
@@ -164,33 +161,38 @@ public class ItemEditor extends JSONElementEditor {
} }
HitEffect hitEffect = Objects.requireNonNullElseGet(item.hit_effect, HitEffect::new); HitEffect hitEffect = Objects.requireNonNullElseGet(item.hit_effect, HitEffect::new);
hitEffectPane.createHitEffectPaneContent(listener, item.writable, hitEffect, hitEffectPane.createPaneContent(listener, item.writable, hitEffect);
new CommonEditor.SourceTimedConditionsListModel(hitEffect),
new CommonEditor.TargetTimedConditionsListModel(hitEffect));
pane.add(hitEffectPane.effectPane, JideBoxLayout.FIX); pane.add(hitEffectPane.effectPane, JideBoxLayout.FIX);
DeathEffect killEffect = Objects.requireNonNullElseGet(item.kill_effect, DeathEffect::new); DeathEffect killEffect = Objects.requireNonNullElseGet(item.kill_effect, DeathEffect::new);
killEffectPane.createDeathEffectPaneContent(listener, item.writable, killEffect, killEffectPane.createPaneContent(listener, item.writable, killEffect);
new CommonEditor.SourceTimedConditionsListModel(killEffect));
pane.add(killEffectPane.effectPane, JideBoxLayout.FIX); pane.add(killEffectPane.effectPane, JideBoxLayout.FIX);
HitReceivedEffect hitReceivedEffect = Objects.requireNonNullElseGet(item.hit_received_effect, HitReceivedEffect hitReceivedEffect = Objects.requireNonNullElseGet(item.hit_received_effect, HitReceivedEffect::new);
HitReceivedEffect::new); hitReceivedEffectPane.createPaneContent(listener, item.writable, hitReceivedEffect);
hitReceivedEffectPane.createHitReceivedEffectPaneContent(listener, item.writable, hitReceivedEffect, pane.add(hitReceivedEffectPane.effectPane, JideBoxLayout.FIX);
new CommonEditor.SourceTimedConditionsListModel(
hitReceivedEffect),
new CommonEditor.TargetTimedConditionsListModel(
hitReceivedEffect));
pane.add(killEffectPane.effectPane, JideBoxLayout.FIX);
HitEffect missEffect = Objects.requireNonNullElseGet(item.miss_effect, HitEffect::new);
missEffectPane.createPaneContent(listener, item.writable, missEffect);
pane.add(missEffectPane.effectPane, JideBoxLayout.FIX);
HitReceivedEffect missReceivedEffect = Objects.requireNonNullElseGet(item.miss_received_effect, HitReceivedEffect::new);
missReceivedEffectPane.createPaneContent(listener, item.writable, missReceivedEffect);
pane.add(missReceivedEffectPane.effectPane, JideBoxLayout.FIX);
if (item.category == null || item.category.action_type == null || item.category.action_type == ItemCategory.ActionType.none) { if (item.category == null || item.category.action_type == null || item.category.action_type == ItemCategory.ActionType.none) {
equipEffectPane.setVisible(false); equipEffectPane.setVisible(false);
hitEffectPane.effectPane.setVisible(false); hitEffectPane.effectPane.setVisible(false);
hitReceivedEffectPane.effectPane.setVisible(false);
missEffectPane.effectPane.setVisible(false);
missReceivedEffectPane.effectPane.setVisible(false);
killEffectPane.effectPane.setVisible(false); killEffectPane.effectPane.setVisible(false);
} else if (item.category.action_type == ItemCategory.ActionType.use) { } else if (item.category.action_type == ItemCategory.ActionType.use) {
equipEffectPane.setVisible(false); equipEffectPane.setVisible(false);
hitEffectPane.effectPane.setVisible(false); hitEffectPane.effectPane.setVisible(false);
hitReceivedEffectPane.effectPane.setVisible(false);
missEffectPane.effectPane.setVisible(false);
missReceivedEffectPane.effectPane.setVisible(false);
killEffectPane.effectPane.setVisible(true); killEffectPane.effectPane.setVisible(true);
killEffectPane.effectPane.setTitle(useLabel); killEffectPane.effectPane.setTitle(useLabel);
killEffectPane.effectPane.revalidate(); killEffectPane.effectPane.revalidate();
@@ -198,6 +200,9 @@ public class ItemEditor extends JSONElementEditor {
} else if (item.category.action_type == ItemCategory.ActionType.equip) { } else if (item.category.action_type == ItemCategory.ActionType.equip) {
equipEffectPane.setVisible(true); equipEffectPane.setVisible(true);
hitEffectPane.effectPane.setVisible(true); hitEffectPane.effectPane.setVisible(true);
hitReceivedEffectPane.effectPane.setVisible(true);
missEffectPane.effectPane.setVisible(true);
missReceivedEffectPane.effectPane.setVisible(true);
killEffectPane.effectPane.setVisible(true); killEffectPane.effectPane.setVisible(true);
killEffectPane.effectPane.setTitle(killLabel); killEffectPane.effectPane.setTitle(killLabel);
killEffectPane.effectPane.revalidate(); killEffectPane.effectPane.revalidate();
@@ -294,8 +299,8 @@ public class ItemEditor extends JSONElementEditor {
@Override @Override
public void valueChanged(JComponent source, Object value) { public void valueChanged(JComponent source, Object value) {
Item item = (Item) target; Item item = (Item) target;
boolean updatePrice, updateEquip, updateHit, updateKill, updateHitReceived; boolean updatePrice, updateEquip, updateHit, updateMiss, updateKill, updateHitReceived, updateMissReceived;
updatePrice = updateEquip = updateHit = updateKill = updateHitReceived = false; updatePrice = updateEquip = updateHit = updateMiss = updateKill = updateHitReceived = updateMissReceived = false;
if (source == idField) { if (source == idField) {
//Events caused by cancel an ID edition. Dismiss. //Events caused by cancel an ID edition. Dismiss.
if (skipNext) { if (skipNext) {
@@ -362,10 +367,14 @@ public class ItemEditor extends JSONElementEditor {
item.equip_effect = null; item.equip_effect = null;
hitEffectPane.effectPane.setVisible(false); hitEffectPane.effectPane.setVisible(false);
item.hit_effect = null; item.hit_effect = null;
missEffectPane.effectPane.setVisible(false);
item.miss_effect = null;
killEffectPane.effectPane.setVisible(false); killEffectPane.effectPane.setVisible(false);
item.kill_effect = null; item.kill_effect = null;
hitReceivedEffectPane.effectPane.setVisible(false); hitReceivedEffectPane.effectPane.setVisible(false);
item.hit_received_effect = null; item.hit_received_effect = null;
missReceivedEffectPane.effectPane.setVisible(false);
item.miss_received_effect = null;
ItemEditor.this.revalidate(); ItemEditor.this.revalidate();
ItemEditor.this.repaint(); ItemEditor.this.repaint();
} else if (item.category.action_type == ItemCategory.ActionType.use) { } else if (item.category.action_type == ItemCategory.ActionType.use) {
@@ -373,10 +382,14 @@ public class ItemEditor extends JSONElementEditor {
item.equip_effect = null; item.equip_effect = null;
hitEffectPane.effectPane.setVisible(false); hitEffectPane.effectPane.setVisible(false);
item.hit_effect = null; item.hit_effect = null;
missEffectPane.effectPane.setVisible(false);
item.miss_effect = null;
killEffectPane.effectPane.setVisible(true); killEffectPane.effectPane.setVisible(true);
updateKill = true; updateKill = true;
hitReceivedEffectPane.effectPane.setVisible(false); hitReceivedEffectPane.effectPane.setVisible(false);
item.hit_received_effect = null; item.hit_received_effect = null;
missReceivedEffectPane.effectPane.setVisible(false);
item.miss_received_effect = null;
updateHitReceived = true; updateHitReceived = true;
updateEquip = true; updateEquip = true;
killEffectPane.effectPane.setTitle(useLabel); killEffectPane.effectPane.setTitle(useLabel);
@@ -385,9 +398,11 @@ public class ItemEditor extends JSONElementEditor {
} else if (item.category.action_type == ItemCategory.ActionType.equip) { } else if (item.category.action_type == ItemCategory.ActionType.equip) {
equipEffectPane.setVisible(true); equipEffectPane.setVisible(true);
hitEffectPane.effectPane.setVisible(true); hitEffectPane.effectPane.setVisible(true);
missEffectPane.effectPane.setVisible(true);
killEffectPane.effectPane.setVisible(true); killEffectPane.effectPane.setVisible(true);
updateKill = true; updateKill = true;
hitReceivedEffectPane.effectPane.setVisible(true); hitReceivedEffectPane.effectPane.setVisible(true);
missReceivedEffectPane.effectPane.setVisible(true);
updateHitReceived = true; updateHitReceived = true;
updateEquip = true; updateEquip = true;
killEffectPane.effectPane.setTitle(killLabel); killEffectPane.effectPane.setTitle(killLabel);
@@ -469,12 +484,18 @@ public class ItemEditor extends JSONElementEditor {
} else if (hitEffectPane.valueChanged(source, value, item)) { } else if (hitEffectPane.valueChanged(source, value, item)) {
updatePrice = true; updatePrice = true;
updateHit = true; updateHit = true;
} else if (missEffectPane.valueChanged(source, value, item)) {
updatePrice = true;
updateMiss = true;
} else if (killEffectPane.valueChanged(source, value, item)) { } else if (killEffectPane.valueChanged(source, value, item)) {
updatePrice = true; updatePrice = true;
updateKill = true; updateKill = true;
} else if (hitReceivedEffectPane.valueChanged(source, value, item)) { } else if (hitReceivedEffectPane.valueChanged(source, value, item)) {
updatePrice = true; updatePrice = true;
updateHitReceived = true; updateHitReceived = true;
} else if (missReceivedEffectPane.valueChanged(source, value, item)) {
updatePrice = true;
updateMissReceived = true;
} }
if (updateEquip) { if (updateEquip) {
@@ -491,6 +512,13 @@ public class ItemEditor extends JSONElementEditor {
item.hit_effect = hitEffectPane.effect; item.hit_effect = hitEffectPane.effect;
} }
} }
if (updateMiss) {
if (missEffectPane.effect.isNull()) {
item.miss_effect = null;
} else {
item.miss_effect = missEffectPane.effect;
}
}
if (updateKill) { if (updateKill) {
if (killEffectPane.effect.isNull()) { if (killEffectPane.effect.isNull()) {
item.kill_effect = null; item.kill_effect = null;
@@ -505,6 +533,13 @@ public class ItemEditor extends JSONElementEditor {
item.hit_received_effect = hitReceivedEffectPane.effect; item.hit_received_effect = hitReceivedEffectPane.effect;
} }
} }
if (updateMissReceived) {
if (missReceivedEffectPane.effect.isNull()) {
item.miss_received_effect = null;
} else {
item.miss_received_effect = missReceivedEffectPane.effect;
}
}
if (updatePrice && !manualPriceBox.isSelected()) { if (updatePrice && !manualPriceBox.isSelected()) {
baseCostField.setValue(item.computePrice()); baseCostField.setValue(item.computePrice());
} }

View File

@@ -164,7 +164,7 @@ public abstract class JSONElementEditor extends Editor {
ATContentStudio.frame.closeEditor(node); ATContentStudio.frame.closeEditor(node);
node.childrenRemoved(new ArrayList<ProjectTreeNode>()); node.childrenRemoved(new ArrayList<ProjectTreeNode>());
if (node.getParent() instanceof GameDataCategory<?>) { if (node.getParent() instanceof GameDataCategory<?>) {
((GameDataCategory<?>) node.getParent()).remove(node); ((GameDataCategory<?>) node.getParent()).removeGeneric(node);
node.save(); node.save();
GameDataElement newOne = proj.getGameDataElement(node.getClass(), node.id); GameDataElement newOne = proj.getGameDataElement(node.getClass(), node.id);
if (node instanceof Quest) { if (node instanceof Quest) {

View File

@@ -37,6 +37,7 @@ public class NPCEditor extends JSONElementEditor {
private JTextField nameField; private JTextField nameField;
private JTextField spawnGroupField; private JTextField spawnGroupField;
private JTextField factionField; private JTextField factionField;
private JSpinner horizontalFlipChanceField;
private JSpinner experienceField; private JSpinner experienceField;
private MyComboBox dialogueBox; private MyComboBox dialogueBox;
private MyComboBox droplistBox; private MyComboBox droplistBox;
@@ -59,10 +60,9 @@ public class NPCEditor extends JSONElementEditor {
private JSpinner blockChance; private JSpinner blockChance;
private JSpinner dmgRes; private JSpinner dmgRes;
private CommonEditor.HitEffectPane hitEffectPane = new CommonEditor.HitEffectPane("Effect on every hit: ", TimedActorConditionEffect::new, this, null, null); private final CommonEditor.HitEffectPane<HitEffect> hitEffectPane = new CommonEditor.HitEffectPane<>("Effect on every hit: ", this, null, "player");
private CommonEditor.HitRecievedEffectPane hitReceivedEffectPane = new CommonEditor.HitRecievedEffectPane("Effect on every hit received: ", TimedActorConditionEffect::new, this, "NPC", private final CommonEditor.HitReceivedEffectPane<HitReceivedEffect> hitReceivedEffectPane = new CommonEditor.HitReceivedEffectPane<>("Effect on every hit received: ", this, "npc", "player");
"Attacker"); private final CommonEditor.DeathEffectPane<DeathEffect> deathEffectPane = new CommonEditor.DeathEffectPane<>("Effect when killed: ", this, null);
private CommonEditor.DeathEffectPane deathEffectPane = new CommonEditor.DeathEffectPane("Effect when killed: ", TimedActorConditionEffect::new, this, "Killer");
private JPanel dialogueGraphPane; private JPanel dialogueGraphPane;
private DialogueGraphView dialogueGraphView; private DialogueGraphView dialogueGraphView;
@@ -117,7 +117,6 @@ public class NPCEditor extends JSONElementEditor {
} }
} }
@SuppressWarnings({"rawtypes", "unchecked"})
@Override @Override
public void insertFormViewDataField(JPanel pane) { public void insertFormViewDataField(JPanel pane) {
final NPC npc = (NPC) target; final NPC npc = (NPC) target;
@@ -130,6 +129,7 @@ public class NPCEditor extends JSONElementEditor {
nameField = addTranslatableTextField(pane, "Display name: ", npc.name, npc.writable, listener); nameField = addTranslatableTextField(pane, "Display name: ", npc.name, npc.writable, listener);
spawnGroupField = addTextField(pane, "Spawn group ID: ", npc.spawngroup_id, npc.writable, listener); spawnGroupField = addTextField(pane, "Spawn group ID: ", npc.spawngroup_id, npc.writable, listener);
factionField = addTextField(pane, "Faction ID: ", npc.faction_id, npc.writable, listener); factionField = addTextField(pane, "Faction ID: ", npc.faction_id, npc.writable, listener);
horizontalFlipChanceField = addIntegerField(pane, "Horizontal flip chance: ", npc.horizontalFlipChance, false, npc.writable, listener);
experienceField = addIntegerField(pane, "Experience reward: ", npc.getMonsterExperience(), false, false, listener); experienceField = addIntegerField(pane, "Experience reward: ", npc.getMonsterExperience(), false, false, listener);
dialogueBox = addDialogueBox(pane, npc.getProject(), "Initial phrase: ", npc.dialogue, npc.writable, listener); dialogueBox = addDialogueBox(pane, npc.getProject(), "Initial phrase: ", npc.dialogue, npc.writable, listener);
droplistBox = addDroplistBox(pane, npc.getProject(), "Droplist / Shop inventory: ", npc.droplist, npc.writable, listener); droplistBox = addDroplistBox(pane, npc.getProject(), "Droplist / Shop inventory: ", npc.droplist, npc.writable, listener);
@@ -151,23 +151,15 @@ public class NPCEditor extends JSONElementEditor {
dmgRes = addIntegerField(combatTraitPane, "Damage resistance: ", npc.damage_resistance, false, npc.writable, listener); dmgRes = addIntegerField(combatTraitPane, "Damage resistance: ", npc.damage_resistance, false, npc.writable, listener);
HitEffect hitEffect = Objects.requireNonNullElseGet(npc.hit_effect, HitEffect::new); HitEffect hitEffect = Objects.requireNonNullElseGet(npc.hit_effect, HitEffect::new);
hitEffectPane.createHitEffectPaneContent(listener, npc.writable, hitEffect, hitEffectPane.createPaneContent(listener, npc.writable, hitEffect);
new CommonEditor.SourceTimedConditionsListModel(hitEffect),
new CommonEditor.TargetTimedConditionsListModel(hitEffect));
combatTraitPane.add(hitEffectPane.effectPane, JideBoxLayout.FIX); combatTraitPane.add(hitEffectPane.effectPane, JideBoxLayout.FIX);
HitReceivedEffect hitReceivedEffect = Objects.requireNonNullElseGet(npc.hit_received_effect, HitReceivedEffect hitReceivedEffect = Objects.requireNonNullElseGet(npc.hit_received_effect, HitReceivedEffect::new);
HitReceivedEffect::new); hitReceivedEffectPane.createPaneContent(listener, npc.writable, hitReceivedEffect);
hitReceivedEffectPane.createHitReceivedEffectPaneContent(listener, npc.writable, hitReceivedEffect,
new CommonEditor.SourceTimedConditionsListModel(
hitReceivedEffect),
new CommonEditor.TargetTimedConditionsListModel(
hitReceivedEffect));
combatTraitPane.add(hitReceivedEffectPane.effectPane, JideBoxLayout.FIX); combatTraitPane.add(hitReceivedEffectPane.effectPane, JideBoxLayout.FIX);
DeathEffect deathEffect = Objects.requireNonNullElseGet(npc.death_effect, DeathEffect::new); DeathEffect deathEffect = Objects.requireNonNullElseGet(npc.death_effect, DeathEffect::new);
deathEffectPane.createDeathEffectPaneContent(listener, npc.writable, deathEffect, deathEffectPane.createPaneContent(listener, npc.writable, deathEffect);
new CommonEditor.SourceTimedConditionsListModel(deathEffect));
combatTraitPane.add(deathEffectPane.effectPane, JideBoxLayout.FIX); combatTraitPane.add(deathEffectPane.effectPane, JideBoxLayout.FIX);
pane.add(combatTraitPane, JideBoxLayout.FIX); pane.add(combatTraitPane, JideBoxLayout.FIX);
@@ -215,6 +207,8 @@ public class NPCEditor extends JSONElementEditor {
npc.spawngroup_id = (String) value; npc.spawngroup_id = (String) value;
} else if (source == factionField) { } else if (source == factionField) {
npc.faction_id = (String) value; npc.faction_id = (String) value;
} else if (source == horizontalFlipChanceField) {
npc.horizontalFlipChance = (Integer) value;
} else if (source == dialogueBox) { } else if (source == dialogueBox) {
if (npc.dialogue != null) { if (npc.dialogue != null) {
npc.dialogue.removeBacklink(npc); npc.dialogue.removeBacklink(npc);

View File

@@ -674,6 +674,16 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
requirementObjId = addTextField(pane, "Time type HHMMSS:", requirement.required_obj_id, writable, listener); requirementObjId = addTextField(pane, "Time type HHMMSS:", requirement.required_obj_id, writable, listener);
requirementValue = addIntegerField(pane, "Exact time value: ", requirement.required_value, true, writable, listener); requirementValue = addIntegerField(pane, "Exact time value: ", requirement.required_value, true, writable, listener);
break; break;
case skillIncrease:
skillId = null;
try {
skillId = requirement.required_obj_id == null ? null : Requirement.SkillID.valueOf(requirement.required_obj_id);
} catch (IllegalArgumentException e) {
}
requirementObj = addEnumValueBox(pane, "Skill ID:", Requirement.SkillID.values(), skillId, writable, listener);
requirementObjId = null;//addTextField(pane, "Skill ID:", requirement.required_obj_id, writable, listener);
requirementValue = addIntegerField(pane, "Level: ", requirement.required_value, false, writable, listener);
break;
} }
} }
requirementNegated = addBooleanBasedCheckBox(pane, "Negate this requirement.", requirement.negated, writable, listener); requirementNegated = addBooleanBasedCheckBox(pane, "Negate this requirement.", requirement.negated, writable, listener);
@@ -1921,7 +1931,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} else if (source == requirementObj) { } else if (source == requirementObj) {
if (selectedMapObject instanceof KeyArea) { if (selectedMapObject instanceof KeyArea) {
KeyArea area = (KeyArea) selectedMapObject; KeyArea area = (KeyArea) selectedMapObject;
if (area.requirement.type == Requirement.RequirementType.skillLevel) { if (area.requirement.type == Requirement.RequirementType.skillLevel || area.requirement.type == Requirement.RequirementType.skillIncrease) {
area.requirement.required_obj_id = value == null ? null : value.toString(); area.requirement.required_obj_id = value == null ? null : value.toString();
} else { } else {
area.requirement.required_obj = (GameDataElement) value; area.requirement.required_obj = (GameDataElement) value;
@@ -1938,7 +1948,7 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
} }
} else if (selectedMapObject instanceof ReplaceArea) { } else if (selectedMapObject instanceof ReplaceArea) {
ReplaceArea area = (ReplaceArea) selectedMapObject; ReplaceArea area = (ReplaceArea) selectedMapObject;
if (area.requirement.type == Requirement.RequirementType.skillLevel) { if (area.requirement.type == Requirement.RequirementType.skillLevel || area.requirement.type == Requirement.RequirementType.skillIncrease) {
area.requirement.required_obj_id = value == null ? null : value.toString(); area.requirement.required_obj_id = value == null ? null : value.toString();
} else { } else {
area.requirement.required_obj = (GameDataElement) value; area.requirement.required_obj = (GameDataElement) value;

View File

@@ -1,30 +0,0 @@
package com.gpl.rpg.atcontentstudio.ui.saves;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.Editor;
import javax.swing.*;
import java.awt.*;
public class SavedGameEditor extends Editor {
private static final long serialVersionUID = 6055910379650778737L;
public SavedGameEditor(SavedGame save) {
this.name = save.loadedSave.displayInfo;
this.icon = new ImageIcon(DefaultIcons.getHeroIcon());
this.target = save;
setLayout(new BorderLayout());
add(new JScrollPane(new com.gpl.rpg.andorstrainer.ui.SavedGameEditor(save.loadedSave, ATContentStudio.frame)), BorderLayout.CENTER);
}
@Override
public void targetUpdated() {
// TODO Auto-generated method stub
}
}

View File

@@ -53,9 +53,14 @@ public class SpritesheetEditor extends Editor {
public SpritesheetEditor(Spritesheet sheet) { public SpritesheetEditor(Spritesheet sheet) {
super(); super();
this.icon = new ImageIcon(sheet.getIcon(0));
this.name = sheet.id; this.name = sheet.id;
this.target = sheet; this.target = sheet;
Image icon = sheet.getIcon(0);
if (icon == null) {
Notification.addError("Unable to open spritesheet " + sheet.id + " because the image is missing. This might be because its an UI spritesheet, which is not supported in ATCS");
return;
}
this.icon = new ImageIcon(icon);
JPanel pane = new JPanel(); JPanel pane = new JPanel();

View File

@@ -1,219 +1,309 @@
package com.gpl.rpg.atcontentstudio.utils; package com.gpl.rpg.atcontentstudio.utils;
import java.io.*; import com.gpl.rpg.atcontentstudio.Notification;
import java.nio.file.Files; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import java.nio.file.Path; import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import java.nio.file.Paths; import org.json.simple.JSONArray;
import java.nio.file.StandardCopyOption; import org.json.simple.JSONObject;
import java.util.zip.ZipEntry; import org.json.simple.parser.JSONParser;
import java.util.zip.ZipOutputStream; import org.json.simple.parser.ParseException;
public class FileUtils { import java.io.*;
import java.nio.file.Files;
public static void deleteDir(File dir) { import java.nio.file.Path;
if (dir.exists()) { import java.nio.file.Paths;
for (File f : dir.listFiles()) { import java.nio.file.StandardCopyOption;
if (f.isDirectory()) { import java.util.List;
deleteDir(f); import java.util.Map;
} else { import java.util.zip.ZipEntry;
f.delete(); import java.util.zip.ZipOutputStream;
}
} public class FileUtils {
dir.delete(); public static String toJsonString(JsonSerializable jsonSerializable) {
} return toJsonString(jsonSerializable.toMap());
} }
public static String toJsonString(Map json) {
public static void copyFile(File sourceLocation, File targetLocation) { StringWriter writer = new JsonPrettyWriter();
try { try {
InputStream in = new FileInputStream(sourceLocation); JSONObject.writeJSONString(json, writer);
OutputStream out = new FileOutputStream(targetLocation); } catch (IOException e) {
//Impossible with a StringWriter
// Copy the bits from instream to outstream }
byte[] buf = new byte[1024]; return writer.toString();
int len; }
try { public static String toJsonString(List json) {
while ((len = in.read(buf)) > 0) { StringWriter writer = new JsonPrettyWriter();
out.write(buf, 0, len); try {
} JSONArray.writeJSONString(json, writer);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block //Impossible with a StringWriter
} finally { }
try { return writer.toString();
in.close(); }
} catch (IOException e) {
// TODO Auto-generated catch block public static Object fromJsonString(String json) {
} Object o;
try { try {
out.close(); JSONParser parser = new JSONParser();
} catch (IOException e) { o = parser.parse(json);
// TODO Auto-generated catch block } catch (ParseException e) {
} throw new RuntimeException(e);
} }
} catch (FileNotFoundException e1) { return o;
// TODO Auto-generated catch block }
}
} public static Map mapFromJsonFile(File file){
String json = readFileToString(file);
private static final int BUFFER = 2048; if (json == null) {
return null;
public static void writeToZip(File folder, File target) { }
try { Map map = (Map)FileUtils.fromJsonString(json);
FileOutputStream dest = new FileOutputStream(target); return map;
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); }
zipDir(folder, "", out);
out.flush(); public static boolean writeStringToFile(String toWrite, File file, String type) {
out.close(); return writeStringToFile(toWrite, file, type, true);
} catch (Exception e) { }
// TODO Auto-generated catch block public static boolean writeStringToFile(String toWrite, File file, String type, boolean notifyOnSuccess) {
e.printStackTrace(); try {
} FileWriter w = new FileWriter(file);
w.write(toWrite);
} w.close();
if(type != null) {
/** Notification.addSuccess(type + " saved.");
* cp sourceFolder/* targetFolder/ }
* return true;
* @param sourceFolder } catch (IOException e) {
* @param targetFolder if(type != null) {
*/ Notification.addError("Error while saving " + type + " : " + e.getMessage());
public static void copyOver(File sourceFolder, File targetFolder) { }
if (!sourceFolder.isDirectory() || !targetFolder.isDirectory()) return; e.printStackTrace();
for (File f : sourceFolder.listFiles()) { return false;
if (Files.isSymbolicLink(f.toPath())) { }
//Skip symlinks }
continue;
} else if (f.isDirectory()) { public static String readFileToString(File settingsFile) {
File dest = new File(targetFolder, f.getName()); String json;
if (!dest.exists()) { try{
dest.mkdir(); FileReader file = new FileReader(settingsFile);
} BufferedReader reader = new BufferedReader(file);
copyOver(f, dest); StringBuilder builder = new StringBuilder();
} else { int c;
copyFile(f, new File(targetFolder, f.getName())); while ((c = reader.read()) != -1) {
} builder.append((char) c);
} }
} json = builder.toString();
}catch (IOException e){
private static void zipDir(File dir, String prefix, ZipOutputStream zos) { json = null;
if (prefix != "") { e.printStackTrace();
prefix = prefix + File.separator; }
} return json;
for (File f : dir.listFiles()) { }
if (f.isDirectory()) {
zipDir(f, prefix + f.getName(), zos); public static void deleteDir(File dir) {
} else { if (dir.exists()) {
FileInputStream fis; for (File f : dir.listFiles()) {
try { if (f.isDirectory()) {
fis = new FileInputStream(f); deleteDir(f);
BufferedInputStream origin = new BufferedInputStream(fis, BUFFER); } else {
ZipEntry entry = new ZipEntry(prefix + f.getName()); f.delete();
try { }
zos.putNextEntry(entry); }
int count; dir.delete();
byte data[] = new byte[BUFFER]; }
while ((count = origin.read(data, 0, BUFFER)) != -1) { }
zos.write(data, 0, count);
zos.flush(); public static void copyFile(File sourceLocation, File targetLocation) {
} try {
} catch (IOException e) { InputStream in = new FileInputStream(sourceLocation);
// TODO Auto-generated catch block OutputStream out = new FileOutputStream(targetLocation);
e.printStackTrace();
} finally { // Copy the bits from instream to outstream
try { byte[] buf = new byte[1024];
origin.close(); int len;
} catch (IOException e) { try {
// TODO Auto-generated catch block while ((len = in.read(buf)) > 0) {
e.printStackTrace(); out.write(buf, 0, len);
} }
} } catch (IOException e) {
} catch (FileNotFoundException e) { // TODO Auto-generated catch block
// TODO Auto-generated catch block } finally {
e.printStackTrace(); try {
} in.close();
} } catch (IOException e) {
} // TODO Auto-generated catch block
} }
try {
public static boolean makeSymlink(File targetFile, File linkFile) { out.close();
Path target = Paths.get(targetFile.getAbsolutePath()); } catch (IOException e) {
Path link = Paths.get(linkFile.getAbsolutePath()); // TODO Auto-generated catch block
if (!Files.exists(link)) { }
try { }
Files.createSymbolicLink(link, target); } catch (FileNotFoundException e1) {
} catch (Exception e) { // TODO Auto-generated catch block
System.err.println("Failed to create symbolic link to target \"" + targetFile.getAbsolutePath() + "\" as \"" + linkFile.getAbsolutePath() + "\" the java.nio way:"); }
e.printStackTrace(); }
switch (DesktopIntegration.detectedOS) {
case Windows: private static final int BUFFER = 2048;
System.err.println("Trying the Windows way with mklink");
try { public static void writeToZip(File folder, File target) {
Runtime.getRuntime().exec( try {
"cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\""); FileOutputStream dest = new FileOutputStream(target);
} catch (IOException e1) { ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
e1.printStackTrace(); zipDir(folder, "", out);
} out.flush();
if (!linkFile.exists()) { out.close();
System.err.println("Attempting UAC elevation through VBS script."); } catch (Exception e) {
runWithUac("cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"", 3, linkFile); // TODO Auto-generated catch block
} e.printStackTrace();
break; }
case MacOS:
case NIX: }
case Other:
System.err.println("Trying the unix way with ln -s"); /**
try { * cp sourceFolder/* targetFolder/
Runtime.getRuntime().exec("ln -s " + targetFile.getAbsolutePath() + " " + linkFile.getAbsolutePath()); *
} catch (IOException e1) { * @param sourceFolder
e1.printStackTrace(); * @param targetFolder
} */
break; public static void copyOver(File sourceFolder, File targetFolder) {
default: if (!sourceFolder.isDirectory() || !targetFolder.isDirectory()) return;
System.out.println("Unrecognized OS. Please contact ATCS dev."); for (File f : sourceFolder.listFiles()) {
break; if (Files.isSymbolicLink(f.toPath())) {
//Skip symlinks
} continue;
} } else if (f.isDirectory()) {
} File dest = new File(targetFolder, f.getName());
if (!Files.exists(link)) { if (!dest.exists()) {
System.err.println("Failed to create link \"" + linkFile.getAbsolutePath() + "\" targetting \"" + targetFile.getAbsolutePath() + "\""); dest.mkdir();
System.err.println("You can try running ATCS with administrative privileges once, or create the symbolic link manually."); }
} copyOver(f, dest);
return true; } else {
} copyFile(f, new File(targetFolder, f.getName()));
}
public static File backupFile(File f) { }
try { }
Path returned = Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(f.getAbsolutePath() + ".bak"), StandardCopyOption.REPLACE_EXISTING);
return returned.toFile(); private static void zipDir(File dir, String prefix, ZipOutputStream zos) {
} catch (IOException e) { if (prefix != "") {
e.printStackTrace(); prefix = prefix + File.separator;
} }
return null; for (File f : dir.listFiles()) {
} if (f.isDirectory()) {
zipDir(f, prefix + f.getName(), zos);
static final String uacBatName = "ATCS_elevateWithUac.bat"; } else {
FileInputStream fis;
public static void runWithUac(String command, int tries, File checkExists) { try {
File tmpFolder = new File(System.getProperty("java.io.tmpdir")); fis = new FileInputStream(f);
File batFile = new File(tmpFolder, uacBatName); BufferedInputStream origin = new BufferedInputStream(fis, BUFFER);
batFile.deleteOnExit(); ZipEntry entry = new ZipEntry(prefix + f.getName());
FileWriter writer; try {
try { zos.putNextEntry(entry);
writer = new FileWriter(batFile, false); int count;
writer.write( byte data[] = new byte[BUFFER];
"@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n" while ((count = origin.read(data, 0, BUFFER)) != -1) {
+ "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n" zos.write(data, 0, count);
+ "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n" zos.flush();
+ "@cscript %temp%\\sudo.tmp.vbs\r\n" }
+ "del /f %temp%\\sudo.tmp.vbs\r\n"); } catch (IOException e) {
writer.close(); // TODO Auto-generated catch block
while (!checkExists.exists() && tries-- > 0) { e.printStackTrace();
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", batFile.getAbsolutePath() + " " + command}); } finally {
} try {
} catch (IOException e) { origin.close();
e.printStackTrace(); } catch (IOException e) {
} // TODO Auto-generated catch block
e.printStackTrace();
} }
}
} } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static boolean makeSymlink(File targetFile, File linkFile) {
Path target = Paths.get(targetFile.getAbsolutePath());
Path link = Paths.get(linkFile.getAbsolutePath());
if (!Files.exists(link)) {
try {
Files.createSymbolicLink(link, target);
} catch (Exception e) {
System.err.println("Failed to create symbolic link to target \"" + targetFile.getAbsolutePath() + "\" as \"" + linkFile.getAbsolutePath() + "\" the java.nio way:");
e.printStackTrace();
switch (DesktopIntegration.detectedOS) {
case Windows:
System.err.println("Trying the Windows way with mklink");
try {
Runtime.getRuntime().exec(
"cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"");
} catch (IOException e1) {
e1.printStackTrace();
}
if (!linkFile.exists()) {
System.err.println("Attempting UAC elevation through VBS script.");
runWithUac("cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"", 3, linkFile);
}
break;
case MacOS:
case NIX:
case Other:
System.err.println("Trying the unix way with ln -s");
try {
Runtime.getRuntime().exec("ln -s " + targetFile.getAbsolutePath() + " " + linkFile.getAbsolutePath());
} catch (IOException e1) {
e1.printStackTrace();
}
break;
default:
System.out.println("Unrecognized OS. Please contact ATCS dev.");
break;
}
}
}
if (!Files.exists(link)) {
System.err.println("Failed to create link \"" + linkFile.getAbsolutePath() + "\" targetting \"" + targetFile.getAbsolutePath() + "\"");
System.err.println("You can try running ATCS with administrative privileges once, or create the symbolic link manually.");
}
return true;
}
public static File backupFile(File f) {
try {
Path returned = Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(f.getAbsolutePath() + ".bak"), StandardCopyOption.REPLACE_EXISTING);
return returned.toFile();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
static final String uacBatName = "ATCS_elevateWithUac.bat";
public static void runWithUac(String command, int tries, File checkExists) {
File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
File batFile = new File(tmpFolder, uacBatName);
batFile.deleteOnExit();
FileWriter writer;
try {
writer = new FileWriter(batFile, false);
writer.write(
"@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n"
+ "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n"
+ "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n"
+ "@cscript %temp%\\sudo.tmp.vbs\r\n"
+ "del /f %temp%\\sudo.tmp.vbs\r\n");
writer.close();
while (!checkExists.exists() && tries-- > 0) {
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", batFile.getAbsolutePath() + " " + command});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}