Compare commits

..

27 Commits

Author SHA1 Message Date
OMGeeky
dbff7fb571 Refactor version handling to read APP_VERSION from ATCS_latest file
(cherry picked from commit c9cccf9eb2)
2025-02-18 23:34:08 +01:00
OMGeeky
dfb3e31a7a Update package.sh to copy version file from VERSION_FILE variable
(cherry picked from commit 5ff45746d8)
2025-02-18 23:33:48 +01:00
OMGeeky
022c9ad229 Update release workflow to read version from the correct file path
(cherry picked from commit f14d21e322)
2025-02-18 23:33:27 +01:00
OMGeeky
38a3d4082b Update package.sh to reference ATCS_latest from the source directory and copy it to the temporary packaging directory
(cherry picked from commit 5191f56a01)
2025-02-18 23:31:20 +01:00
OMGeeky
cd78ee3ad0 Add .gitattributes to normalize line endings and enforce LF for bash scripts
(cherry picked from commit a71e8fe0a4)
2025-02-18 23:29:00 +01:00
OMGeeky
7b30cc6355 Remove unnecessary exit command from ATCS.sh
(cherry picked from commit a76d425ab7)
2025-02-18 23:29:00 +01:00
OMGeeky
9a6c5ecf6e delete obsolete Linux folder 2025-02-18 22:34:29 +01:00
OMGeeky
ed81c2382f Fix some issues with the linux ATCS.sh when the current path has spaces etc. 2025-02-18 22:33:08 +01:00
OMGeeky
ed2ad56b76 cleanup some packaging stuff 2025-02-18 18:08:02 +01:00
OMGeeky
becf45f249 Refactor release workflow to consolidate asset uploads 2025-02-16 01:19:20 +01:00
OMGeeky
c950324cd9 Reorder NSIS installation step in release workflow 2025-02-16 01:10:25 +01:00
OMGeeky
b58d080f4d Update installer script and release workflow to improve version handling 2025-02-16 01:07:44 +01:00
OMGeeky
a2640c2da0 Update installer script and release workflow to use dynamic versioning 2025-02-16 00:57:27 +01:00
OMGeeky
4fe7e71a43 Refactor GitHub Actions workflow to streamline version retrieval process 2025-02-16 00:39:10 +01:00
OMGeeky
9a162ac58d Refactor release workflow to improve directory navigation and version handling 2025-02-16 00:36:02 +01:00
OMGeeky
93718230a5 Merge pull request #1 from OMGeeky/package-improvements
Package improvements
2025-02-16 00:27:35 +01:00
OMGeeky
4fbf7de85a Merge remote-tracking branch 'omgeeky/package-improvements' into package-improvements
# Conflicts:
#	packaging/Windows/ATCS_Installer.nsi
2025-02-16 00:26:03 +01:00
OMGeeky
f0be1a8135 Add GitHub Actions workflow for automated release builds 2025-02-16 00:24:50 +01:00
OMGeeky
104d3db5ad Update ATCS_Installer.nsi to change ATCS_SOURCE_DIR path for improved directory structure and allow github actions 2025-02-16 00:24:47 +01:00
OMGeeky
f154efcecc Update ATCS_Installer.nsi to dynamically set VERSION from ATCS_latest file 2025-02-16 00:24:05 +01:00
OMGeeky
00e9e3b2a7 Enhance package.sh to support platform-specific archive creation using PowerShell on Windows 2025-02-16 00:23:52 +01:00
OMGeeky
92436d3ce9 Update package.sh to switch from tar.gz to zip for archive creation 2025-02-16 00:23:52 +01:00
OMGeeky
b6cfe349c0 Add GitHub Actions workflow for automated release builds 2025-02-16 00:21:42 +01:00
OMGeeky
1e2daa56a4 Update ATCS_Installer.nsi to change ATCS_SOURCE_DIR path for improved directory structure and allow github actions 2025-02-16 00:21:05 +01:00
OMGeeky
2caaaeb474 Update ATCS_Installer.nsi to dynamically set VERSION from ATCS_latest file 2025-02-16 00:20:21 +01:00
OMGeeky
0e8ed1a25d Enhance package.sh to support platform-specific archive creation using PowerShell on Windows 2025-02-16 00:01:27 +01:00
OMGeeky
b5dceb9fd1 Update package.sh to switch from tar.gz to zip for archive creation 2025-02-15 23:32:36 +01:00
39 changed files with 8490 additions and 7191 deletions

6
.gitattributes vendored Normal file
View File

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

56
.github/workflows/release.yml vendored Normal file
View File

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

1
.gitignore vendored
View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
!include MUI2.nsh !include MUI2.nsh
!define VERSION "0.6.21" ; Version will be passed as /DVERSION=vx.x.x
!define TRAINER_VERSION "0.1.5" !define TRAINER_VERSION "0.1.5"
!define JAVA_BIN "java" !define JAVA_BIN "java"
!define ATCS_SOURCE_DIR "C:\ATCS" !define ATCS_SOURCE_DIR "..\..\"
Name "Andor's Trail Content Studio v${VERSION}" Name "Andor's Trail Content Studio ${VERSION}"
OutFile "ATCS_v${VERSION}_Setup.exe" OutFile "..\ATCS_${VERSION}_Setup.exe"
InstallDir "$PROGRAMFILES\ATCS\" InstallDir "$PROGRAMFILES\ATCS\"
;SetCompressor /SOLID /FINAL lzma ;SetCompressor /SOLID /FINAL lzma
@@ -14,10 +14,10 @@ InstallDir "$PROGRAMFILES\ATCS\"
Var StartMenuFolder Var StartMenuFolder
!define MUI_WELCOMEPAGE_TITLE "Welcome to Andor's Trail Content Studio installer" !define MUI_WELCOMEPAGE_TITLE "Welcome to Andor's Trail Content Studio installer"
!define MUI_WELCOMEPAGE_TEXT "This will install Andor's Trail Content Studio v${VERSION}" !define MUI_WELCOMEPAGE_TEXT "This will install Andor's Trail Content Studio ${VERSION}"
!define MUI_FINISHPAGE_TEXT "Andor's Trail Content Studio v${VERSION} - Install completed !" !define MUI_FINISHPAGE_TEXT "Andor's Trail Content Studio ${VERSION} - Install completed !"
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Andor's Trail Content Studio" !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Andor's Trail Content Studio"
!define MUI_PAGE_HEADER_TEXT "Installing Andor's Trail Content Studio v${VERSION}" !define MUI_PAGE_HEADER_TEXT "Installing Andor's Trail Content Studio ${VERSION}"
;Start Menu Folder Page Configuration ;Start Menu Folder Page Configuration

View File

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

View File

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

View File

@@ -14,11 +14,7 @@ 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.util.Enumeration; import java.util.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -42,8 +38,7 @@ import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector;
public class ATContentStudio { public class ATContentStudio {
public static final String APP_NAME = "Andor's Trail Content Studio"; public static final String APP_NAME = "Andor's Trail Content Studio";
public static final String APP_VERSION = "v0.6.21"; public static final String APP_VERSION = readVersionFromFile();
public static final String CHECK_UPDATE_URL = "https://andorstrail.com/static/ATCS_latest"; public static final String CHECK_UPDATE_URL = "https://andorstrail.com/static/ATCS_latest";
public static final String DOWNLOAD_URL = "https://andorstrail.com/viewtopic.php?f=6&t=4806"; public static final String DOWNLOAD_URL = "https://andorstrail.com/viewtopic.php?f=6&t=4806";
@@ -231,4 +226,13 @@ public class ATContentStudio {
} }
} }
} }
private static String readVersionFromFile() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
Objects.requireNonNull(ATContentStudio.class.getResourceAsStream("/ATCS_latest"))))) {
return reader.readLine();
} catch (IOException e) {
e.printStackTrace();
return "unknown";
}
}
} }

View File

@@ -190,30 +190,4 @@ public abstract class GameDataElement implements ProjectTreeNode, Serializable {
public abstract List<SaveEvent> attemptSave(); public abstract List<SaveEvent> attemptSave();
/**
* Checks if the current state indicates that parsing/linking should be skipped.
* @return true if the operation should be skipped, false otherwise
*/
protected boolean shouldSkipParseOrLink() {
if (this.state == State.created || this.state == State.modified || this.state == State.saved) {
//This type of state is unrelated to parsing/linking.
return true;
}
if (this.state == State.linked) {
//Already linked.
return true;
}
return false;
}
/**
* Ensures the element is parsed if needed based on its current state.
*/
protected void ensureParseIfNeeded() {
if (this.state == State.init) {
//Not parsed yet.
this.parse();
}
}
} }

View File

@@ -224,10 +224,17 @@ public class ActorCondition extends JSONElement {
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
if (this.icon_id != null) { if (this.icon_id != null) {
String spritesheetId = this.icon_id.split(":")[0]; String spritesheetId = this.icon_id.split(":")[0];
if (getProject().getSpritesheet(spritesheetId) == null) { if (getProject().getSpritesheet(spritesheetId) == null) {

View File

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

View File

@@ -206,10 +206,17 @@ public class Dialogue extends JSONElement {
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
Project proj = getProject(); Project proj = getProject();
if (proj == null) { if (proj == null) {
Notification.addError("Error linking dialogue "+id+". No parent project found."); Notification.addError("Error linking dialogue "+id+". No parent project found.");

View File

@@ -129,10 +129,17 @@ public class Droplist extends JSONElement {
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
Project proj = getProject(); Project proj = getProject();
if (proj == null) { if (proj == null) {
Notification.addError("Error linking droplist "+id+". No parent project found."); Notification.addError("Error linking droplist "+id+". No parent project found.");

View File

@@ -18,8 +18,6 @@ import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import static com.gpl.rpg.atcontentstudio.model.gamedata.Common.*;
public class Item extends JSONElement { public class Item extends JSONElement {
private static final long serialVersionUID = -516874303672548638L; private static final long serialVersionUID = -516874303672548638L;
@@ -37,13 +35,38 @@ public class Item extends JSONElement {
public String description = null; public String description = null;
public HitEffect hit_effect = null; public HitEffect hit_effect = null;
public HitReceivedEffect hit_received_effect = null; public HitReceivedEffect hit_received_effect = null;
public DeathEffect kill_effect = null; public KillEffect kill_effect = null;
public EquipEffect equip_effect = null; public EquipEffect equip_effect = null;
//Available from linked state //Available from linked state
public ItemCategory category = null; public ItemCategory category = null;
public static class KillEffect {
//Available from parsed state
public Integer hp_boost_min = null;
public Integer hp_boost_max = null;
public Integer ap_boost_min = null;
public Integer ap_boost_max = null;
public List<TimedConditionEffect> conditions_source = null;
}
//Inheritance for code compactness, not semantically correct.
public static class HitEffect extends KillEffect {
//Available from parsed state
public List<TimedConditionEffect> conditions_target = null;
}
public static class HitReceivedEffect extends HitEffect {
//Available from parsed state
public Integer hp_boost_min_target = null;
public Integer hp_boost_max_target = null;
public Integer ap_boost_min_target = null;
public Integer ap_boost_max_target = null;
}
public static class EquipEffect { public static class EquipEffect {
//Available from parsed state //Available from parsed state
public Integer damage_boost_min = null; public Integer damage_boost_min = null;
@@ -63,6 +86,20 @@ public class Item extends JSONElement {
public Integer damage_modifier = null; public Integer damage_modifier = null;
} }
public static class ConditionEffect {
//Available from parsed state
public Integer magnitude = null;
public String condition_id = null;
//Available from linked state
public ActorCondition condition = null;
}
public static class TimedConditionEffect extends ConditionEffect {
//Available from parsed state
public Integer duration = null;
public Double chance = null;
}
public static enum DisplayType { public static enum DisplayType {
ordinary, ordinary,
@@ -170,7 +207,7 @@ public class Item extends JSONElement {
List conditionsJson = (List) equipEffect.get("addedConditions"); List conditionsJson = (List) equipEffect.get("addedConditions");
if (conditionsJson != null && !conditionsJson.isEmpty()) { if (conditionsJson != null && !conditionsJson.isEmpty()) {
this.equip_effect.conditions = new ArrayList<>(); this.equip_effect.conditions = new ArrayList<Item.ConditionEffect>();
for (Object conditionJsonObj : conditionsJson) { for (Object conditionJsonObj : conditionsJson) {
Map conditionJson = (Map)conditionJsonObj; Map conditionJson = (Map)conditionJsonObj;
ConditionEffect condition = new ConditionEffect(); ConditionEffect condition = new ConditionEffect();
@@ -184,12 +221,88 @@ public class Item extends JSONElement {
Map hitEffect = (Map) itemJson.get("hitEffect"); Map hitEffect = (Map) itemJson.get("hitEffect");
if (hitEffect != null) { if (hitEffect != null) {
this.hit_effect = parseHitEffect(hitEffect); this.hit_effect = new HitEffect();
if (hitEffect.get("increaseCurrentHP") != null) {
this.hit_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentHP")).get("min")));
this.hit_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentHP")).get("max")));
}
if (hitEffect.get("increaseCurrentAP") != null) {
this.hit_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentAP")).get("min")));
this.hit_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentAP")).get("max")));
}
List conditionsSourceJson = (List) hitEffect.get("conditionsSource");
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
this.hit_effect.conditions_source = new ArrayList<Item.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_effect.conditions_source.add(condition);
}
}
List conditionsTargetJson = (List) hitEffect.get("conditionsTarget");
if (conditionsTargetJson != null && !conditionsTargetJson.isEmpty()) {
this.hit_effect.conditions_target = new ArrayList<Item.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsTargetJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_effect.conditions_target.add(condition);
}
}
} }
Map hitReceivedEffect = (Map) itemJson.get("hitReceivedEffect"); Map hitReceivedEffect = (Map) itemJson.get("hitReceivedEffect");
if (hitReceivedEffect != null) { if (hitReceivedEffect != null) {
this.hit_received_effect = parseHitReceivedEffect(hitReceivedEffect); this.hit_received_effect = new HitReceivedEffect();
if (hitReceivedEffect.get("increaseCurrentHP") != null) {
this.hit_received_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("min")));
this.hit_received_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("max")));
}
if (hitReceivedEffect.get("increaseCurrentAP") != null) {
this.hit_received_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("min")));
this.hit_received_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("max")));
}
if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) {
this.hit_received_effect.hp_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min")));
this.hit_received_effect.hp_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max")));
}
if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) {
this.hit_received_effect.ap_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min")));
this.hit_received_effect.ap_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max")));
}
List conditionsSourceJson = (List) hitReceivedEffect.get("conditionsSource");
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
this.hit_received_effect.conditions_source = new ArrayList<Item.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_received_effect.conditions_source.add(condition);
}
}
List conditionsTargetJson = (List) hitReceivedEffect.get("conditionsTarget");
if (conditionsTargetJson != null && !conditionsTargetJson.isEmpty()) {
this.hit_received_effect.conditions_target = new ArrayList<Item.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsTargetJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_received_effect.conditions_target.add(condition);
}
}
} }
Map killEffect = (Map) itemJson.get("killEffect"); Map killEffect = (Map) itemJson.get("killEffect");
@@ -197,19 +310,46 @@ public class Item extends JSONElement {
killEffect = (Map) itemJson.get("useEffect"); killEffect = (Map) itemJson.get("useEffect");
} }
if (killEffect != null) { if (killEffect != null) {
this.kill_effect = parseDeathEffect(killEffect); this.kill_effect = new KillEffect();
if (killEffect.get("increaseCurrentHP") != null) {
this.kill_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)killEffect.get("increaseCurrentHP")).get("min")));
this.kill_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)killEffect.get("increaseCurrentHP")).get("max")));
}
if (killEffect.get("increaseCurrentAP") != null) {
this.kill_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)killEffect.get("increaseCurrentAP")).get("min")));
this.kill_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)killEffect.get("increaseCurrentAP")).get("max")));
}
List conditionsSourceJson = (List) killEffect.get("conditionsSource");
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
this.kill_effect.conditions_source = new ArrayList<Item.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.kill_effect.conditions_source.add(condition);
}
}
} }
this.state = State.parsed; this.state = State.parsed;
} }
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
Project proj = getProject(); Project proj = getProject();
if (proj == null) { if (proj == null) {
Notification.addError("Error linking item "+id+". No parent project found."); Notification.addError("Error linking item "+id+". No parent project found.");
@@ -223,21 +363,40 @@ public class Item extends JSONElement {
if (this.category_id != null) this.category = proj.getItemCategory(this.category_id); if (this.category_id != null) this.category = proj.getItemCategory(this.category_id);
if (this.category != null) this.category.addBacklink(this); if (this.category != null) this.category.addBacklink(this);
if (this.equip_effect != null && this.equip_effect.conditions != null) { if (this.equip_effect != null && this.equip_effect.conditions != null) {
linkConditions(this.equip_effect.conditions, proj, this); for (ConditionEffect ce : this.equip_effect.conditions) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
if (this.hit_effect != null && this.hit_effect.conditions_source != null) {
if (this.hit_effect != null) { for (TimedConditionEffect ce : this.hit_effect.conditions_source) {
linkConditions(this.hit_effect.conditions_source, proj, this); if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
linkConditions(this.hit_effect.conditions_target, proj, this); if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
if (this.hit_effect != null && this.hit_effect.conditions_target != null) {
if (this.hit_received_effect != null) { for (TimedConditionEffect ce : this.hit_effect.conditions_target) {
linkConditions(this.hit_received_effect.conditions_source, proj, this); if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
linkConditions(this.hit_received_effect.conditions_target, proj, this); if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
if (this.hit_received_effect != null && this.hit_received_effect.conditions_source != null) {
if (this.kill_effect != null) { for (TimedConditionEffect ce : this.hit_received_effect.conditions_source) {
linkConditions(this.kill_effect.conditions_source, proj, this); if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
}
if (this.hit_received_effect != null && this.hit_received_effect.conditions_target != null) {
for (TimedConditionEffect ce : this.hit_received_effect.conditions_target) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
}
if (this.kill_effect != null && this.kill_effect.conditions_source != null) {
for (TimedConditionEffect ce : this.kill_effect.conditions_source) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
this.state = State.linked; this.state = State.linked;
} }
@@ -285,7 +444,7 @@ public class Item extends JSONElement {
clone.equip_effect.max_ap_boost = this.equip_effect.max_ap_boost; clone.equip_effect.max_ap_boost = this.equip_effect.max_ap_boost;
clone.equip_effect.max_hp_boost = this.equip_effect.max_hp_boost; clone.equip_effect.max_hp_boost = this.equip_effect.max_hp_boost;
if (this.equip_effect.conditions != null) { if (this.equip_effect.conditions != null) {
clone.equip_effect.conditions = new ArrayList<>(); clone.equip_effect.conditions = new ArrayList<Item.ConditionEffect>();
for (ConditionEffect c : this.equip_effect.conditions) { for (ConditionEffect c : this.equip_effect.conditions) {
ConditionEffect cclone = new ConditionEffect(); ConditionEffect cclone = new ConditionEffect();
cclone.magnitude = c.magnitude; cclone.magnitude = c.magnitude;
@@ -300,15 +459,103 @@ public class Item extends JSONElement {
} }
if (this.hit_effect != null) { if (this.hit_effect != null) {
clone.hit_effect = new HitEffect(); clone.hit_effect = new HitEffect();
copyHitEffectValues(clone.hit_effect, this.hit_effect, clone); clone.hit_effect.ap_boost_max = this.hit_effect.ap_boost_max;
clone.hit_effect.ap_boost_min = this.hit_effect.ap_boost_min;
clone.hit_effect.hp_boost_max = this.hit_effect.hp_boost_max;
clone.hit_effect.hp_boost_min = this.hit_effect.hp_boost_min;
if (this.hit_effect.conditions_source != null) {
clone.hit_effect.conditions_source = new ArrayList<Item.TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_effect.conditions_source) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_effect.conditions_source.add(cclone);
}
}
if (this.hit_effect.conditions_target != null) {
clone.hit_effect.conditions_target = new ArrayList<Item.TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_effect.conditions_target) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_effect.conditions_target.add(cclone);
}
}
} }
if (this.hit_received_effect != null) { if (this.hit_received_effect != null) {
clone.hit_received_effect = new HitReceivedEffect(); clone.hit_received_effect = new HitReceivedEffect();
copyHitReceivedEffectValues(clone.hit_received_effect, this.hit_received_effect, clone); clone.hit_received_effect.ap_boost_max = this.hit_received_effect.ap_boost_max;
clone.hit_received_effect.ap_boost_min = this.hit_received_effect.ap_boost_min;
clone.hit_received_effect.hp_boost_max = this.hit_received_effect.hp_boost_max;
clone.hit_received_effect.hp_boost_min = this.hit_received_effect.hp_boost_min;
clone.hit_received_effect.ap_boost_max_target = this.hit_received_effect.ap_boost_max_target;
clone.hit_received_effect.ap_boost_min_target = this.hit_received_effect.ap_boost_min_target;
clone.hit_received_effect.hp_boost_max_target = this.hit_received_effect.hp_boost_max_target;
clone.hit_received_effect.hp_boost_min_target = this.hit_received_effect.hp_boost_min_target;
if (this.hit_received_effect.conditions_source != null) {
clone.hit_received_effect.conditions_source = new ArrayList<Item.TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_received_effect.conditions_source) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_received_effect.conditions_source.add(cclone);
}
}
if (this.hit_received_effect.conditions_target != null) {
clone.hit_received_effect.conditions_target = new ArrayList<Item.TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_received_effect.conditions_target) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_received_effect.conditions_target.add(cclone);
}
}
} }
if (this.kill_effect != null) { if (this.kill_effect != null) {
clone.kill_effect = new DeathEffect(); clone.kill_effect = new KillEffect();
copyDeathEffectValues(clone.kill_effect, this.kill_effect, clone); clone.kill_effect.ap_boost_max = this.kill_effect.ap_boost_max;
clone.kill_effect.ap_boost_min = this.kill_effect.ap_boost_min;
clone.kill_effect.hp_boost_max = this.kill_effect.hp_boost_max;
clone.kill_effect.hp_boost_min = this.kill_effect.hp_boost_min;
if (this.kill_effect.conditions_source != null) {
clone.kill_effect.conditions_source = new ArrayList<Item.TimedConditionEffect>();
for (TimedConditionEffect c : this.kill_effect.conditions_source) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.kill_effect.conditions_source.add(cclone);
}
}
} }
return clone; return clone;
} }

View File

@@ -171,10 +171,17 @@ public class ItemCategory extends JSONElement {
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
//Nothing to link to :D //Nothing to link to :D
this.state = State.linked; this.state = State.linked;

View File

@@ -26,7 +26,8 @@ public abstract class JSONElement extends GameDataElement {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void parse() { public void parse() {
if (shouldSkipParseOrLink()) { if (this.state == State.created || this.state == State.modified || this.state == State.saved) {
//This type of state is unrelated to parsing/linking.
return; return;
} }
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();

View File

@@ -18,8 +18,6 @@ import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource; import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project; import com.gpl.rpg.atcontentstudio.model.Project;
import static com.gpl.rpg.atcontentstudio.model.gamedata.Common.*;
public class NPC extends JSONElement { public class NPC extends JSONElement {
private static final long serialVersionUID = 1093728879485491933L; private static final long serialVersionUID = 1093728879485491933L;
@@ -75,6 +73,40 @@ public class NPC extends JSONElement {
wholeMap wholeMap
} }
public static class DeathEffect {
//Available from parsed state
public Integer hp_boost_min = null;
public Integer hp_boost_max = null;
public Integer ap_boost_min = null;
public Integer ap_boost_max = null;
public List<TimedConditionEffect> conditions_source = null;
}
public static class HitEffect extends DeathEffect {
//Available from parsed state
public List<TimedConditionEffect> conditions_target = null;
}
public static class HitReceivedEffect extends HitEffect {
//Available from parsed state
public Integer hp_boost_min_target = null;
public Integer hp_boost_max_target = null;
public Integer ap_boost_min_target = null;
public Integer ap_boost_max_target = null;
}
public static class TimedConditionEffect {
//Available from parsed state
public Integer magnitude = null;
public String condition_id = null;
public Integer duration = null;
public Double chance = null;
//Available from linked state
public ActorCondition condition = null;
}
@Override @Override
public String getDesc() { public String getDesc() {
return (needsSaving() ? "*" : "")+name+" ("+id+")"; return (needsSaving() ? "*" : "")+name+" ("+id+")";
@@ -179,14 +211,78 @@ public class NPC extends JSONElement {
this.hit_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentAP")).get("min"))); this.hit_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitEffect.get("increaseCurrentAP")).get("min")));
} }
List conditionsSourceJson = (List) hitEffect.get("conditionsSource"); List conditionsSourceJson = (List) hitEffect.get("conditionsSource");
this.hit_effect.conditions_source = parseTimedConditionEffects(conditionsSourceJson); if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
this.hit_effect.conditions_source = new ArrayList<NPC.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_effect.conditions_source.add(condition);
}
}
List conditionsTargetJson = (List) hitEffect.get("conditionsTarget"); List conditionsTargetJson = (List) hitEffect.get("conditionsTarget");
this.hit_effect.conditions_target = parseTimedConditionEffects(conditionsTargetJson); if (conditionsTargetJson != null && !conditionsTargetJson.isEmpty()) {
this.hit_effect.conditions_target = new ArrayList<NPC.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsTargetJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_effect.conditions_target.add(condition);
}
}
} }
Map hitReceivedEffect = (Map) npcJson.get("hitReceivedEffect"); Map hitReceivedEffect = (Map) npcJson.get("hitReceivedEffect");
if (hitReceivedEffect != null) { if (hitReceivedEffect != null) {
this.hit_received_effect = parseHitReceivedEffect(hitReceivedEffect); this.hit_received_effect = new HitReceivedEffect();
if (hitReceivedEffect.get("increaseCurrentHP") != null) {
this.hit_received_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("max")));
this.hit_received_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("min")));
}
if (hitReceivedEffect.get("increaseCurrentAP") != null) {
this.hit_received_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("max")));
this.hit_received_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("min")));
}
if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) {
this.hit_received_effect.hp_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max")));
this.hit_received_effect.hp_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min")));
}
if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) {
this.hit_received_effect.ap_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max")));
this.hit_received_effect.ap_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min")));
}
List conditionsSourceJson = (List) hitReceivedEffect.get("conditionsSource");
if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
this.hit_received_effect.conditions_source = new ArrayList<NPC.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_received_effect.conditions_source.add(condition);
}
}
List conditionsTargetJson = (List) hitReceivedEffect.get("conditionsTarget");
if (conditionsTargetJson != null && !conditionsTargetJson.isEmpty()) {
this.hit_received_effect.conditions_target = new ArrayList<NPC.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsTargetJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.hit_received_effect.conditions_target.add(condition);
}
}
} }
Map deathEffect = (Map) npcJson.get("deathEffect"); Map deathEffect = (Map) npcJson.get("deathEffect");
@@ -201,17 +297,35 @@ public class NPC extends JSONElement {
this.death_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentAP")).get("min"))); this.death_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentAP")).get("min")));
} }
List conditionsSourceJson = (List) deathEffect.get("conditionsSource"); List conditionsSourceJson = (List) deathEffect.get("conditionsSource");
this.death_effect.conditions_source = parseTimedConditionEffects(conditionsSourceJson); if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) {
this.death_effect.conditions_source = new ArrayList<NPC.TimedConditionEffect>();
for (Object conditionJsonObj : conditionsSourceJson) {
Map conditionJson = (Map)conditionJsonObj;
TimedConditionEffect condition = new TimedConditionEffect();
condition.condition_id = (String) conditionJson.get("condition");
condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude"));
condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration"));
if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString());
this.death_effect.conditions_source.add(condition);
}
}
} }
} }
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
Project proj = getProject(); Project proj = getProject();
if (proj == null) { if (proj == null) {
Notification.addError("Error linking item "+id+". No parent project found."); Notification.addError("Error linking item "+id+". No parent project found.");
@@ -228,16 +342,35 @@ public class NPC extends JSONElement {
if (this.droplist_id != null) this.droplist = proj.getDroplist(this.droplist_id); if (this.droplist_id != null) this.droplist = proj.getDroplist(this.droplist_id);
if (this.droplist != null) this.droplist.addBacklink(this); if (this.droplist != null) this.droplist.addBacklink(this);
if (this.hit_effect != null) { if (this.hit_effect != null && this.hit_effect.conditions_source != null) {
linkConditions(this.hit_effect.conditions_source, proj, this); for (TimedConditionEffect ce : this.hit_effect.conditions_source) {
linkConditions(this.hit_effect.conditions_target, proj, this); if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
if (this.hit_received_effect != null) { if (this.hit_effect != null && this.hit_effect.conditions_target != null) {
linkConditions(this.hit_received_effect.conditions_source, proj, this); for (TimedConditionEffect ce : this.hit_effect.conditions_target) {
linkConditions(this.hit_received_effect.conditions_target, proj, this); if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
if (this.death_effect != null) { if (this.hit_received_effect != null && this.hit_received_effect.conditions_source != null) {
linkConditions(this.death_effect.conditions_source, proj, this); for (TimedConditionEffect ce : this.hit_received_effect.conditions_source) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
}
if (this.hit_received_effect != null && this.hit_received_effect.conditions_target != null) {
for (TimedConditionEffect ce : this.hit_received_effect.conditions_target) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
}
if (this.death_effect != null && this.death_effect.conditions_source != null) {
for (TimedConditionEffect ce : this.death_effect.conditions_source) {
if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id);
if (ce.condition != null) ce.condition.addBacklink(this);
}
} }
this.state = State.linked; this.state = State.linked;
} }
@@ -280,15 +413,103 @@ public class NPC extends JSONElement {
clone.faction_id = this.faction_id; clone.faction_id = this.faction_id;
if (this.hit_effect != null) { if (this.hit_effect != null) {
clone.hit_effect = new HitEffect(); clone.hit_effect = new HitEffect();
copyHitEffectValues(clone.hit_effect, this.hit_effect, clone); clone.hit_effect.ap_boost_max = this.hit_effect.ap_boost_max;
clone.hit_effect.ap_boost_min = this.hit_effect.ap_boost_min;
clone.hit_effect.hp_boost_max = this.hit_effect.hp_boost_max;
clone.hit_effect.hp_boost_min = this.hit_effect.hp_boost_min;
if (this.hit_effect.conditions_source != null) {
clone.hit_effect.conditions_source = new ArrayList<TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_effect.conditions_source) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_effect.conditions_source.add(cclone);
}
}
if (this.hit_effect.conditions_target != null) {
clone.hit_effect.conditions_target = new ArrayList<TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_effect.conditions_target) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_effect.conditions_target.add(cclone);
}
}
} }
if (this.hit_received_effect != null) { if (this.hit_received_effect != null) {
clone.hit_received_effect = new HitReceivedEffect(); clone.hit_received_effect = new HitReceivedEffect();
copyHitReceivedEffectValues(clone.hit_received_effect, this.hit_received_effect, clone); clone.hit_received_effect.ap_boost_max = this.hit_received_effect.ap_boost_max;
clone.hit_received_effect.ap_boost_min = this.hit_received_effect.ap_boost_min;
clone.hit_received_effect.hp_boost_max = this.hit_received_effect.hp_boost_max;
clone.hit_received_effect.hp_boost_min = this.hit_received_effect.hp_boost_min;
clone.hit_received_effect.ap_boost_max_target = this.hit_received_effect.ap_boost_max_target;
clone.hit_received_effect.ap_boost_min_target = this.hit_received_effect.ap_boost_min_target;
clone.hit_received_effect.hp_boost_max_target = this.hit_received_effect.hp_boost_max_target;
clone.hit_received_effect.hp_boost_min_target = this.hit_received_effect.hp_boost_min_target;
if (this.hit_received_effect.conditions_source != null) {
clone.hit_received_effect.conditions_source = new ArrayList<TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_received_effect.conditions_source) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_received_effect.conditions_source.add(cclone);
}
}
if (this.hit_received_effect.conditions_target != null) {
clone.hit_received_effect.conditions_target = new ArrayList<TimedConditionEffect>();
for (TimedConditionEffect c : this.hit_received_effect.conditions_target) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.hit_received_effect.conditions_target.add(cclone);
}
}
} }
if (this.death_effect != null) { if (this.death_effect != null) {
clone.death_effect = new DeathEffect(); clone.death_effect = new DeathEffect();
copyDeathEffectValues(clone.death_effect, this.death_effect, clone); clone.death_effect.ap_boost_max = this.death_effect.ap_boost_max;
clone.death_effect.ap_boost_min = this.death_effect.ap_boost_min;
clone.death_effect.hp_boost_max = this.death_effect.hp_boost_max;
clone.death_effect.hp_boost_min = this.death_effect.hp_boost_min;
if (this.death_effect.conditions_source != null) {
clone.death_effect.conditions_source = new ArrayList<TimedConditionEffect>();
for (TimedConditionEffect c : this.death_effect.conditions_source) {
TimedConditionEffect cclone = new TimedConditionEffect();
cclone.magnitude = c.magnitude;
cclone.condition_id = c.condition_id;
cclone.condition = c.condition;
cclone.chance = c.chance;
cclone.duration = c.duration;
if (cclone.condition != null) {
cclone.condition.addBacklink(clone);
}
clone.death_effect.conditions_source.add(cclone);
}
}
} }
clone.max_ap = this.max_ap; clone.max_ap = this.max_ap;
clone.max_hp = this.max_hp; clone.max_hp = this.max_hp;
@@ -454,7 +675,7 @@ public class NPC extends JSONElement {
} }
if (this.hit_received_effect.ap_boost_min_target != null || this.hit_received_effect.ap_boost_max_target != null) { if (this.hit_received_effect.ap_boost_min_target != null || this.hit_received_effect.ap_boost_max_target != null) {
Map apJson = new LinkedHashMap(); Map apJson = new LinkedHashMap();
hitReceivedEffectJson.put("increaseAttackerCurrentAP", apJson); hitReceivedEffectJson.put("increaseAttackerCurrentAP", apJson);
if (this.hit_received_effect.ap_boost_min_target != null) apJson.put("min", this.hit_received_effect.ap_boost_min_target); if (this.hit_received_effect.ap_boost_min_target != null) apJson.put("min", this.hit_received_effect.ap_boost_min_target);
else apJson.put("min", 0); else apJson.put("min", 0);
if (this.hit_received_effect.ap_boost_max_target != null) apJson.put("max", this.hit_received_effect.ap_boost_max_target); if (this.hit_received_effect.ap_boost_max_target != null) apJson.put("max", this.hit_received_effect.ap_boost_max_target);

View File

@@ -113,10 +113,17 @@ public class Quest extends JSONElement {
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
for (QuestStage stage : stages) { for (QuestStage stage : stages) {
stage.link(); stage.link();

View File

@@ -59,10 +59,17 @@ public class QuestStage extends JSONElement {
@Override @Override
public void link() { public void link() {
if (shouldSkipParseOrLink()) { 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; return;
} }
ensureParseIfNeeded();
//Nothing to link to :D //Nothing to link to :D
this.state = State.linked; this.state = State.linked;

View File

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

View File

@@ -6,8 +6,13 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
@@ -23,7 +28,10 @@ import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
@@ -46,8 +54,6 @@ import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener; import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.OverlayIcon; import com.gpl.rpg.atcontentstudio.ui.OverlayIcon;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree.DialogueGraphView; import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree.DialogueGraphView;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import com.gpl.rpg.atcontentstudio.utils.lambda.CallWithSingleArg;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
public class DialogueEditor extends JSONElementEditor { public class DialogueEditor extends JSONElementEditor {
@@ -172,62 +178,163 @@ public class DialogueEditor extends JSONElementEditor {
messageField = addTranslatableTextArea(pane, "Message: ", dialogue.message, dialogue.writable, listener); messageField = addTranslatableTextArea(pane, "Message: ", dialogue.message, dialogue.writable, listener);
switchToNpcBox = addNPCBox(pane, dialogue.getProject(), "Switch active NPC to: ", dialogue.switch_to_npc, dialogue.writable, listener); switchToNpcBox = addNPCBox(pane, dialogue.getProject(), "Switch active NPC to: ", dialogue.switch_to_npc, dialogue.writable, listener);
String rewardsTitle = "Reaching this phrase gives the following rewards: "; CollapsiblePanel rewards = new CollapsiblePanel("Reaching this phrase gives the following rewards: ");
RewardsCellRenderer rewardsCellRenderer = new RewardsCellRenderer(); rewards.setLayout(new JideBoxLayout(rewards, JideBoxLayout.PAGE_AXIS));
rewardsListModel = new RewardsListModel(dialogue); rewardsListModel = new RewardsListModel(dialogue);
final boolean rewardsMoveUpDownEnabled = false; rewardsList = new JList(rewardsListModel);
rewardsList.setCellRenderer(new RewardsCellRenderer());
CommonEditor.PanelCreateResult<Dialogue.Reward> rewardsResult = CommonEditor.createListPanel( rewardsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
rewardsTitle, rewards.add(new JScrollPane(rewardsList), JideBoxLayout.FIX);
rewardsCellRenderer, final JPanel rewardsEditorPane = new JPanel();
rewardsListModel, final JButton createReward = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
dialogue.writable, final JButton deleteReward = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
rewardsMoveUpDownEnabled, deleteReward.setEnabled(false);
(e) -> selectedReward = e, rewardsList.addListSelectionListener(new ListSelectionListener() {
() -> selectedReward, @Override
this::updateRewardsEditorPane, public void valueChanged(ListSelectionEvent e) {
listener, selectedReward = (Dialogue.Reward) rewardsList.getSelectedValue();
Dialogue.Reward::new); if (selectedReward == null) {
CollapsiblePanel rewards = rewardsResult.panel; deleteReward.setEnabled(false);
rewardsList = rewardsResult.list; } else {
deleteReward.setEnabled(true);
}
updateRewardsEditorPane(rewardsEditorPane, selectedReward, listener);
}
});
if (dialogue.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createReward.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Dialogue.Reward reward = new Dialogue.Reward();
rewardsListModel.addItem(reward);
rewardsList.setSelectedValue(reward, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteReward.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedReward != null) {
rewardsListModel.removeItem(selectedReward);
selectedReward = null;
rewardsList.clearSelection();
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createReward, JideBoxLayout.FIX);
listButtonsPane.add(deleteReward, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
rewards.add(listButtonsPane, JideBoxLayout.FIX);
}
if (dialogue.rewards == null || dialogue.rewards.isEmpty()) { if (dialogue.rewards == null || dialogue.rewards.isEmpty()) {
rewards.collapse(); rewards.collapse();
} }
rewardsEditorPane.setLayout(new JideBoxLayout(rewardsEditorPane, JideBoxLayout.PAGE_AXIS));
rewards.add(rewardsEditorPane, JideBoxLayout.FIX);
pane.add(rewards, JideBoxLayout.FIX); pane.add(rewards, JideBoxLayout.FIX);
String title = "Replies / Next Phrase: "; CollapsiblePanel replies = new CollapsiblePanel("Replies / Next Phrase: ");
RepliesCellRenderer cellRenderer = new RepliesCellRenderer(); replies.setLayout(new JideBoxLayout(replies, JideBoxLayout.PAGE_AXIS));
repliesListModel = new RepliesListModel(dialogue);
repliesListModel = new DialogueEditor.RepliesListModel(dialogue); repliesList = new JList(repliesListModel);
boolean moveUpDownEnabled = true; repliesList.setCellRenderer(new RepliesCellRenderer());
CallWithSingleArg<Dialogue.Reply> selectedReplyChanged = e -> { repliesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
selectedReply = e; replies.add(new JScrollPane(repliesList), JideBoxLayout.FIX);
if (selectedReply != null && !Dialogue.Reply.GO_NEXT_TEXT.equals(selectedReply.text)) { final JPanel repliesEditorPane = new JPanel();
replyTextCache = selectedReply.text; final JButton createReply = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
} else { final JButton deleteReply = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
replyTextCache = null; final JButton moveReplyUp = new JButton(new ImageIcon(DefaultIcons.getArrowUpIcon()));
final JButton moveReplyDown = new JButton(new ImageIcon(DefaultIcons.getArrowDownIcon()));
deleteReply.setEnabled(false);
moveReplyUp.setEnabled(false);
moveReplyDown.setEnabled(false);
repliesList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
selectedReply = (Dialogue.Reply) repliesList.getSelectedValue();
if (selectedReply != null && !Dialogue.Reply.GO_NEXT_TEXT.equals(selectedReply.text)) {
replyTextCache = selectedReply.text;
} else {
replyTextCache = null;
}
if (selectedReply != null) {
deleteReply.setEnabled(true);
moveReplyUp.setEnabled(repliesList.getSelectedIndex() > 0);
moveReplyDown.setEnabled(repliesList.getSelectedIndex() < (repliesListModel.getSize() - 1));
} else {
deleteReply.setEnabled(false);
moveReplyUp.setEnabled(false);
moveReplyDown.setEnabled(false);
}
updateRepliesEditorPane(repliesEditorPane, selectedReply, listener);
} }
}; });
CollapsiblePanel replies = CommonEditor.createListPanel( if (dialogue.writable) {
title, JPanel listButtonsPane = new JPanel();
cellRenderer, listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
repliesListModel, createReply.addActionListener(new ActionListener() {
dialogue.writable, @Override
moveUpDownEnabled, public void actionPerformed(ActionEvent e) {
selectedReplyChanged, Dialogue.Reply reply = new Dialogue.Reply();
()->selectedReply, repliesListModel.addItem(reply);
this::updateRepliesEditorPane, repliesList.setSelectedValue(reply, true);
listener, listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
Dialogue.Reply::new).panel; }
});
deleteReply.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedReply != null) {
repliesListModel.removeItem(selectedReply);
selectedReply = null;
repliesList.clearSelection();
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
moveReplyUp.addActionListener(new ActionListener() {
boolean isEmpty = dialogue.replies == null || dialogue.replies.isEmpty(); @Override
if (isEmpty) { public void actionPerformed(ActionEvent e) {
if (selectedReply != null) {
repliesListModel.moveUp(selectedReply);
repliesList.setSelectedValue(selectedReply, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
moveReplyDown.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedReply != null) {
repliesListModel.moveDown(selectedReply);
repliesList.setSelectedValue(selectedReply, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createReply, JideBoxLayout.FIX);
listButtonsPane.add(deleteReply, JideBoxLayout.FIX);
listButtonsPane.add(moveReplyUp, JideBoxLayout.FIX);
listButtonsPane.add(moveReplyDown, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
replies.add(listButtonsPane, JideBoxLayout.FIX);
}
if (dialogue.replies == null || dialogue.replies.isEmpty()) {
replies.collapse(); replies.collapse();
} }
repliesEditorPane.setLayout(new JideBoxLayout(repliesEditorPane, JideBoxLayout.PAGE_AXIS));
replies.add(repliesEditorPane, JideBoxLayout.FIX);
pane.add(replies, JideBoxLayout.FIX); pane.add(replies, JideBoxLayout.FIX);
} }
public void updateRewardsEditorPane(final JPanel pane, final Dialogue.Reward reward, final FieldUpdateListener listener) { public void updateRewardsEditorPane(final JPanel pane, final Dialogue.Reward reward, final FieldUpdateListener listener) {
@@ -479,24 +586,80 @@ public class DialogueEditor extends JSONElementEditor {
updateRepliesParamsEditorPane(repliesParamsPane, reply, listener); updateRepliesParamsEditorPane(repliesParamsPane, reply, listener);
pane.add(repliesParamsPane, JideBoxLayout.FIX); pane.add(repliesParamsPane, JideBoxLayout.FIX);
ReplyRequirementsCellRenderer cellRenderer = new ReplyRequirementsCellRenderer(); CollapsiblePanel requirementsPane = new CollapsiblePanel("Requirements the player must fulfill to select this reply: ");
String title = "Requirements the player must fulfill to select this reply: "; requirementsPane.setLayout(new JideBoxLayout(requirementsPane, JideBoxLayout.PAGE_AXIS));
requirementsListModel = new ReplyRequirementsListModel(reply); requirementsListModel = new ReplyRequirementsListModel(reply);
requirementsList = new JList(requirementsListModel);
requirementsList.setCellRenderer(new ReplyRequirementsCellRenderer());
requirementsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
requirementsPane.add(new JScrollPane(requirementsList), JideBoxLayout.FIX);
final JPanel requirementsEditorPane = new JPanel();
final JButton createReq = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
final JButton deleteReq = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
deleteReq.setEnabled(false);
requirementsList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
selectedRequirement = (Requirement) requirementsList.getSelectedValue();
if (selectedRequirement != null) {
deleteReq.setEnabled(true);
} else {
deleteReq.setEnabled(false);
}
updateRequirementsEditorPane(requirementsEditorPane, selectedRequirement, listener);
}
});
requirementsList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
if (requirementsList.getSelectedValue() != null && ((Requirement)requirementsList.getSelectedValue()).required_obj != null) {
ATContentStudio.frame.openEditor(((Requirement)requirementsList.getSelectedValue()).required_obj);
ATContentStudio.frame.selectInTree(((Requirement)requirementsList.getSelectedValue()).required_obj);
}
}
}
});
requirementsList.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
ATContentStudio.frame.openEditor(((Requirement)requirementsList.getSelectedValue()).required_obj);
ATContentStudio.frame.selectInTree(((Requirement)requirementsList.getSelectedValue()).required_obj);
}
}
});
if (((Dialogue)target).writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createReq.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Requirement req = new Requirement();
requirementsListModel.addItem(req);
requirementsList.setSelectedValue(req, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteReq.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedRequirement != null) {
requirementsListModel.removeItem(selectedRequirement);
selectedRequirement = null;
requirementsList.clearSelection();
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
final boolean moveUpDownEnabled = false; listButtonsPane.add(createReq, JideBoxLayout.FIX);
listButtonsPane.add(deleteReq, JideBoxLayout.FIX);
CollapsiblePanel requirementsPane = CommonEditor.createListPanel( listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
title, requirementsPane.add(listButtonsPane, JideBoxLayout.FIX);
cellRenderer, }
requirementsListModel, requirementsEditorPane.setLayout(new JideBoxLayout(requirementsEditorPane, JideBoxLayout.PAGE_AXIS));
target.writable, requirementsPane.add(requirementsEditorPane, JideBoxLayout.FIX);
moveUpDownEnabled,
(e)->selectedRequirement=e,
()->selectedRequirement,
this::updateRequirementsEditorPane,
listener,
Requirement::new).panel;
if (reply.requirements == null || reply.requirements.isEmpty()) { if (reply.requirements == null || reply.requirements.isEmpty()) {
requirementsPane.collapse(); requirementsPane.collapse();
} }
@@ -649,23 +812,67 @@ public class DialogueEditor extends JSONElementEditor {
} }
public static class RewardsListModel extends CommonEditor.AtListModel<Dialogue.Reward, Dialogue> { public static class RewardsListModel implements ListModel<Dialogue.Reward> {
Dialogue source;
public RewardsListModel(Dialogue dialogue) { public RewardsListModel(Dialogue dialogue) {
super(dialogue); this.source = dialogue;
} }
@Override @Override
protected List<Dialogue.Reward> getInner() { public int getSize() {
return source.rewards; if (source.rewards == null) return 0;
return source.rewards.size();
} }
@Override @Override
protected void setInner(List<Dialogue.Reward> value) { public Dialogue.Reward getElementAt(int index) {
source.rewards = value; if (source.rewards == null) return null;
return source.rewards.get(index);
} }
} public void addItem(Dialogue.Reward item) {
if (source.rewards == null) {
source.rewards = new ArrayList<Dialogue.Reward>();
}
source.rewards.add(item);
int index = source.rewards.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Dialogue.Reward item) {
int index = source.rewards.indexOf(item);
source.rewards.remove(item);
if (source.rewards.isEmpty()) {
source.rewards = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Dialogue.Reward item) {
int index = source.rewards.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
public static class RewardsCellRenderer extends DefaultListCellRenderer { public static class RewardsCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@@ -774,21 +981,88 @@ public class DialogueEditor extends JSONElementEditor {
} }
public static class RepliesListModel extends CommonEditor.AtListModel<Dialogue.Reply, Dialogue> { public static class RepliesListModel implements ListModel<Dialogue.Reply> {
Dialogue source;
public RepliesListModel(Dialogue dialogue) { public RepliesListModel(Dialogue dialogue) {
super(dialogue); this.source = dialogue;
}
@Override
public int getSize() {
if (source.replies == null) return 0;
return source.replies.size();
} }
@Override @Override
protected List<Dialogue.Reply> getInner() { public Dialogue.Reply getElementAt(int index) {
return source.replies; if (source.replies == null) return null;
return source.replies.get(index);
}
public void addItem(Dialogue.Reply item) {
if (source.replies == null) {
source.replies = new ArrayList<Dialogue.Reply>();
}
source.replies.add(item);
int index = source.replies.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
source.replies.remove(item);
if (source.replies.isEmpty()) {
source.replies = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
public void moveUp(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
Dialogue.Reply exchanged = source.replies.get(index - 1);
source.replies.set(index, exchanged);
source.replies.set(index - 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index - 1, index));
}
}
public void moveDown(Dialogue.Reply item) {
int index = source.replies.indexOf(item);
Dialogue.Reply exchanged = source.replies.get(index + 1);
source.replies.set(index, exchanged);
source.replies.set(index + 1, item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index + 1));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
protected void setInner(List<Dialogue.Reply> value) { public void removeListDataListener(ListDataListener l) {
source.replies = value; listeners.remove(l);
} }
} }
public static class RepliesCellRenderer extends DefaultListCellRenderer { public static class RepliesCellRenderer extends DefaultListCellRenderer {
@@ -841,27 +1115,70 @@ public class DialogueEditor extends JSONElementEditor {
} }
} }
public static class ReplyRequirementsListModel extends CommonEditor.AtListModel<Requirement, Dialogue.Reply> { public static class ReplyRequirementsListModel implements ListModel<Requirement> {
public ReplyRequirementsListModel(Dialogue.Reply reply) { Dialogue.Reply reply;
super(reply);
}
@Override public ReplyRequirementsListModel(Dialogue.Reply reply) {
protected List<Requirement> getInner() { this.reply = reply;
return source.requirements; }
}
@Override @Override
protected void setInner(List<Requirement> value) { public int getSize() {
source.requirements = value; if (reply.requirements == null) return 0;
} return reply.requirements.size();
}
@Override @Override
protected GameDataElement getNavigationElement(Requirement element) { public Requirement getElementAt(int index) {
return element != null ? element.required_obj : null; if (reply.requirements == null) return null;
} return reply.requirements.get(index);
} }
public void addItem(Requirement item) {
if (reply.requirements == null) {
reply.requirements = new ArrayList<Requirement>();
}
reply.requirements.add(item);
int index = reply.requirements.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Requirement item) {
int index = reply.requirements.indexOf(item);
reply.requirements.remove(item);
if (reply.requirements.isEmpty()) {
reply.requirements = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Requirement item) {
int index = reply.requirements.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
public static class ReplyRequirementsCellRenderer extends DefaultListCellRenderer { public static class ReplyRequirementsCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;

View File

@@ -1,17 +1,28 @@
package com.gpl.rpg.atcontentstudio.ui.gamedataeditors; package com.gpl.rpg.atcontentstudio.ui.gamedataeditors;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
@@ -21,8 +32,8 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist;
import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist.DroppedItem; import com.gpl.rpg.atcontentstudio.model.gamedata.Droplist.DroppedItem;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item; import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel; import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener; import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
public class DroplistEditor extends JSONElementEditor { public class DroplistEditor extends JSONElementEditor {
@@ -47,6 +58,7 @@ public class DroplistEditor extends JSONElementEditor {
addEditorTab(json_view_id, getJSONView()); addEditorTab(json_view_id, getJSONView());
} }
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public void insertFormViewDataField(JPanel pane) { public void insertFormViewDataField(JPanel pane) {
@@ -57,23 +69,60 @@ public class DroplistEditor extends JSONElementEditor {
idField = addTextField(pane, "Droplist ID: ", droplist.id, droplist.writable, listener); idField = addTextField(pane, "Droplist ID: ", droplist.id, droplist.writable, listener);
String title = "Items in this droplist: "; CollapsiblePanel itemsPane = new CollapsiblePanel("Items in this droplist: ");
DroppedItemsCellRenderer cellRenderer = new DroppedItemsCellRenderer(); itemsPane.setLayout(new JideBoxLayout(itemsPane, JideBoxLayout.PAGE_AXIS));
droppedItemsListModel = new DroppedItemsListModel(droplist); droppedItemsListModel = new DroppedItemsListModel(droplist);
final boolean moveUpDownEnabled = false; final JList itemsList = new JList(droppedItemsListModel);
itemsList.setCellRenderer(new DroppedItemsCellRenderer());
CollapsiblePanel itemsPane = CommonEditor.createListPanel( itemsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
title, itemsPane.add(new JScrollPane(itemsList), JideBoxLayout.FIX);
cellRenderer, final JPanel droppedItemsEditorPane = new JPanel();
droppedItemsListModel, final JButton createDroppedItem = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
droplist.writable, final JButton deleteDroppedItem = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
moveUpDownEnabled, deleteDroppedItem.setEnabled(false);
(e) -> selectedItem = e, itemsList.addListSelectionListener(new ListSelectionListener() {
() -> selectedItem, @Override
this::updateDroppedItemsEditorPane, public void valueChanged(ListSelectionEvent e) {
listener, selectedItem = (Droplist.DroppedItem) itemsList.getSelectedValue();
Droplist.DroppedItem::new).panel; if (selectedItem == null) {
deleteDroppedItem.setEnabled(false);
} else {
deleteDroppedItem.setEnabled(true);
}
updateDroppedItemsEditorPane(droppedItemsEditorPane, selectedItem, listener);
}
});
if (droplist.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createDroppedItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Droplist.DroppedItem tempItem = new Droplist.DroppedItem();
droppedItemsListModel.addItem(tempItem);
itemsList.setSelectedValue(tempItem, true);
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteDroppedItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedItem != null) {
droppedItemsListModel.removeItem(selectedItem);
selectedItem = null;
itemsList.clearSelection();
listener.valueChanged(new JLabel(), null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createDroppedItem, JideBoxLayout.FIX);
listButtonsPane.add(deleteDroppedItem, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
itemsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
droppedItemsEditorPane.setLayout(new JideBoxLayout(droppedItemsEditorPane, JideBoxLayout.PAGE_AXIS));
itemsPane.add(droppedItemsEditorPane, JideBoxLayout.FIX);
if (droplist.dropped_items == null || droplist.dropped_items.isEmpty()) { if (droplist.dropped_items == null || droplist.dropped_items.isEmpty()) {
itemsPane.collapse(); itemsPane.collapse();
} }
@@ -83,8 +132,8 @@ public class DroplistEditor extends JSONElementEditor {
} }
public void updateDroppedItemsEditorPane(JPanel pane, DroppedItem di, FieldUpdateListener listener) { public void updateDroppedItemsEditorPane(JPanel pane, DroppedItem di, FieldUpdateListener listener) {
boolean writable = target.writable; boolean writable = ((Droplist)target).writable;
Project proj = target.getProject(); Project proj = ((Droplist)target).getProject();
pane.removeAll(); pane.removeAll();
if (itemCombo != null) { if (itemCombo != null) {
removeElementListener(itemCombo); removeElementListener(itemCombo);
@@ -99,20 +148,65 @@ public class DroplistEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public static class DroppedItemsListModel extends CommonEditor.AtListModel<Droplist.DroppedItem, Droplist> { public class DroppedItemsListModel implements ListModel<Droplist.DroppedItem> {
Droplist source;
public DroppedItemsListModel(Droplist droplist) { public DroppedItemsListModel(Droplist droplist) {
super(droplist); this.source = droplist;
} }
@Override @Override
protected List<Droplist.DroppedItem> getInner() { public int getSize() {
return source.dropped_items; if (source.dropped_items == null) return 0;
return source.dropped_items.size();
} }
@Override @Override
protected void setInner(List<Droplist.DroppedItem> value) { public Droplist.DroppedItem getElementAt(int index) {
source.dropped_items = value; if (source.dropped_items == null) return null;
return source.dropped_items.get(index);
}
public void addItem(Droplist.DroppedItem item) {
if (source.dropped_items == null) {
source.dropped_items = new ArrayList<Droplist.DroppedItem>();
}
source.dropped_items.add(item);
int index = source.dropped_items.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Droplist.DroppedItem item) {
int index = source.dropped_items.indexOf(item);
source.dropped_items.remove(item);
if (source.dropped_items.isEmpty()) {
source.dropped_items = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Droplist.DroppedItem item) {
int index = source.dropped_items.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
} }
} }
@@ -120,7 +214,7 @@ public class DroplistEditor extends JSONElementEditor {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@Override @Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
JLabel label = ((JLabel)c); JLabel label = ((JLabel)c);
@@ -159,12 +253,12 @@ public class DroplistEditor extends JSONElementEditor {
skipNext = false; skipNext = false;
return; return;
} }
if (target.id.equals(value)) return; if (target.id.equals((String) value)) return;
if (idChanging()) { if (idChanging()) {
droplist.id = (String) value; droplist.id = (String) value;
DroplistEditor.this.name = droplist.getDesc(); DroplistEditor.this.name = droplist.getDesc();
droplist.childrenChanged(new ArrayList<>()); droplist.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DroplistEditor.this); ATContentStudio.frame.editorChanged(DroplistEditor.this);
} else { } else {
cancelIdEdit(idField); cancelIdEdit(idField);
@@ -196,7 +290,7 @@ public class DroplistEditor extends JSONElementEditor {
if (droplist.state != GameDataElement.State.modified) { if (droplist.state != GameDataElement.State.modified) {
droplist.state = GameDataElement.State.modified; droplist.state = GameDataElement.State.modified;
DroplistEditor.this.name = droplist.getDesc(); DroplistEditor.this.name = droplist.getDesc();
droplist.childrenChanged(new ArrayList<>()); droplist.childrenChanged(new ArrayList<ProjectTreeNode>());
ATContentStudio.frame.editorChanged(DroplistEditor.this); ATContentStudio.frame.editorChanged(DroplistEditor.this);
} }
updateJsonViewText(droplist.toJsonString()); updateJsonViewText(droplist.toJsonString());

View File

@@ -5,6 +5,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
@@ -16,15 +17,21 @@ import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
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.ActorCondition; import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
import com.gpl.rpg.atcontentstudio.model.gamedata.Common;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item; import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.model.gamedata.ItemCategory; import com.gpl.rpg.atcontentstudio.model.gamedata.ItemCategory;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
@@ -33,7 +40,6 @@ import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener; import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox; import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox;
import com.gpl.rpg.atcontentstudio.ui.OverlayIcon; import com.gpl.rpg.atcontentstudio.ui.OverlayIcon;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
public class ItemEditor extends JSONElementEditor { public class ItemEditor extends JSONElementEditor {
@@ -47,12 +53,12 @@ public class ItemEditor extends JSONElementEditor {
private static final String useLabel = "Effect on use: "; private static final String useLabel = "Effect on use: ";
private Common.ConditionEffect selectedEquipEffectCondition; private Item.ConditionEffect selectedEquipEffectCondition;
private Common.TimedConditionEffect selectedHitEffectSourceCondition; private Item.TimedConditionEffect selectedHitEffectSourceCondition;
private Common.TimedConditionEffect selectedHitEffectTargetCondition; private Item.TimedConditionEffect selectedHitEffectTargetCondition;
private Common.TimedConditionEffect selectedKillEffectCondition; private Item.TimedConditionEffect selectedKillEffectCondition;
private Common.TimedConditionEffect selectedHitReceivedEffectSourceCondition; private Item.TimedConditionEffect selectedHitReceivedEffectSourceCondition;
private Common.TimedConditionEffect selectedHitReceivedEffectTargetCondition; private Item.TimedConditionEffect selectedHitReceivedEffectTargetCondition;
private JButton itemIcon; private JButton itemIcon;
@@ -91,7 +97,7 @@ public class ItemEditor extends JSONElementEditor {
private JSpinner equipConditionMagnitude; private JSpinner equipConditionMagnitude;
private CollapsiblePanel hitEffectPane; private CollapsiblePanel hitEffectPane;
private Common.HitEffect hitEffect;//TODO: Check if this was set anywhere before my changes private Item.HitEffect hitEffect;
private JSpinner hitHPMin; private JSpinner hitHPMin;
private JSpinner hitHPMax; private JSpinner hitHPMax;
private JSpinner hitAPMin; private JSpinner hitAPMin;
@@ -122,7 +128,7 @@ public class ItemEditor extends JSONElementEditor {
private JSpinner hitTargetConditionDuration; private JSpinner hitTargetConditionDuration;
private CollapsiblePanel killEffectPane; private CollapsiblePanel killEffectPane;
private Common.DeathEffect killEffect; private Item.KillEffect killEffect;
private JSpinner killHPMin; private JSpinner killHPMin;
private JSpinner killHPMax; private JSpinner killHPMax;
private JSpinner killAPMin; private JSpinner killAPMin;
@@ -141,7 +147,7 @@ public class ItemEditor extends JSONElementEditor {
private JSpinner killSourceConditionDuration; private JSpinner killSourceConditionDuration;
private CollapsiblePanel hitReceivedEffectPane; private CollapsiblePanel hitReceivedEffectPane;
private Common.HitReceivedEffect hitReceivedEffect; private Item.HitReceivedEffect hitReceivedEffect;
private JSpinner hitReceivedHPMin; private JSpinner hitReceivedHPMin;
private JSpinner hitReceivedHPMax; private JSpinner hitReceivedHPMax;
private JSpinner hitReceivedAPMin; private JSpinner hitReceivedAPMin;
@@ -224,25 +230,59 @@ public class ItemEditor extends JSONElementEditor {
equipIncUseCost = addIntegerField(equipEffectPane, "Increase item use cost: ", equipEffect.increase_use_item_cost, true, item.writable, listener); equipIncUseCost = addIntegerField(equipEffectPane, "Increase item use cost: ", equipEffect.increase_use_item_cost, true, item.writable, listener);
equipIncReequipCost = addIntegerField(equipEffectPane, "Increase reequip cost: ", equipEffect.increase_reequip_cost, true, item.writable, listener); equipIncReequipCost = addIntegerField(equipEffectPane, "Increase reequip cost: ", equipEffect.increase_reequip_cost, true, item.writable, listener);
equipIncAttackCost = addIntegerField(equipEffectPane, "Increase attack cost: ", equipEffect.increase_attack_cost, true, item.writable, listener); equipIncAttackCost = addIntegerField(equipEffectPane, "Increase attack cost: ", equipEffect.increase_attack_cost, true, item.writable, listener);
String title = "Actor Conditions applied when equipped: "; CollapsiblePanel equipConditionsPane = new CollapsiblePanel("Actor Conditions applied when equipped: ");
ConditionsCellRenderer cellRenderer = new ConditionsCellRenderer(); equipConditionsPane.setLayout(new JideBoxLayout(equipConditionsPane, JideBoxLayout.PAGE_AXIS));
equipConditionsModel = new ConditionsListModel(equipEffect); equipConditionsModel = new ConditionsListModel(equipEffect);
final boolean moveUpDownEnabled = false; equipConditionsList = new JList(equipConditionsModel);
equipConditionsList.setCellRenderer(new ConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.ConditionEffect> equipConditionsCreation = CommonEditor.createListPanel( equipConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
title, equipConditionsPane.add(new JScrollPane(equipConditionsList), JideBoxLayout.FIX);
cellRenderer, final JPanel equipConditionsEditorPane = new JPanel();
equipConditionsModel, final JButton createEquipCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
item.writable, final JButton deleteEquipCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
moveUpDownEnabled, equipConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedEquipEffectCondition = e, @Override
() -> selectedEquipEffectCondition, public void valueChanged(ListSelectionEvent e) {
this::updateEquipConditionEditorPane, selectedEquipEffectCondition = (Item.ConditionEffect) equipConditionsList.getSelectedValue();
listener, if (selectedEquipEffectCondition == null) {
Common.ConditionEffect::new); deleteEquipCondition.setEnabled(false);
CollapsiblePanel equipConditionsPane = equipConditionsCreation.panel; } else {
equipConditionsList = equipConditionsCreation.list; deleteEquipCondition.setEnabled(true);
}
updateEquipConditionEditorPane(equipConditionsEditorPane, selectedEquipEffectCondition, listener);
}
});
if (item.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createEquipCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Item.ConditionEffect condition = new Item.ConditionEffect();
equipConditionsModel.addItem(condition);
equipConditionsList.setSelectedValue(condition, true);
listener.valueChanged(equipConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteEquipCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedEquipEffectCondition != null) {
equipConditionsModel.removeItem(selectedEquipEffectCondition);
selectedEquipEffectCondition = null;
equipConditionsList.clearSelection();
listener.valueChanged(equipConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createEquipCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteEquipCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
equipConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
equipConditionsEditorPane.setLayout(new JideBoxLayout(equipConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
equipConditionsPane.add(equipConditionsEditorPane, JideBoxLayout.FIX);
if (item.equip_effect == null || item.equip_effect.conditions == null || item.equip_effect.conditions.isEmpty()) { if (item.equip_effect == null || item.equip_effect.conditions == null || item.equip_effect.conditions.isEmpty()) {
equipConditionsPane.collapse(); equipConditionsPane.collapse();
} }
@@ -252,55 +292,127 @@ public class ItemEditor extends JSONElementEditor {
equipEffectPane.collapse(); equipEffectPane.collapse();
} }
CommonEditor.CreateDeathEffectPanelResult hitEffectPanelResult = CommonEditor.createDeathEffectPanel(item.hit_effect, item.writable, listener, "Effect on every hit: "); hitEffectPane = new CollapsiblePanel("Effect on every hit: ");
hitEffectPane = hitEffectPanelResult.panel; hitEffectPane.setLayout(new JideBoxLayout(hitEffectPane, JideBoxLayout.PAGE_AXIS));
hitHPMin = hitEffectPanelResult.HPMin; if (item.hit_effect == null) {
hitHPMax = hitEffectPanelResult.HPMax; hitEffect = new Item.HitEffect();
hitAPMax = hitEffectPanelResult.APMax; } else {
hitAPMin = hitEffectPanelResult.APMin; hitEffect = item.hit_effect;
}
String hitSourceTitle = "Actor Conditions applied to the source: "; hitHPMin = addIntegerField(hitEffectPane, "HP bonus min: ", hitEffect.hp_boost_min, true, item.writable, listener);
TimedConditionsCellRenderer hitSourceCellRenderer = new TimedConditionsCellRenderer(); hitHPMax = addIntegerField(hitEffectPane, "HP bonus max: ", hitEffect.hp_boost_max, true, item.writable, listener);
hitAPMin = addIntegerField(hitEffectPane, "AP bonus min: ", hitEffect.ap_boost_min, true, item.writable, listener);
hitAPMax = addIntegerField(hitEffectPane, "AP bonus max: ", hitEffect.ap_boost_max, true, item.writable, listener);
final CollapsiblePanel hitSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the source: ");
hitSourceConditionsPane.setLayout(new JideBoxLayout(hitSourceConditionsPane, JideBoxLayout.PAGE_AXIS));
hitSourceConditionsModel = new SourceTimedConditionsListModel(hitEffect); hitSourceConditionsModel = new SourceTimedConditionsListModel(hitEffect);
final boolean hitSourceMoveUpDownEnabled = false; hitSourceConditionsList = new JList(hitSourceConditionsModel);
hitSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> hitSourceConditionsCreation = CommonEditor.createListPanel( hitSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitSourceTitle, hitSourceConditionsPane.add(new JScrollPane(hitSourceConditionsList), JideBoxLayout.FIX);
hitSourceCellRenderer, final JPanel sourceTimedConditionsEditorPane = new JPanel();
hitSourceConditionsModel, final JButton createHitSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
item.writable, final JButton deleteHitSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitSourceMoveUpDownEnabled, hitSourceConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitEffectSourceCondition = e, @Override
() -> selectedHitEffectSourceCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitSourceTimedConditionEditorPane, selectedHitEffectSourceCondition = (Item.TimedConditionEffect) hitSourceConditionsList.getSelectedValue();
listener, updateHitSourceTimedConditionEditorPane(sourceTimedConditionsEditorPane, selectedHitEffectSourceCondition, listener);
Common.TimedConditionEffect::new); if (selectedHitEffectSourceCondition == null) {
final CollapsiblePanel hitSourceConditionsPane = hitSourceConditionsCreation.panel; deleteHitSourceCondition.setEnabled(false);
hitSourceConditionsList = hitSourceConditionsCreation.list; } else {
deleteHitSourceCondition.setEnabled(true);
}
}
});
if (item.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Item.TimedConditionEffect condition = new Item.TimedConditionEffect();
hitSourceConditionsModel.addItem(condition);
hitSourceConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitEffectSourceCondition != null) {
hitSourceConditionsModel.removeItem(selectedHitEffectSourceCondition);
selectedHitEffectSourceCondition = null;
hitSourceConditionsList.clearSelection();
listener.valueChanged(hitSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
sourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(sourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitSourceConditionsPane.add(sourceTimedConditionsEditorPane, JideBoxLayout.FIX);
if (item.hit_effect == null || item.hit_effect.conditions_source == null || item.hit_effect.conditions_source.isEmpty()) { if (item.hit_effect == null || item.hit_effect.conditions_source == null || item.hit_effect.conditions_source.isEmpty()) {
hitSourceConditionsPane.collapse(); hitSourceConditionsPane.collapse();
} }
hitEffectPane.add(hitSourceConditionsPane, JideBoxLayout.FIX); hitEffectPane.add(hitSourceConditionsPane, JideBoxLayout.FIX);
String hitTargetTitle = "Actor Conditions applied to the target: "; final CollapsiblePanel hitTargetConditionsPane = new CollapsiblePanel("Actor Conditions applied to the target: ");
TimedConditionsCellRenderer hitTargetCellRenderer = new TimedConditionsCellRenderer(); hitTargetConditionsPane.setLayout(new JideBoxLayout(hitTargetConditionsPane, JideBoxLayout.PAGE_AXIS));
hitTargetConditionsModel = new TargetTimedConditionsListModel(hitEffect); hitTargetConditionsModel = new TargetTimedConditionsListModel(hitEffect);
final boolean hitTargetMoveUpDownEnabled = false; hitTargetConditionsList = new JList(hitTargetConditionsModel);
hitTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> listPanel2 = CommonEditor.createListPanel( hitTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitTargetTitle, hitTargetConditionsPane.add(new JScrollPane(hitTargetConditionsList), JideBoxLayout.FIX);
hitTargetCellRenderer, final JPanel targetTimedConditionsEditorPane = new JPanel();
hitTargetConditionsModel, final JButton createHitTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
item.writable, final JButton deleteHitTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitTargetMoveUpDownEnabled, hitTargetConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitEffectTargetCondition = e, @Override
() -> selectedHitEffectTargetCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitTargetTimedConditionEditorPane, selectedHitEffectTargetCondition = (Item.TimedConditionEffect) hitTargetConditionsList.getSelectedValue();
listener, updateHitTargetTimedConditionEditorPane(targetTimedConditionsEditorPane, selectedHitEffectTargetCondition, listener);
Common.TimedConditionEffect::new); if (selectedHitEffectTargetCondition == null) {
final CollapsiblePanel hitTargetConditionsPane = (CollapsiblePanel) listPanel2.panel; deleteHitTargetCondition.setEnabled(false);
hitTargetConditionsList = listPanel2.list; } else {
deleteHitTargetCondition.setEnabled(true);
}
}
});
if (item.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Item.TimedConditionEffect condition = new Item.TimedConditionEffect();
hitTargetConditionsModel.addItem(condition);
hitTargetConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitEffectTargetCondition != null) {
hitTargetConditionsModel.removeItem(selectedHitEffectTargetCondition);
selectedHitEffectTargetCondition = null;
hitTargetConditionsList.clearSelection();
listener.valueChanged(hitTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
targetTimedConditionsEditorPane.setLayout(new JideBoxLayout(targetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitTargetConditionsPane.add(targetTimedConditionsEditorPane, JideBoxLayout.FIX);
if (item.hit_effect == null || item.hit_effect.conditions_target == null || item.hit_effect.conditions_target.isEmpty()) { if (item.hit_effect == null || item.hit_effect.conditions_target == null || item.hit_effect.conditions_target.isEmpty()) {
hitTargetConditionsPane.collapse(); hitTargetConditionsPane.collapse();
} }
@@ -311,38 +423,71 @@ public class ItemEditor extends JSONElementEditor {
pane.add(hitEffectPane, JideBoxLayout.FIX); pane.add(hitEffectPane, JideBoxLayout.FIX);
killEffectPane = new CollapsiblePanel(killLabel);
killEffectPane.setLayout(new JideBoxLayout(killEffectPane, JideBoxLayout.PAGE_AXIS));
if (item.kill_effect == null) { if (item.kill_effect == null) {
killEffect = new Common.DeathEffect(); killEffect = new Item.KillEffect();
} else { } else {
killEffect = item.kill_effect; killEffect = item.kill_effect;
} }
killHPMin = addIntegerField(killEffectPane, "HP bonus min: ", killEffect.hp_boost_min, true, item.writable, listener);
CommonEditor.CreateDeathEffectPanelResult x = CommonEditor.createDeathEffectPanel(killEffect, item.writable, listener, killLabel); killHPMax = addIntegerField(killEffectPane, "HP bonus max: ", killEffect.hp_boost_max, true, item.writable, listener);
killEffectPane = x.panel; killAPMin = addIntegerField(killEffectPane, "AP bonus min: ", killEffect.ap_boost_min, true, item.writable, listener);
killHPMin = x.HPMin; killAPMax = addIntegerField(killEffectPane, "AP bonus max: ", killEffect.ap_boost_max, true, item.writable, listener);
killHPMax = x.HPMax; final CollapsiblePanel killSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the source: ");
killAPMin = x.APMin; killSourceConditionsPane.setLayout(new JideBoxLayout(killSourceConditionsPane, JideBoxLayout.PAGE_AXIS));
killAPMax = x.APMax;
String killSourceTitle = "Actor Conditions applied to the source: ";
TimedConditionsCellRenderer killSourceCellRenderer = new TimedConditionsCellRenderer();
killSourceConditionsModel = new SourceTimedConditionsListModel(killEffect); killSourceConditionsModel = new SourceTimedConditionsListModel(killEffect);
final boolean killSourceMoveUpDownEnabled = false; killSourceConditionsList = new JList(killSourceConditionsModel);
killSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> listPanel = CommonEditor.createListPanel( killSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
killSourceTitle, killSourceConditionsPane.add(new JScrollPane(killSourceConditionsList), JideBoxLayout.FIX);
killSourceCellRenderer, final JPanel killSourceTimedConditionsEditorPane = new JPanel();
killSourceConditionsModel, final JButton createKillSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
item.writable, final JButton deleteKillSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
killSourceMoveUpDownEnabled, killSourceConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedKillEffectCondition = e, @Override
() -> selectedKillEffectCondition, public void valueChanged(ListSelectionEvent e) {
this::updateKillSourceTimedConditionEditorPane, selectedKillEffectCondition = (Item.TimedConditionEffect) killSourceConditionsList.getSelectedValue();
listener, updateKillSourceTimedConditionEditorPane(killSourceTimedConditionsEditorPane, selectedKillEffectCondition, listener);
Common.TimedConditionEffect::new); if (selectedKillEffectCondition == null) {
final CollapsiblePanel killSourceConditionsPane = listPanel.panel; deleteKillSourceCondition.setEnabled(false);
killSourceConditionsList = listPanel.list; } else {
deleteKillSourceCondition.setEnabled(true);
}
}
});
if (item.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createKillSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Item.TimedConditionEffect condition = new Item.TimedConditionEffect();
killSourceConditionsModel.addItem(condition);
killSourceConditionsList.setSelectedValue(condition, true);
listener.valueChanged(killSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteKillSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedKillEffectCondition != null) {
killSourceConditionsModel.removeItem(selectedKillEffectCondition);
selectedKillEffectCondition = null;
killSourceConditionsList.clearSelection();
listener.valueChanged(killSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createKillSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteKillSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
killSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
killSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(killSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
killSourceConditionsPane.add(killSourceTimedConditionsEditorPane, JideBoxLayout.FIX);
if (item.kill_effect == null || item.kill_effect.conditions_source == null || item.kill_effect.conditions_source.isEmpty()) { if (item.kill_effect == null || item.kill_effect.conditions_source == null || item.kill_effect.conditions_source.isEmpty()) {
killSourceConditionsPane.collapse(); killSourceConditionsPane.collapse();
} }
@@ -353,14 +498,13 @@ public class ItemEditor extends JSONElementEditor {
pane.add(killEffectPane, JideBoxLayout.FIX); pane.add(killEffectPane, JideBoxLayout.FIX);
hitReceivedEffectPane = new CollapsiblePanel("Effect on every hit received: ");
hitReceivedEffectPane.setLayout(new JideBoxLayout(hitReceivedEffectPane, JideBoxLayout.PAGE_AXIS));
if (item.hit_received_effect == null) { if (item.hit_received_effect == null) {
hitReceivedEffect = new Common.HitReceivedEffect(); hitReceivedEffect = new Item.HitReceivedEffect();
} else { } else {
hitReceivedEffect = item.hit_received_effect; hitReceivedEffect = item.hit_received_effect;
} }
String titleHitReceived = "Effect on every hit received: ";
hitReceivedEffectPane = new CollapsiblePanel(titleHitReceived);
hitReceivedEffectPane.setLayout(new JideBoxLayout(hitReceivedEffectPane, JideBoxLayout.PAGE_AXIS));
hitReceivedHPMin = addIntegerField(hitReceivedEffectPane, "Player HP bonus min: ", hitReceivedEffect.hp_boost_min, true, item.writable, listener); hitReceivedHPMin = addIntegerField(hitReceivedEffectPane, "Player HP bonus min: ", hitReceivedEffect.hp_boost_min, true, item.writable, listener);
hitReceivedHPMax = addIntegerField(hitReceivedEffectPane, "Player HP bonus max: ", hitReceivedEffect.hp_boost_max, true, item.writable, listener); hitReceivedHPMax = addIntegerField(hitReceivedEffectPane, "Player HP bonus max: ", hitReceivedEffect.hp_boost_max, true, item.writable, listener);
hitReceivedAPMin = addIntegerField(hitReceivedEffectPane, "Player AP bonus min: ", hitReceivedEffect.ap_boost_min, true, item.writable, listener); hitReceivedAPMin = addIntegerField(hitReceivedEffectPane, "Player AP bonus min: ", hitReceivedEffect.ap_boost_min, true, item.writable, listener);
@@ -369,48 +513,116 @@ public class ItemEditor extends JSONElementEditor {
hitReceivedHPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker HP bonus max: ", hitReceivedEffect.hp_boost_max_target, true, item.writable, listener); hitReceivedHPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker HP bonus max: ", hitReceivedEffect.hp_boost_max_target, true, item.writable, listener);
hitReceivedAPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus min: ", hitReceivedEffect.ap_boost_min_target, true, item.writable, listener); hitReceivedAPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus min: ", hitReceivedEffect.ap_boost_min_target, true, item.writable, listener);
hitReceivedAPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus max: ", hitReceivedEffect.ap_boost_max_target, true, item.writable, listener); hitReceivedAPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus max: ", hitReceivedEffect.ap_boost_max_target, true, item.writable, listener);
String hitReceivedSourceTitle = "Actor Conditions applied to the player: "; final CollapsiblePanel hitReceivedSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the player: ");
TimedConditionsCellRenderer hitReceivedSourceCellRenderer = new TimedConditionsCellRenderer(); hitReceivedSourceConditionsPane.setLayout(new JideBoxLayout(hitReceivedSourceConditionsPane, JideBoxLayout.PAGE_AXIS));
hitReceivedSourceConditionsModel = new SourceTimedConditionsListModel(hitReceivedEffect); hitReceivedSourceConditionsModel = new SourceTimedConditionsListModel(hitReceivedEffect);
final boolean hitReceivedSourceMoveUpDownEnabled = false; hitReceivedSourceConditionsList = new JList(hitReceivedSourceConditionsModel);
hitReceivedSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> listPanel1 = CommonEditor.createListPanel( hitReceivedSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitReceivedSourceTitle, hitReceivedSourceConditionsPane.add(new JScrollPane(hitReceivedSourceConditionsList), JideBoxLayout.FIX);
hitReceivedSourceCellRenderer, final JPanel hitReceivedSourceTimedConditionsEditorPane = new JPanel();
hitReceivedSourceConditionsModel, final JButton createHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
item.writable, final JButton deleteHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitReceivedSourceMoveUpDownEnabled, hitReceivedSourceConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitReceivedEffectSourceCondition = e, @Override
() -> selectedHitReceivedEffectSourceCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitReceivedSourceTimedConditionEditorPane, selectedHitReceivedEffectSourceCondition = (Item.TimedConditionEffect) hitReceivedSourceConditionsList.getSelectedValue();
listener, updateHitReceivedSourceTimedConditionEditorPane(hitReceivedSourceTimedConditionsEditorPane, selectedHitReceivedEffectSourceCondition, listener);
Common.TimedConditionEffect::new); if (selectedHitReceivedEffectSourceCondition == null) {
final CollapsiblePanel hitReceivedSourceConditionsPane = listPanel1.panel; deleteHitReceivedSourceCondition.setEnabled(false);
hitReceivedSourceConditionsList = listPanel1.list; } else {
deleteHitReceivedSourceCondition.setEnabled(true);
}
}
});
if (item.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitReceivedSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Item.TimedConditionEffect condition = new Item.TimedConditionEffect();
hitReceivedSourceConditionsModel.addItem(condition);
hitReceivedSourceConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitReceivedSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitReceivedEffectSourceCondition != null) {
hitReceivedSourceConditionsModel.removeItem(selectedHitReceivedEffectSourceCondition);
selectedHitReceivedEffectSourceCondition = null;
hitReceivedSourceConditionsList.clearSelection();
listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitReceivedSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitReceivedSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitReceivedSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
hitReceivedSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitReceivedSourceConditionsPane.add(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.FIX);
if (item.hit_received_effect == null || item.hit_received_effect.conditions_source == null || item.hit_received_effect.conditions_source.isEmpty()) { if (item.hit_received_effect == null || item.hit_received_effect.conditions_source == null || item.hit_received_effect.conditions_source.isEmpty()) {
hitReceivedSourceConditionsPane.collapse(); hitReceivedSourceConditionsPane.collapse();
} }
hitReceivedEffectPane.add(hitReceivedSourceConditionsPane, JideBoxLayout.FIX); hitReceivedEffectPane.add(hitReceivedSourceConditionsPane, JideBoxLayout.FIX);
String hitReceivedTargetTitle = "Actor Conditions applied to the attacker: "; final CollapsiblePanel hitReceivedTargetConditionsPane = new CollapsiblePanel("Actor Conditions applied to the attacker: ");
TimedConditionsCellRenderer hitReceivedTargetCellRenderer = new TimedConditionsCellRenderer(); hitReceivedTargetConditionsPane.setLayout(new JideBoxLayout(hitReceivedTargetConditionsPane, JideBoxLayout.PAGE_AXIS));
hitReceivedTargetConditionsModel = new TargetTimedConditionsListModel(hitReceivedEffect); hitReceivedTargetConditionsModel = new TargetTimedConditionsListModel(hitReceivedEffect);
final boolean hitReceivedTargetMoveUpDownEnabled = false; hitReceivedTargetConditionsList = new JList(hitReceivedTargetConditionsModel);
hitReceivedTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> hitReceivedTargetResult = CommonEditor.createListPanel( hitReceivedTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitReceivedTargetTitle, hitReceivedTargetConditionsPane.add(new JScrollPane(hitReceivedTargetConditionsList), JideBoxLayout.FIX);
hitReceivedTargetCellRenderer, final JPanel hitReceivedTargetTimedConditionsEditorPane = new JPanel();
hitReceivedTargetConditionsModel, final JButton createHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
item.writable, final JButton deleteHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitReceivedTargetMoveUpDownEnabled, hitReceivedTargetConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitReceivedEffectTargetCondition = e, @Override
() -> selectedHitReceivedEffectTargetCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitReceivedTargetTimedConditionEditorPane, selectedHitReceivedEffectTargetCondition = (Item.TimedConditionEffect) hitReceivedTargetConditionsList.getSelectedValue();
listener, updateHitReceivedTargetTimedConditionEditorPane(hitReceivedTargetTimedConditionsEditorPane, selectedHitReceivedEffectTargetCondition, listener);
Common.TimedConditionEffect::new); if (selectedHitReceivedEffectTargetCondition == null) {
final CollapsiblePanel hitReceivedTargetConditionsPane = hitReceivedTargetResult.panel; deleteHitReceivedTargetCondition.setEnabled(false);
hitReceivedTargetConditionsList = hitReceivedTargetResult.list; } else {
deleteHitReceivedTargetCondition.setEnabled(true);
}
}
});
if (item.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitReceivedTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Item.TimedConditionEffect condition = new Item.TimedConditionEffect();
hitReceivedTargetConditionsModel.addItem(condition);
hitReceivedTargetConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitReceivedTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitReceivedEffectTargetCondition != null) {
hitReceivedTargetConditionsModel.removeItem(selectedHitReceivedEffectTargetCondition);
selectedHitReceivedEffectTargetCondition = null;
hitReceivedTargetConditionsList.clearSelection();
listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitReceivedTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitReceivedTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitReceivedTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
hitReceivedTargetTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitReceivedTargetConditionsPane.add(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.FIX);
if (item.hit_received_effect == null || item.hit_received_effect.conditions_target == null || item.hit_received_effect.conditions_target.isEmpty()) { if (item.hit_received_effect == null || item.hit_received_effect.conditions_target == null || item.hit_received_effect.conditions_target.isEmpty()) {
hitReceivedTargetConditionsPane.collapse(); hitReceivedTargetConditionsPane.collapse();
} }
@@ -443,7 +655,7 @@ public class ItemEditor extends JSONElementEditor {
} }
public void updateHitSourceTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitSourceConditionBox != null) { if (hitSourceConditionBox != null) {
removeElementListener(hitSourceConditionBox); removeElementListener(hitSourceConditionBox);
@@ -454,8 +666,8 @@ public class ItemEditor extends JSONElementEditor {
return; return;
} }
boolean writable = target.writable; boolean writable = ((Item)target).writable;
Project proj = target.getProject(); Project proj = ((Item)target).getProject();
hitSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); hitSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener);
hitSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); hitSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener);
@@ -521,7 +733,7 @@ public class ItemEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitSourceTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitSourceTimedConditionWidgets(Item.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -539,7 +751,7 @@ public class ItemEditor extends JSONElementEditor {
hitSourceConditionForever.setEnabled(!clear); hitSourceConditionForever.setEnabled(!clear);
} }
public void updateHitTargetTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitTargetTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitTargetConditionBox != null) { if (hitTargetConditionBox != null) {
removeElementListener(hitTargetConditionBox); removeElementListener(hitTargetConditionBox);
@@ -550,8 +762,8 @@ public class ItemEditor extends JSONElementEditor {
return; return;
} }
boolean writable = target.writable; boolean writable = ((Item)target).writable;
Project proj = target.getProject(); Project proj = ((Item)target).getProject();
hitTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); hitTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener);
hitTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); hitTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener);
@@ -617,7 +829,7 @@ public class ItemEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitTargetTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitTargetTimedConditionWidgets(Item.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -635,7 +847,7 @@ public class ItemEditor extends JSONElementEditor {
hitTargetConditionForever.setEnabled(!clear); hitTargetConditionForever.setEnabled(!clear);
} }
public void updateKillSourceTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateKillSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (killSourceConditionBox != null) { if (killSourceConditionBox != null) {
removeElementListener(killSourceConditionBox); removeElementListener(killSourceConditionBox);
@@ -713,7 +925,7 @@ public class ItemEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateKillSourceTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateKillSourceTimedConditionWidgets(Item.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -731,7 +943,7 @@ public class ItemEditor extends JSONElementEditor {
killSourceConditionForever.setEnabled(!clear); killSourceConditionForever.setEnabled(!clear);
} }
public void updateEquipConditionEditorPane(JPanel pane, Common.ConditionEffect condition, final FieldUpdateListener listener) { public void updateEquipConditionEditorPane(JPanel pane, Item.ConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (equipConditionBox != null) { if (equipConditionBox != null) {
removeElementListener(equipConditionBox); removeElementListener(equipConditionBox);
@@ -779,7 +991,7 @@ public class ItemEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitReceivedSourceTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitReceivedSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitReceivedSourceConditionBox != null) { if (hitReceivedSourceConditionBox != null) {
removeElementListener(hitReceivedSourceConditionBox); removeElementListener(hitReceivedSourceConditionBox);
@@ -857,7 +1069,7 @@ public class ItemEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitReceivedSourceTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitReceivedSourceTimedConditionWidgets(Item.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -875,7 +1087,7 @@ public class ItemEditor extends JSONElementEditor {
hitReceivedSourceConditionForever.setEnabled(!clear); hitReceivedSourceConditionForever.setEnabled(!clear);
} }
public void updateHitReceivedTargetTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitReceivedTargetTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitReceivedTargetConditionBox != null) { if (hitReceivedTargetConditionBox != null) {
removeElementListener(hitReceivedTargetConditionBox); removeElementListener(hitReceivedTargetConditionBox);
@@ -953,7 +1165,7 @@ public class ItemEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitReceivedTargetTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitReceivedTargetTimedConditionWidgets(Item.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -972,41 +1184,129 @@ public class ItemEditor extends JSONElementEditor {
} }
public static class SourceTimedConditionsListModel extends CommonEditor.AtListModel<Common.TimedConditionEffect, Common.DeathEffect> { public static class SourceTimedConditionsListModel implements ListModel<Item.TimedConditionEffect> {
public SourceTimedConditionsListModel(Common.DeathEffect effect) { Item.KillEffect source;
super(effect);
public SourceTimedConditionsListModel(Item.KillEffect effect) {
this.source = effect;;
} }
@Override @Override
protected List<Common.TimedConditionEffect> getInner() { public int getSize() {
return source.conditions_source; if (source.conditions_source == null) return 0;
return source.conditions_source.size();
} }
@Override @Override
protected void setInner(List<Common.TimedConditionEffect> value) { public Item.TimedConditionEffect getElementAt(int index) {
source.conditions_source = value; if (source.conditions_source == null) return null;
return source.conditions_source.get(index);
} }
} public void addItem(Item.TimedConditionEffect item) {
if (source.conditions_source == null) {
source.conditions_source = new ArrayList<Item.TimedConditionEffect>();
}
source.conditions_source.add(item);
int index = source.conditions_source.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public static class TargetTimedConditionsListModel extends CommonEditor.AtListModel<Common.TimedConditionEffect, Common.HitEffect> { public void removeItem(Item.TimedConditionEffect item) {
int index = source.conditions_source.indexOf(item);
source.conditions_source.remove(item);
if (source.conditions_source.isEmpty()) {
source.conditions_source = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public TargetTimedConditionsListModel(Common.HitEffect effect) { public void itemChanged(Item.TimedConditionEffect item) {
super(effect); int index = source.conditions_source.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
protected List<Common.TimedConditionEffect> getInner() { public void removeListDataListener(ListDataListener l) {
return source.conditions_target; listeners.remove(l);
}
}
public static class TargetTimedConditionsListModel implements ListModel<Item.TimedConditionEffect> {
Item.HitEffect source;
public TargetTimedConditionsListModel(Item.HitEffect effect) {
this.source = effect;;
} }
@Override @Override
protected void setInner(List<Common.TimedConditionEffect> value) { public int getSize() {
source.conditions_target = value; if (source.conditions_target == null) return 0;
return source.conditions_target.size();
} }
} @Override
public Item.TimedConditionEffect getElementAt(int index) {
if (source.conditions_target == null) return null;
return source.conditions_target.get(index);
}
public void addItem(Item.TimedConditionEffect item) {
if (source.conditions_target == null) {
source.conditions_target = new ArrayList<Item.TimedConditionEffect>();
}
source.conditions_target.add(item);
int index = source.conditions_target.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Item.TimedConditionEffect item) {
int index = source.conditions_target.indexOf(item);
source.conditions_target.remove(item);
if (source.conditions_target.isEmpty()) {
source.conditions_target = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Item.TimedConditionEffect item) {
int index = source.conditions_target.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
public static class TimedConditionsCellRenderer extends DefaultListCellRenderer { public static class TimedConditionsCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@@ -1016,7 +1316,7 @@ public class ItemEditor extends JSONElementEditor {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
JLabel label = ((JLabel)c); JLabel label = ((JLabel)c);
Common.TimedConditionEffect effect = (Common.TimedConditionEffect) value; Item.TimedConditionEffect effect = (Item.TimedConditionEffect) value;
if (effect.condition != null) { if (effect.condition != null) {
@@ -1042,22 +1342,67 @@ public class ItemEditor extends JSONElementEditor {
} }
} }
public static class ConditionsListModel extends CommonEditor.AtListModel<Common.ConditionEffect, Item.EquipEffect> { public static class ConditionsListModel implements ListModel<Item.ConditionEffect> {
Item.EquipEffect source;
public ConditionsListModel(Item.EquipEffect equipEffect) { public ConditionsListModel(Item.EquipEffect equipEffect) {
super(equipEffect); this.source = equipEffect;
} }
@Override @Override
protected List<Common.ConditionEffect> getInner() { public int getSize() {
return source.conditions; if (source.conditions == null) return 0;
return source.conditions.size();
} }
@Override @Override
protected void setInner(List<Common.ConditionEffect> value) { public Item.ConditionEffect getElementAt(int index) {
source.conditions = value; if (source.conditions == null) return null;
return source.conditions.get(index);
} }
}
public void addItem(Item.ConditionEffect item) {
if (source.conditions == null) {
source.conditions = new ArrayList<Item.ConditionEffect>();
}
source.conditions.add(item);
int index = source.conditions.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(Item.ConditionEffect item) {
int index = source.conditions.indexOf(item);
source.conditions.remove(item);
if (source.conditions.isEmpty()) {
source.conditions = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(Item.ConditionEffect item) {
int index = source.conditions.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
public static class ConditionsCellRenderer extends DefaultListCellRenderer { public static class ConditionsCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@@ -1067,7 +1412,7 @@ public class ItemEditor extends JSONElementEditor {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
JLabel label = ((JLabel)c); JLabel label = ((JLabel)c);
Common.ConditionEffect effect = (Common.ConditionEffect) value; Item.ConditionEffect effect = (Item.ConditionEffect) value;
if (effect.condition != null) { if (effect.condition != null) {
if (effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) { if (effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) {
@@ -1105,7 +1450,7 @@ public class ItemEditor extends JSONElementEditor {
} }
public static boolean isNull(Common.HitEffect effect) { public static boolean isNull(Item.HitEffect effect) {
if (effect.ap_boost_min != null) return false; if (effect.ap_boost_min != null) return false;
if (effect.ap_boost_max != null) return false; if (effect.ap_boost_max != null) return false;
if (effect.hp_boost_min != null) return false; if (effect.hp_boost_min != null) return false;
@@ -1116,7 +1461,7 @@ public class ItemEditor extends JSONElementEditor {
} }
public static boolean isNull(Common.DeathEffect effect) { public static boolean isNull(Item.KillEffect effect) {
if (effect.ap_boost_min != null) return false; if (effect.ap_boost_min != null) return false;
if (effect.ap_boost_max != null) return false; if (effect.ap_boost_max != null) return false;
if (effect.hp_boost_min != null) return false; if (effect.hp_boost_min != null) return false;
@@ -1125,7 +1470,7 @@ public class ItemEditor extends JSONElementEditor {
return true; return true;
} }
public static boolean isNull(Common.HitReceivedEffect effect) { public static boolean isNull(Item.HitReceivedEffect effect) {
if (effect.ap_boost_min != null) return false; if (effect.ap_boost_min != null) return false;
if (effect.ap_boost_max != null) return false; if (effect.ap_boost_max != null) return false;
if (effect.hp_boost_min != null) return false; if (effect.hp_boost_min != null) return false;

View File

@@ -6,6 +6,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
@@ -17,14 +18,24 @@ import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
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.*; 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.NPC;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel; import com.gpl.rpg.atcontentstudio.ui.CollapsiblePanel;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
@@ -32,7 +43,6 @@ import com.gpl.rpg.atcontentstudio.ui.FieldUpdateListener;
import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox; import com.gpl.rpg.atcontentstudio.ui.IntegerBasedCheckBox;
import com.gpl.rpg.atcontentstudio.ui.OverlayIcon; import com.gpl.rpg.atcontentstudio.ui.OverlayIcon;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree.DialogueGraphView; import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.dialoguetree.DialogueGraphView;
import com.gpl.rpg.atcontentstudio.ui.tools.CommonEditor;
import com.jidesoft.swing.JideBoxLayout; import com.jidesoft.swing.JideBoxLayout;
public class NPCEditor extends JSONElementEditor { public class NPCEditor extends JSONElementEditor {
@@ -43,11 +53,11 @@ public class NPCEditor extends JSONElementEditor {
private static final String json_view_id = "JSON"; private static final String json_view_id = "JSON";
private static final String dialogue_tree_id = "Dialogue Tree"; private static final String dialogue_tree_id = "Dialogue Tree";
private Common.TimedConditionEffect selectedHitEffectSourceCondition; private NPC.TimedConditionEffect selectedHitEffectSourceCondition;
private Common.TimedConditionEffect selectedHitEffectTargetCondition; private NPC.TimedConditionEffect selectedHitEffectTargetCondition;
private Common.TimedConditionEffect selectedHitReceivedEffectSourceCondition; private NPC.TimedConditionEffect selectedHitReceivedEffectSourceCondition;
private Common.TimedConditionEffect selectedHitReceivedEffectTargetCondition; private NPC.TimedConditionEffect selectedHitReceivedEffectTargetCondition;
private Common.TimedConditionEffect selectedDeathEffectSourceCondition; private NPC.TimedConditionEffect selectedDeathEffectSourceCondition;
private JButton npcIcon; private JButton npcIcon;
private JTextField idField; private JTextField idField;
@@ -76,7 +86,7 @@ public class NPCEditor extends JSONElementEditor {
private JSpinner blockChance; private JSpinner blockChance;
private JSpinner dmgRes; private JSpinner dmgRes;
private Common.HitEffect hitEffect; private NPC.HitEffect hitEffect;
private CollapsiblePanel hitEffectPane; private CollapsiblePanel hitEffectPane;
private JSpinner hitEffectHPMin; private JSpinner hitEffectHPMin;
private JSpinner hitEffectHPMax; private JSpinner hitEffectHPMax;
@@ -109,7 +119,7 @@ public class NPCEditor extends JSONElementEditor {
private JRadioButton hitTargetConditionForever; private JRadioButton hitTargetConditionForever;
private JSpinner hitTargetConditionDuration; private JSpinner hitTargetConditionDuration;
private Common.HitReceivedEffect hitReceivedEffect; private NPC.HitReceivedEffect hitReceivedEffect;
private CollapsiblePanel hitReceivedEffectPane; private CollapsiblePanel hitReceivedEffectPane;
private JSpinner hitReceivedEffectHPMin; private JSpinner hitReceivedEffectHPMin;
private JSpinner hitReceivedEffectHPMax; private JSpinner hitReceivedEffectHPMax;
@@ -146,7 +156,7 @@ public class NPCEditor extends JSONElementEditor {
private JRadioButton hitReceivedTargetConditionForever; private JRadioButton hitReceivedTargetConditionForever;
private JSpinner hitReceivedTargetConditionDuration; private JSpinner hitReceivedTargetConditionDuration;
private Common.DeathEffect deathEffect; private NPC.DeathEffect deathEffect;
private CollapsiblePanel deathEffectPane; private CollapsiblePanel deathEffectPane;
private JSpinner deathEffectHPMin; private JSpinner deathEffectHPMin;
private JSpinner deathEffectHPMax; private JSpinner deathEffectHPMax;
@@ -260,7 +270,7 @@ public class NPCEditor extends JSONElementEditor {
hitEffectPane = new CollapsiblePanel("Effect on every hit: "); hitEffectPane = new CollapsiblePanel("Effect on every hit: ");
hitEffectPane.setLayout(new JideBoxLayout(hitEffectPane, JideBoxLayout.PAGE_AXIS)); hitEffectPane.setLayout(new JideBoxLayout(hitEffectPane, JideBoxLayout.PAGE_AXIS));
if (npc.hit_effect == null) { if (npc.hit_effect == null) {
hitEffect = new Common.HitEffect(); hitEffect = new NPC.HitEffect();
} else { } else {
hitEffect = npc.hit_effect; hitEffect = npc.hit_effect;
} }
@@ -269,48 +279,106 @@ public class NPCEditor extends JSONElementEditor {
hitEffectAPMin = addIntegerField(hitEffectPane, "AP bonus min: ", hitEffect.ap_boost_min, true, npc.writable, listener); hitEffectAPMin = addIntegerField(hitEffectPane, "AP bonus min: ", hitEffect.ap_boost_min, true, npc.writable, listener);
hitEffectAPMax = addIntegerField(hitEffectPane, "AP bonus max: ", hitEffect.ap_boost_max, true, npc.writable, listener); hitEffectAPMax = addIntegerField(hitEffectPane, "AP bonus max: ", hitEffect.ap_boost_max, true, npc.writable, listener);
String hitSourceTitle = "Actor Conditions applied to the source: "; CollapsiblePanel hitSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the source: ");
TimedConditionsCellRenderer hitSourceCellRenderer = new TimedConditionsCellRenderer(); hitSourceConditionsPane.setLayout(new JideBoxLayout(hitSourceConditionsPane, JideBoxLayout.PAGE_AXIS));
hitSourceConditionsListModel = new SourceTimedConditionsListModel(hitEffect); hitSourceConditionsListModel = new SourceTimedConditionsListModel(hitEffect);
final boolean hitSourceMoveUpDownEnabled = false; hitSourceConditionsList = new JList(hitSourceConditionsListModel);
hitSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> hitSourceResult = CommonEditor.createListPanel( hitSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitSourceTitle, hitSourceConditionsPane.add(new JScrollPane(hitSourceConditionsList), JideBoxLayout.FIX);
hitSourceCellRenderer, final JPanel hitSourceTimedConditionsEditorPane = new JPanel();
hitSourceConditionsListModel, final JButton createHitSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
npc.writable, final JButton deleteHitSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitSourceMoveUpDownEnabled, hitSourceConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitEffectSourceCondition = e, @Override
() -> selectedHitEffectSourceCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitSourceTimedConditionEditorPane, selectedHitEffectSourceCondition = (NPC.TimedConditionEffect) hitSourceConditionsList.getSelectedValue();
listener, updateHitSourceTimedConditionEditorPane(hitSourceTimedConditionsEditorPane, selectedHitEffectSourceCondition, listener);
Common.TimedConditionEffect::new); }
CollapsiblePanel hitSourceConditionsPane = hitSourceResult.panel; });
hitSourceConditionsList = hitSourceResult.list; if (npc.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect();
hitSourceConditionsListModel.addItem(condition);
hitSourceConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitEffectSourceCondition != null) {
hitSourceConditionsListModel.removeItem(selectedHitEffectSourceCondition);
selectedHitEffectSourceCondition = null;
hitSourceConditionsList.clearSelection();
listener.valueChanged(hitSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
hitSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitSourceConditionsPane.add(hitSourceTimedConditionsEditorPane, JideBoxLayout.FIX);
if (npc.hit_effect == null || npc.hit_effect.conditions_source == null || npc.hit_effect.conditions_source.isEmpty()) { if (npc.hit_effect == null || npc.hit_effect.conditions_source == null || npc.hit_effect.conditions_source.isEmpty()) {
hitSourceConditionsPane.collapse(); hitSourceConditionsPane.collapse();
} }
hitEffectPane.add(hitSourceConditionsPane, JideBoxLayout.FIX); hitEffectPane.add(hitSourceConditionsPane, JideBoxLayout.FIX);
String hitTargetTitle = "Actor Conditions applied to the target: "; final CollapsiblePanel hitTargetConditionsPane = new CollapsiblePanel("Actor Conditions applied to the target: ");
TimedConditionsCellRenderer hitTargetCellRenderer = new TimedConditionsCellRenderer(); hitTargetConditionsPane.setLayout(new JideBoxLayout(hitTargetConditionsPane, JideBoxLayout.PAGE_AXIS));
hitTargetConditionsListModel = new TargetTimedConditionsListModel(hitEffect); hitTargetConditionsListModel = new TargetTimedConditionsListModel(hitEffect);
final boolean hitTargetMoveUpDownEnabled = false; hitTargetConditionsList = new JList(hitTargetConditionsListModel);
hitTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> hitTargetResult = CommonEditor.createListPanel( hitTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitTargetTitle, hitTargetConditionsPane.add(new JScrollPane(hitTargetConditionsList), JideBoxLayout.FIX);
hitTargetCellRenderer, final JPanel hitTargetTimedConditionsEditorPane = new JPanel();
hitTargetConditionsListModel, final JButton createHitTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
npc.writable, final JButton deleteHitTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitTargetMoveUpDownEnabled, hitTargetConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitEffectTargetCondition = e, @Override
() -> selectedHitEffectTargetCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitTargetTimedConditionEditorPane, selectedHitEffectTargetCondition = (NPC.TimedConditionEffect) hitTargetConditionsList.getSelectedValue();
listener, updateHitTargetTimedConditionEditorPane(hitTargetTimedConditionsEditorPane, selectedHitEffectTargetCondition, listener);
Common.TimedConditionEffect::new); }
CollapsiblePanel hitTargetConditionsPane = hitTargetResult.panel; });
hitTargetConditionsList = hitTargetResult.list; if (npc.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect();
hitTargetConditionsListModel.addItem(condition);
hitTargetConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitEffectTargetCondition != null) {
hitTargetConditionsListModel.removeItem(selectedHitEffectTargetCondition);
selectedHitEffectTargetCondition = null;
hitTargetConditionsList.clearSelection();
listener.valueChanged(hitTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
hitTargetTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitTargetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitTargetConditionsPane.add(hitTargetTimedConditionsEditorPane, JideBoxLayout.FIX);
hitEffectPane.add(hitTargetConditionsPane, JideBoxLayout.FIX); hitEffectPane.add(hitTargetConditionsPane, JideBoxLayout.FIX);
if (npc.hit_effect == null || npc.hit_effect.conditions_target == null || npc.hit_effect.conditions_target.isEmpty()) { if (npc.hit_effect == null || npc.hit_effect.conditions_target == null || npc.hit_effect.conditions_target.isEmpty()) {
hitTargetConditionsPane.collapse(); hitTargetConditionsPane.collapse();
@@ -320,7 +388,7 @@ public class NPCEditor extends JSONElementEditor {
hitReceivedEffectPane = new CollapsiblePanel("Effect on every hit received: "); hitReceivedEffectPane = new CollapsiblePanel("Effect on every hit received: ");
hitReceivedEffectPane.setLayout(new JideBoxLayout(hitReceivedEffectPane, JideBoxLayout.PAGE_AXIS)); hitReceivedEffectPane.setLayout(new JideBoxLayout(hitReceivedEffectPane, JideBoxLayout.PAGE_AXIS));
if (npc.hit_received_effect == null) { if (npc.hit_received_effect == null) {
hitReceivedEffect = new Common.HitReceivedEffect(); hitReceivedEffect = new NPC.HitReceivedEffect();
} else { } else {
hitReceivedEffect = npc.hit_received_effect; hitReceivedEffect = npc.hit_received_effect;
} }
@@ -333,48 +401,106 @@ public class NPCEditor extends JSONElementEditor {
hitReceivedEffectAPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus min: ", hitReceivedEffect.ap_boost_min_target, true, npc.writable, listener); hitReceivedEffectAPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus min: ", hitReceivedEffect.ap_boost_min_target, true, npc.writable, listener);
hitReceivedEffectAPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus max: ", hitReceivedEffect.ap_boost_max_target, true, npc.writable, listener); hitReceivedEffectAPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus max: ", hitReceivedEffect.ap_boost_max_target, true, npc.writable, listener);
String hitReceivedSourceTitle = "Actor Conditions applied to this NPC: "; CollapsiblePanel hitReceivedSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to this NPC: ");
TimedConditionsCellRenderer hitReceivedSourceCellRenderer = new TimedConditionsCellRenderer(); hitReceivedSourceConditionsPane.setLayout(new JideBoxLayout(hitReceivedSourceConditionsPane, JideBoxLayout.PAGE_AXIS));
hitReceivedSourceConditionsListModel = new SourceTimedConditionsListModel(hitReceivedEffect); hitReceivedSourceConditionsListModel = new SourceTimedConditionsListModel(hitReceivedEffect);
final boolean hitReceivedSourceMoveUpDownEnabled = false; hitReceivedSourceConditionsList = new JList(hitReceivedSourceConditionsListModel);
hitReceivedSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> hitReceivedSourceResult = CommonEditor.createListPanel( hitReceivedSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitReceivedSourceTitle, hitReceivedSourceConditionsPane.add(new JScrollPane(hitReceivedSourceConditionsList), JideBoxLayout.FIX);
hitReceivedSourceCellRenderer, final JPanel hitReceivedSourceTimedConditionsEditorPane = new JPanel();
hitReceivedSourceConditionsListModel, final JButton createHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
npc.writable, final JButton deleteHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitReceivedSourceMoveUpDownEnabled, hitReceivedSourceConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitReceivedEffectSourceCondition = e, @Override
() -> selectedHitReceivedEffectSourceCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitReceivedSourceTimedConditionEditorPane, selectedHitReceivedEffectSourceCondition = (NPC.TimedConditionEffect) hitReceivedSourceConditionsList.getSelectedValue();
listener, updateHitReceivedSourceTimedConditionEditorPane(hitReceivedSourceTimedConditionsEditorPane, selectedHitReceivedEffectSourceCondition, listener);
Common.TimedConditionEffect::new); }
CollapsiblePanel hitReceivedSourceConditionsPane = hitReceivedSourceResult.panel; });
hitReceivedSourceConditionsList = hitReceivedSourceResult.list; if (npc.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitReceivedSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect();
hitReceivedSourceConditionsListModel.addItem(condition);
hitReceivedSourceConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitReceivedSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitReceivedEffectSourceCondition != null) {
hitReceivedSourceConditionsListModel.removeItem(selectedHitReceivedEffectSourceCondition);
selectedHitReceivedEffectSourceCondition = null;
hitReceivedSourceConditionsList.clearSelection();
listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitReceivedSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitReceivedSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitReceivedSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
hitReceivedSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitReceivedSourceConditionsPane.add(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.FIX);
if (npc.hit_received_effect == null || npc.hit_received_effect.conditions_source == null || npc.hit_received_effect.conditions_source.isEmpty()) { if (npc.hit_received_effect == null || npc.hit_received_effect.conditions_source == null || npc.hit_received_effect.conditions_source.isEmpty()) {
hitReceivedSourceConditionsPane.collapse(); hitReceivedSourceConditionsPane.collapse();
} }
hitReceivedEffectPane.add(hitReceivedSourceConditionsPane, JideBoxLayout.FIX); hitReceivedEffectPane.add(hitReceivedSourceConditionsPane, JideBoxLayout.FIX);
String hitReceivedTargetTitle = "Actor Conditions applied to the attacker: "; final CollapsiblePanel hitReceivedTargetConditionsPane = new CollapsiblePanel("Actor Conditions applied to the attacker: ");
TimedConditionsCellRenderer hitReceivedTargetCellRenderer = new TimedConditionsCellRenderer(); hitReceivedTargetConditionsPane.setLayout(new JideBoxLayout(hitReceivedTargetConditionsPane, JideBoxLayout.PAGE_AXIS));
hitReceivedTargetConditionsListModel = new TargetTimedConditionsListModel(hitReceivedEffect); hitReceivedTargetConditionsListModel = new TargetTimedConditionsListModel(hitReceivedEffect);
final boolean hitReceivedTargetMoveUpDownEnabled = false; hitReceivedTargetConditionsList = new JList(hitReceivedTargetConditionsListModel);
hitReceivedTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> hitReceivedTargetResult = CommonEditor.createListPanel( hitReceivedTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
hitReceivedTargetTitle, hitReceivedTargetConditionsPane.add(new JScrollPane(hitReceivedTargetConditionsList), JideBoxLayout.FIX);
hitReceivedTargetCellRenderer, final JPanel hitReceivedTargetTimedConditionsEditorPane = new JPanel();
hitReceivedTargetConditionsListModel, final JButton createHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
npc.writable, final JButton deleteHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
hitReceivedTargetMoveUpDownEnabled, hitReceivedTargetConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedHitReceivedEffectTargetCondition = e, @Override
() -> selectedHitReceivedEffectTargetCondition, public void valueChanged(ListSelectionEvent e) {
this::updateHitReceivedTargetTimedConditionEditorPane, selectedHitReceivedEffectTargetCondition = (NPC.TimedConditionEffect) hitReceivedTargetConditionsList.getSelectedValue();
listener, updateHitReceivedTargetTimedConditionEditorPane(hitReceivedTargetTimedConditionsEditorPane, selectedHitReceivedEffectTargetCondition, listener);
Common.TimedConditionEffect::new); }
final CollapsiblePanel hitReceivedTargetConditionsPane = hitReceivedTargetResult.panel; });
hitReceivedTargetConditionsList = hitReceivedTargetResult.list; if (npc.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createHitReceivedTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect();
hitReceivedTargetConditionsListModel.addItem(condition);
hitReceivedTargetConditionsList.setSelectedValue(condition, true);
listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteHitReceivedTargetCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedHitReceivedEffectTargetCondition != null) {
hitReceivedTargetConditionsListModel.removeItem(selectedHitReceivedEffectTargetCondition);
selectedHitReceivedEffectTargetCondition = null;
hitReceivedTargetConditionsList.clearSelection();
listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createHitReceivedTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteHitReceivedTargetCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
hitReceivedTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
hitReceivedTargetTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
hitReceivedTargetConditionsPane.add(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.FIX);
hitReceivedEffectPane.add(hitReceivedTargetConditionsPane, JideBoxLayout.FIX); hitReceivedEffectPane.add(hitReceivedTargetConditionsPane, JideBoxLayout.FIX);
if (npc.hit_received_effect == null || npc.hit_received_effect.conditions_target == null || npc.hit_received_effect.conditions_target.isEmpty()) { if (npc.hit_received_effect == null || npc.hit_received_effect.conditions_target == null || npc.hit_received_effect.conditions_target.isEmpty()) {
hitReceivedTargetConditionsPane.collapse(); hitReceivedTargetConditionsPane.collapse();
@@ -384,7 +510,7 @@ public class NPCEditor extends JSONElementEditor {
deathEffectPane = new CollapsiblePanel("Effect when killed: "); deathEffectPane = new CollapsiblePanel("Effect when killed: ");
deathEffectPane.setLayout(new JideBoxLayout(deathEffectPane, JideBoxLayout.PAGE_AXIS)); deathEffectPane.setLayout(new JideBoxLayout(deathEffectPane, JideBoxLayout.PAGE_AXIS));
if (npc.death_effect == null) { if (npc.death_effect == null) {
deathEffect = new Common.DeathEffect(); deathEffect = new NPC.DeathEffect();
} else { } else {
deathEffect = npc.death_effect; deathEffect = npc.death_effect;
} }
@@ -393,25 +519,54 @@ public class NPCEditor extends JSONElementEditor {
deathEffectAPMin = addIntegerField(deathEffectPane, "Killer AP bonus min: ", deathEffect.ap_boost_min, true, npc.writable, listener); deathEffectAPMin = addIntegerField(deathEffectPane, "Killer AP bonus min: ", deathEffect.ap_boost_min, true, npc.writable, listener);
deathEffectAPMax = addIntegerField(deathEffectPane, "Killer AP bonus max: ", deathEffect.ap_boost_max, true, npc.writable, listener); deathEffectAPMax = addIntegerField(deathEffectPane, "Killer AP bonus max: ", deathEffect.ap_boost_max, true, npc.writable, listener);
String deathSourceTitle = "Actor Conditions applied to the killer: "; CollapsiblePanel deathSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the killer: ");
TimedConditionsCellRenderer deathSourceCellRenderer = new TimedConditionsCellRenderer(); deathSourceConditionsPane.setLayout(new JideBoxLayout(deathSourceConditionsPane, JideBoxLayout.PAGE_AXIS));
deathSourceConditionsListModel = new SourceTimedConditionsListModel(deathEffect); deathSourceConditionsListModel = new SourceTimedConditionsListModel(deathEffect);
final boolean deathSourceMoveUpDownEnabled = false; deathSourceConditionsList = new JList(deathSourceConditionsListModel);
deathSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer());
CommonEditor.PanelCreateResult<Common.TimedConditionEffect> deathSourceResult = CommonEditor.createListPanel( deathSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
deathSourceTitle, deathSourceConditionsPane.add(new JScrollPane(deathSourceConditionsList), JideBoxLayout.FIX);
deathSourceCellRenderer, final JPanel deathSourceTimedConditionsEditorPane = new JPanel();
deathSourceConditionsListModel, final JButton createDeathSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon()));
npc.writable, final JButton deleteDeathSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon()));
deathSourceMoveUpDownEnabled, deathSourceConditionsList.addListSelectionListener(new ListSelectionListener() {
(e) -> selectedDeathEffectSourceCondition = e, @Override
() -> selectedDeathEffectSourceCondition, public void valueChanged(ListSelectionEvent e) {
this::updateDeathSourceTimedConditionEditorPane, selectedDeathEffectSourceCondition = (NPC.TimedConditionEffect) deathSourceConditionsList.getSelectedValue();
listener, updateDeathSourceTimedConditionEditorPane(deathSourceTimedConditionsEditorPane, selectedDeathEffectSourceCondition, listener);
Common.TimedConditionEffect::new); }
CollapsiblePanel deathSourceConditionsPane = deathSourceResult.panel; });
deathSourceConditionsList = deathSourceResult.list; if (npc.writable) {
JPanel listButtonsPane = new JPanel();
listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6));
createDeathSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect();
deathSourceConditionsListModel.addItem(condition);
deathSourceConditionsList.setSelectedValue(condition, true);
listener.valueChanged(deathSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
});
deleteDeathSourceCondition.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedDeathEffectSourceCondition != null) {
deathSourceConditionsListModel.removeItem(selectedDeathEffectSourceCondition);
selectedDeathEffectSourceCondition = null;
deathSourceConditionsList.clearSelection();
listener.valueChanged(deathSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff.
}
}
});
listButtonsPane.add(createDeathSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(deleteDeathSourceCondition, JideBoxLayout.FIX);
listButtonsPane.add(new JPanel(), JideBoxLayout.VARY);
deathSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX);
}
deathSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(deathSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS));
deathSourceConditionsPane.add(deathSourceTimedConditionsEditorPane, JideBoxLayout.FIX);
if (npc.death_effect == null || npc.death_effect.conditions_source == null || npc.death_effect.conditions_source.isEmpty()) { if (npc.death_effect == null || npc.death_effect.conditions_source == null || npc.death_effect.conditions_source.isEmpty()) {
deathSourceConditionsPane.collapse(); deathSourceConditionsPane.collapse();
} }
@@ -422,7 +577,7 @@ public class NPCEditor extends JSONElementEditor {
pane.add(combatTraitPane, JideBoxLayout.FIX); pane.add(combatTraitPane, JideBoxLayout.FIX);
} }
public void updateHitSourceTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitSourceConditionBox != null) { if (hitSourceConditionBox != null) {
removeElementListener(hitSourceConditionBox); removeElementListener(hitSourceConditionBox);
@@ -494,7 +649,7 @@ public class NPCEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitSourceTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitSourceTimedConditionWidgets(NPC.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -513,7 +668,7 @@ public class NPCEditor extends JSONElementEditor {
} }
public void updateHitTargetTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitTargetConditionBox != null) { if (hitTargetConditionBox != null) {
removeElementListener(hitTargetConditionBox); removeElementListener(hitTargetConditionBox);
@@ -584,7 +739,7 @@ public class NPCEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitTargetTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitTargetTimedConditionWidgets(NPC.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -603,7 +758,7 @@ public class NPCEditor extends JSONElementEditor {
} }
public void updateHitReceivedSourceTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitReceivedSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitReceivedSourceConditionBox != null) { if (hitReceivedSourceConditionBox != null) {
removeElementListener(hitReceivedSourceConditionBox); removeElementListener(hitReceivedSourceConditionBox);
@@ -675,7 +830,7 @@ public class NPCEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitReceivedSourceTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitReceivedSourceTimedConditionWidgets(NPC.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -694,7 +849,7 @@ public class NPCEditor extends JSONElementEditor {
} }
public void updateHitReceivedTargetTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateHitReceivedTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (hitReceivedTargetConditionBox != null) { if (hitReceivedTargetConditionBox != null) {
removeElementListener(hitReceivedTargetConditionBox); removeElementListener(hitReceivedTargetConditionBox);
@@ -765,7 +920,7 @@ public class NPCEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateHitReceivedTargetTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateHitReceivedTargetTimedConditionWidgets(NPC.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -783,7 +938,7 @@ public class NPCEditor extends JSONElementEditor {
hitReceivedTargetConditionForever.setEnabled(!clear); hitReceivedTargetConditionForever.setEnabled(!clear);
} }
public void updateDeathSourceTimedConditionEditorPane(JPanel pane, Common.TimedConditionEffect condition, final FieldUpdateListener listener) { public void updateDeathSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) {
pane.removeAll(); pane.removeAll();
if (deathSourceConditionBox != null) { if (deathSourceConditionBox != null) {
removeElementListener(deathSourceConditionBox); removeElementListener(deathSourceConditionBox);
@@ -855,7 +1010,7 @@ public class NPCEditor extends JSONElementEditor {
pane.repaint(); pane.repaint();
} }
public void updateDeathSourceTimedConditionWidgets(Common.TimedConditionEffect condition) { public void updateDeathSourceTimedConditionWidgets(NPC.TimedConditionEffect condition) {
boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE);
boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE);
@@ -873,41 +1028,129 @@ public class NPCEditor extends JSONElementEditor {
deathSourceConditionForever.setEnabled(!clear); deathSourceConditionForever.setEnabled(!clear);
} }
public static class TargetTimedConditionsListModel extends CommonEditor.AtListModel<Common.TimedConditionEffect, Common.HitEffect> { public static class TargetTimedConditionsListModel implements ListModel<NPC.TimedConditionEffect> {
public TargetTimedConditionsListModel(Common.HitEffect effect) { NPC.HitEffect source;
super(effect);
public TargetTimedConditionsListModel(NPC.HitEffect effect) {
this.source = effect;
} }
@Override @Override
protected List<Common.TimedConditionEffect> getInner() { public int getSize() {
return source.conditions_target; if (source.conditions_target == null) return 0;
return source.conditions_target.size();
} }
@Override @Override
protected void setInner(List<Common.TimedConditionEffect> value) { public NPC.TimedConditionEffect getElementAt(int index) {
source.conditions_target = value; if (source.conditions_target == null) return null;
return source.conditions_target.get(index);
} }
} public void addItem(NPC.TimedConditionEffect item) {
if (source.conditions_target == null) {
source.conditions_target = new ArrayList<NPC.TimedConditionEffect>();
}
source.conditions_target.add(item);
int index = source.conditions_target.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public static class SourceTimedConditionsListModel extends CommonEditor.AtListModel<Common.TimedConditionEffect, Common.DeathEffect> { public void removeItem(NPC.TimedConditionEffect item) {
int index = source.conditions_target.indexOf(item);
source.conditions_target.remove(item);
if (source.conditions_target.isEmpty()) {
source.conditions_target = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public SourceTimedConditionsListModel(Common.DeathEffect effect) { public void itemChanged(NPC.TimedConditionEffect item) {
super(effect); int index = source.conditions_target.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
} }
@Override @Override
protected List<Common.TimedConditionEffect> getInner() { public void removeListDataListener(ListDataListener l) {
return source.conditions_source; listeners.remove(l);
}
}
public static class SourceTimedConditionsListModel implements ListModel<NPC.TimedConditionEffect> {
NPC.DeathEffect source;
public SourceTimedConditionsListModel(NPC.DeathEffect effect) {
this.source = effect;
} }
@Override @Override
protected void setInner(List<Common.TimedConditionEffect> value) { public int getSize() {
source.conditions_source = value; if (source.conditions_source == null) return 0;
return source.conditions_source.size();
} }
} @Override
public NPC.TimedConditionEffect getElementAt(int index) {
if (source.conditions_source == null) return null;
return source.conditions_source.get(index);
}
public void addItem(NPC.TimedConditionEffect item) {
if (source.conditions_source == null) {
source.conditions_source = new ArrayList<NPC.TimedConditionEffect>();
}
source.conditions_source.add(item);
int index = source.conditions_source.indexOf(item);
for (ListDataListener l : listeners) {
l.intervalAdded(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, index, index));
}
}
public void removeItem(NPC.TimedConditionEffect item) {
int index = source.conditions_source.indexOf(item);
source.conditions_source.remove(item);
if (source.conditions_source.isEmpty()) {
source.conditions_source = null;
}
for (ListDataListener l : listeners) {
l.intervalRemoved(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, index, index));
}
}
public void itemChanged(NPC.TimedConditionEffect item) {
int index = source.conditions_source.indexOf(item);
for (ListDataListener l : listeners) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index));
}
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
}
public static class TimedConditionsCellRenderer extends DefaultListCellRenderer { public static class TimedConditionsCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 7987880146189575234L; private static final long serialVersionUID = 7987880146189575234L;
@@ -917,7 +1160,7 @@ public class NPCEditor extends JSONElementEditor {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) { if (c instanceof JLabel) {
JLabel label = ((JLabel)c); JLabel label = ((JLabel)c);
Common.TimedConditionEffect effect = (Common.TimedConditionEffect) value; NPC.TimedConditionEffect effect = (NPC.TimedConditionEffect) value;
if (effect.condition != null) { if (effect.condition != null) {
@@ -943,7 +1186,7 @@ public class NPCEditor extends JSONElementEditor {
} }
} }
public static boolean isNull(Common.HitEffect effect) { public static boolean isNull(NPC.HitEffect effect) {
if (effect.ap_boost_min != null) return false; if (effect.ap_boost_min != null) return false;
if (effect.ap_boost_max != null) return false; if (effect.ap_boost_max != null) return false;
if (effect.hp_boost_min != null) return false; if (effect.hp_boost_min != null) return false;
@@ -953,7 +1196,7 @@ public class NPCEditor extends JSONElementEditor {
return true; return true;
} }
public static boolean isNull(Common.HitReceivedEffect effect) { public static boolean isNull(NPC.HitReceivedEffect effect) {
if (effect.ap_boost_min != null) return false; if (effect.ap_boost_min != null) return false;
if (effect.ap_boost_max != null) return false; if (effect.ap_boost_max != null) return false;
if (effect.hp_boost_min != null) return false; if (effect.hp_boost_min != null) return false;
@@ -967,7 +1210,7 @@ public class NPCEditor extends JSONElementEditor {
return true; return true;
} }
public static boolean isNull(Common.DeathEffect effect) { public static boolean isNull(NPC.DeathEffect effect) {
if (effect.ap_boost_min != null) return false; if (effect.ap_boost_min != null) return false;
if (effect.ap_boost_max != null) return false; if (effect.ap_boost_max != null) return false;
if (effect.hp_boost_min != null) return false; if (effect.hp_boost_min != null) return false;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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