Compare commits

...

163 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
090584dbcc add warning about icon 2025-07-13 02:25:01 +02:00
OMGeeky
e858e436c6 Merge remote-tracking branch 'origin/master' into dedup-1
# Conflicts:
#	src/com/gpl/rpg/atcontentstudio/ATContentStudio.java
#	src/com/gpl/rpg/atcontentstudio/model/gamedata/NPC.java
2025-07-13 02:21:49 +02:00
OMGeeky
4b2aa77cb6 refactor to keep compatibility with old java version (openjdk-11 tested) 2025-07-03 20:16:36 +02:00
OMGeeky
24e1e526ce refactor to keep compatibility with old java version (openjdk-11 tested) 2025-07-03 20:05:00 +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
OMGeeky
1cbcd5b661 remove finished todo list 2025-06-24 20:36:59 +02:00
OMGeeky
0eddd25292 delete inspectionProfile 2025-06-24 20:29:43 +02:00
OMGeeky
1c83eedd80 format 2025-06-24 20:10:18 +02:00
OMGeeky
6c296868c0 add null check 2025-06-24 19:50:35 +02:00
OMGeeky
8f5452b487 add myself to Contributor list 2025-06-24 19:11:56 +02:00
OMGeeky
f9f1caafc6 extract some code 2025-06-24 18:57:53 +02:00
OMGeeky
c0e24b4cf5 fix bug, where condition buttons are enabled in readonly mode 2025-06-24 18:45:15 +02:00
OMGeeky
cd36813050 move some things around and make the code sturdier 2025-06-24 18:40:54 +02:00
OMGeeky
358d855eec fix number comparison bugs 2025-06-24 18:11:24 +02:00
OMGeeky
281e314815 extract ConditionEffectEditorPane 2025-06-24 18:00:47 +02:00
OMGeeky
3f19ca959b improve code a bit 2025-06-24 16:51:29 +02:00
OMGeeky
6b74ad5cbe fix bug, where some values were not being updated when switching category to a different action type 2025-06-24 16:40:42 +02:00
OMGeeky
93e44a2b50 improve *EffectPane initialisation 2025-06-24 16:39:46 +02:00
OMGeeky
652da07cc8 change warning message when no action type can be determined for an item when writing 2025-06-24 16:30:49 +02:00
OMGeeky
2dbe881dd7 change ItemEditor to use *EffectPane classes 2025-06-24 16:25:13 +02:00
OMGeeky
b7e9bf0582 move ListModels to CommonEditor for re-use 2025-06-24 16:07:50 +02:00
OMGeeky
6dcd8599b3 reformat CommonEditor 2025-06-24 15:38:55 +02:00
OMGeeky
62ed795fed add codeStyle to git 2025-06-24 15:38:41 +02:00
OMGeeky
ec04b810d9 fix bug 2025-06-24 15:23:44 +02:00
OMGeeky
18b92a3921 add valueChanged override for HitRecievedEffectPane 2025-06-24 15:16:36 +02:00
OMGeeky
127ed76006 improve isNull check 2025-06-24 14:53:59 +02:00
OMGeeky
56242e85f2 check TODOs 2025-06-24 14:44:45 +02:00
OMGeeky
de2b47821b add TODOs that need to be done before finishing. 2025-06-23 22:12:16 +02:00
OMGeeky
7eb60117c4 fix bug in writeMinMaxToMap 2025-06-23 22:09:45 +02:00
OMGeeky
0c69438a33 move the hitReceivedEffect fields to the correct position 2025-06-23 21:55:08 +02:00
OMGeeky
380bb1de17 improve DeathEffectPane generics & inheritance 2025-06-23 21:47:36 +02:00
OMGeeky
9ae9914dde cleanup 2025-06-23 21:29:09 +02:00
OMGeeky
c78fcde633 extract hitReceivedEffect stuff into HitReceivedEffectPane 2025-06-23 21:29:02 +02:00
OMGeeky
270c613f66 add applyToTargetHint to HitEffectPanel 2025-06-23 21:17:44 +02:00
OMGeeky
ebafae7503 extract some valueChanged stuff for DeathEffectPane & HitEffectPane 2025-06-23 21:03:04 +02:00
OMGeeky
572c658b43 change some constructor stuff for it and switch the deathEffectPane to the new DeathEffectPane class 2025-06-23 20:41:40 +02:00
OMGeeky
5031fa3c72 rename some stuff 2025-06-23 19:58:22 +02:00
OMGeeky
7f0b55a71c add possibility for hint where the effect is applied to 2025-06-23 18:57:59 +02:00
OMGeeky
ab91d330bd extract parts of HitEffectPane into DeathEffectPane for better usage 2025-06-23 18:51:04 +02:00
OMGeeky
27a86ee654 continue to extract HitEffectPane 2025-06-23 18:43:54 +02:00
OMGeeky
ad15063dcc start to extract HitEffectPane 2025-06-23 18:23:54 +02:00
OMGeeky
2ea425dda6 use isImmunity & isClear & isInfinite more 2025-06-23 18:20:52 +02:00
OMGeeky
f22052525c change wrong ConditionsCellRenderer to TimedConditionsCellRenderer 2025-06-23 17:37:13 +02:00
OMGeeky
63e381a804 move ConditionsCellRenderer to CommonEditor 2025-06-23 17:35:46 +02:00
OMGeeky
488dd92893 extract actorConditionElementChanged + some parse stuff 2025-06-23 17:25:39 +02:00
OMGeeky
f04f062723 extract some more toJson stuff to reduce duplication 2025-06-23 16:24:47 +02:00
OMGeeky
e91f770975 extract some toJson stuff to reduce duplication 2025-06-23 16:08:21 +02:00
OMGeeky
7018703ba6 extract linkIcon 2025-06-23 15:15:16 +02:00
OMGeeky
93f0a902ba extract linkEffects 2025-06-23 15:09:52 +02:00
OMGeeky
1ca2b9068e extract isImmunity & isClear & isInfinite 2025-06-23 15:09:41 +02:00
OMGeeky
a7f214a1cb extract TimedConditionsCellRenderer into CommonEditor 2025-06-23 14:35:27 +02:00
OMGeeky
b2c05037e5 use BasicEffect for HitReceivedEffect values to reuse logic 2025-06-23 14:31:50 +02:00
OMGeeky
517a798b6f extract BasicEffect and rename TimedConditionEffect to TimedActorConditionEffect 2025-06-23 14:31:06 +02:00
OMGeeky
e9fecee876 extract some code into updateConditionEffect (ITEM & NPC) 2025-06-23 14:03:13 +02:00
OMGeeky
967bbf918b extract some more CollapsibleItemLists (in ItemEditor) 2025-06-23 13:21:07 +02:00
OMGeeky
5ce84dc1b1 extract some CollapsibleItemLists (in ItemEditor) 2025-06-23 13:02:03 +02:00
OMGeeky
0a18309bfe remove some leftover code 2025-06-23 12:36:54 +02:00
OMGeeky
edc4634cbe extract some CollapsibleItemLists (in QUEST & NPC) 2025-06-22 20:03:18 +02:00
OMGeeky
1e25eabb50 fix deprecated warnings 2025-06-22 19:13:58 +02:00
OMGeeky
1c7de2b97f misc 2025-06-22 18:57:44 +02:00
OMGeeky
e40fe058dd fix oversight, where changes would call the wrong event 2025-06-22 18:57:37 +02:00
OMGeeky
919e65187f improve addNumberField 2025-06-22 18:55:05 +02:00
OMGeeky
7b780462ea handle wrong values passed to addNumberField better 2025-06-22 17:48:12 +02:00
OMGeeky
00147c2708 extract one CollapsibleItemList defs in ItemEditor 2025-06-21 21:07:45 +02:00
OMGeeky
70cc945010 misc 2025-06-21 20:24:33 +02:00
OMGeeky
21005f1ba6 improve bounds check in getElementAt 2025-06-21 20:16:57 +02:00
OMGeeky
b5a6aa6706 rename some stuff and be more specific on some usages 2025-06-21 20:16:05 +02:00
OMGeeky
3cc6eb9edb enable buttons to move up and down on all (extracted) list panels 2025-06-21 20:01:01 +02:00
OMGeeky
d166e49f4d extract common stuff of addIntegerField & addDoubleField 2025-06-21 19:25:44 +02:00
OMGeeky
d1568cd2ed extract common stuff of addTextField & addTextArea 2025-06-21 19:10:03 +02:00
OMGeeky
685ce223da extract refresh button creation 2025-06-21 19:09:35 +02:00
OMGeeky
18cb73385f remove Unnecessary semicolons 2025-06-21 18:37:54 +02:00
OMGeeky
90359bf285 reformat all code 2025-06-21 18:36:37 +02:00
OMGeeky
bb187621b7 remove a bunch of unused assignments 2025-06-21 18:19:25 +02:00
OMGeeky
a4b431efdd remove some commented out code from earlier 2025-06-21 17:59:59 +02:00
OMGeeky
cffbf973e1 change more ListModel implementations to more specific implementations
like ListenerListModel, ListenerCollectionModel or OrderedListenerListModel
2025-06-21 17:59:59 +02:00
OMGeeky
979a7bc43f add interface ListenerCollectionModel and use it in the OrderedListenerListModel 2025-06-21 17:59:59 +02:00
OMGeeky
6b049d3b7b rename CustomListModel to OrderedListenerListModel 2025-06-21 17:59:59 +02:00
OMGeeky
edd0160c9d extract some code into ListenerListModel interface 2025-06-21 17:59:59 +02:00
OMGeeky
fdcc4fab55 extract some code 2025-06-21 17:59:59 +02:00
OMGeeky
d030e11019 change more ListModel implementations to CustomListModel 2025-06-21 17:59:59 +02:00
OMGeeky
333100b19b add more ListModel to CustomListModel changes 2025-06-21 17:59:59 +02:00
OMGeeky
cfb906736d extract into sub-methods 2025-06-21 17:59:59 +02:00
OMGeeky
cf8c0497bc add navigation to getCollapsibleItemList 2025-06-21 17:59:59 +02:00
OMGeeky
355bb2bc54 extract collapsibleItemList with buttons into method
this is currently done for
- items in a droplist
- replies
- rewards

others should follow
2025-06-21 17:59:59 +02:00
OMGeeky
e1e85d7a90 extract into CustomListModel 2025-06-01 20:26:18 +02:00
OMGeeky
9ed9393b16 extract wordWrap to TextUtils helper-class 2025-06-01 19:24:24 +02:00
OMGeeky
8c42b498b0 rename needsToBeLinked to linkCheck and continue dedupe 2025-06-01 19:16:59 +02:00
OMGeeky
8561415574 dedup link check 2025-06-01 19:01:35 +02:00
OMGeeky
185f168b19 misc 2025-06-01 18:52:12 +02:00
OMGeeky
70055be6d2 improve usings 2025-05-03 20:16:57 +02:00
OMGeeky
286d95d83d improve imports 2025-05-03 20:14:45 +02:00
OMGeeky
04b704daf0 more de-duplication 2025-05-03 20:10:36 +02:00
OMGeeky
3f1f988808 fix missed null check 2025-05-03 20:07:28 +02:00
OMGeeky
e232c33339 more de-duplication 2025-05-03 20:07:28 +02:00
OMGeeky
4239beb825 de-dupe code 2025-05-03 20:07:28 +02:00
144 changed files with 30261 additions and 33976 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>

19
.idea/codeStyles/Project.xml generated Normal file
View File

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

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Binary file not shown.

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,28 +1,6 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import java.awt.Image; import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet; import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
@@ -32,263 +10,317 @@ import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class GameSource implements ProjectTreeNode, Serializable { import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.*;
private static final long serialVersionUID = -1512979360971918158L; public class GameSource implements ProjectTreeNode, Serializable, JsonSerializable {
public static final String DEFAULT_REL_PATH_FOR_GAME_RESOURCE = "res"+File.separator+"values"+File.separator+"loadresources.xml";
public static final String DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE = "res"+File.separator+"values"+File.separator+"loadresources_debug.xml";
public transient GameDataSet gameData;
public transient TMXMapSet gameMaps;
public transient SpriteSheetSet gameSprites;
public transient Worldmap worldmap;
public transient WriterModeDataSet writerModeDataSet;
private transient SavedSlotCollection v;
public static enum Type {
source,
referenced,
altered,
created
}
public File baseFolder;
public Type type;
public transient Project parent = null;
public transient Map<String, List<String>> referencedSourceFiles = null;
public GameSource(File folder, Project parent) {
this.parent = parent;
this.baseFolder = folder;
this.type = Type.source;
initData();
}
public GameSource(Project parent, Type type) {
this.parent = parent;
this.baseFolder = new File(parent.baseFolder, type.toString());
this.type = type;
initData();
}
public void refreshTransients(Project p) {
parent = p;
initData();
}
public void initData() { private static final long serialVersionUID = -1512979360971918158L;
if (type == Type.source) {
if (parent.sourceSetToUse == ResourceSet.gameData || parent.sourceSetToUse == ResourceSet.debugData) { public static final String DEFAULT_REL_PATH_FOR_GAME_RESOURCE = "res" + File.separator + "values" + File.separator + "loadresources.xml";
referencedSourceFiles = new LinkedHashMap<String, List<String>>(); public static final String DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE = "res" + File.separator + "values" + File.separator + "loadresources_debug.xml";
readResourceList();
} public transient GameDataSet gameData;
} public transient TMXMapSet gameMaps;
if (type == Type.created) { public transient SpriteSheetSet gameSprites;
this.writerModeDataSet = new WriterModeDataSet(this); public transient Worldmap worldmap;
} public transient WriterModeDataSet writerModeDataSet;
this.gameData = new GameDataSet(this); private transient SavedSlotCollection v;
this.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this);
this.worldmap = new Worldmap(this); @Override
v = new SavedSlotCollection(); public Map toMap() {
v.add(gameData); Map map = new HashMap();
v.add(gameMaps); map.put("type", type.toString());
v.add(gameSprites); map.put("baseFolder", baseFolder.getPath());
v.add(worldmap); return map;
if (type == Type.created) { }
v.add(writerModeDataSet);
} @Override
} public void fromMap(Map map) {
if(map==null)return;
public void readResourceList() { type = Enum.valueOf(Type.class, (String)map.get("type"));
File xmlFile = null; baseFolder = new File((String) map.get("baseFolder"));
if (parent.sourceSetToUse == ResourceSet.gameData) { }
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_GAME_RESOURCE);
} else if (parent.sourceSetToUse == ResourceSet.debugData) { public static enum Type {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE); source,
} else { referenced,
return; altered,
} created
}
if (!xmlFile.exists()) return;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); public File baseFolder;
Document doc; public Type type;
try {
factory.setIgnoringComments(true); public transient Project parent;
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false); public transient Map<String, List<String>> referencedSourceFiles = null;
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(xmlFile)); public GameSource(Map json, Project parent) {
fromMap(json);
refreshTransients(parent);
}
public GameSource(File folder, Project parent) {
this.parent = parent;
this.baseFolder = folder;
this.type = Type.source;
initData();
}
public GameSource(Project parent, Type type) {
this.parent = parent;
this.baseFolder = new File(parent.baseFolder, type.toString());
this.type = type;
initData();
}
public void refreshTransients(Project p) {
parent = p;
initData();
}
public void initData() {
if (type == Type.source) {
if (parent.sourceSetToUse == ResourceSet.gameData || parent.sourceSetToUse == ResourceSet.debugData) {
referencedSourceFiles = new LinkedHashMap<String, List<String>>();
readResourceList();
}
}
if (type == Type.created) {
this.writerModeDataSet = new WriterModeDataSet(this);
}
this.gameData = new GameDataSet(this);
this.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this);
this.worldmap = new Worldmap(this);
v = new SavedSlotCollection();
v.add(gameData);
v.add(gameMaps);
v.add(gameSprites);
v.add(worldmap);
if (type == Type.created) {
v.add(writerModeDataSet);
}
}
public void readResourceList() {
File xmlFile;
if (parent.sourceSetToUse == ResourceSet.gameData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_GAME_RESOURCE);
} else if (parent.sourceSetToUse == ResourceSet.debugData) {
xmlFile = new File(baseFolder, DEFAULT_REL_PATH_FOR_DEBUG_RESOURCE);
} else {
return;
}
if (!xmlFile.exists()) return;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc;
try {
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(xmlFile));
// insrc.setSystemId("http://worldmap/"); // insrc.setSystemId("http://worldmap/");
insrc.setEncoding("UTF-8"); insrc.setEncoding("UTF-8");
doc = builder.parse(insrc); doc = builder.parse(insrc);
Element root = (Element) doc.getElementsByTagName("resources").item(0);
if (root != null) {
NodeList arraysList = root.getElementsByTagName("array");
if (arraysList != null) {
for (int i = 0; i < arraysList.getLength(); i++) {
Element arrayNode = (Element) arraysList.item(i);
String name = arrayNode.getAttribute("name");
List<String> arrayContents = new ArrayList<String>();
NodeList arrayItems = arrayNode.getElementsByTagName("item");
if (arrayItems != null) {
for (int j = 0; j < arrayItems.getLength(); j++) {
arrayContents.add(((Element)arrayItems.item(j)).getTextContent());
}
referencedSourceFiles.put(name, arrayContents);
}
}
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return v.getNonEmptyElements();
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return v.getNonEmptyElementAt(arg0);
}
@Override
public int getChildCount() {
return v.getNonEmptySize();
}
@Override
public int getIndex(TreeNode arg0) {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
switch(type) {
case altered: return (needsSaving() ? "*" : "")+"Altered data";
case created: return (needsSaving() ? "*" : "")+"Created data";
case referenced: return (needsSaving() ? "*" : "")+"Referenced data";
case source: return (needsSaving() ? "*" : "")+"AT Source"; //The fact that it is from "source" is already mentionned by its parent.
default: return (needsSaving() ? "*" : "")+"Game data";
}
}
@Override
public Project getProject() {
return parent == null ? null : parent.getProject();
}
public Image getIcon(String iconId) { Element root = (Element) doc.getElementsByTagName("resources").item(0);
String[] data = iconId.split(":"); if (root != null) {
for (Spritesheet sheet : gameSprites.spritesheets) { NodeList arraysList = root.getElementsByTagName("array");
if (sheet.id.equals(data[0])) { if (arraysList != null) {
return sheet.getIcon(Integer.parseInt(data[1])); for (int i = 0; i < arraysList.getLength(); i++) {
} Element arrayNode = (Element) arraysList.item(i);
} String name = arrayNode.getAttribute("name");
return null; List<String> arrayContents = new ArrayList<String>();
} NodeList arrayItems = arrayNode.getElementsByTagName("item");
if (arrayItems != null) {
public Image getImage(String iconId) { for (int j = 0; j < arrayItems.getLength(); j++) {
String[] data = iconId.split(":"); arrayContents.add(((Element) arrayItems.item(j)).getTextContent());
for (Spritesheet sheet : gameSprites.spritesheets) { }
if (sheet.id.equals(data[0])) { referencedSourceFiles.put(name, arrayContents);
return sheet.getImage(Integer.parseInt(data[1])); }
} }
} }
return null; }
} } catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override @Override
public Image getIcon() { public Enumeration<ProjectTreeNode> children() {
return getOpenIcon(); return v.getNonEmptyElements();
} }
@Override
public Image getClosedIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getATOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override @Override
public Type getDataType() { public boolean getAllowsChildren() {
return type; return true;
} }
@Override
public boolean isEmpty() {
return v.isEmpty();
}
public WorldmapSegment getWorldmapSegment(String id) { @Override
return worldmap.getWorldmapSegment(id); public TreeNode getChildAt(int arg0) {
} return v.getNonEmptyElementAt(arg0);
}
@Override
public boolean needsSaving() { @Override
for (ProjectTreeNode node : v.getNonEmptyIterable()) { public int getChildCount() {
if (node.needsSaving()) return true; return v.getNonEmptySize();
} }
return false;
} @Override
public int getIndex(TreeNode arg0) {
return v.getNonEmptyIndexOf((ProjectTreeNode) arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.v.getNonEmptySize() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
node.notifyCreated();
}
}
@Override
public String getDesc() {
switch (type) {
case altered:
return (needsSaving() ? "*" : "") + "Altered data";
case created:
return (needsSaving() ? "*" : "") + "Created data";
case referenced:
return (needsSaving() ? "*" : "") + "Referenced data";
case source:
return (needsSaving() ? "*" : "") + "AT Source"; //The fact that it is from "source" is already mentionned by its parent.
default:
return (needsSaving() ? "*" : "") + "Game data";
}
}
@Override
public Project getProject() {
return parent == null ? null : parent.getProject();
}
public Image getIcon(String iconId) {
String[] data = iconId.split(":");
for (Spritesheet sheet : gameSprites.spritesheets) {
if (sheet.id.equals(data[0])) {
return sheet.getIcon(Integer.parseInt(data[1]));
}
}
return null;
}
public Image getImage(String iconId) {
String[] data = iconId.split(":");
for (Spritesheet sheet : gameSprites.spritesheets) {
if (sheet.id.equals(data[0])) {
return sheet.getImage(Integer.parseInt(data[1]));
}
}
return null;
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getATClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getATOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return type;
}
@Override
public boolean isEmpty() {
return v.isEmpty();
}
public WorldmapSegment getWorldmapSegment(String id) {
return worldmap.getWorldmapSegment(id);
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : v.getNonEmptyIterable()) {
if (node.needsSaving()) return true;
}
return false;
}
} }

View File

@@ -1,19 +1,53 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import java.awt.Dimension; import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
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 Map<String, Integer> splittersPositions = new HashMap<String, Integer>();
public Preferences() {
} public Dimension windowSize = null;
public Map<String, Integer> splittersPositions = new HashMap<>();
public Preferences() {
}
@Override
public Map toMap() {
Map map = new HashMap();
if(windowSize!= null){
Map windowSizeMap = new HashMap<>();
windowSizeMap.put("width", windowSize.width);
windowSizeMap.put("height", windowSize.height);
map.put("windowSize", windowSizeMap);
}
map.put("splittersPositions", splittersPositions);
return map;
}
@Override
public void fromMap(Map map) {
if(map == null) return;
Map windowSize1 = (Map) map.get("windowSize");
if(windowSize1 != null){
windowSize = new Dimension(((Number) windowSize1.get("width")).intValue(), ((Number) windowSize1.get("height")).intValue());
}
Map<String, Number> splitters = (Map<String, Number>) map.get("splittersPositions");
Map<String, Integer> splittersInt = new HashMap<>(splitters.size());
for (Map.Entry<String, Number> entry : splitters. entrySet()){
splittersInt.put(entry.getKey(), entry.getValue().intValue());
}
splittersPositions = splittersInt;
}
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,384 @@
package com.gpl.rpg.atcontentstudio.model.gamedata;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public final class Common {
public static <T extends ActorConditionEffect> void actorConditionElementChanged(List<T> list, GameDataElement oldOne, GameDataElement newOne, GameDataElement backlink) {
if (list != null) {
for (T c : list) {
if (c.condition == oldOne) {
oldOne.removeBacklink(backlink);
c.condition = (ActorCondition) newOne;
if (newOne != null) newOne.addBacklink(backlink);
}
}
}
}
//region link common stuff
public static void linkConditions(List<? extends ActorConditionEffect> conditions, Project proj, GameDataElement backlink) {
if (conditions != null) {
for (ActorConditionEffect ce : conditions) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(backlink);
}
}
}
public static void linkEffects(HitEffect effect, Project proj, GameDataElement backlink) {
linkEffects((DeathEffect) effect, proj, backlink);
if (effect != null) {
linkConditions(effect.conditions_target, proj, backlink);
}
}
public static void linkEffects(DeathEffect effect, Project proj, GameDataElement backlink) {
if (effect != null) {
linkConditions(effect.conditions_source, proj, backlink);
}
}
public static void linkIcon(Project proj, String iconId, GameDataElement backlink) {
if (iconId != null) {
String spritesheetId = iconId.split(":")[0];
if (proj.getSpritesheet(spritesheetId) == null) {
Notification.addError("Error Spritesheet " + spritesheetId + ". has no backlink. (" + iconId + ")");
return;
}
proj.getSpritesheet(spritesheetId).addBacklink(backlink);
}
}
//endregion
//region write common stuff
public static void writeMinMaxToMap(Map parent, Integer min, Integer max, int defaultValue) {
if (min != null || max != null) {
if (min != null)
parent.put("min", min);
else parent.put("min", defaultValue);
if (max != null)
parent.put("max", max);
else parent.put("max", defaultValue);
}
}
public static void writeMinMaxToMap(Map parent, String key, Integer min, Integer max, int defaultValue) {
if (min != null || max != null) {
Map minMaxMap = new LinkedHashMap();
parent.put(key, minMaxMap);
writeMinMaxToMap(minMaxMap, min, max, defaultValue);
}
}
public static void writeDescriptionToMap(Map parent, String description) {
if (description != null) parent.put("description", description);
}
public static void writeIconToMap(Map parent, String icon_id) {
if (icon_id != null) parent.put("iconID", icon_id);
}
public static void writeHitReceivedEffectToMap(Map parent, HitReceivedEffect effect) {
if (effect != null) {
writeHitEffectToMap(parent, effect);
writeBasicEffectObjectToMap(effect.target, parent, "increaseAttackerCurrentHP", "increaseAttackerCurrentAP");
}
}
public static void writeHitReceivedEffectToMap(Map parent, HitReceivedEffect effect, String key) {
if (effect != null) {
Map effectJson = new LinkedHashMap();
parent.put(key, effectJson);
writeHitReceivedEffectToMap(effectJson, effect);
}
}
public static void writeHitEffectToMap(Map parent, HitEffect effect) {
if (effect != null) {
writeDeathEffectToMap(parent, effect);
writeTimedActorConditionEffectObjectToMap(effect.conditions_target, parent, "conditionsTarget");
}
}
public static void writeHitEffectToMap(Map parent, HitEffect effect, String key) {
if (effect != null) {
Map effectJson = new LinkedHashMap();
parent.put(key, effectJson);
writeHitEffectToMap(effectJson, effect);
}
}
public static void writeDeathEffectToMap(Map parent, DeathEffect effect) {
writeBasicEffectObjectToMap(effect, parent, "increaseCurrentHP", "increaseCurrentAP");
writeTimedActorConditionEffectObjectToMap(effect.conditions_source, parent, "conditionsSource");
}
public static void writeDeathEffectToMap(Map parent, DeathEffect effect, String key) {
if (effect != null) {
Map effectJson = new LinkedHashMap();
parent.put(key, effectJson);
writeDeathEffectToMap(effectJson, effect);
}
}
public static void writeBasicEffectObjectToMap(BasicEffect effect, Map parent, String keyHP, String keyAP) {
writeMinMaxToMap(parent, keyHP, effect.hp_boost_min, effect.hp_boost_max, 0);
writeMinMaxToMap(parent, keyAP, effect.ap_boost_min, effect.ap_boost_max, 0);
}
public static void writeTimedActorConditionEffectObjectToMap(List<TimedActorConditionEffect> list, Map parent, String key) {
if (list != null) {
List conditionsSourceJson = new ArrayList();
parent.put(key, conditionsSourceJson);
for (TimedActorConditionEffect condition : list) {
Map conditionJson = new LinkedHashMap();
conditionsSourceJson.add(conditionJson);
writeTimedConditionEffectToMap(condition, conditionJson);
}
}
}
public static void writeConditionEffectToMap(ActorConditionEffect condition, Map parent) {
if (condition.condition != null) {
parent.put("condition", condition.condition.id);
} else if (condition.condition_id != null) {
parent.put("condition", condition.condition_id);
}
if (condition.magnitude != null) {
parent.put("magnitude", condition.magnitude);
}
}
public static void writeTimedConditionEffectToMap(TimedActorConditionEffect condition, Map parent) {
writeConditionEffectToMap(condition, parent);
if (condition.duration != null) {
parent.put("duration", condition.duration);
}
if (condition.chance != null) {
parent.put("chance", JSONElement.printJsonChance(condition.chance));
}
}
//endregion
public static class TimedActorConditionEffect extends ActorConditionEffect {
//Available from parsed state
public Integer duration = null;
public Double chance = null;
public TimedActorConditionEffect createClone() {
TimedActorConditionEffect cclone = new TimedActorConditionEffect();
cclone.magnitude = this.magnitude;
cclone.condition_id = this.condition_id;
cclone.condition = this.condition;
cclone.chance = this.chance;
cclone.duration = this.duration;
return cclone;
}
public boolean isInfinite() {
return duration != null && duration.equals(ActorCondition.DURATION_FOREVER);
}
public boolean isImmunity() {
return (super.isClear()) && (duration != null && duration > ActorCondition.DURATION_NONE);
}
@Override
public boolean isClear() {
return (super.isClear()) && (duration == null || duration.equals(ActorCondition.DURATION_NONE));
}
}
public static class ActorConditionEffect {
//Available from parsed state
public Integer magnitude = null;
public String condition_id = null;
//Available from linked state
public ActorCondition condition = null;
public boolean isClear() {
return magnitude == null || magnitude.equals(ActorCondition.MAGNITUDE_CLEAR);
}
}
@SuppressWarnings("rawtypes")
public static ArrayList<TimedActorConditionEffect> parseTimedConditionEffects(List conditionsSourceJson) {
ArrayList<TimedActorConditionEffect> conditions_source;
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
conditions_source = new ArrayList<>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map) conditionJsonObj;
TimedActorConditionEffect condition = new TimedActorConditionEffect();
readConditionEffect(condition, conditionJson);
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null)
condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
conditions_source.add(condition);
}
} else {
conditions_source = null;
}
return conditions_source;
}
@SuppressWarnings("rawtypes")
private static void readConditionEffect(ActorConditionEffect condition, Map conditionJson) {
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
}
@SuppressWarnings("rawtypes")
public static Common.DeathEffect parseDeathEffect(Map killEffect) {
Common.DeathEffect kill_effect = new Common.DeathEffect();
readDeathEffect(killEffect, kill_effect);
return kill_effect;
}
@SuppressWarnings("rawtypes")
public static HitEffect parseHitEffect(Map hitEffect) {
Common.HitEffect hit_effect = new Common.HitEffect();
readHitEffect(hitEffect, hit_effect);
return hit_effect;
}
@SuppressWarnings("rawtypes")
public static HitReceivedEffect parseHitReceivedEffect(Map hitReceivedEffect) {
HitReceivedEffect hit_received_effect = new Common.HitReceivedEffect();
readHitEffect(hitReceivedEffect, hit_received_effect);
if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) {
hit_received_effect.target.hp_boost_max = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max")));
hit_received_effect.target.hp_boost_min = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min")));
}
if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) {
hit_received_effect.target.ap_boost_max = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max")));
hit_received_effect.target.ap_boost_min = JSONElement.getInteger((Number) (((Map) hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min")));
}
return hit_received_effect;
}
@SuppressWarnings("rawtypes")
private static void readDeathEffect(Map killEffect, DeathEffect kill_effect) {
if (killEffect.get("increaseCurrentHP") != null) {
kill_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentHP")).get("min")));
kill_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentHP")).get("max")));
}
if (killEffect.get("increaseCurrentAP") != null) {
kill_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentAP")).get("min")));
kill_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map) killEffect.get("increaseCurrentAP")).get("max")));
}
List conditionsSourceJson = (List) killEffect.get("conditionsSource");
kill_effect.conditions_source = parseTimedConditionEffects(conditionsSourceJson);
}
@SuppressWarnings("rawtypes")
private static void readHitEffect(Map hitEffect, HitEffect hit_effect) {
readDeathEffect(hitEffect, hit_effect);
List conditionsTargetJson = (List) hitEffect.get("conditionsTarget");
hit_effect.conditions_target = parseTimedConditionEffects(conditionsTargetJson);
}
public static class BasicEffect {
public Integer hp_boost_min = null;
public Integer hp_boost_max = null;
public Integer ap_boost_min = null;
public Integer ap_boost_max = null;
public boolean isNull() {
if (ap_boost_min != null) return false;
if (ap_boost_max != null) return false;
if (hp_boost_min != null) return false;
if (hp_boost_max != null) return false;
return true;
}
}
public static class DeathEffect extends BasicEffect {
//Available from parsed state
public List<TimedActorConditionEffect> conditions_source = null;
@Override
public boolean isNull() {
if (!super.isNull()) return false;
if (conditions_source != null) return false;
return true;
}
}
public static class HitEffect extends DeathEffect {
//Available from parsed state
public List<TimedActorConditionEffect> conditions_target = null;
@Override
public boolean isNull() {
if (!super.isNull()) return false;
if (conditions_target != null) return false;
return true;
}
}
public static class HitReceivedEffect extends Common.HitEffect {
//Available from parsed state
public BasicEffect target = new BasicEffect();
@Override
public boolean isNull() {
if (!super.isNull()) return false;
if (!target.isNull()) return false;
return true;
}
}
public static void copyDeathEffectValues(Common.DeathEffect target, Common.DeathEffect source, GameDataElement backlink) {
copyEffectValues(target, source);
if (source.conditions_source != null) {
target.conditions_source = new ArrayList<>();
for (TimedActorConditionEffect c : source.conditions_source) {
TimedActorConditionEffect cclone = c.createClone();
if (cclone.condition != null) {
cclone.condition.addBacklink(backlink);
}
target.conditions_source.add(cclone);
}
}
}
private static void copyEffectValues(BasicEffect target, BasicEffect source) {
target.ap_boost_max = source.ap_boost_max;
target.ap_boost_min = source.ap_boost_min;
target.hp_boost_max = source.hp_boost_max;
target.hp_boost_min = source.hp_boost_min;
}
public static void copyHitEffectValues(Common.HitEffect target, Common.HitEffect source, GameDataElement backlink) {
copyDeathEffectValues(target, source, backlink);
if (source.conditions_target != null) {
target.conditions_target = new ArrayList<>();
for (TimedActorConditionEffect c : source.conditions_target) {
TimedActorConditionEffect cclone = c.createClone();
if (cclone.condition != null) {
cclone.condition.addBacklink(backlink);
}
target.conditions_target.add(cclone);
}
}
}
public static void copyHitReceivedEffectValues(Common.HitReceivedEffect target, Common.HitReceivedEffect source, GameDataElement backlink) {
copyHitEffectValues(target, source, backlink);
copyEffectValues(target.target, source.target);
}
}

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,103 +1,96 @@
package com.gpl.rpg.atcontentstudio.model.gamedata; package com.gpl.rpg.atcontentstudio.model.gamedata;
import java.awt.Image;
import java.util.LinkedHashMap;
import java.util.Map;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import java.awt.*;
import java.util.LinkedHashMap;
import java.util.Map;
public class QuestStage extends JSONElement { public class QuestStage extends JSONElement {
private static final long serialVersionUID = 8313645819951513431L;
public Integer progress = null;
public String log_text = null;
public Integer exp_reward = null;
public Integer finishes_quest = null;
public QuestStage(Quest parent){
this.parent = parent;
}
public QuestStage clone(Quest cloneParent) {
QuestStage clone = new QuestStage(cloneParent);
clone.progress = progress != null ? new Integer(progress) : null;
clone.log_text = log_text != null ? new String(log_text) : null;
clone.exp_reward = exp_reward != null ? new Integer(exp_reward) : null;
clone.finishes_quest = finishes_quest != null ? new Integer(finishes_quest) : null;
clone.id = this.id;
return clone;
}
@SuppressWarnings("rawtypes") private static final long serialVersionUID = 8313645819951513431L;
@Override
public void parse(Map jsonObj) {
progress = JSONElement.getInteger((Number) jsonObj.get("progress"));
this.id = ((Quest)parent).id+":"+progress;
log_text = (String) jsonObj.get("logText");
exp_reward = JSONElement.getInteger((Number) jsonObj.get("rewardExperience"));
finishes_quest = JSONElement.getInteger((Number) jsonObj.get("finishesQuest"));
state = State.parsed;
}
@SuppressWarnings({ "rawtypes", "unchecked" }) public Integer progress = null;
@Override public String log_text = null;
public Map toJson() { public Integer exp_reward = null;
Map stageJson = new LinkedHashMap(); public Integer finishes_quest = null;
if (progress != null) stageJson.put("progress", progress);
if (log_text != null) stageJson.put("logText", log_text);
if (exp_reward != null) stageJson.put("rewardExperience", exp_reward);
if (finishes_quest != null) stageJson.put("finishesQuest", finishes_quest);
return stageJson;
}
@Override public QuestStage(Quest parent) {
public String getDesc() { this.parent = parent;
return progress+" - "+(exp_reward != null ? "["+exp_reward+"XP]" : "")+((finishes_quest != null) && (finishes_quest == 1) ? "[END]" : "")+log_text; }
}
@Override public QuestStage clone(Quest cloneParent) {
public void link() { QuestStage clone = new QuestStage(cloneParent);
if (this.state == State.created || this.state == State.modified || this.state == State.saved) { clone.progress = progress != null ? new Integer(progress) : null;
//This type of state is unrelated to parsing/linking. clone.log_text = log_text != null ? new String(log_text) : null;
return; clone.exp_reward = exp_reward != null ? new Integer(exp_reward) : null;
} clone.finishes_quest = finishes_quest != null ? new Integer(finishes_quest) : null;
if (this.state == State.init) { clone.id = this.id;
//Not parsed yet. return clone;
this.parse(); }
} else if (this.state == State.linked) {
//Already linked.
return;
}
//Nothing to link to :D
this.state = State.linked;
}
@Override @SuppressWarnings("rawtypes")
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) { @Override
// Nothing to link to. public void parse(Map jsonObj) {
} progress = JSONElement.getInteger((Number) jsonObj.get("progress"));
this.id = ((Quest) parent).id + ":" + progress;
log_text = (String) jsonObj.get("logText");
exp_reward = JSONElement.getInteger((Number) jsonObj.get("rewardExperience"));
finishes_quest = JSONElement.getInteger((Number) jsonObj.get("finishesQuest"));
state = State.parsed;
}
@Override @SuppressWarnings({"rawtypes", "unchecked"})
public String getProjectFilename() { @Override
return ((Quest)parent).getProjectFilename(); public Map toJson() {
} Map stageJson = new LinkedHashMap();
if (progress != null) stageJson.put("progress", progress);
if (log_text != null) stageJson.put("logText", log_text);
if (exp_reward != null) stageJson.put("rewardExperience", exp_reward);
if (finishes_quest != null) stageJson.put("finishesQuest", finishes_quest);
return stageJson;
}
@Override
public String getDesc() {
return progress + " - " + (exp_reward != null ? "[" + exp_reward + "XP]" : "") + ((finishes_quest != null) && (finishes_quest == 1) ? "[END]" : "") + log_text;
}
@Override
public void link() {
if (shouldSkipParseOrLink()) {
return;
}
ensureParseIfNeeded();
//Nothing to link to :D
this.state = State.linked;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
// Nothing to link to.
}
@Override
public String getProjectFilename() {
return ((Quest) parent).getProjectFilename();
}
@Override
public GameDataElement clone() {
return null;
}
@Override
public Image getIcon() {
return DefaultIcons.getQuestIcon();
}
public Image getImage() {
return DefaultIcons.getQuestImage();
}
@Override
public GameDataElement clone() {
return null;
}
@Override
public Image getIcon() {
return DefaultIcons.getQuestIcon();
}
public Image getImage() {
return DefaultIcons.getQuestImage();
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,35 +1,32 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.Component; import javax.swing.*;
import java.awt.Graphics; import java.awt.*;
import java.awt.Image;
import javax.swing.Icon;
public class OverlayIcon implements Icon { public class OverlayIcon implements Icon {
private Image background;
private Image overlay;
public OverlayIcon(Image background, Image overlay) {
this.background = background;
this.overlay = overlay;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.drawImage(background, x, y, null);
g.drawImage(overlay, x, y, null);
}
@Override private Image background;
public int getIconWidth() { private Image overlay;
return Math.max(background.getWidth(null), overlay.getWidth(null));
}
@Override public OverlayIcon(Image background, Image overlay) {
public int getIconHeight() { this.background = background;
return Math.max(background.getHeight(null), overlay.getHeight(null)); this.overlay = overlay;
} }
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.drawImage(background, x, y, null);
g.drawImage(overlay, x, y, null);
}
@Override
public int getIconWidth() {
return Math.max(background.getWidth(null), overlay.getWidth(null));
}
@Override
public int getIconHeight() {
return Math.max(background.getHeight(null), overlay.getHeight(null));
}
} }

View File

@@ -1,31 +1,5 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet; import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
@@ -34,293 +8,305 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
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;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ProjectCreationWizard extends JDialog { public class ProjectCreationWizard extends JDialog {
private static final long serialVersionUID = -2854969975146867119L; private static final long serialVersionUID = -2854969975146867119L;
final JTextField projectNameField; final JTextField projectNameField;
final JComboBox<String> atSourceSelectionCombo; final JComboBox<String> atSourceSelectionCombo;
final JComboBox<Project.ResourceSet> resourceSetToUse; final JComboBox<Project.ResourceSet> resourceSetToUse;
final JButton browse; final JButton browse;
final JButton okButton; final JButton okButton;
final JButton cancelButton; final JButton cancelButton;
final JLabel errorLabel;
public ProjectCreationWizard() {
super(ATContentStudio.frame);
setTitle("Create project");
projectNameField = new JTextField();
atSourceSelectionCombo = new JComboBox<String>();
resourceSetToUse = new JComboBox<Project.ResourceSet>(new ComboBoxModel<Project.ResourceSet>() {
Project.ResourceSet selected = Project.ResourceSet.gameData; final JLabel errorLabel;
@Override
public int getSize() {
return Project.ResourceSet.values().length;
}
@Override public ProjectCreationWizard() {
public ResourceSet getElementAt(int index) { super(ATContentStudio.frame);
return Project.ResourceSet.values()[index]; setTitle("Create project");
} projectNameField = new JTextField();
atSourceSelectionCombo = new JComboBox<String>();
resourceSetToUse = new JComboBox<Project.ResourceSet>(new ComboBoxModel<Project.ResourceSet>() {
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>(); Project.ResourceSet selected = Project.ResourceSet.gameData;
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override @Override
public void removeListDataListener(ListDataListener l) { public int getSize() {
listeners.remove(l); return Project.ResourceSet.values().length;
} }
@Override @Override
public void setSelectedItem(Object anItem) { public ResourceSet getElementAt(int index) {
selected = (ResourceSet) anItem; return Project.ResourceSet.values()[index];
} }
@Override List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
public Object getSelectedItem() {
return selected;
}
});
resourceSetToUse.setRenderer(new ListCellRenderer<Project.ResourceSet>() {
@Override
public Component getListCellRendererComponent(
JList<? extends ResourceSet> list, ResourceSet value,
int index, boolean isSelected, boolean cellHasFocus) {
switch (value) {
case allFiles:
return new JLabel("All available files");
case debugData:
return new JLabel("Debug data");
case gameData:
return new JLabel("Real game data");
default:
return new JLabel();
}
}
});
browse = new JButton("Browse...");
okButton = new JButton("Ok");
cancelButton = new JButton("Cancel");
errorLabel = new JLabel("Enter the following information about your project.");
projectNameField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateOkButtonEnablement();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateOkButtonEnablement();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateOkButtonEnablement();
}
});
for (File f : Workspace.activeWorkspace.knownMapSourcesFolders) {
atSourceSelectionCombo.addItem(f.getAbsolutePath());
}
atSourceSelectionCombo.setEditable(true);
atSourceSelectionCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateOkButtonEnablement();
}
});
browse.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
boolean keepTrying = true;
if (atSourceSelectionCombo.getSelectedItem() != null && ((String)atSourceSelectionCombo.getSelectedItem()).length() > 0) {
File f = new File((String)atSourceSelectionCombo.getSelectedItem());
if (f.exists()) {
chooser.setCurrentDirectory(f);
keepTrying = false;
}
}
if (keepTrying && Workspace.activeWorkspace.knownMapSourcesFolders != null && !Workspace.activeWorkspace.knownMapSourcesFolders.isEmpty()) {
chooser.setCurrentDirectory(Workspace.activeWorkspace.knownMapSourcesFolders.iterator().next());
}
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = chooser.showOpenDialog(ProjectCreationWizard.this);
if (result == JFileChooser.APPROVE_OPTION) {
atSourceSelectionCombo.setSelectedItem(chooser.getSelectedFile().getAbsolutePath());
updateOkButtonEnablement();
}
}
});
okButton.setEnabled(false);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
File atSourceFolder = new File((String) atSourceSelectionCombo.getSelectedItem());
if (!Workspace.activeWorkspace.knownMapSourcesFolders.contains(atSourceFolder)) {
Workspace.activeWorkspace.knownMapSourcesFolders.add(atSourceFolder);
}
Workspace.createProject(projectNameField.getText(), atSourceFolder, (Project.ResourceSet)resourceSetToUse.getSelectedItem());
ProjectCreationWizard.this.dispose();
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ProjectCreationWizard.this.dispose();
}
});
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c =new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.BOTH;
c.gridheight = 1;
c.gridwidth = 3;
c.gridx = 1;
c.gridy = 1;
c.weightx = 100;
c.weighty = 100;
panel.add(errorLabel, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("Project name: "), c);
c.gridx++;
c.gridwidth = 2;
c.weightx = 80;
panel.add(projectNameField, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("AT Source: "), c);
c.gridx++; @Override
c.weightx = 60; public void addListDataListener(ListDataListener l) {
panel.add(atSourceSelectionCombo, c); listeners.add(l);
}
c.gridx++;
c.weightx = 20;
panel.add(browse, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("Resource set: "), c);
c.gridx++; @Override
c.weightx = 80; public void removeListDataListener(ListDataListener l) {
c.gridwidth = 2; listeners.remove(l);
panel.add(resourceSetToUse, c); }
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new GridBagLayout());
GridBagConstraints c2 = new GridBagConstraints();
c2.fill = GridBagConstraints.HORIZONTAL;
c2.gridx = 1;
c2.weightx = 80;
c2.gridx = 1;
c2.weightx = 80;
buttonPane.add(new JLabel(), c2);
c2.gridx++; @Override
c2.weightx = 10; public void setSelectedItem(Object anItem) {
c.fill = GridBagConstraints.NONE; selected = (ResourceSet) anItem;
buttonPane.add(cancelButton, c2); }
c2.gridx++; @Override
c2.weightx = 10; public Object getSelectedItem() {
buttonPane.add(okButton, c2); return selected;
}
c.gridy++;
c.fill = GridBagConstraints.HORIZONTAL; });
c.gridwidth = 3; resourceSetToUse.setRenderer(new ListCellRenderer<Project.ResourceSet>() {
panel.add(buttonPane, c); @Override
public Component getListCellRendererComponent(
updateOkButtonEnablement(); JList<? extends ResourceSet> list, ResourceSet value,
int index, boolean isSelected, boolean cellHasFocus) {
setContentPane(panel); switch (value) {
case allFiles:
pack(); return new JLabel("All available files");
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize(); case debugData:
Dimension wdim = getSize(); return new JLabel("Debug data");
setLocation((sdim.width - wdim.width)/2, (sdim.height - wdim.height)/2); case gameData:
} return new JLabel("Real game data");
default:
return new JLabel();
}
}
});
browse = new JButton("Browse...");
okButton = new JButton("Ok");
cancelButton = new JButton("Cancel");
errorLabel = new JLabel("Enter the following information about your project.");
projectNameField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateOkButtonEnablement();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateOkButtonEnablement();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateOkButtonEnablement();
}
});
for (File f : Workspace.activeWorkspace.knownMapSourcesFolders) {
atSourceSelectionCombo.addItem(f.getAbsolutePath());
}
atSourceSelectionCombo.setEditable(true);
atSourceSelectionCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateOkButtonEnablement();
}
});
browse.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
boolean keepTrying = true;
if (atSourceSelectionCombo.getSelectedItem() != null && ((String) atSourceSelectionCombo.getSelectedItem()).length() > 0) {
File f = new File((String) atSourceSelectionCombo.getSelectedItem());
if (f.exists()) {
chooser.setCurrentDirectory(f);
keepTrying = false;
}
}
if (keepTrying && Workspace.activeWorkspace.knownMapSourcesFolders != null && !Workspace.activeWorkspace.knownMapSourcesFolders.isEmpty()) {
chooser.setCurrentDirectory(Workspace.activeWorkspace.knownMapSourcesFolders.iterator().next());
}
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = chooser.showOpenDialog(ProjectCreationWizard.this);
if (result == JFileChooser.APPROVE_OPTION) {
atSourceSelectionCombo.setSelectedItem(chooser.getSelectedFile().getAbsolutePath());
updateOkButtonEnablement();
}
}
});
okButton.setEnabled(false);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
File atSourceFolder = new File((String) atSourceSelectionCombo.getSelectedItem());
if (!Workspace.activeWorkspace.knownMapSourcesFolders.contains(atSourceFolder)) {
Workspace.activeWorkspace.knownMapSourcesFolders.add(atSourceFolder);
}
Workspace.createProject(projectNameField.getText(), atSourceFolder, (Project.ResourceSet) resourceSetToUse.getSelectedItem());
ProjectCreationWizard.this.dispose();
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ProjectCreationWizard.this.dispose();
}
});
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.BOTH;
c.gridheight = 1;
c.gridwidth = 3;
c.gridx = 1;
c.gridy = 1;
c.weightx = 100;
c.weighty = 100;
panel.add(errorLabel, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("Project name: "), c);
c.gridx++;
c.gridwidth = 2;
c.weightx = 80;
panel.add(projectNameField, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("AT Source: "), c);
c.gridx++;
c.weightx = 60;
panel.add(atSourceSelectionCombo, c);
c.gridx++;
c.weightx = 20;
panel.add(browse, c);
c.gridy++;
c.gridx = 1;
c.gridwidth = 1;
c.weightx = 20;
panel.add(new JLabel("Resource set: "), c);
c.gridx++;
c.weightx = 80;
c.gridwidth = 2;
panel.add(resourceSetToUse, c);
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new GridBagLayout());
GridBagConstraints c2 = new GridBagConstraints();
c2.fill = GridBagConstraints.HORIZONTAL;
c2.gridx = 1;
c2.weightx = 80;
buttonPane.add(new JLabel(), c2);
c2.gridx++;
c2.weightx = 10;
c.fill = GridBagConstraints.NONE;
buttonPane.add(cancelButton, c2);
c2.gridx++;
c2.weightx = 10;
buttonPane.add(okButton, c2);
c.gridy++;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 3;
panel.add(buttonPane, c);
updateOkButtonEnablement();
setContentPane(panel);
pack();
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
Dimension wdim = getSize();
setLocation((sdim.width - wdim.width) / 2, (sdim.height - wdim.height) / 2);
}
protected void updateOkButtonEnablement() { protected void updateOkButtonEnablement() {
if (projectNameField.getText() == null || projectNameField.getText().length() <= 0) { if (projectNameField.getText() == null || projectNameField.getText().length() <= 0) {
errorLabel.setText("<html><font color=\"#FF0000\">Select a project name.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">Select a project name.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} }
if (atSourceSelectionCombo.getSelectedItem() == null || ((String)atSourceSelectionCombo.getSelectedItem()).length() <= 0) { if (atSourceSelectionCombo.getSelectedItem() == null || ((String) atSourceSelectionCombo.getSelectedItem()).length() <= 0) {
errorLabel.setText("<html><font color=\"#FF0000\">Select an AT source root folder.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">Select an AT source root folder.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} }
File projFolder = new File(Workspace.activeWorkspace.baseFolder, projectNameField.getText()+File.separator); File projFolder = new File(Workspace.activeWorkspace.baseFolder, projectNameField.getText() + File.separator);
File sourceFolder = new File((String) atSourceSelectionCombo.getSelectedItem()); File sourceFolder = new File((String) atSourceSelectionCombo.getSelectedItem());
if (projFolder.exists()) { if (projFolder.exists()) {
errorLabel.setText("<html><font color=\"#FF0000\">A project with this name already exists.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">A project with this name already exists.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} else { } else {
try { try {
projFolder.getCanonicalPath(); projFolder.getCanonicalPath();
} catch (IOException ioe) { } catch (IOException ioe) {
errorLabel.setText("<html><font color=\"#FF0000\">"+projectNameField.getText()+" is not a valid project name.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">" + projectNameField.getText() + " is not a valid project name.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} }
} }
if (!sourceFolder.exists()) { if (!sourceFolder.exists()) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not exist.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not exist.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} else { } else {
File res = new File(sourceFolder, GameDataSet.DEFAULT_REL_PATH_IN_SOURCE); File res = new File(sourceFolder, GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!res.exists()) { if (!res.exists()) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not contain the \"res\" folder.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not contain the \"res\" folder.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} }
File drawable = new File(sourceFolder, SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE); File drawable = new File(sourceFolder, SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!drawable.exists()) { if (!drawable.exists()) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not contain the \"drawable\" folder.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not contain the \"drawable\" folder.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} }
File xml = new File(sourceFolder, TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE); File xml = new File(sourceFolder, TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!xml.exists()) { if (!xml.exists()) {
errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not contain the \"xml\" folder.</font></html>"); errorLabel.setText("<html><font color=\"#FF0000\">The selected AT source root folder does not contain the \"xml\" folder.</font></html>");
this.okButton.setEnabled(false); this.okButton.setEnabled(false);
return; return;
} }
} }
if (!projFolder.exists() && sourceFolder.exists()) { if (!projFolder.exists() && sourceFolder.exists()) {
errorLabel.setText("<html><font color=\"#00AA00\">Everything looks good !</font></html>"); errorLabel.setText("<html><font color=\"#00AA00\">Everything looks good !</font></html>");
this.okButton.setEnabled(true); this.okButton.setEnabled(true);
return; return;
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +1,5 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
@@ -29,246 +7,254 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataCategory;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement; import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;
import java.util.*;
public class SaveItemsWizard extends JDialog { public class SaveItemsWizard extends JDialog {
private static final long serialVersionUID = -3301878024575930527L; private static final long serialVersionUID = -3301878024575930527L;
List<SaveEvent> events; List<SaveEvent> events;
@SuppressWarnings("rawtypes")
JList movedToCreated;
@SuppressWarnings("rawtypes")
JList movedToAltered;
@SuppressWarnings("rawtypes")
JList willBeSaved;
@SuppressWarnings({ "unchecked", "rawtypes" })
public SaveItemsWizard(List<SaveEvent> events, GameDataElement originalRequester) {
super(ATContentStudio.frame);
this.events = events;
final List<SaveEvent> movedToAlteredList = new ArrayList<SaveEvent>();
final List<SaveEvent> movedToCreatedList = new ArrayList<SaveEvent>();
final List<SaveEvent> alsoSavedList = new ArrayList<SaveEvent>();
final List<SaveEvent> errors = new ArrayList<SaveEvent>();
for (SaveEvent event : events) {
if (event.error) {
errors.add(event);
} else {
switch (event.type) {
case alsoSave:
alsoSavedList.add(event);
break;
case moveToAltered:
movedToAlteredList.add(event);
break;
case moveToCreated:
movedToCreatedList.add(event);
break;
}
}
}
if (!errors.isEmpty()) {
setTitle("Errors in project. Cannot save.");
JPanel pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
if (originalRequester != null) {
pane.add(new JLabel(" While trying to save: "), JideBoxLayout.FIX);
JLabel origItemDesc = new JLabel();
origItemDesc.setIcon(new ImageIcon(originalRequester.getIcon()));
origItemDesc.setText(originalRequester.getDataType().toString()+"/"+originalRequester.id);
pane.add(origItemDesc, JideBoxLayout.FIX);
pane.add(new JLabel(" the following errors have been encountered and must be corrected before saving can occur: "), JideBoxLayout.FIX);
} else {
pane.add(new JLabel("After deleting element(s), the following errors have been encountered and must be coorected before saving can occur: "), JideBoxLayout.FIX);
}
movedToCreated = new JList(errors.toArray());
movedToCreated.setCellRenderer(new SaveEventsListCellRenderer());
JPanel movedToCreatedPane = new JPanel();
movedToCreatedPane.setLayout(new BorderLayout());
movedToCreatedPane.add(new JScrollPane(movedToCreated), BorderLayout.CENTER);
pane.add(movedToCreatedPane, JideBoxLayout.FLEXIBLE);
pane.add(new JPanel(), JideBoxLayout.VARY); @SuppressWarnings("rawtypes")
JList movedToCreated;
JPanel buttonPane = new JPanel(); @SuppressWarnings("rawtypes")
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6)); JList movedToAltered;
buttonPane.add(new JPanel(), JideBoxLayout.VARY); @SuppressWarnings("rawtypes")
JButton cancelButton = new JButton("Ok, back to work..."); JList willBeSaved;
buttonPane.add(cancelButton, JideBoxLayout.FIX);
pane.add(buttonPane, JideBoxLayout.FIX);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SaveItemsWizard.this.setVisible(false);
SaveItemsWizard.this.dispose();
}
});
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
} else {
setTitle("Other elements impacted.");
JPanel pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
if (originalRequester != null) {
pane.add(new JLabel(" While trying to save: "), JideBoxLayout.FIX);
JLabel origItemDesc = new JLabel();
origItemDesc.setIcon(new ImageIcon(originalRequester.getIcon()));
origItemDesc.setText(originalRequester.getDataType().toString()+"/"+originalRequester.id);
pane.add(origItemDesc, JideBoxLayout.FIX);
pane.add(new JLabel(" the following side-effects have been identified and must be applied to the project before saving: "), JideBoxLayout.FIX);
} else {
pane.add(new JLabel("After deleting element(s), the following side-effects have been identified and must be applied to the project before saving: "), JideBoxLayout.FIX);
}
if (!movedToCreatedList.isEmpty()) {
movedToCreated = new JList(movedToCreatedList.toArray());
movedToCreated.setCellRenderer(new SaveEventsListCellRenderer());
JPanel movedToCreatedPane = new JPanel();
movedToCreatedPane.setLayout(new BorderLayout());
movedToCreatedPane.setBorder(BorderFactory.createTitledBorder("The following elements will be moved under the \"Created\" folder and saved:"));
movedToCreatedPane.add(new JScrollPane(movedToCreated), BorderLayout.CENTER);
pane.add(movedToCreatedPane, JideBoxLayout.FLEXIBLE);
}
if (!movedToAlteredList.isEmpty()) { @SuppressWarnings({"unchecked", "rawtypes"})
movedToAltered = new JList(movedToAlteredList.toArray()); public SaveItemsWizard(List<SaveEvent> events, GameDataElement originalRequester) {
movedToAltered.setCellRenderer(new SaveEventsListCellRenderer()); super(ATContentStudio.frame);
JPanel movedToAlteredPane = new JPanel(); this.events = events;
movedToAlteredPane.setLayout(new BorderLayout()); final List<SaveEvent> movedToAlteredList = new ArrayList<SaveEvent>();
movedToAlteredPane.setBorder(BorderFactory.createTitledBorder("The following elements will be moved under the \"Altered\" folder and saved:")); final List<SaveEvent> movedToCreatedList = new ArrayList<SaveEvent>();
movedToAlteredPane.add(new JScrollPane(movedToAltered), BorderLayout.CENTER); final List<SaveEvent> alsoSavedList = new ArrayList<SaveEvent>();
pane.add(movedToAlteredPane, JideBoxLayout.FLEXIBLE); final List<SaveEvent> errors = new ArrayList<SaveEvent>();
} for (SaveEvent event : events) {
if (event.error) {
errors.add(event);
} else {
switch (event.type) {
case alsoSave:
alsoSavedList.add(event);
break;
case moveToAltered:
movedToAlteredList.add(event);
break;
case moveToCreated:
movedToCreatedList.add(event);
break;
}
}
}
if (!alsoSavedList.isEmpty()) { if (!errors.isEmpty()) {
willBeSaved = new JList(alsoSavedList.toArray()); setTitle("Errors in project. Cannot save.");
willBeSaved.setCellRenderer(new SaveEventsListCellRenderer()); JPanel pane = new JPanel();
JPanel willBeSavedPane = new JPanel(); pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
willBeSavedPane.setLayout(new BorderLayout()); if (originalRequester != null) {
willBeSavedPane.setBorder(BorderFactory.createTitledBorder("The following elements will be saved too:")); pane.add(new JLabel(" While trying to save: "), JideBoxLayout.FIX);
willBeSavedPane.add(new JScrollPane(willBeSaved), BorderLayout.CENTER); JLabel origItemDesc = new JLabel();
pane.add(willBeSavedPane, JideBoxLayout.FLEXIBLE); origItemDesc.setIcon(new ImageIcon(originalRequester.getIcon()));
} origItemDesc.setText(originalRequester.getDataType().toString() + "/" + originalRequester.id);
pane.add(origItemDesc, JideBoxLayout.FIX);
pane.add(new JLabel(" the following errors have been encountered and must be corrected before saving can occur: "), JideBoxLayout.FIX);
} else {
pane.add(new JLabel("After deleting element(s), the following errors have been encountered and must be coorected before saving can occur: "), JideBoxLayout.FIX);
}
pane.add(new JPanel(), JideBoxLayout.VARY); movedToCreated = new JList(errors.toArray());
movedToCreated.setCellRenderer(new SaveEventsListCellRenderer());
JPanel movedToCreatedPane = new JPanel();
movedToCreatedPane.setLayout(new BorderLayout());
movedToCreatedPane.add(new JScrollPane(movedToCreated), BorderLayout.CENTER);
pane.add(movedToCreatedPane, JideBoxLayout.FLEXIBLE);
JPanel buttonPane = new JPanel(); pane.add(new JPanel(), JideBoxLayout.VARY);
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
JButton cancelButton = new JButton("Cancel");
buttonPane.add(cancelButton, JideBoxLayout.FIX);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SaveItemsWizard.this.setVisible(false);
SaveItemsWizard.this.dispose();
}
});
JButton okButton = new JButton("Apply all changes and save");
buttonPane.add(okButton, JideBoxLayout.FIX);
pane.add(buttonPane, JideBoxLayout.FIX);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Map<GameDataCategory<JSONElement>, Set<File>> jsonToSave = new IdentityHashMap<GameDataCategory<JSONElement>, Set<File>>(); JPanel buttonPane = new JPanel();
for (SaveEvent event : movedToCreatedList) { buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
if (event.target instanceof JSONElement) { buttonPane.add(new JPanel(), JideBoxLayout.VARY);
if (!jsonToSave.containsKey(event.target.getParent())){ JButton cancelButton = new JButton("Ok, back to work...");
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>()); buttonPane.add(cancelButton, JideBoxLayout.FIX);
} pane.add(buttonPane, JideBoxLayout.FIX);
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement)event.target).jsonFile); cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SaveItemsWizard.this.setVisible(false);
SaveItemsWizard.this.dispose();
}
});
event.target.getProject().moveToCreated((JSONElement) event.target);
if (!jsonToSave.containsKey(event.target.getParent())){ getContentPane().setLayout(new BorderLayout());
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>()); getContentPane().add(pane, BorderLayout.CENTER);
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement)event.target).jsonFile);
}
//TODO movable maps, when ID is editable.
} } else {
for (SaveEvent event : movedToAlteredList) { setTitle("Other elements impacted.");
if (event.target instanceof JSONElement) { JPanel pane = new JPanel();
if (!jsonToSave.containsKey(event.target.getParent())){ pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>()); if (originalRequester != null) {
} pane.add(new JLabel(" While trying to save: "), JideBoxLayout.FIX);
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement)event.target).jsonFile); JLabel origItemDesc = new JLabel();
origItemDesc.setIcon(new ImageIcon(originalRequester.getIcon()));
origItemDesc.setText(originalRequester.getDataType().toString() + "/" + originalRequester.id);
pane.add(origItemDesc, JideBoxLayout.FIX);
pane.add(new JLabel(" the following side-effects have been identified and must be applied to the project before saving: "), JideBoxLayout.FIX);
} else {
pane.add(new JLabel("After deleting element(s), the following side-effects have been identified and must be applied to the project before saving: "), JideBoxLayout.FIX);
}
event.target.getProject().moveToAltered((JSONElement) event.target); if (!movedToCreatedList.isEmpty()) {
movedToCreated = new JList(movedToCreatedList.toArray());
movedToCreated.setCellRenderer(new SaveEventsListCellRenderer());
JPanel movedToCreatedPane = new JPanel();
movedToCreatedPane.setLayout(new BorderLayout());
movedToCreatedPane.setBorder(BorderFactory.createTitledBorder("The following elements will be moved under the \"Created\" folder and saved:"));
movedToCreatedPane.add(new JScrollPane(movedToCreated), BorderLayout.CENTER);
pane.add(movedToCreatedPane, JideBoxLayout.FLEXIBLE);
}
if (!jsonToSave.containsKey(event.target.getParent())){ if (!movedToAlteredList.isEmpty()) {
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>()); movedToAltered = new JList(movedToAlteredList.toArray());
} movedToAltered.setCellRenderer(new SaveEventsListCellRenderer());
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement)event.target).jsonFile); JPanel movedToAlteredPane = new JPanel();
} movedToAlteredPane.setLayout(new BorderLayout());
//TODO movable maps, when ID is editable. movedToAlteredPane.setBorder(BorderFactory.createTitledBorder("The following elements will be moved under the \"Altered\" folder and saved:"));
} movedToAlteredPane.add(new JScrollPane(movedToAltered), BorderLayout.CENTER);
for (SaveEvent event : alsoSavedList) { pane.add(movedToAlteredPane, JideBoxLayout.FLEXIBLE);
if (event.target instanceof JSONElement) { }
if (!jsonToSave.containsKey(event.target.getParent())){
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>());
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement)event.target).jsonFile);
}
}
for (GameDataCategory<JSONElement> cat : jsonToSave.keySet()) { if (!alsoSavedList.isEmpty()) {
if (jsonToSave.get(cat) != null && !jsonToSave.get(cat).isEmpty()) { willBeSaved = new JList(alsoSavedList.toArray());
for (File f : jsonToSave.get(cat)) { willBeSaved.setCellRenderer(new SaveEventsListCellRenderer());
cat.save(f); JPanel willBeSavedPane = new JPanel();
} willBeSavedPane.setLayout(new BorderLayout());
} willBeSavedPane.setBorder(BorderFactory.createTitledBorder("The following elements will be saved too:"));
} willBeSavedPane.add(new JScrollPane(willBeSaved), BorderLayout.CENTER);
pane.add(willBeSavedPane, JideBoxLayout.FLEXIBLE);
}
for (SaveEvent event : movedToCreatedList) { pane.add(new JPanel(), JideBoxLayout.VARY);
ATContentStudio.frame.nodeChanged(event.target);
}
for (SaveEvent event : movedToAlteredList) {
ATContentStudio.frame.nodeChanged(event.target);
}
for (SaveEvent event : alsoSavedList) {
ATContentStudio.frame.nodeChanged(event.target);
}
SaveItemsWizard.this.setVisible(false);
SaveItemsWizard.this.dispose();
}
});
getContentPane().setLayout(new BorderLayout()); JPanel buttonPane = new JPanel();
getContentPane().add(pane, BorderLayout.CENTER); buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
JButton cancelButton = new JButton("Cancel");
buttonPane.add(cancelButton, JideBoxLayout.FIX);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SaveItemsWizard.this.setVisible(false);
SaveItemsWizard.this.dispose();
}
});
JButton okButton = new JButton("Apply all changes and save");
buttonPane.add(okButton, JideBoxLayout.FIX);
pane.add(buttonPane, JideBoxLayout.FIX);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Map<GameDataCategory<JSONElement>, Set<File>> jsonToSave = new IdentityHashMap<>();
for (SaveEvent event : movedToCreatedList) {
if (event.target instanceof JSONElement) {
if (!jsonToSave.containsKey(event.target.getParent())) {
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>());
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement) event.target).jsonFile);
event.target.getProject().moveToCreated((JSONElement) event.target);
if (!jsonToSave.containsKey(event.target.getParent())) {
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>());
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement) event.target).jsonFile);
}
//TODO movable maps, when ID is editable.
}
for (SaveEvent event : movedToAlteredList) {
if (event.target instanceof JSONElement) {
if (!jsonToSave.containsKey(event.target.getParent())) {
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>());
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement) event.target).jsonFile);
event.target.getProject().moveToAltered((JSONElement) event.target);
if (!jsonToSave.containsKey(event.target.getParent())) {
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>());
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement) event.target).jsonFile);
}
//TODO movable maps, when ID is editable.
}
for (SaveEvent event : alsoSavedList) {
if (event.target instanceof JSONElement) {
if (!jsonToSave.containsKey(event.target.getParent())) {
jsonToSave.put((GameDataCategory<JSONElement>) event.target.getParent(), new HashSet<File>());
}
jsonToSave.get((GameDataCategory<JSONElement>) event.target.getParent()).add(((JSONElement) event.target).jsonFile);
}
}
for (GameDataCategory<JSONElement> cat : jsonToSave.keySet()) {
if (jsonToSave.get(cat) != null && !jsonToSave.get(cat).isEmpty()) {
for (File f : jsonToSave.get(cat)) {
cat.save(f);
}
}
}
for (SaveEvent event : movedToCreatedList) {
ATContentStudio.frame.nodeChanged(event.target);
}
for (SaveEvent event : movedToAlteredList) {
ATContentStudio.frame.nodeChanged(event.target);
}
for (SaveEvent event : alsoSavedList) {
ATContentStudio.frame.nodeChanged(event.target);
}
SaveItemsWizard.this.setVisible(false);
SaveItemsWizard.this.dispose();
}
});
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
}
pack();
}
public class SaveEventsListCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 5764079243906396333L;
@Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) {
JLabel label = (JLabel) c;
SaveEvent event = (SaveEvent) value;
label.setIcon(new ImageIcon(event.target.getIcon()));
if (event.error) {
label.setText(event.target.getDataType().toString() + "/" + event.target.id + ": " + event.errorText);
} else {
label.setText(event.target.getDataType().toString() + "/" + event.target.id);
}
}
return c;
}
}
}
pack();
}
public class SaveEventsListCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 5764079243906396333L;
@Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) {
JLabel label = (JLabel) c;
SaveEvent event = (SaveEvent) value;
label.setIcon(new ImageIcon(event.target.getIcon()));
if (event.error) {
label.setText(event.target.getDataType().toString()+"/"+event.target.id+": "+event.errorText);
} else {
label.setText(event.target.getDataType().toString()+"/"+event.target.id);
}
}
return c;
}
}
} }

View File

@@ -1,338 +1,300 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.Dimension; import javax.swing.*;
import java.awt.FlowLayout; import java.awt.*;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import javax.swing.JPanel;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
public class ScrollablePanel extends JPanel implements Scrollable, SwingConstants { public class ScrollablePanel extends JPanel implements Scrollable, SwingConstants {
private static final long serialVersionUID = 6498229143202972325L;
public enum ScrollableSizeHint private static final long serialVersionUID = 6498229143202972325L;
{
NONE,
FIT,
STRETCH;
}
public enum IncrementType public enum ScrollableSizeHint {
{ NONE,
PERCENT, FIT,
PIXELS; STRETCH
} }
private ScrollableSizeHint scrollableHeight = ScrollableSizeHint.NONE; public enum IncrementType {
private ScrollableSizeHint scrollableWidth = ScrollableSizeHint.NONE; PERCENT,
PIXELS
}
private IncrementInfo horizontalBlock; private ScrollableSizeHint scrollableHeight = ScrollableSizeHint.NONE;
private IncrementInfo horizontalUnit; private ScrollableSizeHint scrollableWidth = ScrollableSizeHint.NONE;
private IncrementInfo verticalBlock;
private IncrementInfo verticalUnit;
/** private IncrementInfo horizontalBlock;
* Default constructor that uses a FlowLayout private IncrementInfo horizontalUnit;
*/ private IncrementInfo verticalBlock;
public ScrollablePanel() private IncrementInfo verticalUnit;
{
this( new FlowLayout() );
}
/** /**
* Constuctor for specifying the LayoutManager of the panel. * Default constructor that uses a FlowLayout
* */
* @param layout the LayountManger for the panel public ScrollablePanel() {
*/ this(new FlowLayout());
public ScrollablePanel(LayoutManager layout) }
{
super( layout );
IncrementInfo block = new IncrementInfo(IncrementType.PERCENT, 100); /**
IncrementInfo unit = new IncrementInfo(IncrementType.PERCENT, 10); * Constuctor for specifying the LayoutManager of the panel.
*
* @param layout the LayountManger for the panel
*/
public ScrollablePanel(LayoutManager layout) {
super(layout);
setScrollableBlockIncrement(HORIZONTAL, block); IncrementInfo block = new IncrementInfo(IncrementType.PERCENT, 100);
setScrollableBlockIncrement(VERTICAL, block); IncrementInfo unit = new IncrementInfo(IncrementType.PERCENT, 10);
setScrollableUnitIncrement(HORIZONTAL, unit);
setScrollableUnitIncrement(VERTICAL, unit);
}
/** setScrollableBlockIncrement(HORIZONTAL, block);
* Get the height ScrollableSizeHint enum setScrollableBlockIncrement(VERTICAL, block);
* setScrollableUnitIncrement(HORIZONTAL, unit);
* @return the ScrollableSizeHint enum for the height setScrollableUnitIncrement(VERTICAL, unit);
*/ }
public ScrollableSizeHint getScrollableHeight()
{
return scrollableHeight;
}
/** /**
* Set the ScrollableSizeHint enum for the height. The enum is used to * Get the height ScrollableSizeHint enum
* determine the boolean value that is returned by the *
* getScrollableTracksViewportHeight() method. The valid values are: * @return the ScrollableSizeHint enum for the height
* */
* ScrollableSizeHint.NONE - return "false", which causes the height public ScrollableSizeHint getScrollableHeight() {
* of the panel to be used when laying out the children return scrollableHeight;
* ScrollableSizeHint.FIT - return "true", which causes the height of }
* the viewport to be used when laying out the children
* ScrollableSizeHint.STRETCH - return "true" when the viewport height
* is greater than the height of the panel, "false" otherwise.
*
* @param scrollableHeight as represented by the ScrollableSizeHint enum.
*/
public void setScrollableHeight(ScrollableSizeHint scrollableHeight)
{
this.scrollableHeight = scrollableHeight;
revalidate();
}
/** /**
* Get the width ScrollableSizeHint enum * Set the ScrollableSizeHint enum for the height. The enum is used to
* * determine the boolean value that is returned by the
* @return the ScrollableSizeHint enum for the width * getScrollableTracksViewportHeight() method. The valid values are:
*/ * <p>
public ScrollableSizeHint getScrollableWidth() * ScrollableSizeHint.NONE - return "false", which causes the height
{ * of the panel to be used when laying out the children
return scrollableWidth; * ScrollableSizeHint.FIT - return "true", which causes the height of
} * the viewport to be used when laying out the children
* ScrollableSizeHint.STRETCH - return "true" when the viewport height
* is greater than the height of the panel, "false" otherwise.
*
* @param scrollableHeight as represented by the ScrollableSizeHint enum.
*/
public void setScrollableHeight(ScrollableSizeHint scrollableHeight) {
this.scrollableHeight = scrollableHeight;
revalidate();
}
/** /**
* Set the ScrollableSizeHint enum for the width. The enum is used to * Get the width ScrollableSizeHint enum
* determine the boolean value that is returned by the *
* getScrollableTracksViewportWidth() method. The valid values are: * @return the ScrollableSizeHint enum for the width
* */
* ScrollableSizeHint.NONE - return "false", which causes the width public ScrollableSizeHint getScrollableWidth() {
* of the panel to be used when laying out the children return scrollableWidth;
* ScrollableSizeHint.FIT - return "true", which causes the width of }
* the viewport to be used when laying out the children
* ScrollableSizeHint.STRETCH - return "true" when the viewport width
* is greater than the width of the panel, "false" otherwise.
*
* @param scrollableWidth as represented by the ScrollableSizeHint enum.
*/
public void setScrollableWidth(ScrollableSizeHint scrollableWidth)
{
this.scrollableWidth = scrollableWidth;
revalidate();
}
/** /**
* Get the block IncrementInfo for the specified orientation * Set the ScrollableSizeHint enum for the width. The enum is used to
* * determine the boolean value that is returned by the
* @return the block IncrementInfo for the specified orientation * getScrollableTracksViewportWidth() method. The valid values are:
*/ * <p>
public IncrementInfo getScrollableBlockIncrement(int orientation) * ScrollableSizeHint.NONE - return "false", which causes the width
{ * of the panel to be used when laying out the children
return orientation == SwingConstants.HORIZONTAL ? horizontalBlock : verticalBlock; * ScrollableSizeHint.FIT - return "true", which causes the width of
} * the viewport to be used when laying out the children
* ScrollableSizeHint.STRETCH - return "true" when the viewport width
* is greater than the width of the panel, "false" otherwise.
*
* @param scrollableWidth as represented by the ScrollableSizeHint enum.
*/
public void setScrollableWidth(ScrollableSizeHint scrollableWidth) {
this.scrollableWidth = scrollableWidth;
revalidate();
}
/** /**
* Specify the information needed to do block scrolling. * Get the block IncrementInfo for the specified orientation
* *
* @param orientation specify the scrolling orientation. Must be either: * @return the block IncrementInfo for the specified orientation
* SwingContants.HORIZONTAL or SwingContants.VERTICAL. */
* @paran type specify how the amount parameter in the calculation of public IncrementInfo getScrollableBlockIncrement(int orientation) {
* the scrollable amount. Valid values are: return orientation == SwingConstants.HORIZONTAL ? horizontalBlock : verticalBlock;
* IncrementType.PERCENT - treat the amount as a % of the viewport size }
* IncrementType.PIXEL - treat the amount as the scrollable amount
* @param amount a value used with the IncrementType to determine the
* scrollable amount
*/
public void setScrollableBlockIncrement(int orientation, IncrementType type, int amount)
{
IncrementInfo info = new IncrementInfo(type, amount);
setScrollableBlockIncrement(orientation, info);
}
/** /**
* Specify the information needed to do block scrolling. * Specify the information needed to do block scrolling.
* *
* @param orientation specify the scrolling orientation. Must be either: * @param orientation specify the scrolling orientation. Must be either:
* SwingContants.HORIZONTAL or SwingContants.VERTICAL. * SwingContants.HORIZONTAL or SwingContants.VERTICAL.
* @param info An IncrementInfo object containing information of how to * @param amount a value used with the IncrementType to determine the
* calculate the scrollable amount. * scrollable amount
*/ * @paran type specify how the amount parameter in the calculation of
public void setScrollableBlockIncrement(int orientation, IncrementInfo info) * the scrollable amount. Valid values are:
{ * IncrementType.PERCENT - treat the amount as a % of the viewport size
switch(orientation) * IncrementType.PIXEL - treat the amount as the scrollable amount
{ */
case SwingConstants.HORIZONTAL: public void setScrollableBlockIncrement(int orientation, IncrementType type, int amount) {
horizontalBlock = info; IncrementInfo info = new IncrementInfo(type, amount);
break; setScrollableBlockIncrement(orientation, info);
case SwingConstants.VERTICAL: }
verticalBlock = info;
break;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
/** /**
* Get the unit IncrementInfo for the specified orientation * Specify the information needed to do block scrolling.
* *
* @return the unit IncrementInfo for the specified orientation * @param orientation specify the scrolling orientation. Must be either:
*/ * SwingContants.HORIZONTAL or SwingContants.VERTICAL.
public IncrementInfo getScrollableUnitIncrement(int orientation) * @param info An IncrementInfo object containing information of how to
{ * calculate the scrollable amount.
return orientation == SwingConstants.HORIZONTAL ? horizontalUnit : verticalUnit; */
} public void setScrollableBlockIncrement(int orientation, IncrementInfo info) {
switch (orientation) {
case SwingConstants.HORIZONTAL:
horizontalBlock = info;
break;
case SwingConstants.VERTICAL:
verticalBlock = info;
break;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
/** /**
* Specify the information needed to do unit scrolling. * Get the unit IncrementInfo for the specified orientation
* *
* @param orientation specify the scrolling orientation. Must be either: * @return the unit IncrementInfo for the specified orientation
* SwingContants.HORIZONTAL or SwingContants.VERTICAL. */
* @paran type specify how the amount parameter in the calculation of public IncrementInfo getScrollableUnitIncrement(int orientation) {
* the scrollable amount. Valid values are: return orientation == SwingConstants.HORIZONTAL ? horizontalUnit : verticalUnit;
* IncrementType.PERCENT - treat the amount as a % of the viewport size }
* IncrementType.PIXEL - treat the amount as the scrollable amount
* @param amount a value used with the IncrementType to determine the
* scrollable amount
*/
public void setScrollableUnitIncrement(int orientation, IncrementType type, int amount)
{
IncrementInfo info = new IncrementInfo(type, amount);
setScrollableUnitIncrement(orientation, info);
}
/** /**
* Specify the information needed to do unit scrolling. * Specify the information needed to do unit scrolling.
* *
* @param orientation specify the scrolling orientation. Must be either: * @param orientation specify the scrolling orientation. Must be either:
* SwingContants.HORIZONTAL or SwingContants.VERTICAL. * SwingContants.HORIZONTAL or SwingContants.VERTICAL.
* @param info An IncrementInfo object containing information of how to * @param amount a value used with the IncrementType to determine the
* calculate the scrollable amount. * scrollable amount
*/ * @paran type specify how the amount parameter in the calculation of
public void setScrollableUnitIncrement(int orientation, IncrementInfo info) * the scrollable amount. Valid values are:
{ * IncrementType.PERCENT - treat the amount as a % of the viewport size
switch(orientation) * IncrementType.PIXEL - treat the amount as the scrollable amount
{ */
case SwingConstants.HORIZONTAL: public void setScrollableUnitIncrement(int orientation, IncrementType type, int amount) {
horizontalUnit = info; IncrementInfo info = new IncrementInfo(type, amount);
break; setScrollableUnitIncrement(orientation, info);
case SwingConstants.VERTICAL: }
verticalUnit = info;
break;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
//Implement Scrollable interface /**
* Specify the information needed to do unit scrolling.
*
* @param orientation specify the scrolling orientation. Must be either:
* SwingContants.HORIZONTAL or SwingContants.VERTICAL.
* @param info An IncrementInfo object containing information of how to
* calculate the scrollable amount.
*/
public void setScrollableUnitIncrement(int orientation, IncrementInfo info) {
switch (orientation) {
case SwingConstants.HORIZONTAL:
horizontalUnit = info;
break;
case SwingConstants.VERTICAL:
verticalUnit = info;
break;
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
public Dimension getPreferredScrollableViewportSize() //Implement Scrollable interface
{
return getPreferredSize();
}
public int getScrollableUnitIncrement( public Dimension getPreferredScrollableViewportSize() {
Rectangle visible, int orientation, int direction) return getPreferredSize();
{ }
switch(orientation)
{
case SwingConstants.HORIZONTAL:
return getScrollableIncrement(horizontalUnit, visible.width);
case SwingConstants.VERTICAL:
return getScrollableIncrement(verticalUnit, visible.height);
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
public int getScrollableBlockIncrement( public int getScrollableUnitIncrement(
Rectangle visible, int orientation, int direction) Rectangle visible, int orientation, int direction) {
{ switch (orientation) {
switch(orientation) case SwingConstants.HORIZONTAL:
{ return getScrollableIncrement(horizontalUnit, visible.width);
case SwingConstants.HORIZONTAL: case SwingConstants.VERTICAL:
return getScrollableIncrement(horizontalBlock, visible.width); return getScrollableIncrement(verticalUnit, visible.height);
case SwingConstants.VERTICAL: default:
return getScrollableIncrement(verticalBlock, visible.height); throw new IllegalArgumentException("Invalid orientation: " + orientation);
default: }
throw new IllegalArgumentException("Invalid orientation: " + orientation); }
}
}
protected int getScrollableIncrement(IncrementInfo info, int distance) public int getScrollableBlockIncrement(
{ Rectangle visible, int orientation, int direction) {
if (info.getIncrement() == IncrementType.PIXELS) switch (orientation) {
return info.getAmount(); case SwingConstants.HORIZONTAL:
else return getScrollableIncrement(horizontalBlock, visible.width);
return distance * info.getAmount() / 100; case SwingConstants.VERTICAL:
} return getScrollableIncrement(verticalBlock, visible.height);
default:
throw new IllegalArgumentException("Invalid orientation: " + orientation);
}
}
public boolean getScrollableTracksViewportWidth() protected int getScrollableIncrement(IncrementInfo info, int distance) {
{ if (info.getIncrement() == IncrementType.PIXELS)
if (scrollableWidth == ScrollableSizeHint.NONE) return info.getAmount();
return false; else
return distance * info.getAmount() / 100;
}
if (scrollableWidth == ScrollableSizeHint.FIT) public boolean getScrollableTracksViewportWidth() {
return true; if (scrollableWidth == ScrollableSizeHint.NONE)
return false;
// STRETCH sizing, use the greater of the panel or viewport width if (scrollableWidth == ScrollableSizeHint.FIT)
return true;
if (getParent() instanceof JViewport) // STRETCH sizing, use the greater of the panel or viewport width
{
return (((JViewport)getParent()).getWidth() > getPreferredSize().width);
}
return false; if (getParent() instanceof JViewport) {
} return (((JViewport) getParent()).getWidth() > getPreferredSize().width);
}
public boolean getScrollableTracksViewportHeight() return false;
{ }
if (scrollableHeight == ScrollableSizeHint.NONE)
return false;
if (scrollableHeight == ScrollableSizeHint.FIT) public boolean getScrollableTracksViewportHeight() {
return true; if (scrollableHeight == ScrollableSizeHint.NONE)
return false;
// STRETCH sizing, use the greater of the panel or viewport height if (scrollableHeight == ScrollableSizeHint.FIT)
return true;
// STRETCH sizing, use the greater of the panel or viewport height
if (getParent() instanceof JViewport) if (getParent() instanceof JViewport) {
{ return (((JViewport) getParent()).getHeight() > getPreferredSize().height);
return (((JViewport)getParent()).getHeight() > getPreferredSize().height); }
}
return false; return false;
} }
/** /**
* Helper class to hold the information required to calculate the scroll amount. * Helper class to hold the information required to calculate the scroll amount.
*/ */
static class IncrementInfo static class IncrementInfo {
{ private IncrementType type;
private IncrementType type; private int amount;
private int amount;
public IncrementInfo(IncrementType type, int amount) public IncrementInfo(IncrementType type, int amount) {
{ this.type = type;
this.type = type; this.amount = amount;
this.amount = amount; }
}
public IncrementType getIncrement() public IncrementType getIncrement() {
{ return type;
return type; }
}
public int getAmount() public int getAmount() {
{ return amount;
return amount; }
}
public String toString() public String toString() {
{ return
return "ScrollablePanel[" +
"ScrollablePanel[" + type + ", " +
type + ", " + amount + "]";
amount + "]"; }
} }
}
} }

View File

@@ -1,29 +1,5 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.ConfigCache; import com.gpl.rpg.atcontentstudio.ConfigCache;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
@@ -32,227 +8,217 @@ 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;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
public class StudioFrame extends JFrame { public class StudioFrame extends JFrame {
private static final long serialVersionUID = -3391514100319186661L; private static final long serialVersionUID = -3391514100319186661L;
final ProjectsTree projectTree;
final EditorsArea editors;
final WorkspaceActions actions = new WorkspaceActions();
public StudioFrame(String name) {
super(name);
setIconImage(DefaultIcons.getMainIconImage());
final JSplitPane topDown = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
final JSplitPane leftRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
@SuppressWarnings("rawtypes")
JList notifs = new NotificationsPane();
projectTree = new ProjectsTree();
editors = new EditorsArea();
setJMenuBar(new JMenuBar());
buildMenu();
JScrollPane treeScroller = new JScrollPane(projectTree);
treeScroller.getVerticalScrollBar().setUnitIncrement(16);
leftRight.setLeftComponent(treeScroller);
leftRight.setRightComponent(editors);
leftRight.setName("StudioFrame.leftRight");
topDown.setTopComponent(leftRight);
JScrollPane notifScroller = new JScrollPane(notifs);
notifScroller.getVerticalScrollBar().setUnitIncrement(16);
topDown.setBottomComponent(notifScroller);
topDown.setName("StudioFrame.topDown");
getContentPane().setLayout(new BorderLayout());
getContentPane().add(topDown, BorderLayout.CENTER);
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
Workspace.activeWorkspace.preferences.windowSize = StudioFrame.this.getSize();
}
});
pack();
if (Workspace.activeWorkspace.preferences.windowSize != null) {
setSize(Workspace.activeWorkspace.preferences.windowSize);
} else {
setSize(800, 600);
}
if (Workspace.activeWorkspace.preferences.splittersPositions.get(topDown.getName()) != null) {
topDown.setDividerLocation(Workspace.activeWorkspace.preferences.splittersPositions.get(topDown.getName()));
} else {
topDown.setDividerLocation(0.2);
}
topDown.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Workspace.activeWorkspace.preferences.splittersPositions.put(topDown.getName(), topDown.getDividerLocation());
}
});
if (Workspace.activeWorkspace.preferences.splittersPositions.get(leftRight.getName()) != null) {
leftRight.setDividerLocation(Workspace.activeWorkspace.preferences.splittersPositions.get(leftRight.getName()));
} else {
leftRight.setDividerLocation(0.3);
}
leftRight.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Workspace.activeWorkspace.preferences.splittersPositions.put(leftRight.getName(), leftRight.getDividerLocation());
}
});
showAbout();
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Workspace.saveActive();
actions.exitATCS.actionPerformed(null);
}
});
}
private void buildMenu() {
JMenu fileMenu = new JMenu("File");
fileMenu.add(new JMenuItem(actions.createProject));
fileMenu.add(new JMenuItem(actions.openProject));
fileMenu.add(new JMenuItem(actions.closeProject));
fileMenu.add(new JMenuItem(actions.deleteProject));
fileMenu.add(new JSeparator());
fileMenu.add(new JMenuItem(actions.editWorkspaceSettings));
fileMenu.add(new JSeparator());
fileMenu.add(new JMenuItem(actions.exitATCS));
getJMenuBar().add(fileMenu);
JMenu projectMenu = new JMenu("Project");
projectMenu.add(new JMenuItem(actions.saveElement));
projectMenu.add(new JMenuItem(actions.deleteSelected));
projectMenu.add(new JSeparator());
projectMenu.add(new JMenuItem(actions.createGDE));
projectMenu.add(new JMenuItem(actions.importJSON));
projectMenu.add(new JMenuItem(actions.createMap));
projectMenu.add(new JMenuItem(actions.createWorldmap));
projectMenu.add(new JMenuItem(actions.loadSave));
getJMenuBar().add(projectMenu);
JMenu toolsMenu = new JMenu("Tools");
toolsMenu.add(new JMenuItem(actions.compareItems));
toolsMenu.add(new JMenuItem(actions.compareNPCs));
toolsMenu.add(new JSeparator());
toolsMenu.add(new JMenuItem(actions.runBeanShell));
toolsMenu.add(new JSeparator());
toolsMenu.add(new JMenuItem(actions.exportProject));
getJMenuBar().add(toolsMenu);
JMenu viewMenu = new JMenu("View");
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());
ATContentStudio.scaleUIFont();
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();
}
}
});
}
viewMenu.add(changeLaF);
viewMenu.add(new JSeparator());
viewMenu.add(new JMenuItem(actions.showAbout));
getJMenuBar().add(viewMenu);
}
public void openEditor(JSONElement node) {
node.link();
editors.openEditor(node);
}
public void openEditor(Spritesheet node) {
editors.openEditor(node);
}
public void openEditor(TMXMap node) {
node.parse();
editors.openEditor(node);
}
public void openEditor(WriterModeData node) {
node.link();
editors.openEditor(node);
}
public void openEditor(GameDataElement node) {
if (node instanceof JSONElement) {
openEditor((JSONElement) node);
} else if (node instanceof Spritesheet) {
openEditor((Spritesheet) node);
} else if (node instanceof TMXMap) {
openEditor((TMXMap) node);
} else if (node instanceof WorldmapSegment) {
openEditor((WorldmapSegment) node);
} else if (node instanceof WriterModeData) {
openEditor((WriterModeData) node);
}
}
public void openEditor(SavedGame save) {
editors.openEditor(save);
}
public void openEditor(WorldmapSegment node) {
editors.openEditor(node);
}
public void closeEditor(ProjectTreeNode node) {
editors.closeEditor(node);
}
public void selectInTree(ProjectTreeNode node) {
projectTree.setSelectedNode(node);
}
public void editorChanged(Editor e) {
editors.editorTabChanged(e);
}
public void editorChanged(ProjectTreeNode node) {
editors.editorTabChanged(node);
}
public void nodeChanged(ProjectTreeNode node) {
node.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(node);
}
public void showAbout() {
editors.showAbout();
}
final ProjectsTree projectTree;
final EditorsArea editors;
final WorkspaceActions actions = new WorkspaceActions();
public StudioFrame(String name) {
super(name);
setIconImage(DefaultIcons.getMainIconImage());
final JSplitPane topDown = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
final JSplitPane leftRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
@SuppressWarnings("rawtypes")
JList notifs = new NotificationsPane();
projectTree = new ProjectsTree();
editors = new EditorsArea();
setJMenuBar(new JMenuBar());
buildMenu();
JScrollPane treeScroller = new JScrollPane(projectTree);
treeScroller.getVerticalScrollBar().setUnitIncrement(16);
leftRight.setLeftComponent(treeScroller);
leftRight.setRightComponent(editors);
leftRight.setName("StudioFrame.leftRight");
topDown.setTopComponent(leftRight);
JScrollPane notifScroller = new JScrollPane(notifs);
notifScroller.getVerticalScrollBar().setUnitIncrement(16);
topDown.setBottomComponent(notifScroller);
topDown.setName("StudioFrame.topDown");
getContentPane().setLayout(new BorderLayout());
getContentPane().add(topDown, BorderLayout.CENTER);
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
Workspace.activeWorkspace.preferences.windowSize = StudioFrame.this.getSize();
}
});
pack();
if (Workspace.activeWorkspace.preferences.windowSize != null) {
setSize(Workspace.activeWorkspace.preferences.windowSize);
} else {
setSize(800, 600);
}
if (Workspace.activeWorkspace.preferences.splittersPositions.get(topDown.getName()) != null) {
topDown.setDividerLocation(Workspace.activeWorkspace.preferences.splittersPositions.get(topDown.getName()));
} else {
topDown.setDividerLocation(0.2);
}
topDown.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Workspace.activeWorkspace.preferences.splittersPositions.put(topDown.getName(), topDown.getDividerLocation());
}
});
if (Workspace.activeWorkspace.preferences.splittersPositions.get(leftRight.getName()) != null) {
leftRight.setDividerLocation(Workspace.activeWorkspace.preferences.splittersPositions.get(leftRight.getName()));
} else {
leftRight.setDividerLocation(0.3);
}
leftRight.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Workspace.activeWorkspace.preferences.splittersPositions.put(leftRight.getName(), leftRight.getDividerLocation());
}
});
showAbout();
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Workspace.saveActive();
actions.exitATCS.actionPerformed(null);
}
});
}
private void buildMenu() {
JMenu fileMenu = new JMenu("File");
fileMenu.add(new JMenuItem(actions.createProject));
fileMenu.add(new JMenuItem(actions.openProject));
fileMenu.add(new JMenuItem(actions.closeProject));
fileMenu.add(new JMenuItem(actions.deleteProject));
fileMenu.add(new JSeparator());
fileMenu.add(new JMenuItem(actions.editWorkspaceSettings));
fileMenu.add(new JSeparator());
fileMenu.add(new JMenuItem(actions.exitATCS));
getJMenuBar().add(fileMenu);
JMenu projectMenu = new JMenu("Project");
projectMenu.add(new JMenuItem(actions.saveElement));
projectMenu.add(new JMenuItem(actions.deleteSelected));
projectMenu.add(new JSeparator());
projectMenu.add(new JMenuItem(actions.createGDE));
projectMenu.add(new JMenuItem(actions.importJSON));
projectMenu.add(new JMenuItem(actions.createMap));
projectMenu.add(new JMenuItem(actions.createWorldmap));
getJMenuBar().add(projectMenu);
JMenu toolsMenu = new JMenu("Tools");
toolsMenu.add(new JMenuItem(actions.compareItems));
toolsMenu.add(new JMenuItem(actions.compareNPCs));
toolsMenu.add(new JSeparator());
toolsMenu.add(new JMenuItem(actions.runBeanShell));
toolsMenu.add(new JSeparator());
toolsMenu.add(new JMenuItem(actions.exportProject));
getJMenuBar().add(toolsMenu);
JMenu viewMenu = new JMenu("View");
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) {
String lookAndFeel = i.getClassName();
ATContentStudio.setLookAndFeel(lookAndFeel);
SwingUtilities.updateComponentTreeUI(ATContentStudio.frame);
ConfigCache.setFavoriteLaFClassName(lookAndFeel);
}
});
}
viewMenu.add(changeLaF);
viewMenu.add(new JSeparator());
viewMenu.add(new JMenuItem(actions.showAbout));
getJMenuBar().add(viewMenu);
}
public void openEditor(JSONElement node) {
node.link();
editors.openEditor(node);
}
public void openEditor(Spritesheet node) {
editors.openEditor(node);
}
public void openEditor(TMXMap node) {
node.parse();
editors.openEditor(node);
}
public void openEditor(WriterModeData node) {
node.link();
editors.openEditor(node);
}
public void openEditor(GameDataElement node) {
if (node instanceof JSONElement) {
openEditor((JSONElement) node);
} else if (node instanceof Spritesheet) {
openEditor((Spritesheet) node);
} else if (node instanceof TMXMap) {
openEditor((TMXMap) node);
} else if (node instanceof WorldmapSegment) {
openEditor((WorldmapSegment) node);
} else if (node instanceof WriterModeData) {
openEditor((WriterModeData) node);
}
}
public void openEditor(WorldmapSegment node) {
editors.openEditor(node);
}
public void closeEditor(ProjectTreeNode node) {
editors.closeEditor(node);
}
public void selectInTree(ProjectTreeNode node) {
projectTree.setSelectedNode(node);
}
public void editorChanged(Editor e) {
editors.editorTabChanged(e);
}
public void editorChanged(ProjectTreeNode node) {
editors.editorTabChanged(node);
}
public void nodeChanged(ProjectTreeNode node) {
node.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(node);
}
public void showAbout() {
editors.showAbout();
}
} }

View File

@@ -1,31 +1,5 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ButtonGroup;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State; import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
@@ -33,267 +7,280 @@ import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class TMXMapCreationWizard extends JDialog { public class TMXMapCreationWizard extends JDialog {
private static final long serialVersionUID = -474689694453543575L; private static final long serialVersionUID = -474689694453543575L;
private static final String DEFAULT_TEMPLATE = "template.tmx"; private static final String DEFAULT_TEMPLATE = "template.tmx";
private TMXMap creation = null;
final File templateFile;
final JLabel message;
final JRadioButton useTemplate, copyMap;
final JComboBox<TMXMap> templateCombo;
final JTextField idField;
final JButton ok;
final Project proj;
@SuppressWarnings({ "unchecked", "rawtypes" })
public TMXMapCreationWizard(final Project proj) {
super(ATContentStudio.frame);
this.proj = proj;
templateFile=new File(proj.baseContent.gameMaps.mapFolder, DEFAULT_TEMPLATE);
setTitle("Create new TMX map");
JPanel pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
pane.add(new JLabel("Create a new TMX map."), JideBoxLayout.FIX);
message = new JLabel("Enter new map name:");
pane.add(message, JideBoxLayout.FIX);
final JPanel idPane = new JPanel();
idPane.setLayout(new BorderLayout());
JLabel idLabel = new JLabel("Internal ID: ");
idPane.add(idLabel, BorderLayout.WEST);
idField = new JTextField("");
idField.setEditable(true);
idPane.add(idField, BorderLayout.CENTER);
pane.add(idPane, JideBoxLayout.FIX);
useTemplate = new JRadioButton("Use default template file ("+DEFAULT_TEMPLATE+")");
useTemplate.setToolTipText(templateFile.getAbsolutePath());
pane.add(useTemplate, JideBoxLayout.FIX);
copyMap = new JRadioButton("Copy existing map");
pane.add(copyMap, JideBoxLayout.FIX);
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(useTemplate);
radioGroup.add(copyMap);
final JPanel templatePane = new JPanel();
templatePane.setLayout(new BorderLayout());
JLabel templateLabel = new JLabel("Template to copy: ");
templatePane.add(templateLabel, BorderLayout.WEST);
templateCombo = new JComboBox(new TemplateComboModel());
templateCombo.setRenderer(new TemplateComboCellRenderer());
if (proj.getMap(DEFAULT_TEMPLATE) != null) templateCombo.setSelectedItem(proj.getMap(DEFAULT_TEMPLATE));
templatePane.add(templateCombo, BorderLayout.CENTER);
pane.add(templatePane, JideBoxLayout.FIX);
pane.add(templateCombo);
if (templateFile.exists()) {
useTemplate.setSelected(true);
copyMap.setSelected(false);
templateCombo.setEnabled(false);
} else {
useTemplate.setSelected(false);
useTemplate.setEnabled(false);
useTemplate.setToolTipText("Cannot find file "+templateFile.getAbsolutePath());
templateCombo.setEnabled(true);
copyMap.setSelected(true);
}
ActionListener radioListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (useTemplate.isSelected()) {
templateCombo.setEnabled(false);
} else if(copyMap.isSelected()) {
templateCombo.setEnabled(true);
}
updateStatus();
}
};
useTemplate.addActionListener(radioListener);
copyMap.addActionListener(radioListener);
templateCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateStatus();
}
});
pane.add(new JPanel(), JideBoxLayout.VARY);
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
JButton cancel = new JButton("Cancel");
buttonPane.add(cancel, JideBoxLayout.FIX);
ok = new JButton("Ok");
buttonPane.add(ok, JideBoxLayout.FIX);
pane.add(new JPanel(), JideBoxLayout.VARY);
pane.add(buttonPane, JideBoxLayout.FIX);
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (copyMap.isSelected()) {
creation = ((TMXMap)templateCombo.getSelectedItem()).clone();
} else if (useTemplate.isSelected()) {
creation = new TMXMap(proj.createdContent.gameMaps, templateFile);
creation.parse();
}
creation.id = idField.getText();
creation.tmxFile = new File(creation.id+".tmx");
TMXMapCreationWizard.this.setVisible(false);
TMXMapCreationWizard.this.dispose();
creation.state = State.created;
proj.createElement(creation);
notifyCreated();
ATContentStudio.frame.selectInTree(creation);
ATContentStudio.frame.openEditor(creation);
}
});
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
creation = null;
TMXMapCreationWizard.this.setVisible(false);
TMXMapCreationWizard.this.dispose();
}
});
DocumentListener statusUpdater = new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateStatus();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateStatus();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateStatus();
}
};
idField.getDocument().addDocumentListener(statusUpdater);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
setMinimumSize(new Dimension(350,250));
updateStatus();
pack();
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
Dimension wdim = getSize();
setLocation((sdim.width - wdim.width)/2, (sdim.height - wdim.height)/2);
}
public void updateStatus() {
boolean trouble = false;
message.setText("<html><font color=\"#00AA00\">Looks OK to me.</font></html>");
if (copyMap.isSelected() && templateCombo.getSelectedItem() == null) {
message.setText("<html><font color=\"#FF0000\">Select a map template below:</font></html>");
trouble = true;
} else if (idField.getText() == null || idField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">Internal ID must not be empty.</font></html>");
trouble = true;
} else if (proj.getMap(idField.getText()) != null) {
if (proj.getMap(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">A map with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getMap(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">A map with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getMap(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">A map with the same ID exists in the game. The new one will be added under \"altered\".</font></html>");
}
}
ok.setEnabled(!trouble);
message.revalidate();
message.repaint();
}
public static interface CreationCompletedListener {
public void mapCreated(TMXMap created);
}
private List<CreationCompletedListener> listeners = new CopyOnWriteArrayList<TMXMapCreationWizard.CreationCompletedListener>();
public void addCreationListener(CreationCompletedListener l) {
listeners.add(l);
}
public void notifyCreated() {
for (CreationCompletedListener l : listeners) {
l.mapCreated(creation);
}
}
class TemplateComboModel implements ComboBoxModel<TMXMap> {
Object selected;
@Override private TMXMap creation = null;
public int getSize() { final File templateFile;
return proj.getMapCount();
}
@Override final JLabel message;
public TMXMap getElementAt(int index) { final JRadioButton useTemplate, copyMap;
return proj.getMap(index); final JComboBox<TMXMap> templateCombo;
} final JTextField idField;
final JButton ok;
final Project proj;
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>(); @SuppressWarnings({"unchecked", "rawtypes"})
public TMXMapCreationWizard(final Project proj) {
@Override super(ATContentStudio.frame);
public void addListDataListener(ListDataListener l) { this.proj = proj;
listeners.add(l); templateFile = new File(proj.baseContent.gameMaps.mapFolder, DEFAULT_TEMPLATE);
}
@Override setTitle("Create new TMX map");
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
@Override JPanel pane = new JPanel();
public void setSelectedItem(Object anItem) { pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
selected = anItem;
}
@Override pane.add(new JLabel("Create a new TMX map."), JideBoxLayout.FIX);
public Object getSelectedItem() {
return selected; message = new JLabel("Enter new map name:");
} pane.add(message, JideBoxLayout.FIX);
} final JPanel idPane = new JPanel();
idPane.setLayout(new BorderLayout());
class TemplateComboCellRenderer extends DefaultListCellRenderer { JLabel idLabel = new JLabel("Internal ID: ");
private static final long serialVersionUID = 5621373849299980998L; idPane.add(idLabel, BorderLayout.WEST);
idField = new JTextField("");
idField.setEditable(true);
idPane.add(idField, BorderLayout.CENTER);
pane.add(idPane, JideBoxLayout.FIX);
useTemplate = new JRadioButton("Use default template file (" + DEFAULT_TEMPLATE + ")");
useTemplate.setToolTipText(templateFile.getAbsolutePath());
pane.add(useTemplate, JideBoxLayout.FIX);
copyMap = new JRadioButton("Copy existing map");
pane.add(copyMap, JideBoxLayout.FIX);
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(useTemplate);
radioGroup.add(copyMap);
final JPanel templatePane = new JPanel();
templatePane.setLayout(new BorderLayout());
JLabel templateLabel = new JLabel("Template to copy: ");
templatePane.add(templateLabel, BorderLayout.WEST);
templateCombo = new JComboBox(new TemplateComboModel());
templateCombo.setRenderer(new TemplateComboCellRenderer());
if (proj.getMap(DEFAULT_TEMPLATE) != null) templateCombo.setSelectedItem(proj.getMap(DEFAULT_TEMPLATE));
templatePane.add(templateCombo, BorderLayout.CENTER);
pane.add(templatePane, JideBoxLayout.FIX);
pane.add(templateCombo);
if (templateFile.exists()) {
useTemplate.setSelected(true);
copyMap.setSelected(false);
templateCombo.setEnabled(false);
} else {
useTemplate.setSelected(false);
useTemplate.setEnabled(false);
useTemplate.setToolTipText("Cannot find file " + templateFile.getAbsolutePath());
templateCombo.setEnabled(true);
copyMap.setSelected(true);
}
ActionListener radioListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (useTemplate.isSelected()) {
templateCombo.setEnabled(false);
} else if (copyMap.isSelected()) {
templateCombo.setEnabled(true);
}
updateStatus();
}
};
useTemplate.addActionListener(radioListener);
copyMap.addActionListener(radioListener);
templateCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateStatus();
}
});
pane.add(new JPanel(), JideBoxLayout.VARY);
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
JButton cancel = new JButton("Cancel");
buttonPane.add(cancel, JideBoxLayout.FIX);
ok = new JButton("Ok");
buttonPane.add(ok, JideBoxLayout.FIX);
pane.add(new JPanel(), JideBoxLayout.VARY);
pane.add(buttonPane, JideBoxLayout.FIX);
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (copyMap.isSelected()) {
creation = ((TMXMap) templateCombo.getSelectedItem()).clone();
} else if (useTemplate.isSelected()) {
creation = new TMXMap(proj.createdContent.gameMaps, templateFile);
creation.parse();
}
creation.id = idField.getText();
creation.tmxFile = new File(creation.id + ".tmx");
TMXMapCreationWizard.this.setVisible(false);
TMXMapCreationWizard.this.dispose();
creation.state = State.created;
proj.createElement(creation);
notifyCreated();
ATContentStudio.frame.selectInTree(creation);
ATContentStudio.frame.openEditor(creation);
}
});
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
creation = null;
TMXMapCreationWizard.this.setVisible(false);
TMXMapCreationWizard.this.dispose();
}
});
DocumentListener statusUpdater = new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateStatus();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateStatus();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateStatus();
}
};
idField.getDocument().addDocumentListener(statusUpdater);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
setMinimumSize(new Dimension(350, 250));
updateStatus();
pack();
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
Dimension wdim = getSize();
setLocation((sdim.width - wdim.width) / 2, (sdim.height - wdim.height) / 2);
}
public void updateStatus() {
boolean trouble = false;
message.setText("<html><font color=\"#00AA00\">Looks OK to me.</font></html>");
if (copyMap.isSelected() && templateCombo.getSelectedItem() == null) {
message.setText("<html><font color=\"#FF0000\">Select a map template below:</font></html>");
trouble = true;
} else if (idField.getText() == null || idField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">Internal ID must not be empty.</font></html>");
trouble = true;
} else if (proj.getMap(idField.getText()) != null) {
if (proj.getMap(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">A map with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getMap(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">A map with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getMap(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">A map with the same ID exists in the game. The new one will be added under \"altered\".</font></html>");
}
}
ok.setEnabled(!trouble);
message.revalidate();
message.repaint();
}
public static interface CreationCompletedListener {
public void mapCreated(TMXMap created);
}
private List<CreationCompletedListener> listeners = new CopyOnWriteArrayList<TMXMapCreationWizard.CreationCompletedListener>();
public void addCreationListener(CreationCompletedListener l) {
listeners.add(l);
}
public void notifyCreated() {
for (CreationCompletedListener l : listeners) {
l.mapCreated(creation);
}
}
class TemplateComboModel implements ComboBoxModel<TMXMap> {
Object selected;
@Override
public int getSize() {
return proj.getMapCount();
}
@Override
public TMXMap getElementAt(int index) {
return proj.getMap(index);
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
@Override
public void setSelectedItem(Object anItem) {
selected = anItem;
}
@Override
public Object getSelectedItem() {
return selected;
}
}
class TemplateComboCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 5621373849299980998L;
@Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel && value != null) {
((JLabel) c).setText(((TMXMap) value).getDesc());
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getTiledIconIcon()));
}
return c;
}
}
@Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel && value != null) {
((JLabel)c).setText(((TMXMap)value).getDesc());
((JLabel)c).setIcon(new ImageIcon(DefaultIcons.getTiledIconIcon()));
}
return c;
}
}
} }

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