Compare commits

...

26 Commits

Author SHA1 Message Date
OMGeeky
1b643f4aa1 fix nsis arguments (from switching to linux) 2025-10-02 17:10:23 +02:00
OMGeeky
4293095e8e fix warning/error output in action 2025-10-02 17:09:08 +02:00
OMGeeky
5f2927e00c switch to linux runner (windows-latest is annoying me with undocumented breaking changes...) 2025-10-02 16:59:48 +02:00
OMGeeky
79eddde155 handle errors during nsis exe creation and only upload zip in those cases 2025-10-02 16:46:08 +02:00
OMGeeky
be040a74bd change miss_effect to HitEffect instead of HitReceivedEffect
(the received effects might have been applied, but the game UI would not display them, so better not show them here too)
2025-10-02 15:57:21 +02:00
OMGeeky
31cbdcabab add clarification comment to package.sh 2025-09-23 20:43:08 +02:00
OMGeeky
7e5c8d05ab improve hints on who is getting what effect on hit / hit-received for npcs 2025-09-23 20:26:58 +02:00
OMGeeky
b2003bfc38 improve create pane content calls with overrides
also fixes a bug where the wrong one was used on accident
2025-09-23 20:10:30 +02:00
OMGeeky
3b99a94654 add comments to start script about min required java version; update nsi script to match standalone start script 2025-09-23 19:29:28 +02:00
OMGeeky
806f0b10e6 miss effect 2025-09-23 18:48:46 +02:00
OMGeeky
29241f18b8 improve EffectPane generics and usage & fix hitReceivedEffect 2025-09-23 18:48:46 +02:00
Nut.andor
ef9a2a628d Pull Request #12: startup performance improvements 2025-09-03 20:51:55 +02:00
Nut.andor
9dfd217a27 Merge branch 'pulls/1195352/12'
Pull Request #12: startup performance improvements
2025-09-03 20:49:57 +02:00
Nut.andor
6f10e5b94a startup performance improvements 2025-09-02 20:55:35 +02:00
Nut.andor
7cbce8e4d7 Pull Request #12: startup performance improvements 2025-08-31 23:40:31 +02:00
OMGeeky
364bf8ee11 cleanup some duplicate code 2025-08-31 23:34:46 +02:00
OMGeeky
e2b0b0e81e remove not double linking 2025-08-31 23:33:52 +02:00
OMGeeky
703b723322 improve GameDataCategory lookup time
by changing it to something backed by a HashMap with
 the id as key things can be found without looping over every element.
 This reduced the startup time on my machine to about half of the original time
2025-08-31 23:33:52 +02:00
Nut.andor
297bff84db Merge branch 'pulls/1195352/11' 2025-08-31 12:58:17 +02:00
Nut.andor
67724f5124 Revert "decrease version to avoid swing issue"
This reverts commit 3ceee2e9e6.
2025-08-31 12:53:33 +02:00
Nut.andor
09d23c8cdf Jide oss update 2025-08-30 15:48:32 +02:00
Nut.andor
749e64e09e version 2025-08-14 21:53:30 +02:00
Nut.andor
998560a6ff Pull Request #11: Jide oss update 2025-08-06 23:20:38 +02:00
OMGeeky
2bf64c417f Merge branch 'master' into jide-oss-update 2025-08-06 23:20:37 +02:00
OMGeeky
bc3333bd0e improve some checks when switching look and feel 2025-07-15 12:51:49 +02:00
OMGeeky
e6d9d8fbda update jar to version 3.7.15
this should improve compatibility with newer jdk versions
2025-07-15 12:51:24 +02:00
23 changed files with 410 additions and 302 deletions

View File

@@ -2,55 +2,71 @@ name: Release Build
on:
release:
types: [created]
types: [ created ]
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- 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: 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: 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: Build JAR
shell: bash
run: |
cd packaging
chmod +x package.sh
echo "Building JAR and ZIP for version: ${{ env.VERSION }}"
./package.sh
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: 'Install makensis (apt)'
run: sudo apt update && sudo apt install -y nsis nsis-pluginapi
continue-on-error: true
- 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
- name: Create Windows-Installer with NSIS
uses: joncloud/makensis-action@v4
with:
script-file: packaging/Windows/ATCS_Installer.nsi
arguments: -DVERSION="${{ env.VERSION }}"
continue-on-error: true
- name: Determine Upload Files
id: check_files_to_upload
shell: bash
run: |
FILES="./packaging/ATCS_${VERSION}.zip"
if [ -f "./packaging/ATCS_${VERSION}_Setup.exe" ]; then
FILES="$FILES ./packaging/ATCS_${VERSION}_Setup.exe"
else
echo "::error::exe-installer created by NSIS was not found; only ZIP will be uploaded."
fi
echo "files=$FILES" >> $GITHUB_OUTPUT
- name: Upload Release Assets
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: ${{ steps.check_files_to_upload.outputs.files }}

2
.idea/misc.xml generated
View File

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

Binary file not shown.

View File

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

View File

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

View File

@@ -1,9 +1,11 @@
#!/bin/bash
#!/usr/bin/env bash
# get the directory of this script
ATCS_DIR="$(dirname "$(readlink -f "$0" || greadlink -f "$0" || stat -f "$0")")"
echo "ATCS_DIR: '${ATCS_DIR}'"
MAX_MEM="512M"
JAVA="java"
JAVA="java" # minimum required version is Java 11
JAVA_OPTS='-DFONT_SCALE=1.0 -Dswing.aatext=true'
ENV_FILE="${ATCS_DIR}/ATCS.env"
@@ -13,7 +15,7 @@ if [ -f "${ENV_FILE}" ]; then
else
{
echo "#MAX_MEM=\"${MAX_MEM}\""
echo "#JAVA=\"${JAVA}\""
echo "#JAVA=\"${JAVA}\" # minimum required version is Java 11"
echo "#JAVA_OPTS=\"${JAVA_OPTS}\""
echo ""
}>"${ENV_FILE}"

View File

@@ -13,8 +13,8 @@ else
fi
# --- Configuration ---
PACKAGING_DIR=$(dirname "$(readlink -f "$0" || greadlink -f "$0" || stat -f "$0")")
ATCS_SOURCE_DIR=$(dirname "${PACKAGING_DIR}")
PACKAGING_DIR=$(dirname "$(readlink -f "$0" || greadlink -f "$0" || stat -f "$0")") # Directory of this script
ATCS_SOURCE_DIR=$(dirname "${PACKAGING_DIR}") # Parent directory of this script, assumed to be ATCS source root
TEMP_DIR="${PACKAGING_DIR}/tmp"
JAR_LOCATION="${PACKAGING_DIR}/ATCS.jar" # Output JAR location as per script
MANIFEST_LOCATION="${PACKAGING_DIR}/Manifest.txt"

View File

@@ -1 +1 @@
v0.6.21
v0.6.23

View File

@@ -65,22 +65,8 @@ public class ATContentStudio {
ConfigCache.init();
try {
String laf = ConfigCache.getFavoriteLaFClassName();
if (laf == null)
laf = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(laf);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
scaleUIFont();
String laf = ConfigCache.getFavoriteLaFClassName();
setLookAndFeel(laf);
// Need to keep a strong reference to it, to avoid garbage collection that'll
// reset this setting.
@@ -116,7 +102,6 @@ public class ATContentStudio {
frame.setVisible(true);
frame.setDefaultCloseOperation(StudioFrame.DO_NOTHING_ON_CLOSE);
}
});
for (File f : ConfigCache.getKnownWorkspaces()) {
if (workspaceRoot.equals(f)) {
@@ -134,6 +119,34 @@ public class ATContentStudio {
});
}
public static void setLookAndFeel(String laf) {
if (laf == null)
{
System.out.println("No look and feel specified, using system default.");
laf = UIManager.getSystemLookAndFeelClassName();
}
System.out.println("Info: Setting look and feel to: " + laf);
try {
UIManager.setLookAndFeel(laf);
} catch (ClassNotFoundException e) {
System.err.println("Failed to load system look and feel. ");
System.err.println("Installed look and feel classes: ");
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
System.err.println(" " + info.getName() + " (" + info.getClassName() + ")");
}
System.err.println("Tried to load: " + laf + " but got this error:");
e.printStackTrace();
} catch (InstantiationException | UnsupportedLookAndFeelException | IllegalAccessException e) {
e.printStackTrace();
}
var newLaF = UIManager.getLookAndFeel();
System.out.println("Using look and feel: " + newLaF.getName() + " (" + newLaF.getClass().getName() + ")");
scaleUIFont();
}
private static void checkUpdate() {
BufferedReader in = null;
try {
@@ -156,13 +169,13 @@ public class ATContentStudio {
style.append("font-weight:" + (font.isBold() ? "bold" : "normal") + ";");
style.append("font-size:" + font.getSize() + "pt;");
style.append("background-color: rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue()
+ ");");
+ ");");
JEditorPane ep = new JEditorPane("text/html",
"<html><body style=\"" + style + "\">" + "You are not running the latest ATCS version.<br/>"
+ "You can get the latest version (" + lastLine + ") by clicking the link below.<br/>"
+ "<a href=\"" + DOWNLOAD_URL + "\">" + DOWNLOAD_URL + "</a><br/>" + "<br/>"
+ "</body></html>");
"<html><body style=\"" + style + "\">" + "You are not running the latest ATCS version.<br/>"
+ "You can get the latest version (" + lastLine + ") by clicking the link below.<br/>"
+ "<a href=\"" + DOWNLOAD_URL + "\">" + DOWNLOAD_URL + "</a><br/>" + "<br/>"
+ "</body></html>");
ep.setEditable(false);
ep.setBorder(null);

View File

@@ -106,7 +106,6 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable
this.fromMap(json);
initializeData();
linkAll();
save();
}
public Project(Workspace w, String name, File source, ResourceSet sourceSet){
@@ -288,44 +287,23 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable
}
public void linkAll() {
for (ProjectTreeNode node : baseContent.gameData.v.getNonEmptyIterable()) {
if (node instanceof GameDataCategory<?>) {
for (GameDataElement e : ((GameDataCategory<?>) node)) {
e.link();
}
}
}
for (ProjectTreeNode node : baseContent.gameMaps.tmxMaps) {
((TMXMap) node).link();
}
for (ProjectTreeNode node : alteredContent.gameData.v.getNonEmptyIterable()) {
if (node instanceof GameDataCategory<?>) {
for (GameDataElement e : ((GameDataCategory<?>) node)) {
e.link();
}
}
}
for (ProjectTreeNode node : alteredContent.gameMaps.tmxMaps) {
((TMXMap) node).link();
}
for (ProjectTreeNode node : createdContent.gameData.v.getNonEmptyIterable()) {
if (node instanceof GameDataCategory<?>) {
for (GameDataElement e : ((GameDataCategory<?>) node)) {
e.link();
}
}
}
for (ProjectTreeNode node : createdContent.gameMaps.tmxMaps) {
((TMXMap) node).link();
}
linkGameData(baseContent);
linkGameData(alteredContent);
linkGameData(createdContent);
}
for (WorldmapSegment node : createdContent.worldmap) {
private void linkGameData(GameSource source) {
for (ProjectTreeNode node : source.gameData.v.getNonEmptyIterable()) {
if (node instanceof GameDataCategory<?>) {
for (GameDataElement e : ((GameDataCategory<?>) node).toList()) {
e.link();
}
}
}
for (TMXMap node : source.gameMaps.tmxMaps) {
node.link();
}
for (WorldmapSegment node : alteredContent.worldmap) {
node.link();
}
for (WorldmapSegment node : baseContent.worldmap) {
for (WorldmapSegment node : source.worldmap) {
node.link();
}
}
@@ -937,14 +915,14 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable
public void moveToCreated(JSONElement target) {
target.childrenRemoved(new ArrayList<ProjectTreeNode>());
((GameDataCategory<?>) target.getParent()).remove(target);
((GameDataCategory<?>) target.getParent()).removeGeneric(target);
target.state = GameDataElement.State.created;
createdContent.gameData.addElement(target);
}
public void moveToAltered(JSONElement target) {
target.childrenRemoved(new ArrayList<ProjectTreeNode>());
((GameDataCategory<?>) target.getParent()).remove(target);
((GameDataCategory<?>) target.getParent()).removeGeneric(target);
target.state = GameDataElement.State.created;
((JSONElement) target).jsonFile = new File(baseContent.gameData.getGameDataElement(((JSONElement) target).getClass(), target.id).jsonFile.getAbsolutePath());
alteredContent.gameData.addElement((JSONElement) target);
@@ -1202,18 +1180,18 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable
public List<String> writeDataDeltaForDataType(GameDataCategory<? extends JSONElement> created, GameDataCategory<? extends JSONElement> altered, GameDataCategory<? extends JSONElement> source, Class<? extends JSONElement> gdeClass, File targetFolder) {
List<String> filenamesToWrite = new LinkedList<String>();
Map<String, List<Map>> dataToWritePerFilename = new LinkedHashMap<String, List<Map>>();
for (JSONElement gde : altered) {
for (JSONElement gde : altered.toList()) {
if (!filenamesToWrite.contains(gde.jsonFile.getName())) {
filenamesToWrite.add(gde.jsonFile.getName());
}
}
for (JSONElement gde : created) {
for (JSONElement gde : created.toList()) {
if (!filenamesToWrite.contains(gde.jsonFile.getName())) {
filenamesToWrite.add(gde.jsonFile.getName());
}
}
for (String fName : filenamesToWrite) {
for (JSONElement gde : source) {
for (JSONElement gde : source.toList()) {
if (gde.jsonFile.getName().equals(fName)) {
if (dataToWritePerFilename.get(fName) == null) {
dataToWritePerFilename.put(fName, new ArrayList<Map>());
@@ -1222,7 +1200,7 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable
dataToWritePerFilename.get(fName).add(getGameDataElement(gdeClass, gde.id).toJson());
}
}
for (JSONElement gde : created) {
for (JSONElement gde : created.toList()) {
if (gde.jsonFile.getName().equals(fName)) {
if (dataToWritePerFilename.get(fName) == null) {
dataToWritePerFilename.put(fName, new ArrayList<Map>());

View File

@@ -1,32 +1,115 @@
package com.gpl.rpg.atcontentstudio.model.gamedata;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.*;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONArray;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.io.File;
import java.util.*;
import java.util.List;
public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implements ProjectTreeNode, Serializable {
public class GameDataCategory<E extends JSONElement> implements ProjectTreeNode {
//region Data
private final ArrayList<String> keyList = new ArrayList<>();
private final HashMap<String, E> dataMap = new HashMap<>();
//endregion
private static final long serialVersionUID = 5486008219704443733L;
public GameDataSet parent;
public String name;
public GameDataCategory(GameDataSet parent, String name) {
super();
this.parent = parent;
this.name = name;
}
//region Helpers
public E get(String key) {
return dataMap.get(key);
}
public E get(int index) {
String key = keyList.get(index);
return dataMap.get(key);
}
public E getIgnoreCase(String key) {
for (String k : keyList) {
if (k.equalsIgnoreCase(key)) {
return dataMap.get(k);
}
}
return null;
}
public E put(String key, E element) {
if (!dataMap.containsKey(key)) {
keyList.add(key);
}
return dataMap.put(key, element);
}
public void add(E quest) {
String key = quest.id;
put(key, quest);
}
public E remove(String key) {
if (dataMap.containsKey(key)) {
keyList.remove(key);
}
return dataMap.remove(key);
}
public E remove(int index) {
String key = keyList.get(index);
keyList.remove(index);
return dataMap.remove(key);
}
public boolean removeGeneric(JSONElement element){
return remove((E) element);
}
public boolean remove(E element) {
String key = element.id;
int index = getProject().getNodeIndex(element);
boolean result = false;
if (dataMap.containsKey(key)) {
keyList.remove(key);
dataMap.remove(key);
result = true;
}
getProject().fireElementRemoved(element, index);
return result;
}
public int size() {
return dataMap.size();
}
public int indexOf(String key) {
return keyList.indexOf(key);
}
public int indexOf(E element) {
String key = element.id;
return keyList.indexOf(key);
}
public ArrayList<E> toList() {
ArrayList<E> list = new ArrayList<>();
for (String key : keyList) {
list.add(dataMap.get(key));
}
return list;
}
//endregion
//region copied implementation of ProjectTreeNode
@Override
public TreeNode getChildAt(int childIndex) {
return get(childIndex);
@@ -44,7 +127,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
@Override
public int getIndex(TreeNode node) {
return indexOf(node);
return indexOf((E) node);
}
@Override
@@ -59,7 +142,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
@Override
public Enumeration<E> children() {
return Collections.enumeration(this);
return Collections.enumeration(toList());
}
@Override
@@ -87,7 +170,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (E node : this) {
for (E node : dataMap.values()) {
node.notifyCreated();
}
}
@@ -133,10 +216,15 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
}
@Override
public Type getDataType() {
public GameSource.Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return dataMap.isEmpty();
}
@SuppressWarnings("rawtypes")
public void save(File jsonFile) {
if (getDataType() != GameSource.Type.created && getDataType() != GameSource.Type.altered) {
@@ -144,7 +232,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return;
}
List<Map> dataToSave = new ArrayList<Map>();
for (E element : this) {
for (E element : dataMap.values()) {
if (element.jsonFile.equals(jsonFile)) {
dataToSave.add(element.toJson());
}
@@ -161,7 +249,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
String toWrite = FileUtils.toJsonString(dataToSave);
if(FileUtils.writeStringToFile(toWrite, jsonFile, "JSON file '"+jsonFile.getAbsolutePath()+"'")){
for (E element : this) {
for (E element : dataMap.values()) {
element.state = GameDataElement.State.saved;
}
}
@@ -173,7 +261,8 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
GameDataCategory<? extends JSONElement> impactedCategory = null;
String impactedFileName = fileName;
Map<String, Integer> containedIds = new LinkedHashMap<String, Integer>();
for (JSONElement node : this) {
ArrayList<E> list = toList();
for (JSONElement node : list) {
if (node.getDataType() == GameSource.Type.created && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
if (getProject().alteredContent.gameData.getGameDataElement(node.getClass(), node.id) != null) {
events.add(new SaveEvent(SaveEvent.Type.moveToAltered, node, true, "Element ID matches one already present in the altered game content. Change this ID before saving."));
@@ -202,7 +291,7 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
for (String key : containedIds.keySet()) {
if (containedIds.get(key) > 1) {
E node = null;
for (E n : this) {
for (E n : list) {
if (key.equals(n.id)) {
node = n;
break;
@@ -218,19 +307,15 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return events;
}
public boolean remove(E o) {
int index = getProject().getNodeIndex(o);
boolean result = super.remove(o);
getProject().fireElementRemoved(o, index);
return result;
}
@Override
public boolean needsSaving() {
for (E node : this) {
for (E node : dataMap.values()) {
if (node.needsSaving()) return true;
}
return false;
}
//endregion
}

View File

@@ -67,7 +67,7 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
items = new GameDataCategory<Item>(this, Item.getStaticDesc());
itemCategories = new GameDataCategory<ItemCategory>(this, ItemCategory.getStaticDesc());
npcs = new GameDataCategory<NPC>(this, NPC.getStaticDesc());
quests = new GameDataCategory<Quest>(this, Quest.getStaticDesc());
quests = new GameDataCategory<>(this, Quest.getStaticDesc());
v.add(actorConditions);
v.add(dialogues);
@@ -256,82 +256,42 @@ public class GameDataSet implements ProjectTreeNode, Serializable {
public ActorCondition getActorCondition(String id) {
if (actorConditions == null) return null;
for (ActorCondition gde : actorConditions) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return actorConditions.get(id);
}
public Dialogue getDialogue(String id) {
if (dialogues == null) return null;
for (Dialogue gde : dialogues) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return dialogues.get(id);
}
public Droplist getDroplist(String id) {
if (droplists == null) return null;
for (Droplist gde : droplists) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return droplists.get(id);
}
public Item getItem(String id) {
if (items == null) return null;
for (Item gde : items) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return items.get(id);
}
public ItemCategory getItemCategory(String id) {
if (itemCategories == null) return null;
for (ItemCategory gde : itemCategories) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return itemCategories.get(id);
}
public NPC getNPC(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return npcs.get(id);
}
public NPC getNPCIgnoreCase(String id) {
if (npcs == null) return null;
for (NPC gde : npcs) {
if (id.equalsIgnoreCase(gde.id)) {
return gde;
}
}
return null;
return npcs.getIgnoreCase(id);
}
public Quest getQuest(String id) {
if (quests == null) return null;
for (Quest gde : quests) {
if (id.equals(gde.id)) {
return gde;
}
}
return null;
return quests.get(id);
}
@Override

View File

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

View File

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

View File

@@ -19,12 +19,12 @@ public class PotGenerator {
GameSource gsrc = proj.baseContent;
for (ActorCondition ac : gsrc.gameData.actorConditions) {
for (ActorCondition ac : gsrc.gameData.actorConditions.toList()) {
pushString(stringsResources, resourcesStrings, ac.display_name, getPotContextComment(ac));
pushString(stringsResources, resourcesStrings, ac.description, getPotContextComment(ac) + ":description");
}
for (Dialogue d : gsrc.gameData.dialogues) {
for (Dialogue d : gsrc.gameData.dialogues.toList()) {
pushString(stringsResources, resourcesStrings, d.message, getPotContextComment(d));
if (d.replies == null) continue;
for (Dialogue.Reply r : d.replies) {
@@ -34,20 +34,20 @@ public class PotGenerator {
}
}
for (ItemCategory ic : gsrc.gameData.itemCategories) {
for (ItemCategory ic : gsrc.gameData.itemCategories.toList()) {
pushString(stringsResources, resourcesStrings, ic.name, getPotContextComment(ic));
}
for (Item i : gsrc.gameData.items) {
for (Item i : gsrc.gameData.items.toList()) {
pushString(stringsResources, resourcesStrings, i.name, getPotContextComment(i));
pushString(stringsResources, resourcesStrings, i.description, getPotContextComment(i) + ":description");
}
for (NPC npc : gsrc.gameData.npcs) {
for (NPC npc : gsrc.gameData.npcs.toList()) {
pushString(stringsResources, resourcesStrings, npc.name, getPotContextComment(npc));
}
for (Quest q : gsrc.gameData.quests) {
for (Quest q : gsrc.gameData.quests.toList()) {
if (q.visible_in_log != null && q.visible_in_log != 0) {
pushString(stringsResources, resourcesStrings, q.name, getPotContextComment(q));
for (QuestStage qs : q.stages) {

View File

@@ -3,10 +3,7 @@ package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
@@ -81,12 +78,13 @@ public class ResourcesCompactor {
File folder = new File(baseFolder.getAbsolutePath() + File.separator + GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!folder.exists()) folder.mkdirs();
for (ActorCondition ac : proj.baseContent.gameData.actorConditions) {
ArrayList<ActorCondition> actorConditions = proj.baseContent.gameData.actorConditions.toList();
for (ActorCondition ac : actorConditions) {
if (filesCovered.contains(ac.jsonFile)) continue;
File currentFile = ac.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (ActorCondition acond : proj.baseContent.gameData.actorConditions) {
for (ActorCondition acond : actorConditions) {
if (!acond.jsonFile.equals(currentFile)) continue;
Map json = acond.toJson();
json.put("iconID", convertObjectSprite(acond.icon_id).toStringID());
@@ -96,12 +94,13 @@ public class ResourcesCompactor {
writeJson(dataToSave, target);
}
for (Item it : proj.baseContent.gameData.items) {
ArrayList<Item> items = proj.baseContent.gameData.items.toList();
for (Item it : items) {
if (filesCovered.contains(it.jsonFile)) continue;
File currentFile = it.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (Item item : proj.baseContent.gameData.items) {
for (Item item : items) {
if (!item.jsonFile.equals(currentFile)) continue;
Map json = item.toJson();
json.put("iconID", convertObjectSprite(item.icon_id).toStringID());
@@ -112,12 +111,13 @@ public class ResourcesCompactor {
}
for (NPC np : proj.baseContent.gameData.npcs) {
ArrayList<NPC> npcs = proj.baseContent.gameData.npcs.toList();
for (NPC np : npcs) {
if (filesCovered.contains(np.jsonFile)) continue;
File currentFile = np.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (NPC npc : proj.baseContent.gameData.npcs) {
for (NPC npc : npcs) {
if (!npc.jsonFile.equals(currentFile)) continue;
Map json = npc.toJson();
if (proj.getImage(npc.icon_id).getWidth(null) == TILE_WIDTH_IN_PIXELS || proj.getImage(npc.icon_id).getHeight(null) == TILE_HEIGHT_IN_PIXELS) {

View File

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

View File

@@ -145,20 +145,10 @@ public class StudioFrame extends JFrame {
lafItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(i.getClassName());
ATContentStudio.scaleUIFont();
SwingUtilities.updateComponentTreeUI(ATContentStudio.frame);
ConfigCache.setFavoriteLaFClassName(i.getClassName());
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
String lookAndFeel = i.getClassName();
ATContentStudio.setLookAndFeel(lookAndFeel);
SwingUtilities.updateComponentTreeUI(ATContentStudio.frame);
ConfigCache.setFavoriteLaFClassName(lookAndFeel);
}
});
}
@@ -231,5 +221,4 @@ public class StudioFrame extends JFrame {
editors.showAbout();
}
}

View File

@@ -121,7 +121,7 @@ public class WorkspaceActions {
if (element.getParent() instanceof GameDataCategory<?>) {
@SuppressWarnings("unchecked")
GameDataCategory<JSONElement> category = (GameDataCategory<JSONElement>) element.getParent();
category.remove(element);
category.remove((JSONElement) element);
if (impactedCategories.get(category) == null) {
impactedCategories.put(category, new HashSet<File>());
}
@@ -189,7 +189,7 @@ public class WorkspaceActions {
node.childrenRemoved(new ArrayList<ProjectTreeNode>());
if (node instanceof JSONElement) {
if (node.getParent() instanceof GameDataCategory<?>) {
((GameDataCategory<?>) node.getParent()).remove(node);
((GameDataCategory<?>) node.getParent()).removeGeneric((JSONElement) node);
List<SaveEvent> events = node.attemptSave();
if (events == null || events.isEmpty()) {
node.save();

View File

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

View File

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

View File

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

View File

@@ -59,10 +59,9 @@ public class NPCEditor extends JSONElementEditor {
private JSpinner blockChance;
private JSpinner dmgRes;
private CommonEditor.HitEffectPane hitEffectPane = new CommonEditor.HitEffectPane("Effect on every hit: ", TimedActorConditionEffect::new, this, null, null);
private CommonEditor.HitRecievedEffectPane hitReceivedEffectPane = new CommonEditor.HitRecievedEffectPane("Effect on every hit received: ", TimedActorConditionEffect::new, this, "NPC",
"Attacker");
private CommonEditor.DeathEffectPane deathEffectPane = new CommonEditor.DeathEffectPane("Effect when killed: ", TimedActorConditionEffect::new, this, "Killer");
private final CommonEditor.HitEffectPane<HitEffect> hitEffectPane = new CommonEditor.HitEffectPane<>("Effect on every hit: ", this, null, "player");
private final CommonEditor.HitReceivedEffectPane<HitReceivedEffect> hitReceivedEffectPane = new CommonEditor.HitReceivedEffectPane<>("Effect on every hit received: ", this, "npc", "player");
private final CommonEditor.DeathEffectPane<DeathEffect> deathEffectPane = new CommonEditor.DeathEffectPane<>("Effect when killed: ", this, null);
private JPanel dialogueGraphPane;
private DialogueGraphView dialogueGraphView;
@@ -117,7 +116,6 @@ public class NPCEditor extends JSONElementEditor {
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void insertFormViewDataField(JPanel pane) {
final NPC npc = (NPC) target;
@@ -151,23 +149,15 @@ public class NPCEditor extends JSONElementEditor {
dmgRes = addIntegerField(combatTraitPane, "Damage resistance: ", npc.damage_resistance, false, npc.writable, listener);
HitEffect hitEffect = Objects.requireNonNullElseGet(npc.hit_effect, HitEffect::new);
hitEffectPane.createHitEffectPaneContent(listener, npc.writable, hitEffect,
new CommonEditor.SourceTimedConditionsListModel(hitEffect),
new CommonEditor.TargetTimedConditionsListModel(hitEffect));
hitEffectPane.createPaneContent(listener, npc.writable, hitEffect);
combatTraitPane.add(hitEffectPane.effectPane, JideBoxLayout.FIX);
HitReceivedEffect hitReceivedEffect = Objects.requireNonNullElseGet(npc.hit_received_effect,
HitReceivedEffect::new);
hitReceivedEffectPane.createHitReceivedEffectPaneContent(listener, npc.writable, hitReceivedEffect,
new CommonEditor.SourceTimedConditionsListModel(
hitReceivedEffect),
new CommonEditor.TargetTimedConditionsListModel(
hitReceivedEffect));
HitReceivedEffect hitReceivedEffect = Objects.requireNonNullElseGet(npc.hit_received_effect, HitReceivedEffect::new);
hitReceivedEffectPane.createPaneContent(listener, npc.writable, hitReceivedEffect);
combatTraitPane.add(hitReceivedEffectPane.effectPane, JideBoxLayout.FIX);
DeathEffect deathEffect = Objects.requireNonNullElseGet(npc.death_effect, DeathEffect::new);
deathEffectPane.createDeathEffectPaneContent(listener, npc.writable, deathEffect,
new CommonEditor.SourceTimedConditionsListModel(deathEffect));
deathEffectPane.createPaneContent(listener, npc.writable, deathEffect);
combatTraitPane.add(deathEffectPane.effectPane, JideBoxLayout.FIX);
pane.add(combatTraitPane, JideBoxLayout.FIX);