diff --git a/.github/workflows/gradle-release.yml b/.github/workflows/gradle-release.yml
new file mode 100644
index 00000000000..90bc5907ab7
--- /dev/null
+++ b/.github/workflows/gradle-release.yml
@@ -0,0 +1,106 @@
+name: Create Release
+
+on:
+ push:
+ tags:
+ - "v*.*.*"
+
+permissions:
+ contents: write
+
+jobs:
+ create_release:
+ name: Create Release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create Release
+ id: create_release
+ uses: softprops/action-gh-release@v2
+ with:
+ name: ${{ github.ref_name }}
+ draft: false
+ prerelease: false
+ generate_release_notes: false
+
+ build_release:
+ name: Build Release
+ needs: create_release
+ strategy:
+ matrix:
+ os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
+ include:
+ - os: ubuntu-latest
+ release_suffix: ubuntu
+ - os: ubuntu-24.04-arm
+ release_suffix: ubuntu-arm
+ - os: macos-latest
+ release_suffix: mac
+ - os: windows-latest
+ release_suffix: windows
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ cache: gradle
+ cache-dependency-path: |
+ build.gradle
+ code/gradle/autobuild.gradle
+ code/gradle/distribution.gradle
+ code/gradle/release.gradle
+ code/gradle/reporting.gradle
+ code/gradle/plugins.gradle
+
+ # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
+ # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+ with:
+ cache-disabled: false
+ cache-read-only: false
+ cache-overwrite-existing: true
+
+ - uses: actions/cache@v4
+ with:
+ path: |
+ ${{ github.workspace }}/build/jre
+ ${{ github.workspace }}/build/libs
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ ${{ matrix.os }}-gradle
+
+ - name: Build the image
+ if: success()
+ run: ./gradlew jpackage
+
+ - name: Upload release assets for macos
+ uses: actions/upload-artifact@v4
+ if: matrix.os == 'macos-latest'
+ with:
+ name: ${{ matrix.os }}
+ path: ${{ github.workspace }}/build/jpackage/*.dmg
+
+ - name: Upload release assets for ubuntu
+ uses: actions/upload-artifact@v4
+ if: matrix.os == 'ubuntu-latest'
+ with:
+ name: ${{ matrix.os }}
+ path: ${{ github.workspace }}/build/jpackage/*.deb
+
+ - name: Upload release assets for windows
+ uses: actions/upload-artifact@v4
+ if: matrix.os == 'windows-latest'
+ with:
+ name: ${{ matrix.os }}
+ path: ${{ github.workspace }}/build/jpackage/*.msi
+
+ - name: Release - ${{ matrix.os }}
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: ${{ needs.create_release.outputs.tag-name }}
+ files: ${{ github.workspace }}/build/jpackage/pcgen-*.*
diff --git a/.github/workflows/gradle-test.yml b/.github/workflows/gradle-test.yml
new file mode 100644
index 00000000000..316dd7f991f
--- /dev/null
+++ b/.github/workflows/gradle-test.yml
@@ -0,0 +1,91 @@
+# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
+
+name: Build PCGen with Gradle
+
+on:
+ pull_request:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ permissions:
+ checks: write
+ pull-requests: write
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ cache: gradle
+ cache-dependency-path: |
+ build.gradle
+ code/gradle/autobuild.gradle
+ code/gradle/distribution.gradle
+ code/gradle/release.gradle
+ code/gradle/reporting.gradle
+ code/gradle/plugins.gradle
+
+ # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
+ # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+ with:
+ cache-disabled: false
+ cache-read-only: false
+ cache-overwrite-existing: true
+
+ - uses: actions/cache@v4
+ with:
+ path: |
+ ${{ github.workspace }}/build/jre
+ ${{ github.workspace }}/build/libs
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ ${{ runner.os }}-gradle
+
+ - name: Build with Gradle Wrapper
+ run: ./gradlew build
+
+ - name: Run tests
+ run: ./gradlew test itest datatest slowtest
+
+ - name: Publish Test Results
+ uses: EnricoMi/publish-unit-test-result-action@v2
+ if: always()
+ with:
+ files: |
+ build/test-results/**/*.xml
+ build/test-results/**/*.trx
+ build/test-results/**/*.json
+
+ - name: Run Coverage
+ run: ./gradlew testCoverage
+
+ - name: Upload Report to artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: testCoverage
+ path: ${{ github.workspace }}/build/reports/jacoco/testCoverage/html
+
+ - name: Jacoco Report to PR
+ id: jacoco
+ uses: madrapps/jacoco-report@v1.7.2
+ with:
+ paths: |
+ ${{ github.workspace }}/build/reports/jacoco/testCoverage/testCoverage.xml
+ token: ${{ secrets.GITHUB_TOKEN }}
+ title: '## :construction: PCGen Code Coverage'
+ update-comment: true
+ debug-mode: false
+
+ - name: Get the Coverage info
+ run: |
+ echo "Total coverage ${{ steps.jacoco.outputs.coverage-overall }}"
+ echo "Changed Files coverage ${{ steps.jacoco.outputs.coverage-changed-files }}"
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
deleted file mode 100644
index 829c5554dba..00000000000
--- a/.github/workflows/gradle.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Java CI
-
-on: [push]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Code
- uses: actions/checkout@v3
- - name: Set up JDK 17
- uses: actions/setup-java@v3
- with:
- distribution: 'temurin'
- java-version: '17'
- - name: Build with Gradle
- run: ./gradlew build
diff --git a/.gitignore b/.gitignore
index d55f55791dd..9513db7ac5a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,6 +94,7 @@ code/build.eclipse/
# IntelliJ IDE
.idea/
+.run/
out/
pcgendev.iml
pcgen.iml
diff --git a/.run/Main.run.xml b/.run/Main.run.xml
deleted file mode 100644
index 38778279d24..00000000000
--- a/.run/Main.run.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/PCGen-Formula/code/standards/suppressions.xml b/PCGen-Formula/code/standards/checkstyle-suppressions.xml
similarity index 55%
rename from PCGen-Formula/code/standards/suppressions.xml
rename to PCGen-Formula/code/standards/checkstyle-suppressions.xml
index 417315de6d2..8caabe23f62 100644
--- a/PCGen-Formula/code/standards/suppressions.xml
+++ b/PCGen-Formula/code/standards/checkstyle-suppressions.xml
@@ -1,10 +1,8 @@
-
+ "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
+ "https://checkstyle.org/dtds/suppressions_1_2.dtd">
-
\ No newline at end of file
diff --git a/PCGen-Formula/code/standards/checkstyle.xml b/PCGen-Formula/code/standards/checkstyle.xml
index bf29e09ecab..61b573a988f 100644
--- a/PCGen-Formula/code/standards/checkstyle.xml
+++ b/PCGen-Formula/code/standards/checkstyle.xml
@@ -1,6 +1,7 @@
-
-
+
@@ -83,12 +84,8 @@
-
-
-
-
+
-
diff --git a/PCGen-Formula/code/standards/spotbugs_ignore.xml b/PCGen-Formula/code/standards/spotbugs_ignore.xml
index a971a85cc42..21362c07cbe 100644
--- a/PCGen-Formula/code/standards/spotbugs_ignore.xml
+++ b/PCGen-Formula/code/standards/spotbugs_ignore.xml
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/PCGen-Formula/gradle/reporting.gradle b/PCGen-Formula/gradle/reporting.gradle
index f0a467db0d2..5da1da56aa2 100644
--- a/PCGen-Formula/gradle/reporting.gradle
+++ b/PCGen-Formula/gradle/reporting.gradle
@@ -8,7 +8,7 @@
checkstyle {
configFile = new File('code/standards/checkstyle.xml')
- configProperties = [ "suppressionFile" : project(':').file('code/standards/suppressions.xml')]
+ configProperties = [ "suppressionFile" : project(':').file('code/standards/checkstyle-suppressions.xml')]
ignoreFailures = true
showViolations = false
sourceSets = []
@@ -31,4 +31,6 @@ spotbugs {
toolVersion = "3.1.8"
}
-task allReports { dependsOn = ['checkstyleMain', 'pmdMain', 'spotbugsMain'] }
+tasks.register('allReports') {
+ dependsOn = ['checkstyleMain', 'pmdMain', 'spotbugsMain']
+}
diff --git a/PCGen-base/code/standards/checkstyle.xml b/PCGen-base/code/standards/checkstyle.xml
index ce082f322b8..c6f6fad8e15 100644
--- a/PCGen-base/code/standards/checkstyle.xml
+++ b/PCGen-base/code/standards/checkstyle.xml
@@ -1,6 +1,7 @@
-
-
+
diff --git a/PCGen-base/code/standards/spotbugs_ignore.xml b/PCGen-base/code/standards/spotbugs_ignore.xml
index cf5e8286f4b..166b44426f6 100644
--- a/PCGen-base/code/standards/spotbugs_ignore.xml
+++ b/PCGen-base/code/standards/spotbugs_ignore.xml
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/README.md b/README.md
index 57a710b1fe4..040f0b6c335 100644
--- a/README.md
+++ b/README.md
@@ -58,21 +58,21 @@ It supports numerous game systems, most notably:
1. Run installer and follow instruction
- Windows: Open `pcgen-6.09.xx_win_install.exe`
- Mac:
- - - `dmg`: Open `dmg` and drag into Applications. Right click on `PcGen` and click open.
- - - `pkg`: Right click and `pkg` and click open and click `open` on security warning due to application being unsigned.
+ - - `dmg`: Open `dmg` and drag into Applications. Right-click on `PcGen` and click open.
+ - - `pkg`: Right-click and `pkg` and click open and click `open` on security warning due to application being unsigned.
-1. You should be able to launch PcGen as normal application.
- - Mac: You may need to on first launch right click on application and then click `open`.
+1. You should be able to launch PcGen as a normal application.
+ - Mac: You may need to on first launch right-click on application and then click `open`.
# PCGen Needs You
-PCGen is an open source program driven by contributors, without your help no new fixes or content can be added.
-If you can program Java or want to contribute to expanding the book support please consider joining our team.
-Many of the original members have become inactive and we need new contributors to keep the project going.
+PCGen is an open-source program driven by contributors; without your help, no new fixes or content can be added.
+If you can program Java or want to contribute to expanding the book support, please consider joining our team.
+Many of the original members have become inactive, and we need new contributors to keep the project going.
To join our group:
- Join our [Discord](https://discord.gg/M7GH5BS)
-- Post in the volunteers channel to get access to the [Slack](https://slack.com). A senior member will add you by email.
+- Post in the volunteer channel to get access to the [Slack](https://slack.com). A senior member will add you by email.
- Make an account on the [JIRA] bug tracker. See [CODE] and [DATA] issues. Work is tracked here to easily generate release notes.
- Review the [Basic Workflow](#basic-workflow) & [Development Setup](#development-setup) below to get started.
@@ -82,28 +82,28 @@ Browse it when you have time, it can provide some insight into certain parts of
# PCGen LST Tutorial
Andrew has made a series of videos [explaining the LST files](https://www.youtube.com/watch?v=LhGkqdXNtOw&list=PLLa5A1qjBOPekqEC_R9BAZW-8q5IT-klM).
-These are mainly targetted at new DATA contributors adding new books/content and fixing bugs.
-You can of course ask questions in the discord or slack if you are unsure.
+These are mainly targeted at new DATA contributors adding new books/content and fixing bugs.
+You can, of course, ask questions in the discord or Slack if you are unsure.
Programmers may want to review these if they work on the LST parsing or related systems.
# Basic Workflow
-1. Get a bug from [JIRA] primarily from the [CODE] or [DATA] sections. Alternatively if you want to propose a new feature/change, make a JIRA entry to track it.
+1. Get a bug from [JIRA] primarily from the [CODE] or [DATA] sections. Alternatively, if you want to propose a new feature/change, make a JIRA entry to track it.
1. Create a branch in your fork of [PCGen] during development. It is good to name branches after ticket numbers, like fix_code_3444 or fix_data_3322.
-1. Work until the feature or bug is finished. Add tests if needed, especially if new code added.
-1. Push all work up into your copy of [PCGen]. Try to ensure build passes BEFORE submitting a pull request.
-1. Submit pull request from your fork to master and respond to review by members.
-1. Go back to first step.
+1. Work until the feature or bug is finished. Add tests if needed, especially if new code is added.
+1. Push all work up into your copy of [PCGen]. Try to ensure the build passes BEFORE submitting a pull request.
+1. Submit a pull request from your fork to master and respond to a review by members.
+1. Go back to the first step.
# Development Setup
These steps will guide you to a basic setup for development.
-These steps should work for Linux, Mac or Windows. Where steps differ it will be highlighted.
-If you have trouble, feel free to ask in the discord or slack once you have joined.
+These steps should work for Linux, Mac or Windows. Where steps differ, it will be highlighted.
+If you have trouble, feel free to ask in the Discord or Slack once you have joined.
### Running Commands
Anything `written like this` should be executed in a terminal.
-For Windows this means opening the start menu and typing cmd.exe or Powershell. The latter is more modern if available.
+For Windows this means opening the start menu and typing cmd.exe or PowerShell. The latter is more modern if available.
For Linux or Mac, whatever default terminal you have is fine.
### Install Java
@@ -128,17 +128,17 @@ You can install git on debian machines:
On Windows, [Git For Windows](https://gitforwindows.org) is a good choice. Download and install.
Be sure to install both the GUI & command line version. The default options are fine.
-If you do not know about git, reading the first 3 or 4 chapters of [Pro Git](https://git-scm.com/book/en/v2)
-will go a long way. It is designed about command line but all principles apply to the GUI version.
+If you do not know about git, reading the first three or four chapters of [Pro Git](https://git-scm.com/book/en/v2)
+will go a long way. It is designed about command line, but all principles apply to the GUI version.
### Fork and Clone PCGen
-Log in to github and go to [PCGen] in your browser.
+Log in to GitHub and go to [PCGen] in your browser.
Fork the project to have your own copy.
-Clone the fork locally, if you use ssh for instance it should be:
+Clone the fork locally, if you use ssh for instance, it should be:
git clone git@github.com:USERNAME/pcgen.git
-Where USERNAME is your github username.
+Where USERNAME is your GitHub username.
This can be done on the command line, or else open the git GUI and clone from there.
### Stay Up To Date
@@ -147,39 +147,39 @@ Run the following command:
git remote add upstream https://github.com/PCGen/pcgen
-This sets up the project for upstream rebasing, to keep you level with changes.
-You can rebase the master with latest changes with the following. It can be done from GUI as well.
+This sets up the project for upstream rebasing to keep you level with changes.
+You can rebase the master with the latest changes with the following. It can be done from GUI as well.
git checkout master && git fetch upstream && git rebase master
### Get an IDE
This step is optional. You are free to program in what you prefer, these are several popular IDEs for Java.
-If you are new we would suggest IntelliJ. Follow download/setup instructions then continue.
-These IDEs have git and gradle plugins either out of box or that can be installed.
+If you are new, we would suggest IntelliJ. Follow download/setup instructions, then continue.
+These IDEs have git and gradle plugins either out of the box or that can be installed.
- [IntelliJ Community](https://www.jetbrains.com/idea)
- [Eclipse](https://www.eclipse.org)
- [Netbeans](https://netbeans.org)
Once setup, open your IDE of choice. You should be able to import the cloned fork.
-Import the [PCGen] fork as a gradle project. From this point, you can work on the project.
+Import the [PCGen] fork as a Gradle project. From this point, you can work on the project.
For IntelliJ Community do: File > New > Project from Existing Sources ...
All of these IDEs have git and gradle plugins that can be used instead of commands.
# Essential Gradle Tasks
-This is a __quick__ rundown on gradle. You can get more information from [gradle docs](https://gradle.org/guides).
+This is a __quick__ rundown on Gradle. You can get more information from [gradle docs](https://gradle.org/guides).
Gradle is like make, it allows you to run commands to build projects.
The tasks can depend on one another and will ensure all dependencies are met before running.
These commands will be the same if you use a GUI to execute them.
-Note: `./gradlew` indicates you are executing the gradle wrapper command binary that comes with PCGen's source tree.
-This will automatically download and use the latest version of gradle. If you have gralde installed, you just
+Note: `./gradlew` indicates you are executing the Gradle wrapper command binary that comes with PCGen's source tree.
+This will automatically download and use the latest version of Gradle. If you have Gradle installed, you just
substitute `./gradlew` for `gradle` on the command line.
### See All Available Commands
./gradlew tasks
-### Just (Re)Compile Java
+### (Re)Compile Java
./gradlew compileJava
### Build All Required Files
@@ -193,7 +193,7 @@ substitute `./gradlew` for `gradle` on the command line.
### Run Full Test Suite
Do this primarily __before__ pull requests.
-This is almost exactly the command Travis runs to verify, if it fails locally you will fail the build and your PR will not be merged.
+This is almost exactly the command Travis runs to verify, if it fails locally you will fail the build, and your PR will not be merged.
./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist
diff --git a/appveyor.yml b/appveyor.yml
index f058d367c3d..05bc8305779 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,7 +5,7 @@ pull_requests:
nuget:
disable_publish_on_pr: true
-
+
install:
- cmd: |
choco install gradle nsis
@@ -13,22 +13,22 @@ build_script:
gradle build --info --no-daemon
test_script:
- gradle test compileSlowtest datatest pfinttest buildDist buildNsis --info --no-daemon
+ gradle test compileSlowtest datatest pfinttest buildDist --info --no-daemon
environment:
matrix:
- JAVA_HOME: C:\Program Files\Java\jdk11
-
+
artifacts:
- path: '**/release/*.exe'
name: PCGen Installer
-
+
- path: '**/build/distributions/*.zip'
name: PCGen Zip Distribution
- path: '**/build/distributions/*.tar'
name: PCGen Tar Distribution
-
+
matrix:
fast_finish: true
diff --git a/build-gradle.xml b/build-gradle.xml
deleted file mode 100644
index ef523e76e59..00000000000
--- a/build-gradle.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/build.gradle b/build.gradle
index 9bb7667a8be..e8093cd5c59 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@
* Run the character integration tests: gradle inttest
*/
-// import Ant helper static values to differ system families
+import groovy.json.JsonSlurper
import org.apache.commons.lang3.StringUtils
import org.apache.tools.ant.filters.FixCrLfFilter
@@ -26,25 +26,20 @@ plugins {
id 'application' // Creating application bundles
id 'build-dashboard' // Produces a build report
id 'checkstyle' // Checkstyle for Java, configured further below
- id 'com.github.spotbugs' version '6.4.7' // Spotbugs for Java
- id 'java' // Core java / javac
+ id 'com.github.spotbugs' version '6.4.7' // Spotbugs for Java
id 'maven-publish' // Publishing to Maven Central
id 'pmd' // PMD for Java, configured further below
id 'idea' // For IntelliJ IDEA users
id 'de.undercouch.download' version '5.6.0' // Shows download percentage
- id 'edu.sc.seis.launch4j' version '4.0.0' // Creates launch4j
id 'com.github.ben-manes.versions' version '0.53.0' // Checks versions for plugins and dependencies
id 'com.dorongold.task-tree' version '4.0.1' // Prints the task dependency tree
id 'org.openjfx.javafxplugin' version '0.1.0' // JavaFX support
id 'org.beryx.runtime' version '2.0.1' // Creates custom runtimes
+ id 'jacoco' // Code coverage
}
-/**
- * Set the version and the modules we want from JavaFX (not everything)
- */
-javafx {
- version = "21"
- modules = [ 'javafx.controls', 'javafx.web', 'javafx.swing', 'javafx.fxml', 'javafx.graphics' ]
+jacoco {
+ toolVersion = '0.8.14'
}
// Set the groupId as it helps with Maven
@@ -56,13 +51,6 @@ description = """PCGen"""
// Default task if you just run ./gradlew
defaultTasks 'build'
-// Configure Java, in particular the version to test/compile/run with
-java {
- toolchain {
- languageVersion = JavaLanguageVersion.of(21)
- }
-}
-
// Define properties for the build (directories)
ext {
// Where code gets compiled to
@@ -80,8 +68,31 @@ ext {
// Installers are placed here
releaseDir = layout.projectDirectory.dir("build/release")
- // JavaFX version
- javaFXVersion = "21.0.5"
+ // Java version (always latest release). It will affect JavaFX version too.
+ javaVersion = 25
+
+ latestJavaVersion = { majorJavaVersion ->
+ def uri = new URI("https://api.adoptium.net/v3/assets/feature_releases/${majorJavaVersion}/ga?architecture=x64&page=0&page_size=1&project=jdk&sort_order=DESC&vendor=eclipse")
+ def parsedJson = new JsonSlurper().parse(uri.toURL())
+
+ return parsedJson.first()
+ .version_data.with { [major, minor, security].join('.') }
+ }(javaVersion)
+}
+
+// Configure Java, in particular the version to test/compile/run with
+java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(javaVersion)
+ }
+}
+
+/**
+ * Set the version and the modules we want from JavaFX (not everything)
+ */
+javafx {
+ version = javaVersion
+ modules = [ 'javafx.controls', 'javafx.swing', 'javafx.fxml', 'javafx.graphics', 'javafx.web' ]
}
application {
@@ -107,16 +118,19 @@ repositories {
//}
ivy {
// TODO Enable HTTPS (e.g., add letsencrypt) for that location
- name "fileRepo"
- url 'http://pc-gen.org/librepo/'
+ name = 'fileRepo'
+ url = 'http://pc-gen.org/librepo/'
allowInsecureProtocol = true
}
// Use Maven plugin to reference freehep (https://java.freehep.org/) artifact repository
// TODO Which libs do we pull from here?
+ /*
maven {
name = 'free'
url = 'https://java.freehep.org/maven2'
}
+
+ */
maven {
name = 'local'
url = 'installers'
@@ -125,7 +139,7 @@ repositories {
// TODO Which libs do we pull from here?
maven {
name = 'jboss'
- url "https://repository.jboss.org/nexus/content/repositories/thirdparty-releases/"
+ url = 'https://repository.jboss.org/nexus/content/repositories/thirdparty-releases/'
}
}
@@ -217,46 +231,40 @@ tasks.register("cleanMasterSheets", Delete) {
* https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html
*/
dependencies {
- implementation group: 'commons-io', name: 'commons-io', version: '2.21.0'
-
- implementation group: 'commons-io', name: 'commons-io', version:'2.21.0'
-
- implementation group: 'org.springframework', name: 'spring-web', version:'6.2.12'
- implementation group: 'org.springframework', name: 'spring-beans', version:'6.2.12'
- implementation group: 'org.springframework', name: 'spring-core', version:'6.2.12'
- implementation group: 'org.apache.commons', name: 'commons-lang3', version:'3.20.0'
- implementation group: 'xalan', name: 'serializer', version: '2.7.3'
- implementation('org.apache.xmlgraphics:fop:2.11')
- {
+ implementation 'commons-io:commons-io:2.21.0'
+ implementation 'org.springframework:spring-web:6.2.12'
+ implementation 'org.springframework:spring-beans:6.2.12'
+ implementation 'org.springframework:spring-core:6.2.12'
+ implementation 'org.apache.commons:commons-lang3:3.20.0'
+ implementation 'xalan:serializer:2.7.3'
+ implementation('org.apache.xmlgraphics:fop:2.11') {
exclude group: 'xml-apis', module: 'xml-apis'
}
- implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.5.0'
- implementation group: 'org.scijava', name: 'jep', version: '2.4.2'
- implementation group: 'org.freemarker', name: 'freemarker', version: '2.3.34'
- implementation group: 'org.jdom', name: 'jdom2', version: '2.0.6.1'
- implementation('xalan:xalan:2.7.3')
- {
+ implementation 'org.apache.commons:commons-collections4:4.5.0'
+ implementation 'org.scijava:jep:2.4.2'
+ implementation 'org.freemarker:freemarker:2.3.34'
+ implementation 'org.jdom:jdom2:2.0.6.1'
+ implementation('xalan:xalan:2.7.3') {
exclude group: 'xml-apis', module: 'xml-apis'
}
- implementation group: 'net.sourceforge.argparse4j', name: 'argparse4j', version: '0.9.0'
- implementation group: 'org.xmlunit', name: 'xmlunit-core', version: '2.11.0'
- implementation group: 'org.controlsfx', name: 'controlsfx', version: '11.2.2'
-
- implementation group: 'net.sourceforge.pcgen', name: 'PCGen-base', version: '1.0.170'
+ implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
+ implementation 'org.xmlunit:xmlunit-core:2.11.0'
+ implementation 'org.controlsfx:controlsfx:11.2.2'
+ implementation 'net.sourceforge.pcgen:PCGen-base:1.0.170'
// The latest Base, but pcgen core would need refactoring to support it.
//implementation group: 'net.sourceforge.pcgen', name: 'PCGen-base', version:'1.0.237'
// Use this if you're working from your local PCGen Base
//implementation files("../pcgen-base/PCGen-base/build/libs/PCgen-base-1.0.jar")
- implementation group: 'net.sourceforge.pcgen', name: 'PCGen-Formula', version: '1.0.200'
+ implementation 'net.sourceforge.pcgen:PCGen-Formula:1.0.200'
// The latest Formula, but pcgen core would need refactoring to support it.
//implementation group: 'net.sourceforge.pcgen', name: 'PCGen-Formula', version:'1.0.266'
// Use if you're working from your local PCGen Formula
//implementation files("../pcgen-formula/PCGen-formula/build/libs/PCgen-formula-1.0.jar")
- compileOnly group: 'org.jetbrains', name: 'annotations', version:'26.0.2-1'
- compileOnly group: 'com.yuvimasory', name: 'orange-extensions', version: '1.3.0'
- compileOnly group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: '4.9.8'
+ compileOnly 'org.jetbrains:annotations:26.0.2-1'
+ compileOnly 'com.yuvimasory:orange-extensions:1.3.0'
+ compileOnly 'com.github.spotbugs:spotbugs-annotations:4.9.8'
testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.14.1'
testImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.14.1'
@@ -270,37 +278,10 @@ dependencies {
testImplementation group: 'org.xmlunit', name: 'xmlunit-matchers', version: '2.11.0'
spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.14.0'
- pmd 'net.sourceforge.pmd:pmd-ant:7.19.0'
+ pmd 'net.sourceforge.pmd:pmd-ant:7.19.0' // workaround: https://github.com/pmd/pmd/issues/4554
pmd 'net.sourceforge.pmd:pmd-java:7.19.0'
}
-// Properties to support Ant builds
-def antPluginTasks = []
-ant.importBuild('build-gradle.xml') {
- def (projectName, taskName) = it.tokenize('.')
-
- if (taskName == null && projectName.startsWith("jar") &&
- (projectName.endsWith("plugins") || projectName.endsWith("plugin"))) {
- antPluginTasks.push(projectName)
- }
- return it
-}
-ant.properties['src.java.dir']="code/src/java"
-ant.properties['build.classes.dir']="build/classes/java/main"
-
-// All plugins depend on compiled .class files
-antPluginTasks.each {
- tasks.named(it) {
- dependsOn tasks.named("compileJava")
- }
-}
-
-// Configuration for creating JARs from all of the plugins
-configure('jar-all-plugins') {
- group = BasePlugin.BUILD_GROUP // Or use 'build'
- description = 'Create the plugin jars'
-}
-
ext {
classpath = ""
configurations.runtimeClasspath.each { lib -> classpath += " libs/${lib.name} "}
@@ -308,15 +289,17 @@ ext {
jar {
// Pick up some configuration to JAR up the plugins
- it.dependsOn 'jar-all-plugins'
+ it.dependsOn "jarAllPlugins"
// If we detect duplicate JARs ignore the subsequent ones
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
// Create the manifest for the main JAR
manifest {
- attributes 'Implementation-Title': 'PCGen', 'Implementation-Version': archiveVersion,
- 'Main-Class': 'pcgen.system.Main', 'Class-Path': classpath
+ attributes 'Implementation-Title': 'PCGen',
+ 'Implementation-Version': archiveVersion,
+ 'Main-Class': 'pcgen.system.Main',
+ 'Class-Path': classpath
}
from {
@@ -330,29 +313,29 @@ jar {
* Create a Java runtime built from Java modules
*/
runtime {
- options = ['--compress', 'zip-6'] // Equivalent to the old '2' value pre Java 21
+ options = []
modules = [
- 'jdk.httpserver',
- 'java.management',
- 'java.rmi',
- 'java.desktop',
- 'java.xml',
- 'java.sql',
- 'jdk.unsupported',
- 'java.prefs',
- 'java.logging',
- 'java.naming',
- 'jdk.xml.dom',
- 'jdk.unsupported.desktop',
- 'java.datatransfer',
- 'java.scripting',
- 'jdk.jfr',
- 'jdk.jsobject',
- 'javafx.controls',
- 'javafx.web',
- 'javafx.swing',
- 'javafx.fxml',
- 'javafx.graphics'
+ 'jdk.httpserver',
+ 'java.management',
+ 'java.rmi',
+ 'java.desktop',
+ 'java.xml',
+ 'java.sql',
+ 'jdk.unsupported',
+ 'java.prefs',
+ 'java.logging',
+ 'java.naming',
+ 'jdk.xml.dom',
+ 'jdk.unsupported.desktop',
+// 'java.datatransfer',
+ 'java.scripting',
+ 'jdk.jfr',
+ 'jdk.jsobject',
+ 'javafx.controls',
+ 'javafx.web',
+ 'javafx.swing',
+ 'javafx.fxml',
+ 'javafx.graphics'
]
// We support Mac/Win/Linux x86-64, Mac/Linux aarch64
@@ -368,15 +351,14 @@ runtime {
installerOptions = ["--app-version", "${version.replaceAll('-SNAPSHOT', '')}", "--license-file", licenseFile.asFile.absolutePath]
def hostArchitecture = System.getProperty("os.arch")
- def osFamily = (Os.isFamily(Os.FAMILY_MAC)
- ? "mac"
- : (Os.isFamily(Os.FAMILY_UNIX)
- ? "linux"
- : (Os.isFamily(Os.FAMILY_WINDOWS) ? "windows" : "unknown")))
+ def osFamily =
+ Os.isFamily(Os.FAMILY_MAC) ? "mac" :
+ Os.isFamily(Os.FAMILY_UNIX) ? "linux" :
+ Os.isFamily(Os.FAMILY_WINDOWS) ? "windows" : "unknown"
def targetPlatform = ["x86_64" : "x64",
"amd64" : "x64",
"aarch64" : "aarch64"]
- // formats a string such as "mac-aarch64", or "linux-x64"
+ // formats a string such as "mac -aarch64", or "linux-x64"
targetPlatformName = "${osFamily}-${targetPlatform.get(hostArchitecture, "NOT SUPPORTED")}"
if (osFamily == "mac") {
@@ -405,7 +387,7 @@ tasks.named("jpackageImage") {
if (Os.isFamily(Os.FAMILY_MAC)) {
into layout.buildDirectory.dir("jpackage/PcGen.app/Contents/app")
} else {
- into layout.buildDirectory.dir("jpackage/PcGen/bin")
+ into layout.buildDirectory.dir("jpackage/PcGen")
}
}
@@ -414,7 +396,9 @@ tasks.named("jpackageImage") {
copy {
from layout.projectDirectory.dir("installers/mac-installer")
include "MacDirLauncher"
- fileMode 0755
+ filePermissions {
+ unix(0755)
+ }
into layout.buildDirectory.dir("jpackage/PcGen.app/Contents/MacOS")
}
ant.replace(file: layout.buildDirectory.file("jpackage/PcGen.app/Contents/Info.plist").get(),
@@ -441,13 +425,12 @@ tasks.register("converterJar", Jar) {
include 'none'
}
-artifacts {
- archives converterJar
+tasks.named("assemble") {
+ dependsOn converterJar
}
tasks.register("copyToLibs", Copy) {
- dependsOn startScripts, distTar, distZip, installDist
- mustRunAfter createExe
+ dependsOn startScripts, installDist
doFirst {
println("IN copyToLibs")
@@ -458,7 +441,7 @@ tasks.register("copyToLibs", Copy) {
}
tasks.register("copyToOutput", Copy) {
- dependsOn copyToLibs, createExe, converterJar, jar
+ dependsOn copyToLibs, converterJar, jar
doFirst {
println("IN copyToOutput")
@@ -466,7 +449,6 @@ tasks.register("copyToOutput", Copy) {
from layout.buildDirectory.file("libs/pcgen-${version}.jar"),
layout.buildDirectory.file("libs/pcgen-${version}-batch-convert.jar"),
- layout.buildDirectory.file("launch4j/pcgen.exe"),
layout.projectDirectory.file("code/pcgen.bat")
from(layout.projectDirectory.file("code/pcgen.sh")) {
filter(FixCrLfFilter, eol:FixCrLfFilter.CrLf.newInstance("lf"))
@@ -529,9 +511,12 @@ tasks.named("build") {
}
tasks.register("downloadJRE") {
- def major = 21
+ notCompatibleWithConfigurationCache("Gradle download extension not compatible")
+
+ def major = project.ext.javaVersion
def archs = ['x64', 'aarch64']
def osList = ['windows', 'mac', 'linux']
+ def baseJreDir = project.ext.jresDir
doLast {
println("Downloading JDKs for use in creating the runtime bundles.")
@@ -546,12 +531,12 @@ tasks.register("downloadJRE") {
if (arch == "aarch64" && os == "windows") return
def url = "https://api.adoptium.net/v3/binary/latest/${major}/ga/${os}/${arch}/jdk/hotspot/normal/eclipse"
- def jreDownloadDest = layout.projectDirectory.file("jre/${os}/jre_${arch}.${extension}")
- def jreDir = layout.projectDirectory.dir("jre/${os}/jre_${arch}").asFile
+ def jreDownloadDest = baseJreDir.file("${os}/jre_${arch}.${extension}")
+ def jreDir = baseJreDir.dir("${os}/jre_${arch}").asFile
def jreRelease = (os == "mac"
- ? layout.projectDirectory.dir("jre/${os}/jre_${arch}/Contents/Home/release").asFile
- : layout.projectDirectory.dir("jre/${os}/jre_${arch}/release").asFile)
- def outputDir = layout.projectDirectory.dir("jre/${os}/jre_${arch}")
+ ? baseJreDir.dir("${os}/jre_${arch}/Contents/Home/release").asFile
+ : baseJreDir.dir("${os}/jre_${arch}/release").asFile)
+ def outputDir = baseJreDir.dir("${os}/jre_${arch}")
def shouldDownloadJDK = true
try {
@@ -570,7 +555,7 @@ tasks.register("downloadJRE") {
return
} else if (jreDir.exists()) {
println "Delete the previously downloaded JDK at ${jreDir} as outdated. JavaFX modules will be deleted from jdkDir/jmods."
- project.delete(jreDir)
+ delete(jreDir)
}
println("Downloading Java ${major} ${arch} for ${os} from ${url}")
@@ -580,11 +565,11 @@ tasks.register("downloadJRE") {
overwrite false
}
- layout.projectDirectory.dir("jre/${os}")
+ baseJreDir.dir("${os}")
.asFileTree
.matching { include "*.${extension}" }
.each { simLib ->
- def archFile = layout.projectDirectory.file("jre/${os}/${simLib.name}")
+ def archFile = baseJreDir.file("${os}/${simLib.name}")
copy {
println "* Unpack $simLib.name to ${outputDir}"
@@ -602,7 +587,7 @@ tasks.register("downloadJRE") {
}
}
- project.delete(archFile)
+ delete(archFile)
}
file("${projectDir}/jre/${os}/jre_${arch}").list().each { f ->
@@ -616,13 +601,16 @@ tasks.register("downloadJRE") {
}
tasks.register("downloadJavaFXModules") {
+ notCompatibleWithConfigurationCache("Gradle download extension not compatible")
+
mustRunAfter downloadJRE
// We support Windows/Mac/Linux - x64, and Mac/Linux - aarch64
- // (JavaFX doesn't support Linux/aarch64 in 21 LTS, use 21.0.1 instead)
- def major = project.ext.javaFXVersion
+ def major = project.javaVersion
def archs = ['x64', 'aarch64']
def osList = ["windows", "mac", "linux"]
+ def baseJreDir = project.ext.jresDir
+ def projectDirPath = projectDir.absolutePath
inputs.property("major", major)
@@ -640,20 +628,17 @@ tasks.register("downloadJavaFXModules") {
archAppend = "-x64"
} else if (arch == "aarch64" && os != "windows") {
archAppend = "-aarch64"
- if (os == "linux") {
- major = "21.0.1" // TODO other versions don't supply aarch64 for Linux, use 21.0.1 instead
- }
} else {
return
}
// URLs look like this: https://download2.gluonhq.com/openjfx/21.0.2/openjfx-21.0.2_osx-aarch64_bin-jmods.zip
def url = "https://download2.gluonhq.com/openjfx/${major}/openjfx-${major}_${osPackage}${archAppend}_bin-jmods.zip"
- def jmodsZip = layout.projectDirectory.file("jre/${os}/jmods${arch}.zip")
+ def jmodsZip = baseJreDir.file("${os}/jmods${arch}.zip")
// If we don't already have the jmods, download them and unzip them to the correct place.
if (!jmodsZip.asFile.exists()) {
- println("Downloading JavaFX mods ${major} ${arch} for ${os} from ${url} to ${projectDir}/jre/${os}/")
+ println("Downloading JavaFX mods ${major} ${arch} for ${os} from ${url} to ${projectDirPath}/jre/${os}/")
download.run {
src url
@@ -664,8 +649,8 @@ tasks.register("downloadJavaFXModules") {
copy {
def zipFile = jmodsZip
def outputDir = (os == "mac")
- ? "${projectDir}/jre/${os}/jre_${arch}/Contents/Home/jmods"
- : "${projectDir}/jre/${os}/jre_${arch}/jmods"
+ ? "${projectDirPath}/jre/${os}/jre_${arch}/Contents/Home/jmods"
+ : "${projectDirPath}/jre/${os}/jre_${arch}/jmods"
println "Unzipping ${zipFile} to ${outputDir}"
from zipTree(zipFile)
@@ -697,7 +682,7 @@ tasks.register("downloadJavaFXLocal", Download) {
.filter(i -> Os.isFamily(i.key))
.map { it.value }
.findFirst()
- .orElseThrow { new GradleException("Unsupported OS detected: '${osName}'. Supported families are: ${Os.FAMILY_WINDOWS}, ${Os.FAMILY_MAC} and ${Os.FAMILY_UNIX}") }
+ .orElseThrow { new GradleException("Unsupported OS detected: '${osName}'. Supported families are: ${supportedOS.keySet().join(", ")}") }
def supportedArch = ["x86_64" : "-x64",
"amd64" : "-x64",
@@ -710,12 +695,12 @@ tasks.register("downloadJavaFXLocal", Download) {
}
doFirst {
- println("Downloading JavaFX SDK for use in local testing.")
+ println("Downloading JavaFX SDK for use in local testing for ${currentOS} ${hostArchitecture}.")
}
- def fileName = "openjfx-${project.ext.javaFXVersion}_${currentOS}${archAppend}_bin-sdk.zip"
+ def fileName = "openjfx-${project.ext.latestJavaVersion}_${currentOS}${archAppend}_bin-sdk.zip"
- src "https://download2.gluonhq.com/openjfx/${project.ext.javaFXVersion}/${fileName}"
+ src "https://download2.gluonhq.com/openjfx/${project.ext.latestJavaVersion}/${fileName}"
dest layout.projectDirectory.file("mods/${fileName}")
overwrite false
useETag true
@@ -748,8 +733,27 @@ tasks.named("jre") {
dependsOn downloadJRE, downloadJavaFXModules
}
+tasks.register("testCoverage", JacocoReport) {
+ dependsOn test
+ group = "Reporting"
+ description = "Generate Jacoco coverage reports for the test build."
+
+ reports {
+ html.required.set(true)
+ xml.required.set(true)
+ }
+
+ classDirectories.from = fileTree(dir: layout.buildDirectory.dir("classes/java/main"))
+
+ sourceDirectories.from = files([
+ "$project.projectDir/code/src/java"
+ ])
+
+ executionData.from = fileTree(dir: layout.buildDirectory.dir("jacoco")).include("*.exec")
+}
+
tasks.named("test", Test) {
- exclude 'pcgen/testsupport/**'
+ exclude 'test/pcgen/testsupport/**'
useJUnitPlatform()
}
@@ -768,17 +772,14 @@ tasks.register("slowtest", Test) {
classpath = sourceSets.slowtest.runtimeClasspath
systemProperties['jar.path'] = jar.getArchiveFile().get().getAsFile()
forkEvery = 1
- // Exclude the two suites to avoid duplicate test runs.
- exclude 'AllJUnitTests.class'
- exclude 'pcgen/core/AllJUnitTests.class'
}
tasks.register("datatest", Test) {
dependsOn jar
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
- include 'pcgen/persistence/lst/DataTest.class'
- include 'pcgen/persistence/lst/DataLoadTest.class'
+ include 'main/pcgen/persistence/lst/DataTest.class'
+ include 'main/pcgen/persistence/lst/DataLoadTest.class'
}
tasks.register("inttest", Test) {
@@ -786,7 +787,7 @@ tasks.register("inttest", Test) {
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
forkEvery = 1
- include 'pcgen/inttest/**/*Test.class'
+ include 'slowtest/pcgen/inttest/**/*Test.class'
}
tasks.register("sfinttest", Test) {
@@ -794,7 +795,7 @@ tasks.register("sfinttest", Test) {
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
forkEvery = 1
- include 'pcgen/inttest/game_starfinder/*Test.class'
+ include 'slowtest/pcgen/inttest/game_starfinder/*Test.class'
}
tasks.register("pfinttest", Test) {
@@ -802,7 +803,7 @@ tasks.register("pfinttest", Test) {
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
forkEvery = 1
- include 'pcgen/inttest/game_pathfinder/*Test.class'
+ include 'slowtest/pcgen/inttest/game_pathfinder/*Test.class'
}
tasks.register("rsrdinttest", Test) {
@@ -810,7 +811,7 @@ tasks.register("rsrdinttest", Test) {
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
forkEvery = 1
- include 'pcgen/inttest/game_35e/*Test.class'
+ include 'slowtest/pcgen/inttest/game_35e/*Test.class'
}
tasks.register("srdinttest", Test) {
@@ -818,7 +819,7 @@ tasks.register("srdinttest", Test) {
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
forkEvery = 1
- include 'pcgen/inttest/game_3e/*Test.class'
+ include 'slowtest/pcgen/inttest/game_3e/*Test.class'
}
tasks.register("msrdinttest", Test) {
@@ -826,13 +827,14 @@ tasks.register("msrdinttest", Test) {
testClassesDirs = sourceSets.slowtest.output.classesDirs
classpath = sourceSets.slowtest.runtimeClasspath
forkEvery = 1
- include 'pcgen/inttest/game_modern/*Test.class'
+ include 'slowtest/pcgen/inttest/game_modern/*Test.class'
}
allprojects {
tasks.withType(Javadoc).configureEach {
options.addBooleanOption('Xdoclint:none', true)
}
+
tasks.withType(Test).configureEach {
maxHeapSize = "1024m"
maxParallelForks = 1
@@ -848,6 +850,7 @@ allprojects {
'-Dprism.order=sw',
'-Dprism.verbose=true',
'-Djavafx.macosx.embedded=true',
+ '-Djava.security.manager=disallow',
"--module-path", layout.projectDirectory.dir("mods/lib"),
"--add-modules", "javafx.controls,javafx.web,javafx.swing,javafx.fxml,javafx.graphics",
@@ -860,9 +863,11 @@ allprojects {
'--add-opens', 'javafx.graphics/com.sun.glass.ui=ALL-UNNAMED',
]
}
+
tasks.withType(JavaCompile).configureEach {
dependsOn extractJavaFXLocal
options.fork = true
+ options.release = project.ext.javaVersion
doFirst {
if (name.toLowerCase().contains("test")) {
@@ -949,10 +954,11 @@ apply from: 'code/gradle/distribution.gradle'
apply from: 'code/gradle/autobuild.gradle' // depends on distribution.gradle
apply from: 'code/gradle/reporting.gradle'
apply from: 'code/gradle/release.gradle'
+apply from: 'code/gradle/plugins.gradle'
tasks.register("allTasks") {
- dependsOn build, slowtest, javadoc, buildNsis, allReports
- description = "Runs tasks build, slowtest, javadoc, buildNsis and allReports"
+ dependsOn build, slowtest, javadoc, allReports
+ description = "Runs tasks build, slowtest, javadoc and allReports"
}
// TODO This clean is not as nuclear as it perhaps should be.
@@ -960,21 +966,5 @@ tasks.register("allTasks") {
// you will also need to clean out output/ bin/
// This task is in the end, because other scripts contribute to the building process
tasks.named("clean") {
- dependsOn tasks.named("clean-plugins"), cleanOutput, cleanJre, cleanMods, cleanNsis, cleanMasterSheets
-
- doLast {
- // Delete a file generated by pluginbuild.xml
- project.delete(layout.projectDirectory.file("code/manifest"))
-
- // Delete plugin folders
- project.delete(
- layout.projectDirectory.dir("plugins/bonusplugins"),
- layout.projectDirectory.dir("plugins/converterplugins"),
- layout.projectDirectory.dir("plugins/jepplugins"),
- layout.projectDirectory.dir("plugins/lstplugins"),
- layout.projectDirectory.dir("plugins/outputplugins"),
- layout.projectDirectory.dir("plugins/preplugins"),
- layout.projectDirectory.dir("plugins/systemlstplugins")
- )
- }
+ dependsOn cleanPlugins, cleanOutput, cleanJre, cleanMods, cleanMasterSheets
}
diff --git a/code/gradle/distribution.gradle b/code/gradle/distribution.gradle
index 182e5ea4ea4..42964dc8127 100644
--- a/code/gradle/distribution.gradle
+++ b/code/gradle/distribution.gradle
@@ -98,18 +98,21 @@ application {
tasks.named("run") {
dependsOn assemble, extractJavaFXLocal
+
+ def modsLibPath = layout.projectDirectory.dir("mods/lib").asFile.absolutePath
+
// Required to fixed incorrectly added "--module-path" and adds correct modules.
doFirst {
jvmArgs = ["-ea", // -ea enables assertions
"--enable-preview", // enable Java preview features
- "--module-path", layout.projectDirectory.dir("mods/lib").asFile.absolutePath,
- "--add-modules", "javafx.controls,javafx.web,javafx.swing,javafx.fxml,javafx.graphics"
+ "--module-path", modsLibPath,
+ "--add-modules", "javafx.controls,javafx.web,javafx.swing,javafx.fxml,javafx.graphics",
+ "--enable-native-access", "javafx.graphics,javafx.web" // JDK-8347744
]
}
}
tasks.named("installDist") {
- dependsOn createExe
doLast{
delete {
delete fileTree(layout.buildDirectory.dir("install/pcgen/lib")) {
@@ -119,14 +122,6 @@ tasks.named("installDist") {
}
}
-tasks.named("distTar") {
- dependsOn createExe
-}
-
-tasks.named("distZip") {
- dependsOn createExe
-}
-
tasks.register("testZip", Zip) {
dependsOn converterJar, copyToLibs, copyToOutput
archiveClassifier.set('test')
@@ -158,7 +153,7 @@ tasks.register("docsZip", Zip) {
}
tasks.register("programZip", Zip) {
- dependsOn converterJar, createExe
+ dependsOn converterJar
archiveClassifier.set('program')
into(zipRootFolder) {
with programDistsImage
diff --git a/code/gradle/plugins.gradle b/code/gradle/plugins.gradle
new file mode 100644
index 00000000000..9cc15cd9f99
--- /dev/null
+++ b/code/gradle/plugins.gradle
@@ -0,0 +1,61 @@
+
+def PLUGINS_GROUP = "PCGen plugins"
+
+def manifestFile = "code/manifest"
+
+def srcJavaDir = "code/src/java"
+def buildClassesDir = "build/classes/java/main"
+
+def pluginsDir = "${projectDir}/plugins"
+
+tasks.register("cleanPlugins", Delete) {
+ description = "Clean all working files"
+ group = PLUGINS_GROUP
+
+ delete fileTree(dir: pluginsDir, include: "*.jar")
+}
+
+def createJarTask = {taskName, archiveName, description, includePattern ->
+ tasks.register(taskName, Jar) {
+ this.description = description
+ group = PLUGINS_GROUP
+ dependsOn tasks.named("compileJava")
+
+ archiveFileName = archiveName
+ manifest {
+ attributes(
+ "Implementation-Title": "PCGen ${taskName.replace('jar', '').toLowerCase()} plugins",
+ "Implementation-Version": project.version,
+ "Class-Path": "lib/pcgen.jar",
+ "Built-Date": new Date(),
+ "Built-JDK": "${System.getProperty('java.vm.version')} (${System.getProperty('java.vendor')})",
+ "Created-By": "Gradle ${project.gradle.gradleVersion}"
+ )
+ }
+
+ destinationDirectory = file("${pluginsDir}")
+
+ from("${buildClassesDir}") {
+ include includePattern
+ }
+ }
+}
+
+createJarTask("jarExportPlugins", "exportplugins.jar", "Build (Link) Export Token plugin jar files", "plugin/exporttokens/**/*.class")
+createJarTask("jarBonusPlugins", "bonusplugins.jar", "Build (Link) plugin Bonus Token jar files", "plugin/bonustokens/**/*.class")
+createJarTask("jarLstPlugins", "lstplugins.jar", "Build (Link) plugin LST Token jar files", "plugin/lsttokens/**/*.class")
+createJarTask("jarPrePlugins", "preplugins.jar", "Build (Link) Prereq Token plugin jar files", "plugin/pretokens/**/*.class")
+createJarTask("jarConverterPlugins", "converterplugins.jar", "Build (Link) Converter plugin jar files", "plugin/converter/**/*.class")
+createJarTask("jarModifierPlugins", "modifierplugins.jar", "Build (Link) Lst Modifier Token plugin jar files", "plugin/modifier/**/*.class")
+createJarTask("jarPrimitivePlugins", "primitiveplugins.jar", "Build (Link) Lst Primitive Token plugin jar files", "plugin/primitive/**/*.class")
+createJarTask("jarQualifierPlugins", "qualifierplugins.jar", "Build (Link) Lst Compatibility Token plugin jar files", "plugin/qualifier/**/*.class")
+createJarTask("jarFunctionPlugins", "functionplugins.jar", "Build (Link) Custom Function jar files", "plugin/function/**/*.class")
+createJarTask("jarGroupingPlugins", "groupingplugins.jar", "Build (Link) Grouping plugin jar files", "plugin/grouping/**/*.class")
+createJarTask("jarJepCommandsPlugins", "jepcommandsplugins.jar", "Build (Link) Jep Command plugin jar files", "plugin/jepcommands/**/*.class")
+
+tasks.register("jarAllPlugins") {
+ description = "Create the plugin jars"
+ group = BasePlugin.BUILD_GROUP
+ dependsOn jarExportPlugins, jarBonusPlugins, jarLstPlugins, jarPrePlugins, jarConverterPlugins, jarModifierPlugins,
+ jarPrimitivePlugins, jarQualifierPlugins, jarFunctionPlugins, jarGroupingPlugins, jarJepCommandsPlugins
+}
diff --git a/code/gradle/release.gradle b/code/gradle/release.gradle
index 768dc842053..b31a257b2a4 100644
--- a/code/gradle/release.gradle
+++ b/code/gradle/release.gradle
@@ -3,7 +3,6 @@
* and production releases are made.
*
* Usage: gradle prepareRelease
- * Usage: gradle buildNsis
* Usage: gradle pcgenRelease
*
* Release script
@@ -12,7 +11,7 @@
* b. Commit new version
* c. Clean, Build and check
* d. Run slow tests
- * 2. Manual testing using product of gradle fullZip or gradle buildNsis
+ * 2. Manual testing using product of gradle fullZip
* 3. gradle pcgenRelease
* a. Build
* b. Assemble distributables
@@ -123,76 +122,6 @@ ext {
installerVerNum = result[0].toInteger() + "." + result[1].toInteger() + "." + result[2].take(2).toInteger() + ".0"
}
-tasks.register("layoutNsisBase", Copy) {
- dependsOn runtimeZip, createExe, copyToLibs, jar, converterJar
-
- description="Assemble the required files for all PCGen installations"
-
- //doFirst {
- // Release notes are required! Causes Autobuild Problem
- //assert file(releaseNotes).exists()
- //}
-
- into nsisBaseFolder
- from(layout.projectDirectory.dir("installers/win-installer/Local")) {
- into "../Local"
- }
- from(layout.projectDirectory.dir("installers/win-installer")) {
- into "/docs/acknowledgments/"
- include "PCGenLicense.txt"
- }
- from(layout.projectDirectory) {
- include 'logging.properties'
- include 'system/**' // Later we want to split out the game modes to optional
- include 'docs/**'
- include 'preview/**'
- include 'characters/*.pcg'
- }
- from(layout.buildDirectory.dir("launch4j")) {
- include 'pcgen.exe'
- }
- from(layout.buildDirectory.dir("install/pcgen")) {
- include 'pcgen.bat'
- include 'pcgen'
- filter(FixCrLfFilter, eol:FixCrLfFilter.CrLf.newInstance("lf"))
- filePermissions {
- unix(0755)
- }
- }
- with basePlugins
- with nonPdfOutput
- with baseData
-}
-
-// See: https://github.com/TheBoegl/gradle-launch4j
-launch4j {
- mainClassName = 'pcgen.system.Main'
- icon = layout.projectDirectory.file("installers/win-installer/Local/pcgen.ico").asFile.absolutePath
- requiresJdk = false // false means it'll grab a JRE first if available
- maxHeapPercent = 80
- stayAlive = false
- requires64Bit = false // false means it auto-selects 64 or 32 bit as required.
- bundledJrePath = '.'
- dontWrapJar = true
- splashFileName = layout.projectDirectory.file("installers/win-installer/Local/splash.bmp").asFile.absolutePath
- splashWaitForWindows = true
- splashTimeout = 60
- splashTimeoutError = true
- // Can't be longer than 150 characters
- copyright = "PCGen's source-code is distributed under the GNU Lesser General Public License (LGPL)"
- version = "${shortVerNum}"
- jvmOptions = ["-Dsun.java2d.dpiaware=false"]
- downloadUrl = "http://pcgen.org/download/"
-}
-
-tasks.register("layoutNsisOptional", Copy) {
- dependsOn copyToOutput, tasks.named("runtime")
- description = "Assemble the optional files for PCGen installations"
- into nsisOptionFolder
-
- with pdfLibs, gmgenPlugins, pdfOutput, optionalData, lib32, lib64
-}
-
// Generate the publisher/data list for the Windows installer script
tasks.register("genDataList") {
inputs.dir layout.projectDirectory.dir("data")
@@ -331,96 +260,16 @@ tasks.register("genDataList") {
}
}
-// Create the version specific config files for NSIS
-tasks.register("genProjectNsis") {
- def licenseFile = layout.projectDirectory.file("code/LICENSE")
- inputs.file licenseFile
- inputs.property("plainVerNum", plainVerNum)
- inputs.property("installerVerNum", installerVerNum)
-
- def projectNsh = layout.projectDirectory.file("installers/win-installer/project.nsh")
- def constantsNsh = layout.projectDirectory.file("installers/win-installer/includes/constants.nsh")
-
- outputs.files projectNsh, constantsNsh
-
- doLast {
- projectNsh.asFile
- .text = """
-; Projects file generated by release.gradle
-!define PROJECT_BUILD_DIR "${layout.buildDirectory.dir(".").get()}"
-!define PROJECT_DIST_BIN_DIR "${layout.buildDirectory.dir("nsis").get()}"
-!define PROJECT_DIST_DIR "${layout.buildDirectory.dir(".").get()}"
-!define PROJECT_FINAL_NAME "pcgen"
-!define PROJECT_LICENSE_FILE "${licenseFile.asFile.absolutePath}"
-!define PROJECT_LICENSE_TEXT "This program is Licensed under The GNU Lesser General Public License, Version 2.1."
-!define PROJECT_NAME "PCGen"
-!define PROJECT_ORGANIZATION "SourceForge"
-!define PROJECT_REG_KEY "SOFTWARE\\SourceForge\\PCGen\\${plainVerNum}"
-!define PROJECT_REG_UNINSTALL_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\PCGen ${plainVerNum}"
-!define PROJECT_STARTMENU_FOLDER "\$SMPROGRAMS\\SourceForge\\PCGen ${plainVerNum}"
-!define PROJECT_URL "http://pcgen.sourceforge.net/"
-!define PROJECT_VERSION "${plainVerNum}"
-!define INSTALLER_VERSION "${installerVerNum}"
-"""
-
- constantsNsh.asFile
- .text = """
-; Constants file generated by release.gradle
-!define SIMPVER "${shortVerNum}"
-!define LONGVER "${plainVerNum}"
-!define OutDir "${layout.buildDirectory.dir("nsisRelease").get()}"
-!define SrcDir "${layout.buildDirectory.dir("nsis").get()}"
-"""
- }
-}
-
-// Call NSIS to generate windows installer - Removed "genDataList"
-tasks.register("buildNsis", Exec) {
- dependsOn layoutNsisBase, layoutNsisOptional, genProjectNsis, downloadJRE, genDataList
- mustRunAfter createExe
-
- def makensisPaths = [windows: "C:/Program Files (x86)/NSIS/makensis.exe"]
- def currentOs = System.getProperty('os.name').toLowerCase(Locale.ROOT);
- def makensis = makensisPaths.getOrDefault(currentOs, "makensis")
- def pcgenNsi = layout.projectDirectory.file("installers/win-installer/pcgen.nsi").asFile.absolutePath
- def stdout = new ByteArrayOutputStream()
-
- doFirst {
- println("Running makensis from the path '${makensis}':")
- mkdir layout.buildDirectory.dir("nsis")
- mkdir layout.buildDirectory.dir("nsisRelease")
- }
- workingDir layout.buildDirectory.dir("nsis")
-
- standardOutput = stdout;
- errorOutput = stdout;
-
- if (currentOs == "windows") {
- commandLine makensis, "/V4", "/WX", "/Onsis.output", pcgenNsi
- } else {
- commandLine makensis, "-V4", "-WX", "-Onsis.output", pcgenNsi
- }
-
- doLast {
- def nsisOutput = layout.buildDirectory.file("nsis/nsis.output").get()
- println "NSIS output is located in : ${nsisOutput.asFile.absolutePath}"
- }
-}
-
-tasks.register("cleanNsis", Delete) {
- delete nsisBaseFolder, nsisOptionFolder, layout.buildDirectory.dir("nsis/Local")
-}
-
tasks.register("sourcesJar", Jar) {
- dependsOn classes, copyToOutput, createExe, distTar, distZip, layoutNsisBase, startScripts
- duplicatesStrategy DuplicatesStrategy.INCLUDE
+ dependsOn classes, copyToOutput, distTar, distZip, startScripts
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
description = "build source jar file"
archiveClassifier.set('sources')
from sourceSets.main.allSource
}
tasks.register("assembleArtifacts", Copy) {
- dependsOn build, runtimeZip, sourcesJar, buildNsis
+ dependsOn build, runtimeZip, sourcesJar
if (Os.isFamily(Os.FAMILY_MAC) || Os.isFamily(Os.FAMILY_UNIX))
{
@@ -429,11 +278,7 @@ tasks.register("assembleArtifacts", Copy) {
description = "Create the release artifacts and get them into the release folder."
into releaseDir
- // buildNsis puts the exe into the release folder directly
- from(layout.buildDirectory.dir("nsisRelease")){
- include '*.exe'
- }
from(layout.buildDirectory.dir("libs")){
include 'pcgen*-sources.jar'
}
diff --git a/code/gradle/reporting.gradle b/code/gradle/reporting.gradle
index 4eaf13fffbf..f521206a4c9 100644
--- a/code/gradle/reporting.gradle
+++ b/code/gradle/reporting.gradle
@@ -9,7 +9,7 @@ checkstyle {
configFile = new File('code/standards/checkstyle.xml')
configProperties = [samedir: "${rootDir}/code/standards"]
showViolations = true
- toolVersion = '10.20.1'
+ toolVersion = '12.1.2'
sourceSets = []
}
@@ -19,7 +19,7 @@ pmd {
ruleSetFiles = files('code/standards/ruleset.xml')
consoleOutput = true
sourceSets = []
- toolVersion = "7.7.0"
+ toolVersion = "7.18.0"
incrementalAnalysis = true
}
@@ -28,7 +28,7 @@ spotbugs {
def classLoader = plugins["com.github.spotbugs"].class.classLoader
def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence")
- toolVersion = '4.8.6'
+ toolVersion = '4.9.8'
excludeFilter = file("$rootProject.projectDir/code/standards/spotbugs_ignore.xml")
omitVisitors = ['Naming', 'CrossSiteScripting', 'DontUseEnum', 'DoInsideDoPrivileged']
reportLevel = SpotBugsConfidence.LOW
@@ -39,7 +39,7 @@ spotbugsMain {
reports {
xml.required = false
html.required = true
- html.stylesheet resources.text.fromFile('code/standards/fancy-hist.xsl')
+ html.stylesheet = resources.text.fromFile('code/standards/fancy-hist.xsl')
}
}
diff --git a/code/pluginbuild.xml b/code/pluginbuild.xml
deleted file mode 100644
index f7905f0ecd9..00000000000
--- a/code/pluginbuild.xml
+++ /dev/null
@@ -1,7653 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Manifest-Version: 1.2
-Main-Class: ${manifest.main.class}
-Class-Path: ${manifest.extra.jars}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/code/src/itest/pcgen/output/FreeMarkerTest.java b/code/src/itest/pcgen/output/FreeMarkerTest.java
index 59363157558..8e2828cf8fc 100644
--- a/code/src/itest/pcgen/output/FreeMarkerTest.java
+++ b/code/src/itest/pcgen/output/FreeMarkerTest.java
@@ -1,16 +1,16 @@
/*
* Copyright (c) 2015 Tom Parker
- *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
@@ -39,7 +39,7 @@ public class FreeMarkerTest extends AbstractOutputTestCase
@BeforeEach
@Override
- public void setUp() throws Exception
+ public void setUp()
{
super.setUp();
CDOMWrapperInfoFacet wiFacet =
diff --git a/code/src/itest/pcgen/output/testsupport/AbstractOutputTestCase.java b/code/src/itest/pcgen/output/testsupport/AbstractOutputTestCase.java
index e207171f1da..7934faf3148 100644
--- a/code/src/itest/pcgen/output/testsupport/AbstractOutputTestCase.java
+++ b/code/src/itest/pcgen/output/testsupport/AbstractOutputTestCase.java
@@ -1,16 +1,16 @@
/*
* Copyright (c) 2014-15 Tom Parker
- *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
@@ -42,9 +42,9 @@ public abstract class AbstractOutputTestCase
{
protected DataSetID dsid;
protected CharID id;
-
+
@BeforeEach
- public void setUp() throws Exception
+ public void setUp()
{
Locale.setDefault(Locale.US);
dsid = DataSetID.getID();
diff --git a/code/src/java/pcgen/cdom/base/Constants.java b/code/src/java/pcgen/cdom/base/Constants.java
index 6c95580490c..bd602422eca 100644
--- a/code/src/java/pcgen/cdom/base/Constants.java
+++ b/code/src/java/pcgen/cdom/base/Constants.java
@@ -28,7 +28,6 @@
@SuppressWarnings("PMD.ConstantsInInterface")
public interface Constants
{
-
/********************************************************************
* Static definitions of Equipment location strings
********************************************************************/
@@ -111,7 +110,7 @@ public interface Constants
String INTERNAL_WEAPON_PROF = "PCGENi_WEAPON_PROFICIENCY"; //$NON-NLS-1$
/** Line Separator. */
- String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+ String LINE_SEPARATOR = System.lineSeparator(); //$NON-NLS-1$
/** The constant string "None". */
String NONE = "None"; //$NON-NLS-1$
diff --git a/code/src/java/pcgen/core/GameMode.java b/code/src/java/pcgen/core/GameMode.java
index 92df328e63f..40e188e26ea 100644
--- a/code/src/java/pcgen/core/GameMode.java
+++ b/code/src/java/pcgen/core/GameMode.java
@@ -187,7 +187,7 @@ public GameMode(final String modeName)
}
/**
- * Apply the stored preferences to the game mode.
+ * Apply the stored preferences to the game mode.
*/
public void applyPreferences()
{
@@ -240,7 +240,7 @@ public List getACTypeRemoveString(final String ACType)
}
/**
- * Retrieve the correct case of the supplied ACType name.
+ * Retrieve the correct case of the supplied ACType name.
* @param acType The name to be found.
* @return The name in the correct case.
*/
@@ -636,7 +636,7 @@ public Set getWeaponTypes()
/**
* Gets the abbreviation for the given weapon Type.
- *
+ *
* @param type
* The Type
* @return The abbreviation for the given Type
@@ -1939,7 +1939,7 @@ public void clearLoadContext()
* Takes references and abbreviations that have been placed into the
* LoadContext for this GameMode and copies those references and
* abbreviations into the given ReferenceContext
- *
+ *
* @param referenceContext
* The Reference Context into which the references from this
* GameMode should be copied.
@@ -1960,20 +1960,24 @@ static void resolveReferenceManufacturer(AbstractReferenceC
{
String identityName = rm.getPersistentFormat();
ReferenceManufacturer mfg = rc.getManufacturerByFormatName(identityName, rm.getReferenceClass());
- // If format fails, fall back to class
+ // If a format fails, fall back to class
if ((mfg == null) && (identityName.indexOf('=') == -1))
{
Class cl = rm.getReferenceClass();
mfg = rc.getManufacturer(cl);
}
- if (mfg!=null) {
- for (CDOMReference ref : rm.getAllReferences()) {
+ if (mfg != null)
+ {
+ for (CDOMReference ref : rm.getAllReferences())
+ {
((TransparentReference) ref).resolve(mfg);
}
rm.injectConstructed(mfg);
}
else
- System.out.println("idname="+identityName+" had a null mfg - skipping");
+ {
+ Logging.debugPrint("idname = " + identityName + " had a null mfg - skipping");
+ }
}
public LoadContext getContext()
@@ -2250,7 +2254,7 @@ public String getEquipTypeIcon(String equipType)
}
/**
- * Retrieve the priority of the listed type;s icon. A higher number means a higher
+ * Retrieve the priority of the listed type;s icon. A higher number means a higher
* priority, generally the highest priority icon will be used.
* @param equipType The equipment type
* @return The priority, or 0 if none is known.
diff --git a/code/src/java/pcgen/core/Globals.java b/code/src/java/pcgen/core/Globals.java
index 15b8e1caeaf..c6ef2a83378 100644
--- a/code/src/java/pcgen/core/Globals.java
+++ b/code/src/java/pcgen/core/Globals.java
@@ -540,8 +540,8 @@ public static void clearCampaignsForRefresh()
/**
* Check if enough data has been loaded to support character creation.
- * Will also report to the log the number of items of each of the
- * necessary types that are currently loaded.
+ * Will also report to the log the number of items of each of the
+ * necessary types that are currently loaded.
* @return true or false
*/
public static boolean displayListsHappy()
@@ -722,7 +722,7 @@ public static boolean selectPaper(final String paperName)
}
/**
- * Apply the user's preferences to the initial state of the Globals.
+ * Apply the user's preferences to the initial state of the Globals.
*/
public static void initPreferences()
{
@@ -789,8 +789,8 @@ static List extends CDOMObject> sortPObjectList(final List extends CDOMObjec
/**
* Sort Pcgen Object list by name
- * @param
- *
+ * @param
+ *
* @param aList
* @return Sorted list of Pcgen Objects
*/
@@ -1033,7 +1033,7 @@ else if (fType.equals("mac_user"))
private static int bonusParsing(final String l, final int level, int num, final PlayerCharacter aPC)
{
- // should be in format levelnum,rangenum[,numchoices]
+ // should be in format levelnum,rangenum[,numchoices]
final StringTokenizer aTok = new StringTokenizer(l, "|", false);
final int startLevel = Integer.parseInt(aTok.nextToken());
final String rangeLevelFormula = aTok.nextToken();
diff --git a/code/src/java/pcgen/core/PlayerCharacter.java b/code/src/java/pcgen/core/PlayerCharacter.java
index cde653a123c..447da86e5d5 100644
--- a/code/src/java/pcgen/core/PlayerCharacter.java
+++ b/code/src/java/pcgen/core/PlayerCharacter.java
@@ -501,7 +501,7 @@ public class PlayerCharacter implements Cloneable, VariableContainer
private final CNAbility bonusLanguageAbility =
CNAbilityFactory.getCNAbility(AbilityCategory.LANGBONUS, Nature.VIRTUAL, Globals.getContext()
- .getReferenceContext().getManufacturerId(AbilityCategory.LANGBONUS).getActiveObject("*LANGBONUS"));
+ .getReferenceContext().getManufacturerId(AbilityCategory.LANGBONUS).getActiveObject("*LANGBONUS"));
private final CodeControl controller;
private Map previewSheetVars = new HashMap<>();
@@ -576,8 +576,8 @@ public PlayerCharacter(Collection loadedCampaigns)
setXPTable(SettingsHandler.getGameAsProperty().get().getDefaultXPTableName());
ChannelUtilities.setControlledChannel(id, CControl.CHARACTERTYPE,
- SettingsHandler.getGameAsProperty().get()
- .getDefaultCharacterType());
+ SettingsHandler.getGameAsProperty().get()
+ .getDefaultCharacterType());
setPreviewSheet(SettingsHandler.getGameAsProperty().get().getDefaultPreviewSheet());
setName(Constants.EMPTY_STRING);
@@ -593,8 +593,8 @@ public PlayerCharacter(Collection loadedCampaigns)
* well as setting the proficiency, this zeros out the Weight and cost of
* the equipment.
*
- * @param equip the Weapon to get the proficiency from
- * @param eqm the weapon to set the proficiency in
+ * @param equip the Weapon to get the proficiency from
+ * @param eqm the weapon to set the proficiency in
*/
private static void setProf(final Equipment equip, final Equipment eqm)
{
@@ -643,7 +643,8 @@ private void deityWatchSetup(LoadContext context)
ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, FacetLibrary.getFacet(DeityWeaponProfFacet.class));
ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, FacetLibrary.getFacet(KitChoiceFacet.class));
ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, FacetLibrary.getFacet(RemoveFacet.class));
- ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, FacetLibrary.getFacet(BonusActiviationFacet.class), 1000);
+ ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, FacetLibrary.getFacet(BonusActiviationFacet.class),
+ 1000);
ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, FacetLibrary.getFacet(CalcBonusFacet.class), 5000);
ChannelUtilities.watchChannel(this, CControl.DEITYINPUT, moveResultFacet, 2000);
}
@@ -666,7 +667,7 @@ public void setWeight(int value)
/**
* Sets player character information
*
- * @param attr which attribute to set
+ * @param attr which attribute to set
* @param value the value to set it to
*/
public void setPCAttribute(PCStringKey attr, String value)
@@ -839,8 +840,7 @@ public void setCalcEquipmentList(final boolean useTempBonuses)
eq.put(ObjectKey.CURRENT_COST, BigDecimal.ZERO);
eq.put(ObjectKey.WEIGHT, BigDecimal.ZERO);
eq.setLocation(anEquip.getLocation());
- }
- else
+ } else
{
// replace the orig item with the bonus item
eq.setLocation(anEquip.getLocation());
@@ -852,8 +852,7 @@ public void setCalcEquipmentList(final boolean useTempBonuses)
eq.setIsEquipped(true, this);
eq.setNumberEquipped(1);
- }
- else
+ } else
{
eq.put(ObjectKey.CURRENT_COST, BigDecimal.ZERO);
eq.put(ObjectKey.WEIGHT, BigDecimal.ZERO);
@@ -931,6 +930,7 @@ public List getClassList()
/**
* Gets the Set of PCClass objects for this Character.
+ *
* @return a set of PCClass objects
*/
public Set getClassSet()
@@ -1058,6 +1058,7 @@ private Set getEquipmentSet()
/**
* Get the character's "equipped" equipment.
+ *
* @return a set of the "equipped" equipment
*/
public Set getEquippedEquipmentSet()
@@ -1083,12 +1084,11 @@ public List getEquipmentListInOutputOrder()
* ascending order of the equipment's outputIndex field. If multiple items
* of equipment have the same outputIndex they will be ordered by name. Note
* hidden items (outputIndex = -1) are not included in this list.
- *
+ *
* Deals with merge as well. See the Constants package for acceptable values
* of merge .
*
* @param merge controls how much merging is done.
- *
* @return An ArrayList of the equipment objects in output order.
*/
public List getEquipmentListInOutputOrder(final int merge)
@@ -1112,30 +1112,28 @@ public List getEquipmentMasterList()
/**
* Search for a piece of equipment in the specified list by name.
- *
+ *
* TODO - This does not belong in PlayerCharacter. Move to Equipment if
* needed.
- *
+ *
* TODO - This probably won't work with i18n. Should always search by key.
*
- * @param aString
- * The name of the equipment.
- * @param aList
- * The Collection of equipment to search in.
- *
+ * @param aString The name of the equipment.
+ * @param aList The Collection of equipment to search in.
* @return The Equipment object or null
*/
private static Equipment getEquipmentNamed(final String aString, final Collection aList)
{
return aList.stream()
- .filter(eq -> aString.equalsIgnoreCase(eq.getName()))
- .findFirst()
- .orElse(null);
+ .filter(eq -> aString.equalsIgnoreCase(eq.getName()))
+ .findFirst()
+ .orElse(null);
}
/**
* Search among the PCs equipment for a named piece of equipment.
+ *
* @param name The name of the piece of equipment.
* @return null or the equipment named.
*/
@@ -1147,8 +1145,7 @@ public Equipment getEquipmentNamed(final String name)
/**
* Set the characters eye colour.
*
- * @param aString
- * the colour of their eyes
+ * @param aString the colour of their eyes
*/
public void setEyeColor(final String aString)
{
@@ -1242,6 +1239,7 @@ private double getBonusFeatPool()
}
return bonus;
}
+
/**
* Sets the filename of the character.
*
@@ -1279,8 +1277,7 @@ public Collection getFollowerList()
* The gender will only be changed if the character does not have a template
* that locks the character's gender.
*
- * @param g
- * A gender to try and set.
+ * @param g A gender to try and set.
*/
public void setGender(final Gender g)
{
@@ -1302,8 +1299,7 @@ public void setGender(final Gender g)
*
* TODO - This is pretty dangerous.
*
- * @param newIsImporting
- * true to mark the character as being imported.
+ * @param newIsImporting true to mark the character as being imported.
*/
public void setImporting(final boolean newIsImporting)
{
@@ -1330,8 +1326,7 @@ public Set getLanguageSet()
* be driven off types but now it's driven from a list of companion mods
* but the java doc has not been updated.
*
- * @param compList
- * A list of companionMods to get level for
+ * @param compList A list of companionMods to get level for
* @return The effective level for this companion type
*/
public int getEffectiveCompanionLevel(final CompanionList compList)
@@ -1370,8 +1365,7 @@ public int getEffectiveCompanionLevel(final CompanionList compList)
* on the masters level and info contained in the companionModList Array
* such as HitDie, SR, BONUS, SA, etc.
*
- * @param aM
- * The master to be set.
+ * @param aM The master to be set.
*/
public void setMaster(final Follower aM)
{
@@ -1406,7 +1400,7 @@ public void setMaster(final Follower aM)
boolean found = false;
for (CompanionMod cMod : Globals.getContext().getReferenceContext().getManufacturerId(aM.getType())
- .getAllObjects())
+ .getAllObjects())
{
if ((cMod.getLevelApplied(mClass) > 0) && !found)
{
@@ -1422,7 +1416,7 @@ public void setMaster(final Follower aM)
Collection oldCompanionMods = companionModFacet.removeAll(id);
for (CompanionMod cMod : Globals.getContext().getReferenceContext().getManufacturerId(aM.getType())
- .getAllObjects())
+ .getAllObjects())
{
// Check all the masters classes
for (PCClass mClass : mPC.getClassSet())
@@ -1597,8 +1591,7 @@ public void setMaster(final Follower aM)
* the given companion list. This method does not adjust for any followers
* already selected by the character.
*
- * @param cList
- * A list of potential follower races
+ * @param cList A list of potential follower races
* @return The max number of followers -1 for any number
*/
public int getMaxFollowers(CompanionList cList)
@@ -1677,8 +1670,7 @@ public PlayerCharacter getMasterPC()
/**
* Sets the character's name.
*
- * @param aString
- * A name to set.
+ * @param aString A name to set.
*/
public final void setName(final String aString)
{
@@ -1710,7 +1702,7 @@ public List getNamedTempBonusList()
* Takes all the Temporary Bonuses and Merges them into just the unique
* named bonuses.
*
- * @return List of Strings
+ * @return List of Strings
*/
public List getNamedTempBonusDescList()
{
@@ -1719,6 +1711,7 @@ public List getNamedTempBonusDescList()
/**
* Set the value of the feat pool.
+ *
* @param pool value to set the feat pool to
*/
public void setPoolAmount(final int pool)
@@ -1728,6 +1721,7 @@ public void setPoolAmount(final int pool)
/**
* Get the value of the feat pool.
+ *
* @return the feat pool amount
*/
public int getPoolAmount()
@@ -1738,8 +1732,7 @@ public int getPoolAmount()
/**
* Selector Sets the path to the portrait of the character.
*
- * @param newPortraitPath
- * the path to the portrait file
+ * @param newPortraitPath the path to the portrait file
*/
public void setPortraitPath(final String newPortraitPath)
{
@@ -1748,6 +1741,7 @@ public void setPortraitPath(final String newPortraitPath)
/**
* Set a new outline for the portrait thumbnail.
+ *
* @param rect The thumbnail outline.
*/
public void setPortraitThumbnailRect(Rectangle rect)
@@ -1943,8 +1937,7 @@ public ArrayList getSpecialAbilityTimesList()
numTimes[j]++;
}
}
- }
- else
+ } else
{
sortList.add(ability);
numTimes[i] = 1;
@@ -1968,8 +1961,7 @@ public ArrayList getSpecialAbilityTimesList()
/**
* Set the name of the spellbook to auto add new known spells to.
*
- * @param aString
- * The new spellbook name.
+ * @param aString The new spellbook name.
*/
public void setSpellBookNameToAutoAddKnown(final String aString)
{
@@ -1989,8 +1981,7 @@ public String getSpellBookNameToAutoAddKnown()
/**
* Retrieve a spell book object given the name of the spell book.
*
- * @param name
- * The name of the spell book to be retrieved.
+ * @param name The name of the spell book to be retrieved.
* @return The spellbook (or null if not present).
*/
public SpellBook getSpellBookByName(final String name)
@@ -2080,6 +2071,7 @@ public void unsetTempBonusFilter(final String aBonusStr)
/**
* Get a set of the templates applies to this pc.
+ *
* @return the set of Templates.
*/
public Collection getTemplateSet()
@@ -2089,12 +2081,12 @@ public Collection getTemplateSet()
/**
* Evaluates the variable string passed in and returns its value.
- *
+ *
* This should probably be refactored to return a String instead.
*
* @param variableString the variable to evaluate
- * @param isMax if multiple values are stored, whether to return the largest value
- * found or the first.
+ * @param isMax if multiple values are stored, whether to return the largest value
+ * found or the first.
* @return the value of the variable.
*/
public Float getVariable(final String variableString, final boolean isMax)
@@ -2108,9 +2100,9 @@ public Float getVariable(final String variableString, final boolean isMax)
{
if (Logging.isDebugMode())
{
- final String sb = "This is a deliberate warning message, not an error - "
- + "Avoiding infinite loop in getVariable: repeated lookup " + "of \"" + lastVariable + "\" at "
- + value;
+ String sb = "This is a deliberate warning message, not an error - "
+ + "Avoiding infinite loop in getVariable: repeated lookup " + "of \"" + lastVariable
+ + "\" at " + value;
Logging.debugPrint(sb);
}
lastVariable = null;
@@ -2127,8 +2119,7 @@ public Float getVariable(final String variableString, final boolean isMax)
value = val;
found = true;
}
- }
- catch (IllegalArgumentException e)
+ } catch (IllegalArgumentException e)
{
//This variable is not in the data - must be builtin?
}
@@ -2162,15 +2153,14 @@ public int getPointBuyPoints()
/**
* Sets the total Experience Points for the Player Character to the given value.
- *
+ *
* Note this sets earned Experience Points as a side effect (calculated based on the
* level-adjusted Experience Points the Player Character may have). If the given xp
* value is less than the level-adjusted Experience Points possessed by the Player
* Character, then an error will be logged, and the earned Experience Points will be
* set to 0.
*
- * @param xp
- * The total Experience Points for the Player Character
+ * @param xp The total Experience Points for the Player Character
*/
public void setXP(int xp)
{
@@ -2248,8 +2238,7 @@ public void addEquipSet(final EquipSet set)
/**
* Add an item of equipment to the character.
*
- * @param eq
- * The equipment to be added.
+ * @param eq The equipment to be added.
*/
public void addEquipment(final Equipment eq)
{
@@ -2260,6 +2249,7 @@ public void addEquipment(final Equipment eq)
/**
* Cache the output index of an automatic equipment item.
+ *
* @param item The equipment item.
*/
public void cacheOutputIndex(Equipment item)
@@ -2279,12 +2269,9 @@ public void cacheOutputIndex(Equipment item)
* Mostly concerned with ensuring that the spellbook objects remain in sync
* with the number of equipment spellbooks.
*
- * @param eq
- * The Equipment being updated.
- * @param oldQty
- * The original number of items.
- * @param newQty
- * The new number of items.
+ * @param eq The Equipment being updated.
+ * @param oldQty The original number of items.
+ * @param newQty The new number of items.
*/
public void updateEquipmentQty(final Equipment eq, double oldQty, double newQty)
{
@@ -2362,6 +2349,7 @@ public TempBonusInfo addTempBonus(final BonusObj aBonus, Object source, Object t
/**
* Add a piece of equipment to the temporary bonus list.
+ *
* @param aEq The piece of equipment to add.
*/
public void addTempBonusItemList(final Equipment aEq)
@@ -2373,7 +2361,7 @@ public void addTempBonusItemList(final Equipment aEq)
/**
* Compute the total bonus from a List of BonusObjs.
*
- * @param aList The list of objects
+ * @param aList The list of objects
* @param source The source of the bonus objects.
* @return The aggregate bonus
*/
@@ -2391,6 +2379,7 @@ public double calcBonusFromList(final List aList, CDOMObject source)
/**
* Checks that the parameter passed in is in the list of objects for which this PC qualifies.
+ *
* @param obj the object to test for qualification.
* @return true if the PC is qualified to have this object.
*/
@@ -2401,6 +2390,7 @@ public boolean checkQualifyList(CDOMObject obj)
/**
* Check whether this PC has this WeaponProf.
+ *
* @param wp The WeaponProf to check.
* @return True if the PC has the WeaponProf
*/
@@ -2411,6 +2401,7 @@ public boolean hasWeaponProf(final WeaponProf wp)
/**
* Remove an EqSet from the PC's Equipped Equipment.
+ *
* @param eSet - The EquipSet to remove.
* @return true if the object was removed.
*/
@@ -2423,6 +2414,7 @@ public boolean delEquipSet(final EquipSet eSet)
/**
* Remove a Follower from this PC.
+ *
* @param aFollower The follower to remove.
*/
public void delFollower(final Follower aFollower)
@@ -2433,6 +2425,7 @@ public void delFollower(final Follower aFollower)
/**
* Check whether the PC has this variable.
+ *
* @param variableString The variable to check for.
* @return True if the PC has the variable.
*/
@@ -2441,8 +2434,7 @@ public boolean hasVariable(final String variableString)
try
{
return variableFacet.contains(id, VariableKey.valueOf(variableString));
- }
- catch (IllegalArgumentException e)
+ } catch (IllegalArgumentException e)
{
//Built in variable
return false;
@@ -2450,7 +2442,6 @@ public boolean hasVariable(final String variableString)
}
/**
- *
* @param eq
*/
public void removeEquipment(final Equipment eq)
@@ -2466,7 +2457,6 @@ public void removeEquipment(final Equipment eq)
}
/**
- *
* @param eq
*/
private void removeLocalEquipment(final Equipment eq)
@@ -2503,16 +2493,11 @@ public String getAttackString(AttackType at, final int bonus)
* attacks generated. The second increases both the size and number of
* attacks
*
- * @param at
- * The type of attack. Takes an AttackType (an enumeration)
- *
- * @param TOHITBonus
- * A bonus that will be added to the TOHIT numbers. This bonus
- * affects only the numbers produced, not the number of attacks
- *
- * @param BABBonus
- * This bonus will be added to BAB before the number of attacks
- * has been determined.
+ * @param at The type of attack. Takes an AttackType (an enumeration)
+ * @param TOHITBonus A bonus that will be added to the TOHIT numbers. This bonus
+ * affects only the numbers produced, not the number of attacks
+ * @param BABBonus This bonus will be added to BAB before the number of attacks
+ * has been determined.
* @return The attack string for this character
*/
@@ -2618,8 +2603,7 @@ public String getAttackString(AttackType at, final int TOHITBonus, int BABBonus)
{
attackCycle = defaultAttackCycle;
attackTotal = subTotal;
- }
- else
+ } else
{
workingBAB -= raceBAB;
subTotal -= raceBAB;
@@ -2712,8 +2696,7 @@ public boolean getUseHigherKnownSlots()
* Set whether higher level known spell slots can be used for lower level
* spells, or if known spells are restricted to their own level only.
*
- * @param useHigher
- * Can higher level known spell slots be used?
+ * @param useHigher Can higher level known spell slots be used?
*/
public void setUseHigherKnownSlots(boolean useHigher)
{
@@ -2736,8 +2719,7 @@ public boolean getUseHigherPreppedSlots()
* Set whether higher level prepared spell slots can be used for lower level
* spells, or if prepared spells are restricted to their own level only.
*
- * @param useHigher
- * Can higher level prepared spell slots be used?
+ * @param useHigher Can higher level prepared spell slots be used?
*/
public void setUseHigherPreppedSlots(boolean useHigher)
{
@@ -2748,9 +2730,7 @@ public void setUseHigherPreppedSlots(boolean useHigher)
* Returns the "Base" check value for the check at the index
* specified.
*
- * @param check
- * The index of the check to get
- *
+ * @param check The index of the check to get
* @return The base check value.
*/
public int getBaseCheck(final PCCheck check)
@@ -2801,9 +2781,7 @@ public int getBaseCheck(final PCCheck check)
*
* This total includes all check bonuses the character has.
*
- * @param check
- * The check to get.
- *
+ * @param check The check to get.
* @return A check value.
*/
public int getTotalCheck(PCCheck check)
@@ -2834,11 +2812,9 @@ public double getBonusDueToType(final String mainType, final String subType, fin
* Retrieves an unsorted list of the character's equipment matching the
* supplied type and status criteria.
*
- * @param typeName
- * The type of equipment to be selected
- * @param status
- * The required status: 1 (equipped) 2 (not equipped) 3 (don't
- * care)
+ * @param typeName The type of equipment to be selected
+ * @param status The required status: 1 (equipped) 2 (not equipped) 3 (don't
+ * care)
* @return An ArrayList of the matching equipment objects.
*/
public List getEquipmentOfType(final String typeName, final int status)
@@ -2850,14 +2826,11 @@ public List getEquipmentOfType(final String typeName, final int statu
* Retrieves an unsorted list of the character's equipment matching the
* supplied type, sub type and status criteria.
*
- * @param typeName
- * The type of equipment to be selected
- * @param subtypeName
- * The subtype of equipment to be selected (empty string for no
- * subtype)
- * @param status
- * The required status: 1 (equipped) 2 (not equipped) 3 (don't
- * care)
+ * @param typeName The type of equipment to be selected
+ * @param subtypeName The subtype of equipment to be selected (empty string for no
+ * subtype)
+ * @param status The required status: 1 (equipped) 2 (not equipped) 3 (don't
+ * care)
* @return An ArrayList of the matching equipment objects.
*/
public List getEquipmentOfType(final String typeName, final String subtypeName, final int status)
@@ -2887,11 +2860,9 @@ public List getEquipmentOfType(final String typeName, final String su
* equipment have the same outputIndex they will be ordered by name. Note
* hidden items (outputIndex = -1) are not included in this list.
*
- * @param typeName
- * The type of equipment to be selected
- * @param status
- * The required status: 1 (equipped) 2 (not equipped) 3 (don't
- * care)
+ * @param typeName The type of equipment to be selected
+ * @param status The required status: 1 (equipped) 2 (not equipped) 3 (don't
+ * care)
* @return An ArrayList of the matching equipment objects in output order.
*/
public List getEquipmentOfTypeInOutputOrder(final String typeName, final int status)
@@ -2900,12 +2871,9 @@ public List getEquipmentOfTypeInOutputOrder(final String typeName, fi
}
/**
- * @param typeName
- * The type of equipment to be selected
- * @param status
- * The required status
- * @param merge
- * What type of merge for like equipment
+ * @param typeName The type of equipment to be selected
+ * @param status The required status
+ * @param merge What type of merge for like equipment
* @return An ArrayList of equipment objects
*/
public List getEquipmentOfTypeInOutputOrder(final String typeName, final int status, final int merge)
@@ -2914,18 +2882,14 @@ public List getEquipmentOfTypeInOutputOrder(final String typeName, fi
}
/**
- * @param typeName
- * The type of equipment to be selected
- * @param subtypeName
- * The subtype of equipment to be selected
- * @param status
- * The required status
- * @param merge
- * What sort of merging should occur
+ * @param typeName The type of equipment to be selected
+ * @param subtypeName The subtype of equipment to be selected
+ * @param status The required status
+ * @param merge What sort of merging should occur
* @return An ArrayList of equipment objects
*/
public List getEquipmentOfTypeInOutputOrder(final String typeName, final String subtypeName,
- final int status, final int merge)
+ final int status, final int merge)
{
return sortEquipmentList(getEquipmentOfType(typeName, subtypeName, status), merge);
}
@@ -2936,7 +2900,6 @@ public List getEquipmentOfTypeInOutputOrder(final String typeName, fi
* equipment depends on the passed in int
*
* @param merge The type of merge to perform
- *
* @return the sorted list of weapons.
*/
public List getExpandedWeapons(final int merge)
@@ -3054,8 +3017,7 @@ else if (equip.isMelee() && equip.isRanged())
if (replacedPrimary)
{
primaryWeaponFacet.addAfter(id, eqm, eqr);
- }
- else if (replacedSecondary)
+ } else if (replacedSecondary)
{
secondaryWeaponFacet.addAfter(id, eqm, eqr);
}
@@ -3196,7 +3158,7 @@ public int getMaxCharacterDomains()
* @param source
* @param aPC
* @return the number of Character Domains possible and check the level of
- * the source class if the result is 0.
+ * the source class if the result is 0.
*/
public int getMaxCharacterDomains(final PCClass source, final PlayerCharacter aPC)
{
@@ -3212,11 +3174,9 @@ public int getMaxCharacterDomains(final PCClass source, final PlayerCharacter aP
* Calculate the maximum number of ranks the character is allowed to have in
* the specified skill.
*
- * @param aSkill
- * The skill being checked.
- * @param aClass
- * The name of the current class in which points are being spent -
- * only used to check cross-class skill cost.
+ * @param aSkill The skill being checked.
+ * @param aClass The name of the current class in which points are being spent -
+ * only used to check cross-class skill cost.
* @return max rank
*/
public Float getMaxRank(Skill aSkill, final PCClass aClass)
@@ -3250,26 +3210,22 @@ public Float getMaxRank(Skill aSkill, final PCClass aClass)
levelForSkillPurposes = (getTotalLevels());
maxRanks = SkillUtilities.maxCrossClassSkillForLevel(levelForSkillPurposes, this);
- }
- else
+ } else
{
maxRanks = SkillUtilities.maxClassSkillForLevel(levelForSkillPurposes, this);
}
- }
- else if (!this.isClassSkill(aSkill) && (this.getSkillCostForClass(aSkill, aClass) == SkillCost.CLASS))
+ } else if (!this.isClassSkill(aSkill) && (this.getSkillCostForClass(aSkill, aClass) == SkillCost.CLASS))
{
// Cross class skill - but as cost is 1 only return a whole number
maxRanks =
new BigDecimal(
- SkillUtilities.maxCrossClassSkillForLevel(
- levelForSkillPurposes, this).intValue()); // This was (int) (i/2.0) previously
- }
- else if (!this.isClassSkill(aSkill))
+ SkillUtilities.maxCrossClassSkillForLevel(
+ levelForSkillPurposes, this).intValue()); // This was (int) (i/2.0) previously
+ } else if (!this.isClassSkill(aSkill))
{
// Cross class skill
maxRanks = SkillUtilities.maxCrossClassSkillForLevel(levelForSkillPurposes, this);
- }
- else
+ } else
{
// Class skill
maxRanks = SkillUtilities.maxClassSkillForLevel(levelForSkillPurposes, this);
@@ -3297,12 +3253,10 @@ public boolean isProficientWith(final Equipment eq)
if (eq.isShield())
{
return shieldProfFacet.isProficientWithShield(id, eq);
- }
- else if (eq.isArmor())
+ } else if (eq.isArmor())
{
return armorProfFacet.isProficientWithArmor(id, eq);
- }
- else if (eq.isWeapon())
+ } else if (eq.isWeapon())
{
return weaponProfFacet.isProficientWithWeapon(id, eq);
}
@@ -3322,8 +3276,7 @@ public final boolean setRace(final Race newRace)
if (newRace == null)
{
success = raceInputFacet.set(id, RaceUtilities.getUnselectedRace());
- }
- else
+ } else
{
success = raceInputFacet.set(id, newRace);
}
@@ -3375,8 +3328,7 @@ public double getSizeAdjustmentBonusTo(String aType, String aName)
/**
* Set the skill display filter
*
- * @param filter
- * The new filter
+ * @param filter The new filter
*/
public void setSkillFilter(final SkillFilter filter)
{
@@ -3395,7 +3347,7 @@ public SkillFilter getSkillFilter()
if (filter == null)
{
filter = SkillFilter.getByValue(PCGenSettings.OPTIONS_CONTEXT.initInt(PCGenSettings.OPTION_SKILL_FILTER,
- SkillFilter.Usable.getValue()));
+ SkillFilter.Usable.getValue()));
if (filter == SkillFilter.SkillsTab)
{
filter = SkillFilter.Usable;
@@ -3408,8 +3360,7 @@ public SkillFilter getSkillFilter()
/**
* Set the order in which skills should be sorted for output.
*
- * @param i
- * The new output order
+ * @param i The new output order
*/
public void setSkillsOutputOrder(final SkillsOutputOrder i)
{
@@ -3445,11 +3396,9 @@ public boolean isSpellCaster(final int minLevel)
* and see if they are a spell caster and of the total of all of their
* spellcasting levels is at least the desired caster level.
*
- * @param minLevel
- * The desired caster level
- * @param sumOfLevels
- * True if all of the character caster levels should be added
- * together before the comparison.
+ * @param minLevel The desired caster level
+ * @param sumOfLevels True if all of the character caster levels should be added
+ * together before the comparison.
* @return boolean
*/
public int isSpellCaster(final int minLevel, final boolean sumOfLevels)
@@ -3462,13 +3411,10 @@ public int isSpellCaster(final int minLevel, final boolean sumOfLevels)
* and see if they are a spell caster of the desired type and of the desired
* caster level.
*
- * @param spellType
- * The type of spellcaster (i.e. "Arcane" or "Divine")
- * @param minLevel
- * The desired caster level
- * @param sumLevels
- * True if all of the character caster levels should be added
- * together before the comparison.
+ * @param spellType The type of spellcaster (i.e. "Arcane" or "Divine")
+ * @param minLevel The desired caster level
+ * @param sumLevels True if all of the character caster levels should be added
+ * together before the comparison.
* @return boolean
*/
public int isSpellCaster(final String spellType, final int minLevel, final boolean sumLevels)
@@ -3482,7 +3428,7 @@ public int isSpellCaster(final String spellType, final int minLevel, final boole
{
int classLevels = (int) getTotalBonusTo("CASTERLEVEL", pcClass.getKeyName());
if ((classLevels == 0) && (canCastSpellTypeLevel(pcClass.getSpellType(), 0)
- || canCastSpellTypeLevel(pcClass.getSpellType(), 1)))
+ || canCastSpellTypeLevel(pcClass.getSpellType(), 1)))
{
// missing CASTERLEVEL hack
classLevels = getLevel(pcClass);
@@ -3491,8 +3437,7 @@ public int isSpellCaster(final String spellType, final int minLevel, final boole
if (sumLevels)
{
runningTotal += classLevels;
- }
- else
+ } else
{
if (classLevels >= minLevel)
{
@@ -3527,10 +3472,8 @@ public void getSpellList()
* Parses a spells range (short, medium or long) into an Integer based on
* the spell and spell casters level
*
- * @param aSpell
- * The spell being output.
- * @param si
- * The info about conditions applied to the spell
+ * @param aSpell The spell being output.
+ * @param si The info about conditions applied to the spell
* @return spell range
*/
public String getSpellRange(final CharacterSpell aSpell, final SpellInfo si)
@@ -3543,12 +3486,10 @@ public String getSpellRange(final CharacterSpell aSpell, final SpellInfo si)
if (aRange.equalsIgnoreCase("CLOSE") && (aString == null))
{
aString = "((CASTERLEVEL/2).TRUNC*5)+25"; //$NON-NLS-1$
- }
- else if (aRange.equalsIgnoreCase("MEDIUM") && (aString == null))
+ } else if (aRange.equalsIgnoreCase("MEDIUM") && (aString == null))
{
aString = "(CASTERLEVEL*10)+100"; //$NON-NLS-1$
- }
- else if (aRange.equalsIgnoreCase("LONG") && (aString == null))
+ } else if (aRange.equalsIgnoreCase("LONG") && (aString == null))
{
aString = "(CASTERLEVEL*40)+400"; //$NON-NLS-1$
}
@@ -3577,9 +3518,8 @@ else if (aRange.equalsIgnoreCase("LONG") && (aString == null))
}
aRange += (" (" + Globals.getGameModeUnitSet().displayDistanceInUnitSet(rangeInFeet)
- + Globals.getGameModeUnitSet().getDistanceUnit() + ')');
- }
- else
+ + Globals.getGameModeUnitSet().getDistanceUnit() + ')');
+ } else
{
aRange = parseSpellString(aSpell, aRange);
}
@@ -3641,10 +3581,8 @@ public double getTemplateBonusTo(String aType, String aName)
* companions, Equipment, Feats, Templates, Domains, Races, etc This value
* is taken from an already populated HashMap for speed
*
- * @param bonusType
- * Type of bonus ("COMBAT" or "SKILL")
- * @param bonusName
- * Name of bonus ("AC" or "Hide");
+ * @param bonusType Type of bonus ("COMBAT" or "SKILL")
+ * @param bonusName Name of bonus ("AC" or "Hide");
* @return total bonus to
*/
public double getTotalBonusTo(final String bonusType, final String bonusName)
@@ -3661,12 +3599,9 @@ public int getTotalLevels()
* Get the value of the desired stat at the point just before the character
* was raised to the next level.
*
- * @param stat
- * The Stat to check.
- * @param level
- * The level we want to see the stat at.
- * @param includePost
- * Should stat mods that occurred after levelling be included?
+ * @param stat The Stat to check.
+ * @param level The level we want to see the stat at.
+ * @param includePost Should stat mods that occurred after levelling be included?
* @return The stat as it was at the level
*/
public int getTotalStatAtLevel(final PCStat stat, final int level, final boolean includePost)
@@ -3712,10 +3647,8 @@ public boolean getUseTempMods()
* Evaluates a variable for this character e.g:
* getVariableValue("3+CHA","CLASS:Cleric") for Turn Undead
*
- * @param aString
- * The variable to be evaluated
- * @param src
- * The source within which the variable is evaluated
+ * @param aString The variable to be evaluated
+ * @param src The source within which the variable is evaluated
* @return The value of the variable
*/
public Float getVariableValue(final String aString, final String src)
@@ -3733,13 +3666,10 @@ public Float getVariableValue(final String varName, final String src, final Play
* Evaluates a variable for this character e.g:
* getVariableValue("3+CHA","CLASS:Cleric") for Turn Undead
*
- * @param aSpell
- * This is specifically to compute bonuses to CASTERLEVEL for a
- * specific spell.
- * @param aString
- * The variable to be evaluated
- * @param src
- * The source within which the variable is evaluated
+ * @param aSpell This is specifically to compute bonuses to CASTERLEVEL for a
+ * specific spell.
+ * @param aString The variable to be evaluated
+ * @param src The source within which the variable is evaluated
* @return The value of the variable
*/
private Float getVariableValue(final CharacterSpell aSpell, String aString, String src)
@@ -3756,7 +3686,7 @@ public VariableProcessor getVariableProcessor()
}
public int getTotalCasterLevelWithSpellBonus(CharacterSpell acs, final Spell aSpell, final String spellType,
- final String classOrRace, final int casterLev)
+ final String classOrRace, final int casterLev)
{
if (aSpell != null && acs.getFixedCasterLevel() != null)
{
@@ -3975,7 +3905,7 @@ public int getTotalCasterLevelWithSpellBonus(CharacterSpell acs, final Spell aSp
}
private static int tallyCasterlevelBonuses(final int casterLev, boolean replaceCasterLevel,
- final List bonuses)
+ final List bonuses)
{
// now go through all bonuses, checking types to see what should add
// together
@@ -3995,8 +3925,7 @@ private static int tallyCasterlevelBonuses(final int casterLev, boolean replaceC
{
zType = zType.substring(0, zType.length() - 8);
zReplace = true;
- }
- else
+ } else
{
if (zType.endsWith(".STACK"))
{
@@ -4021,8 +3950,7 @@ private static int tallyCasterlevelBonuses(final int casterLev, boolean replaceC
{
kType = kType.substring(0, kType.length() - 8);
kReplace = true;
- }
- else
+ } else
{
if (kType.endsWith(".STACK"))
{
@@ -4055,8 +3983,7 @@ private static int tallyCasterlevelBonuses(final int casterLev, boolean replaceC
if (zBonus.getBonus() > kBonus.getBonus())
{
kBonus.setBonus(0);
- }
- else
+ } else
{
zBonus.setBonus(0);
}
@@ -4111,8 +4038,7 @@ public List addEqType(final List aList, final String aType
/**
* Adds a Kit to the applied list of kits for the character.
*
- * @param aKit
- * The Kit to add.
+ * @param aKit The Kit to add.
*/
public void addKit(final Kit aKit)
{
@@ -4121,28 +4047,21 @@ public void addKit(final Kit aKit)
}
/**
- * @param acs
- * is the CharacterSpell object containing the spell which is to
- * be modified
- * @param aFeatList
- * is the list of feats to be added to the SpellInfo object
- * @param classKey
- * is the name of the class whose list of character spells will
- * be modified
- * @param bookName
- * is the name of the book for the SpellInfo object
- * @param spellLevel
- * is the original (unadjusted) level of the spell not including
- * feat adjustments
- * @param adjSpellLevel
- * is the adjustedLevel (including feat adjustments) of this
- * spell, it may be higher if the user chooses a higher level.
- *
+ * @param acs is the CharacterSpell object containing the spell which is to
+ * be modified
+ * @param aFeatList is the list of feats to be added to the SpellInfo object
+ * @param classKey is the name of the class whose list of character spells will
+ * be modified
+ * @param bookName is the name of the book for the SpellInfo object
+ * @param spellLevel is the original (unadjusted) level of the spell not including
+ * feat adjustments
+ * @param adjSpellLevel is the adjustedLevel (including feat adjustments) of this
+ * spell, it may be higher if the user chooses a higher level.
* @return an empty string on successful completion, otherwise the return
- * value indicates the reason the add function failed.
+ * value indicates the reason the add function failed.
*/
public String addSpell(CharacterSpell acs, final List aFeatList, final String classKey,
- final String bookName, final int adjSpellLevel, final int spellLevel)
+ final String bookName, final int adjSpellLevel, final int spellLevel)
{
if (acs == null)
{
@@ -4178,11 +4097,11 @@ public String addSpell(CharacterSpell acs, final List aFeatList, final
if (aClass == null && spellBook.getType() == SpellBook.TYPE_SPELL_BOOK)
{
aClass = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class,
- classKey);
+ classKey);
if ((aClass == null) && (classKey.lastIndexOf('(') >= 0))
{
aClass = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class,
- classKey.substring(0, classKey.lastIndexOf('(')).trim());
+ classKey.substring(0, classKey.lastIndexOf('(')).trim());
}
}
@@ -4218,7 +4137,7 @@ public String addSpell(CharacterSpell acs, final List aFeatList, final
// But if a spell is both prohibited and in a speciality
// which can be the case for some spells, then allow it.
if (spellBook.getType() != SpellBook.TYPE_SPELL_BOOK && !acs.isSpecialtySpell(this)
- && SpellCountCalc.isProhibited(aSpell, aClass, this))
+ && SpellCountCalc.isProhibited(aSpell, aClass, this))
{
return acs.getSpell().getDisplayName() + " is prohibited.";
}
@@ -4255,10 +4174,10 @@ public String addSpell(CharacterSpell acs, final List aFeatList, final
// Explicitly should *not* set the dirty flag to true.
spellLevelTemp = spellLevel;
/*
- * TODO Need to understand more about this context of formula
- * resolution (in context of a spell??) in order to understand how
- * to put this method into the Formula interface
- */
+ * TODO Need to understand more about this context of formula
+ * resolution (in context of a spell??) in order to understand how
+ * to put this method into the Formula interface
+ */
numPages = getVariableValue(acs, spellBook.getPageFormula().toString(), "").intValue();
// Check number of pages remaining in the book
if (numPages + spellBook.getNumPagesUsed() > spellBook.getNumPages())
@@ -4267,9 +4186,8 @@ public String addSpell(CharacterSpell acs, final List aFeatList, final
}
spellBook.setNumPagesUsed(numPages + spellBook.getNumPagesUsed());
spellBook.setNumSpells(spellBook.getNumSpells() + 1);
- }
- else if (!aClass.getSafe(ObjectKey.MEMORIZE_SPELLS)
- && !availableSpells(adjSpellLevel, aClass, bookName, true, acs.isSpecialtySpell(this)))
+ } else if (!aClass.getSafe(ObjectKey.MEMORIZE_SPELLS)
+ && !availableSpells(adjSpellLevel, aClass, bookName, true, acs.isSpecialtySpell(this)))
{
String ret;
int maxAllowed;
@@ -4278,11 +4196,10 @@ else if (!aClass.getSafe(ObjectKey.MEMORIZE_SPELLS)
{
ret = "Your remaining slot(s) must be filled with your speciality.";
maxAllowed = known;
- }
- else
+ } else
{
ret = "You can only learn " + (known + specialKnown) + " spells for level " + adjSpellLevel
- + " \nand there are no higher-level slots available.";
+ + " \nand there are no higher-level slots available.";
maxAllowed = known + specialKnown;
}
int memTot = SpellCountCalc.memorizedSpellForLevelBook(this, aClass, adjSpellLevel, bookName);
@@ -4292,9 +4209,8 @@ else if (!aClass.getSafe(ObjectKey.MEMORIZE_SPELLS)
ret += "\n" + spellDifference + " spells from lower levels are using slots for this level.";
}
return ret;
- }
- else if (aClass.getSafe(ObjectKey.MEMORIZE_SPELLS) && !isDefault
- && !availableSpells(adjSpellLevel, aClass, bookName, false, acs.isSpecialtySpell(this)))
+ } else if (aClass.getSafe(ObjectKey.MEMORIZE_SPELLS) && !isDefault
+ && !availableSpells(adjSpellLevel, aClass, bookName, false, acs.isSpecialtySpell(this)))
{
String ret;
int maxAllowed;
@@ -4302,16 +4218,14 @@ else if (aClass.getSafe(ObjectKey.MEMORIZE_SPELLS) && !isDefault
{
ret = "Your remaining slot(s) must be filled with your speciality or domain.";
maxAllowed = this.getSpellSupport(aClass).getCastForLevel(adjSpellLevel, bookName, false, true, this);
- }
- else if (acs.isSpecialtySpell(this) && availableSpells(adjSpellLevel, aClass, bookName, false, false))
+ } else if (acs.isSpecialtySpell(this) && availableSpells(adjSpellLevel, aClass, bookName, false, false))
{
ret = "Your remaining slot(s) must be filled with spells not from your speciality or domain.";
maxAllowed = this.getSpellSupport(aClass).getCastForLevel(adjSpellLevel, bookName, false, true, this);
- }
- else
+ } else
{
ret = "You can only prepare " + cast + " spells for level " + adjSpellLevel
- + " \nand there are no higher-level slots available.";
+ + " \nand there are no higher-level slots available.";
maxAllowed = cast;
int memTot = SpellCountCalc.memorizedSpellForLevelBook(this, aClass, adjSpellLevel, bookName);
int spellDifference = maxAllowed - memTot;
@@ -4349,8 +4263,7 @@ else if (acs.isSpecialtySpell(this) && availableSpells(adjSpellLevel, aClass, bo
{
final CharacterSpell tcs = acsList.get(0);
si = tcs.getSpellInfoFor(bookName, adjSpellLevel, aFeatList);
- }
- else
+ } else
{
si = acs.getSpellInfoFor(bookName, adjSpellLevel, aFeatList);
}
@@ -4367,14 +4280,12 @@ else if (acs.isSpecialtySpell(this) && availableSpells(adjSpellLevel, aClass, bo
+ "You cannot place spells in multiple times.";
}
si.setTimes(si.getTimes() + 1);
- }
- else
+ } else
{
if (isEmpty && !containsCharacterSpell(aClass, acs))
{
addCharacterSpell(aClass, acs);
- }
- else if (isEmpty)
+ } else if (isEmpty)
{
// Make sure that we are working on the same spell object, not just the same spell
for (CharacterSpell characterSpell : getCharacterSpells(aClass))
@@ -4472,7 +4383,7 @@ public boolean addTemplate(final PCTemplate inTemplate)
final int formerGained = pi.getSkillPointsGained(this);
pi.setSkillPointsGained(this, newSkillPointsGained);
pi.setSkillPointsRemaining(
- pi.getSkillPointsRemaining() + newSkillPointsGained - formerGained);
+ pi.getSkillPointsRemaining() + newSkillPointsGained - formerGained);
setSkillPool(pcClass, pcClass.getSkillPool(this) + newSkillPointsGained - formerGained);
}
}
@@ -4514,7 +4425,7 @@ public void adjustMoveRates()
}
public List aggregateSpellList(final String school, final String subschool, final String descriptor,
- final int minLevel, final int maxLevel)
+ final int minLevel, final int maxLevel)
{
final List retList = new ArrayList<>();
@@ -4526,11 +4437,11 @@ public List aggregateSpellList(final String school, final String subschoo
{
final Spell aSpell = cs.getSpell();
SpellSchool ss = Globals.getContext().getReferenceContext()
- .silentlyGetConstructedCDOMObject(SpellSchool.class, school);
+ .silentlyGetConstructedCDOMObject(SpellSchool.class, school);
if ((school.isEmpty()) || (ss != null) && aSpell.containsInList(ListKey.SPELL_SCHOOL, ss)
- || (subschool.isEmpty()) || aSpell.containsInList(ListKey.SPELL_SUBSCHOOL, subschool)
- || (descriptor.isEmpty()) || aSpell.containsInList(ListKey.SPELL_DESCRIPTOR, descriptor))
+ || (subschool.isEmpty()) || aSpell.containsInList(ListKey.SPELL_SUBSCHOOL, subschool)
+ || (descriptor.isEmpty()) || aSpell.containsInList(ListKey.SPELL_DESCRIPTOR, descriptor))
{
retList.add(aSpell);
}
@@ -4648,7 +4559,7 @@ public int calcSR(final boolean includeEquipment)
for (Equipment eq : getEquippedEquipmentSet())
{
SR = Math.max(SR,
- eq.getSafe(ObjectKey.SR).getReduction().resolve(this, eq.getQualifiedKey()).intValue());
+ eq.getSafe(ObjectKey.SR).getReduction().resolve(this, eq.getQualifiedKey()).intValue());
for (EquipmentModifier eqMod : eq.getEqModifierList(true))
{
@@ -4680,12 +4591,10 @@ public int calcSR(final boolean includeEquipment)
* Method will go through the list of classes that the PC has and see if
* they can cast spells of desired type at desired spell level.
*
- * @param spellType
- * Spell type to check for
- * @param spellLevel
- * Desired spell level
+ * @param spellType Spell type to check for
+ * @param spellLevel Desired spell level
* @return boolean
author David Wilson
- *
+ *
*/
private boolean canCastSpellTypeLevel(final String spellType, final int spellLevel)
{
@@ -4694,7 +4603,7 @@ private boolean canCastSpellTypeLevel(final String spellType, final int spellLev
FactKey fk = FactKey.valueOf("SpellType");
String classSpellType = aClass.getResolved(fk);
if (classSpellType != null
- && ("Any".equalsIgnoreCase(spellType) || classSpellType.equalsIgnoreCase(spellType)))
+ && ("Any".equalsIgnoreCase(spellType) || classSpellType.equalsIgnoreCase(spellType)))
{
// Get the number of known spells for the level
int knownForLevel = this.getSpellSupport(aClass).getKnownForLevel(spellLevel, this);
@@ -4715,7 +4624,7 @@ private boolean canCastSpellTypeLevel(final String spellType, final int spellLev
// a CastList then they use something funky
// like Power Points (psionic)
if (!aClass.getSafe(ObjectKey.MEMORIZE_SPELLS) && !this.getSpellSupport(aClass).hasKnownList()
- && this.getSpellSupport(aClass).canCastSpells(this))
+ && this.getSpellSupport(aClass).canCastSpells(this))
{
return true;
}
@@ -4729,10 +4638,8 @@ private boolean canCastSpellTypeLevel(final String spellType, final int spellLev
* Method will go through the list of classes that the PC has and see if
* they can cast spells of desired type at desired spell level.
*
- * @param spellType
- * Spell type to check for
- * @param spellLevel
- * Desired spell level
+ * @param spellType Spell type to check for
+ * @param spellLevel Desired spell level
* @return The number of spells castable
**/
public int countSpellCastTypeLevel(final String spellType, final int spellLevel)
@@ -4744,7 +4651,7 @@ public int countSpellCastTypeLevel(final String spellType, final int spellLevel)
FactKey fk = FactKey.valueOf("SpellType");
String classSpellType = aClass.getResolved(fk);
if (classSpellType != null
- && ("Any".equalsIgnoreCase(spellType) || classSpellType.equalsIgnoreCase(spellType)))
+ && ("Any".equalsIgnoreCase(spellType) || classSpellType.equalsIgnoreCase(spellType)))
{
int numCastLevel = this.getSpellSupport(aClass).getCastForLevel(spellLevel, this);
@@ -4763,7 +4670,7 @@ public int countSpellCastTypeLevel(final String spellType, final int spellLevel)
// a CastList then they use something funky
// like Power Points (psionic)
if (!aClass.getSafe(ObjectKey.MEMORIZE_SPELLS) && !this.getSpellSupport(aClass).hasKnownList()
- && this.getSpellSupport(aClass).canCastSpells(this))
+ && this.getSpellSupport(aClass).canCastSpells(this))
{
return Integer.MAX_VALUE;
}
@@ -4777,8 +4684,8 @@ public int countSpellCastTypeLevel(final String spellType, final int spellLevel)
* Check whether a deity can be selected by this character
*
* @return {@code true} means the deity can be a selected by a
- * character with the given properties; {@code false} means
- * the character cannot.
+ * character with the given properties; {@code false} means
+ * the character cannot.
*/
public boolean canSelectDeity(final Deity aDeity)
{
@@ -4815,10 +4722,10 @@ public String delSpell(SpellInfo si, final PCClass aClass, final String bookName
// there is some weird spell that keeps getting loaded by
// accident (or is saved in the .pcg file)
if (isDefault
- && this.getSpellSupport(aClass).isAutoKnownSpell(acs.getSpell(), si.getActualLevel(), false, this))
+ && this.getSpellSupport(aClass).isAutoKnownSpell(acs.getSpell(), si.getActualLevel(), false, this))
{
Logging.errorPrint(
- "Notice: removing " + acs.getSpell().getDisplayName() + " even though it is an auto known spell");
+ "Notice: removing " + acs.getSpell().getDisplayName() + " even though it is an auto known spell");
}
SpellBook spellBook = getSpellBookByName(bookName);
@@ -4874,8 +4781,7 @@ public String delSpell(SpellInfo si, final PCClass aClass, final String bookName
* author: Thomas Behr 09-03-02
*
* @param check
- * @param tokenString
- * tokenString to parse
+ * @param tokenString tokenString to parse
* @return the calculated save bonus
*/
public int calculateSaveBonus(final PCCheck check, final String tokenString)
@@ -4896,19 +4802,16 @@ public int calculateSaveBonus(final PCCheck check, final String tokenString)
if ("TOTAL".equals(tokens[i]))
{
save += getTotalCheck(check);
- }
- else if ("BASE".equals(tokens[i]))
+ } else if ("BASE".equals(tokens[i]))
{
save += getBaseCheck(check);
- }
- else if ("MISC".equals(tokens[i]))
+ } else if ("MISC".equals(tokens[i]))
{
String saveVar = ControlUtilities.getControlToken(Globals.getContext(), CControl.MISCSAVE);
if (saveVar == null)
{
save += (int) getTotalBonusTo("SAVE", saveType);
- }
- else
+ } else
{
save += ((Number) getLocal(check, saveVar)).intValue();
}
@@ -4920,8 +4823,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save += (int) getBonusDueToType("SAVE", saveType, "EPIC");
- }
- else
+ } else
{
save += ((Number) getLocal(check, saveVar)).intValue();
}
@@ -4933,8 +4835,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save += (int) getEquipmentBonusTo("SAVE", saveType);
- }
- else
+ } else
{
save += ((Number) getLocal(check, saveVar)).intValue();
}
@@ -4946,8 +4847,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save += calculateSaveBonusRace(check);
- }
- else
+ } else
{
save += ((Number) getLocal(check, saveVar)).intValue();
}
@@ -4958,9 +4858,8 @@ else if ("MISC".equals(tokens[i]))
if (ControlUtilities.hasControlToken(Globals.getContext(), CControl.BASESAVE))
{
Logging.errorPrint(
- "FEATS is not a supported SAVE modification " + "when BASESAVE Code Control is used");
- }
- else
+ "FEATS is not a supported SAVE modification " + "when BASESAVE Code Control is used");
+ } else
{
save += (int) getFeatBonusTo("SAVE", saveType);
}
@@ -4972,8 +4871,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save += (int) checkBonusFacet.getCheckBonusTo(id, "SAVE", saveType);
- }
- else
+ } else
{
save += ((Number) getLocal(check, saveVar)).intValue();
}
@@ -4988,8 +4886,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save -= (int) getBonusDueToType("SAVE", saveType, "EPIC");
- }
- else
+ } else
{
save -= ((Number) getLocal(check, saveVar)).intValue();
}
@@ -5001,8 +4898,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save -= (int) getEquipmentBonusTo("SAVE", saveType);
- }
- else
+ } else
{
save -= ((Number) getLocal(check, saveVar)).intValue();
}
@@ -5014,8 +4910,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save -= calculateSaveBonusRace(check);
- }
- else
+ } else
{
save -= ((Number) getLocal(check, saveVar)).intValue();
}
@@ -5026,9 +4921,8 @@ else if ("MISC".equals(tokens[i]))
if (ControlUtilities.hasControlToken(Globals.getContext(), CControl.BASESAVE))
{
Logging.errorPrint(
- "NOFEATS is not a supported SAVE modification " + "when BASESAVE Code Control is used");
- }
- else
+ "NOFEATS is not a supported SAVE modification " + "when BASESAVE Code Control is used");
+ } else
{
save -= (int) getFeatBonusTo("SAVE", saveType);
}
@@ -5040,8 +4934,7 @@ else if ("MISC".equals(tokens[i]))
if (saveVar == null)
{
save -= (int) checkBonusFacet.getCheckBonusTo(id, "SAVE", saveType);
- }
- else
+ } else
{
save -= ((Number) getLocal(check, saveVar)).intValue();
}
@@ -5060,7 +4953,7 @@ else if ("MISC".equals(tokens[i]))
public boolean delSpellBook(final String aName)
{
if ((!aName.isEmpty()) && !aName.equals(Globals.getDefaultSpellBook())
- && spellBookFacet.containsBookNamed(id, aName))
+ && spellBookFacet.containsBookNamed(id, aName))
{
processSpellBookRemoval(aName);
return true;
@@ -5106,25 +4999,22 @@ private void determinePrimaryOffWeapon()
final boolean isEquipped = eq.isEquipped();
if ((eq.getLocation() == EquipmentLocation.EQUIPPED_PRIMARY)
- || ((eq.getLocation() == EquipmentLocation.EQUIPPED_BOTH) && primaryWeaponFacet.isEmpty(id))
- || (eq.getLocation() == EquipmentLocation.EQUIPPED_TWO_HANDS))
+ || ((eq.getLocation() == EquipmentLocation.EQUIPPED_BOTH) && primaryWeaponFacet.isEmpty(id))
+ || (eq.getLocation() == EquipmentLocation.EQUIPPED_TWO_HANDS))
{
if (isEquipped)
{
primaryWeaponFacet.add(id, eq);
- }
- else
+ } else
{
unequippedPrimary.add(eq);
}
- }
- else if ((eq.getLocation() == EquipmentLocation.EQUIPPED_BOTH) && !primaryWeaponFacet.isEmpty(id))
+ } else if ((eq.getLocation() == EquipmentLocation.EQUIPPED_BOTH) && !primaryWeaponFacet.isEmpty(id))
{
if (isEquipped)
{
secondaryWeaponFacet.add(id, eq);
- }
- else
+ } else
{
unequippedSecondary.add(eq);
}
@@ -5135,8 +5025,7 @@ else if ((eq.getLocation() == EquipmentLocation.EQUIPPED_BOTH) && !primaryWeapon
if (isEquipped)
{
secondaryWeaponFacet.add(id, eq);
- }
- else
+ } else
{
unequippedSecondary.add(eq);
}
@@ -5149,8 +5038,7 @@ else if ((eq.getLocation() == EquipmentLocation.EQUIPPED_BOTH) && !primaryWeapon
if (isEquipped)
{
secondaryWeaponFacet.add(id, eq);
- }
- else
+ } else
{
unequippedSecondary.add(eq);
}
@@ -5259,10 +5147,8 @@ private int getClassHitPoints(PCClass pcClass, int iConMod)
* with this method, also this method does not print warning messages see:
* incrementClassLevel(int, PCClass, boolean, boolean);
*
- * @param mod
- * the number of levels to add/remove
- * @param aClass
- * the class to adjust
+ * @param mod the number of levels to add/remove
+ * @param aClass the class to adjust
*/
public void incrementClassLevel(final int mod, final PCClass aClass)
{
@@ -5314,8 +5200,7 @@ public void makeIntoExClass(final PCClass fromClass)
toClass = cl.clone(); //Still required :(
bClassNew = true;
toLevel = 0;
- }
- else
+ } else
{
bClassNew = false;
toLevel = getLevel(toClass);
@@ -5345,8 +5230,7 @@ public void makeIntoExClass(final PCClass fromClass)
if (bClassNew)
{
classFacet.replaceClass(id, fromClass, toClass);
- }
- else
+ } else
{
classFacet.removeClass(id, fromClass);
}
@@ -5382,11 +5266,10 @@ public void makeIntoExClass(final PCClass fromClass)
}
setSkillPool(toClass, fromClass.getSkillPool(this));
- }
- catch (NumberFormatException nfe)
+ } catch (NumberFormatException nfe)
{
ShowMessageDelegate.showMessageDialog(nfe.getMessage(), Constants.APPLICATION_NAME,
- MessageType.INFORMATION);
+ MessageType.INFORMATION);
}
}
@@ -5435,7 +5318,7 @@ public int modToACFromEquipment()
/**
* Calculate the ACCHECK bonus from equipped items. Extracted from
* modToFromEquipment.
- *
+ *
* TODO Penalty for load could/should be GameMode specific?
*
* @return PC's ACCHECK bonus from equipment
@@ -5478,7 +5361,13 @@ public int processOldMaxDex()
{
final int statBonus = (int) getStatBonusTo("MISC", "MAXDEX");
final Load load = getHouseRuledLoadType();
- int bonus = (load == Load.MEDIUM) ? 2 : (load == Load.HEAVY) ? 1 : (load == Load.OVERLOAD) ? 0 : statBonus;
+ int bonus = switch (load)
+ {
+ case MEDIUM -> 3;
+ case HEAVY -> 1;
+ case OVERLOAD -> 0;
+ default -> statBonus;
+ };
// If this is still true after all the equipment has been
// examined, then we should use the Maximum - Maximum Dex modifier.
@@ -5507,8 +5396,7 @@ public int processOldMaxDex()
if (bonus < 0)
{
bonus = 0;
- }
- else if (bonus > Constants.MAX_MAXDEX)
+ } else if (bonus > Constants.MAX_MAXDEX)
{
bonus = Constants.MAX_MAXDEX;
}
@@ -5519,7 +5407,7 @@ else if (bonus > Constants.MAX_MAXDEX)
* Takes a String and a Class name and computes spell based variable such as
* Class level.
*
- * @param aSpell The spell object
+ * @param aSpell The spell object
* @param aString the variable to evaluate
* @return String
*/
@@ -5546,8 +5434,7 @@ public String parseSpellString(final CharacterSpell aSpell, String aString)
if (aString.charAt(i) == '(')
{
level++;
- }
- else if (aString.charAt(i) == ')')
+ } else if (aString.charAt(i) == ')')
{
level--;
if (level == 0)
@@ -5570,8 +5457,8 @@ else if (aString.charAt(i) == ')')
final Float fVal = getVariableValue(aSpell, inCalc, aSpellClass);
if (!CoreUtility.doublesEqual(fVal, 0.0f) || (inCalc.contains("MIN"))
- || (inCalc.contains("MAX")) || inCalc.toUpperCase().contains("MIN(")
- || inCalc.toUpperCase().contains("MAX("))
+ || (inCalc.contains("MAX")) || inCalc.toUpperCase().contains("MIN(")
+ || inCalc.toUpperCase().contains("MAX("))
{
found = true;
replacement = String.valueOf(fVal.intValue());
@@ -5580,8 +5467,7 @@ else if (aString.charAt(i) == ')')
if (found)
{
aString = aString.substring(0, start) + replacement + aString.substring(end + 1);
- }
- else
+ } else
{
aString = aString.substring(0, start) + '[' + inCalc + ']' + aString.substring(end + 1);
}
@@ -5894,7 +5780,7 @@ public int getNumAttacks()
* @return double
*/
private double getPObjectWithCostBonusTo(final Collection extends CDOMObject> aList, final String aType,
- final String aName)
+ final String aName)
{
double iBonus = 0;
@@ -5944,7 +5830,8 @@ public String getClassLevelString(String aClassKey, final boolean doReplace)
{
int totalLevels = 0;
String[] classTypes = aClassKey.substring(5).split("\\.");
- CLASSFOR: for (PCClass cl : getClassSet())
+ CLASSFOR:
+ for (PCClass cl : getClassSet())
{
for (String type : classTypes)
{
@@ -5961,8 +5848,7 @@ public String getClassLevelString(String aClassKey, final boolean doReplace)
}
}
return Integer.toString(totalLevels);
- }
- else
+ } else
{
final PCClass aClass = getClassKeyed(aClassKey);
@@ -6034,7 +5920,7 @@ public List extends CDOMObject> getCDOMObjectList()
if (isFeatureEnabled(CControl.DOMAINFEATURE))
{
list.add((Deity) ChannelUtilities.readControlledChannel(getCharID(),
- CControl.DEITYINPUT));
+ CControl.DEITYINPUT));
}
// Domain
@@ -6092,24 +5978,19 @@ public List extends CDOMObject> getCDOMObjectList()
/**
* availableSpells sk4p 13 Dec 2002
- *
+ *
* For learning or preparing a spell: Are there slots available at this
* level or higher Fixes BUG [569517]
*
- * @param level
- * the level being checked for availability
- * @param aClass
- * the class under consideration
- * @param bookName
- * the name of the spellbook
- * @param knownLearned
- * "true" if this is learning a spell, "false" if prepping
- * @param isSpecialtySpell
- * "true" if this is a speciality for the given class
+ * @param level the level being checked for availability
+ * @param aClass the class under consideration
+ * @param bookName the name of the spellbook
+ * @param knownLearned "true" if this is learning a spell, "false" if prepping
+ * @param isSpecialtySpell "true" if this is a speciality for the given class
* @return true or false, a new spell can be added
*/
public boolean availableSpells(final int level, final PCClass aClass, final String bookName,
- final boolean knownLearned, final boolean isSpecialtySpell)
+ final boolean knownLearned, final boolean isSpecialtySpell)
{
boolean available = false;
FactKey fk = FactKey.valueOf("SpellType");
@@ -6140,8 +6021,7 @@ public boolean availableSpells(final int level, final PCClass aClass, final Stri
{
knownNon = this.getSpellSupport(aClass).getKnownForLevel(i, this);
knownSpec = this.getSpellSupport(aClass).getSpecialtyKnownForLevel(i, this);
- }
- else
+ } else
{
// Get the number of castable slots
knownTot = this.getSpellSupport(aClass).getCastForLevel(i, bookName, true, true, this);
@@ -6216,8 +6096,7 @@ public boolean availableSpells(final int level, final PCClass aClass, final Stri
{
knownNon = this.getSpellSupport(aClass).getKnownForLevel(i, this);
knownSpec = this.getSpellSupport(aClass).getSpecialtyKnownForLevel(i, this);
- }
- else
+ } else
{
// Get the number of castable slots
knownTot = this.getSpellSupport(aClass).getCastForLevel(i, bookName, true, true, this);
@@ -6321,8 +6200,7 @@ public boolean availableSpells(final int level, final PCClass aClass, final Stri
{
available = true;
}
- }
- else if (isSpecialtySpell && (excNon + excSpec > 0))
+ } else if (isSpecialtySpell && (excNon + excSpec > 0))
{
available = true;
}
@@ -6355,14 +6233,14 @@ else if (isSpecialtySpell && (excNon + excSpec > 0))
/**
* Compute total bonus from a List of BonusObjs Use cost of bonus to adjust
* total bonus up or down This method takes a list of bonus objects.
- *
+ *
* For each object in the list, it gets the creating object and queries it
* for its "COST". It then multiplies the value of the bonus by this cost
* and adds it to the cumulative total so far. If subSearch is true, the
* choices made in the object that the bonus originated in are searched, the
* effective bonus is multiplied by the number of times this bonus appears
* in the list.
- *
+ *
* Note: This COST seems to be used for several different things in the code
* base, in feats for instance, it is used to modify the feat pool by
* amounts other than 1 when selecting a given feat. Here it is used as a
@@ -6370,8 +6248,7 @@ else if (isSpecialtySpell && (excNon + excSpec > 0))
* of 0.5 counts for half its normal value. The COST is limited to a max of
* 1, so it can only make bonuses less effective.
*
- * @param aList
- * a list of bonus objects
+ * @param aList a list of bonus objects
* @return the calculated cumulative bonus
*/
private double calcBonusWithCostFromList(final List aList)
@@ -6419,8 +6296,7 @@ public int countSpellsInBook(final String aString)
if (aTok.hasMoreTokens())
{
levelNum = Integer.parseInt(aTok.nextToken());
- }
- else
+ } else
{
levelNum = -1;
}
@@ -6449,8 +6325,7 @@ public SizeAdjustment getSizeAdjustment()
if (sizeControl != null)
{
return (SizeAdjustment) getGlobal(sizeControl);
- }
- else
+ } else
{
return sizeFacet.get(id);
}
@@ -6495,17 +6370,17 @@ public boolean includeSkill(final Skill skill, final SkillFilter filter)
}
return switch (filter)
- {
- case Ranks -> (SkillRankControl.getTotalRank(this, skill) > 0);
- case NonDefault -> (
- SkillRankControl.getTotalRank(this, skill) > 0
- || SkillModifier.modifier(skill, this) != SkillModifier.getStatMod(skill, this)
- + getSizeAdjustmentBonusTo("SKILL", skill.getKeyName()));
- case Usable -> qualifySkill(skill) && (
- SkillRankControl.getTotalRank(this, skill) > 0
- || skill.getSafe(ObjectKey.USE_UNTRAINED));
- default -> qualifySkill(skill);
- };
+ {
+ case Ranks -> (SkillRankControl.getTotalRank(this, skill) > 0);
+ case NonDefault -> (
+ SkillRankControl.getTotalRank(this, skill) > 0
+ || SkillModifier.modifier(skill, this) != SkillModifier.getStatMod(skill, this)
+ + getSizeAdjustmentBonusTo("SKILL", skill.getKeyName()));
+ case Usable -> qualifySkill(skill) && (
+ SkillRankControl.getTotalRank(this, skill) > 0
+ || skill.getSafe(ObjectKey.USE_UNTRAINED));
+ default -> qualifySkill(skill);
+ };
}
private boolean qualifySkill(final Skill skill)
@@ -6520,13 +6395,9 @@ private boolean qualifySkill(final Skill skill)
* with this method, see: incrementClassLevel(int, PCClass, boolean,
* boolean);
*
- *
- * @param numberOfLevels
- * number of levels to add
- * @param globalClass
- * the class to add the levels to
- * @param bSilent
- * whether or not to display warning messages
+ * @param numberOfLevels number of levels to add
+ * @param globalClass the class to add the levels to
+ * @param bSilent whether or not to display warning messages
*/
public void incrementClassLevel(final int numberOfLevels, final PCClass globalClass, final boolean bSilent)
{
@@ -6538,25 +6409,21 @@ public void incrementClassLevel(final int numberOfLevels, final PCClass globalCl
* It is assumed that this method is not used as part of loading a
* previously saved character.
*
- * @param numberOfLevels
- * The number of levels to add or remove. If a positive number is
- * passed in then that many levels will be added. If the number
- * of levels passed in is negative then that many levels will be
- * removed from the specified class.
- * @param globalClass
- * The global class from the data store. The class as stored in
- * the character will be compared to this one using the
- * getClassNamed() method
- * @param bSilent
- * If true do not display any warning messages about adding or
- * removing too many levels
- * @param bypassPrereqs
- * Whether we should bypass the checks as to whether or not the
- * PC qualifies to take this class. If true, the checks will be
- * bypassed
+ * @param numberOfLevels The number of levels to add or remove. If a positive number is
+ * passed in then that many levels will be added. If the number
+ * of levels passed in is negative then that many levels will be
+ * removed from the specified class.
+ * @param globalClass The global class from the data store. The class as stored in
+ * the character will be compared to this one using the
+ * getClassNamed() method
+ * @param bSilent If true do not display any warning messages about adding or
+ * removing too many levels
+ * @param bypassPrereqs Whether we should bypass the checks as to whether or not the
+ * PC qualifies to take this class. If true, the checks will be
+ * bypassed
*/
public void incrementClassLevel(final int numberOfLevels, final PCClass globalClass, final boolean bSilent,
- final boolean bypassPrereqs)
+ final boolean bypassPrereqs)
{
// If not importing, load the spell list
if (!importing)
@@ -6574,12 +6441,12 @@ public void incrementClassLevel(final int numberOfLevels, final PCClass globalCl
Race race = getRace();
if (globalClass.isMonster() && !SettingsHandler.isIgnoreMonsterHDCap() && !race.isAdvancementUnlimited()
- && ((totalHitDice() + numberOfLevels) > race.maxHitDiceAdvancement()) && !bSilent)
+ && ((totalHitDice() + numberOfLevels) > race.maxHitDiceAdvancement()) && !bSilent)
{
ShowMessageDelegate.showMessageDialog(
- "Cannot increase Monster Hit Dice for this character beyond " + race.maxHitDiceAdvancement()
- + ". This character's current number of Monster Hit Dice is " + totalHitDice(),
- Constants.APPLICATION_NAME, MessageType.INFORMATION);
+ "Cannot increase Monster Hit Dice for this character beyond " + race.maxHitDiceAdvancement()
+ + ". This character's current number of Monster Hit Dice is " + totalHitDice(),
+ Constants.APPLICATION_NAME, MessageType.INFORMATION);
return;
}
@@ -6601,7 +6468,7 @@ public void incrementClassLevel(final int numberOfLevels, final PCClass globalCl
if (pcClassClone == null)
{
Logging.errorPrint("PlayerCharacter::incrementClassLevel => " + "Clone of class "
- + globalClass.getKeyName() + " failed!");
+ + globalClass.getKeyName() + " failed!");
return;
}
@@ -6614,8 +6481,7 @@ public void incrementClassLevel(final int numberOfLevels, final PCClass globalCl
// Add the class to the character classes as level 0
classFacet.addClass(id, pcClassClone);
- }
- else
+ } else
{
// mod is < 0 and character does not have class. Return.
return;
@@ -6636,8 +6502,7 @@ public void incrementClassLevel(final int numberOfLevels, final PCClass globalCl
return;
}
}
- }
- else if (numberOfLevels < 0)
+ } else if (numberOfLevels < 0)
{
for (int i = 0; i < -numberOfLevels; ++i)
{
@@ -6683,8 +6548,7 @@ private PCLevelInfo removeLevelInfo(final String classKeyName)
* drop lowest 5: 4d6 reroll 1's and 2's drop lowest 6: 3d6 +5 7: 5d6 Drop
* lowest and middle as per FREQ #458917
*
- * @param method
- * the method to be used for rolling.
+ * @param method the method to be used for rolling.
*/
public final void rollStats(final int method)
{
@@ -6693,11 +6557,12 @@ public final void rollStats(final int method)
{
aMethod = Constants.CHARACTER_STAT_METHOD_PURCHASE;
}
- rollStats(aMethod, statFacet.getSet(id), SettingsHandler.getGameAsProperty().get().getCurrentRollingMethod(), false);
+ rollStats(aMethod, statFacet.getSet(id), SettingsHandler.getGameAsProperty().get().getCurrentRollingMethod(),
+ false);
}
public void rollStats(final int method, final Collection aStatList, final RollMethod rollMethod,
- boolean aSortedFlag)
+ boolean aSortedFlag)
{
int[] rolls = new int[aStatList.size()];
@@ -6709,7 +6574,8 @@ public void rollStats(final int method, final Collection aStatList, fina
SettingsHandler.getGameAsProperty().get().getPurchaseModeBaseStatScore(this);
case Constants.CHARACTER_STAT_METHOD_ALL_THE_SAME -> rolls[i] =
SettingsHandler.getGameAsProperty().get().getAllStatsValue();
- case Constants.CHARACTER_STAT_METHOD_ROLLED -> {
+ case Constants.CHARACTER_STAT_METHOD_ROLLED ->
+ {
final String diceExpression = rollMethod.getMethodRoll();
rolls[i] = RollingMethods.roll(diceExpression);
}
@@ -6763,10 +6629,8 @@ public void rollStats(final int method, final Collection aStatList, fina
* of equipment have the same outputIndex they will be ordered by name. Note
* hidden items (outputIndex = -1) are not included in list.
*
- * @param unsortedEquip
- * An ArrayList of the equipment to be sorted.
- * @param merge
- * How to merge.
+ * @param unsortedEquip An ArrayList of the equipment to be sorted.
+ * @param merge How to merge.
* @return An ArrayList of the equipment objects in output order.
*/
private static List sortEquipmentList(final Collection unsortedEquip, final int merge)
@@ -6911,12 +6775,9 @@ public Set getLanguageBonusSelectionList()
* to all included bonuses. If not excluding either, it is quicker to use
* getTotalBonusTo.
*
- * @param stat
- * The stat to calculate the bonus for.
- * @param useTemp
- * Should temp bonuses be included?
- * @param useEquip
- * Should equipment bonuses be included?
+ * @param stat The stat to calculate the bonus for.
+ * @param useTemp Should temp bonuses be included?
+ * @param useEquip Should equipment bonuses be included?
* @return The bonus to the stat.
*/
public int getPartialStatFor(PCStat stat, boolean useTemp, boolean useEquip)
@@ -6931,16 +6792,11 @@ public int getPartialStatFor(PCStat stat, boolean useTemp, boolean useEquip)
* stacking rules are applied to all included bonuses. If not excluding
* either, it is quicker to use getTotalStatAtLevel.
*
- * @param stat
- * The stat to calculate the value of.
- * @param level
- * The level we want to see the stat at.
- * @param usePost
- * Should stat mods that occurred after levelling be included?
- * @param useTemp
- * Should temp bonuses be included?
- * @param useEquip
- * Should equipment bonuses be included?
+ * @param stat The stat to calculate the value of.
+ * @param level The level we want to see the stat at.
+ * @param usePost Should stat mods that occurred after levelling be included?
+ * @param useTemp Should temp bonuses be included?
+ * @param useEquip Should equipment bonuses be included?
* @return The stat as it was at the level
*/
public int getPartialStatAtLevel(PCStat stat, int level, boolean usePost, boolean useTemp, boolean useEquip)
@@ -6975,8 +6831,7 @@ public PlayerCharacter clone()
try
{
aClone.assocSupt = assocSupt.clone();
- }
- catch (CloneNotSupportedException e)
+ } catch (CloneNotSupportedException e)
{
Logging.errorPrint("PlayerCharacter.clone failed", e);
}
@@ -7001,8 +6856,7 @@ public PlayerCharacter clone()
if (followerMaster != null)
{
aClone.masterFacet.set(id, followerMaster.clone());
- }
- else
+ } else
{
aClone.masterFacet.remove(id);
}
@@ -7138,6 +6992,7 @@ private String getSingleLocation(Equipment eqI)
/**
* Identify the equipping location for a natural weapon.
+ *
* @param eqI The natural weapon
* @return The location name, or null if not a natural weapon.
*/
@@ -7178,8 +7033,8 @@ private boolean canEquipItem(EquipSet eSet, String locName, Equipment eqI, Equip
// If Carried/Equipped/Not Carried slot
// allow as many as they would like
if (locName.startsWith(Constants.EQUIP_LOCATION_CARRIED)
- || locName.startsWith(Constants.EQUIP_LOCATION_EQUIPPED)
- || locName.startsWith(Constants.EQUIP_LOCATION_NOTCARRIED))
+ || locName.startsWith(Constants.EQUIP_LOCATION_EQUIPPED)
+ || locName.startsWith(Constants.EQUIP_LOCATION_NOTCARRIED))
{
return true;
}
@@ -7256,7 +7111,7 @@ private boolean canEquipItem(EquipSet eSet, String locName, Equipment eqI, Equip
// if Double Weapon or Both Hands, then no
// other weapon slots can be occupied
if ((locName.equals(Constants.EQUIP_LOCATION_BOTH) || locName.equals(Constants.EQUIP_LOCATION_DOUBLE))
- && (es.getName().equals(Constants.EQUIP_LOCATION_PRIMARY)
+ && (es.getName().equals(Constants.EQUIP_LOCATION_PRIMARY)
|| es.getName().equals(Constants.EQUIP_LOCATION_SECONDARY)
|| es.getName().equals(Constants.EQUIP_LOCATION_BOTH)
|| es.getName().equals(Constants.EQUIP_LOCATION_DOUBLE)))
@@ -7266,8 +7121,8 @@ private boolean canEquipItem(EquipSet eSet, String locName, Equipment eqI, Equip
// inverse of above case
if ((locName.equals(Constants.EQUIP_LOCATION_PRIMARY)
- || locName.equals(Constants.EQUIP_LOCATION_SECONDARY))
- && (es.getName().equals(Constants.EQUIP_LOCATION_BOTH)
+ || locName.equals(Constants.EQUIP_LOCATION_SECONDARY))
+ && (es.getName().equals(Constants.EQUIP_LOCATION_BOTH)
|| es.getName().equals(Constants.EQUIP_LOCATION_DOUBLE)))
{
return false;
@@ -7390,14 +7245,13 @@ public int getNewChildId(String pid)
}
public EquipSet addEquipToTarget(final EquipSet eSet, final Equipment eqTarget, String locName, final Equipment eqI,
- Float newQty)
+ Float newQty)
{
float tempQty = 1.0f;
if (newQty != null)
{
tempQty = newQty;
- }
- else
+ } else
{
newQty = tempQty;
}
@@ -7443,8 +7297,7 @@ public EquipSet addEquipToTarget(final EquipSet eSet, final Equipment eqTarget,
locName = eqTarget.getName();
addAll = true;
mergeItem = true;
- }
- else
+ } else
{
return null;
}
@@ -7527,6 +7380,7 @@ else if (locName.equalsIgnoreCase("Equipped"))
/**
* Move the equipset to a new unique path under its existing parent.
+ *
* @param es The equipment set item to be moved.
*/
public void moveEquipSetToNewPath(EquipSet es)
@@ -7561,8 +7415,7 @@ public String getSafeStringFor(PCStringKey key)
* Note: This is kind of a hack used by the Kit code to allow a kit
* to specify what the level abilities are.
*
- * @param yesNo
- * Yes if level increases should process ADD: level abilities.
+ * @param yesNo Yes if level increases should process ADD: level abilities.
*/
public void setDoLevelAbilities(boolean yesNo)
{
@@ -7622,8 +7475,7 @@ public void adjustAbilities(final Category aCategory, final BigDecimal
if (userMods != null)
{
userMods = userMods.add(arg);
- }
- else
+ } else
{
userMods = arg;
}
@@ -7661,8 +7513,7 @@ public BigDecimal getTotalAbilityPool(final AbilityCategory aCategory)
if (AbilityCategory.FEAT.equals(aCategory))
{
bonus = getBonusFeatPool();
- }
- else
+ } else
{
bonus = getTotalBonusTo("ABILITYPOOL", aCategory.getKeyName());
}
@@ -7736,16 +7587,14 @@ private BigDecimal getAbilityPoolSpent(final AbilityCategory aCategory)
if (ChooseActivation.hasNewChooseToken(ability))
{
spent += Math.ceil(subfeatCount * cost);
- }
- else
+ } else
{
int select = ability.getSafe(FormulaKey.SELECT).resolve(this, "").intValue();
double relativeCost = cost / select;
if (aCategory.allowFractionalPool())
{
spent += relativeCost;
- }
- else
+ } else
{
spent += (int) Math.ceil(relativeCost);
}
@@ -7870,7 +7719,7 @@ private void processAbilityList(CDOMObject cdo, CDOMReference ref)
if (ab == null)
{
Logging.log(Logging.LST_ERROR, "Missing object referenced in the ability list for '" + cdo
- + "' list is " + ref + ". Source " + cdo.getSourceURI());
+ + "' list is " + ref + ". Source " + cdo.getSourceURI());
continue;
}
for (AssociatedPrereqObject apo : assoc)
@@ -7888,8 +7737,7 @@ private void processAbilityList(CDOMObject cdo, CDOMReference ref)
new CNAbilitySelection(CNAbilityFactory.getCNAbility(cat, nature, ab), "");
cas.addAllPrerequisites(apo.getPrerequisiteList());
applyAbility(cas, cdo);
- }
- else
+ } else
{
for (final String choice : choices)
{
@@ -7899,8 +7747,7 @@ private void processAbilityList(CDOMObject cdo, CDOMReference ref)
applyAbility(cas, cdo);
}
}
- }
- else
+ } else
{
CNAbilitySelection cas = new CNAbilitySelection(CNAbilityFactory.getCNAbility(cat, nature, ab));
cas.addAllPrerequisites(apo.getPrerequisiteList());
@@ -7918,8 +7765,7 @@ public void applyAbility(CNAbilitySelection cas, Object source)
if (cas.hasPrerequisites())
{
conditionalFacet.add(id, cas, source);
- }
- else
+ } else
{
directAbilityFacet.add(id, cas, source);
}
@@ -8149,7 +7995,7 @@ public boolean hasNonStatStat(PCStat stat)
// Check for a non stat, but only if it hasn't been reset to a stat
if (!nonStatToStatFacet.contains(id, stat))
{
- return nonStatStatFacet.contains(id, stat);
+ return nonStatStatFacet.contains(id, stat);
}
return false;
}
@@ -8169,7 +8015,7 @@ public String getDescription(PObject pobj)
return getDescription(Collections.singletonList(pobj));
}
- public String getDescription(List extends Object> objList)
+ public String getDescription(List> objList)
{
if (objList.isEmpty())
{
@@ -8177,11 +8023,18 @@ public String getDescription(List extends Object> objList)
}
PObject cdo;
Object b = objList.get(0);
- if (b instanceof CNAbility)
+ if (b instanceof PObject)
+ {
+ cdo = (PObject) b;
+ String dString = getInfoToken(".INFO.DESC", cdo);
+ if (!dString.equals(".INFO.DESC"))
+ {
+ return dString;
+ }
+ } else if (b instanceof CNAbility)
{
cdo = ((CNAbility) b).getAbility();
- }
- else
+ } else
{
Logging.errorPrint("Unable to resolve Description with object of type: " + b.getClass().getName());
return Constants.EMPTY_STRING;
@@ -8210,20 +8063,28 @@ public String getDescription(List extends Object> objList)
return sb.toString();
}
- public String getInfoToken(String token, PObject po) {
+ public String getInfoToken(String token, PObject po)
+ {
// looking for a token in the form of RACE.INFO.TAG where
// RACE indicate which token map to check for a INFO label of TAG to return
int i = token.indexOf(".INFO.");
String ts = token;
if (i>-1)
- ts = token.substring(i+6);
+ {
+ ts = token.substring(i + 6);
+ }
else
+ {
return token;
+ }
Set> keys = po.getMapKeys();
- for (MapKey, ?> key : keys) {
+ for (MapKey, ?> key : keys)
+ {
Map, ?> key2 = po.getMapFor(key);
- for(Object k : key2.keySet()) {
- if (k.toString().equalsIgnoreCase(ts)) {
+ for(Object k : key2.keySet())
+ {
+ if (k.toString().equalsIgnoreCase(ts))
+ {
MessageFormat m = (MessageFormat) key2.get(k);
return m.toPattern();
}
@@ -8238,9 +8099,8 @@ public String getInfoToken(String token, PObject po) {
* domains may cast the spell.
*
* @param sp The spell to get the info for.
- *
* @return Map containing the class levels and domains that may cast the
- * spell
+ * spell
*/
public HashMapToList, Integer> getSpellLevelInfo(Spell sp)
{
@@ -8257,7 +8117,8 @@ public HashMapToList, Integer> getSpellLevelInfo(Spell sp)
/**
* Retrieve the character's existing version of this spell, if any.
- * @param po The source of the spell list for this spell (normally a PCClass)
+ *
+ * @param po The source of the spell list for this spell (normally a PCClass)
* @param spell The spell to be retrieved
* @param owner The source of the spell (either the PCClass or the Domian)
* @return The character's existing instance of the spell, or null if none.
@@ -8281,6 +8142,7 @@ public CharacterSpell getCharacterSpellForSpell(PObject po, Spell spell, PObject
/**
* Get a list of CharacterSpells from the character spell list.
+ *
* @param spellSource
* @param aSpell
* @param book
@@ -8288,7 +8150,7 @@ public CharacterSpell getCharacterSpellForSpell(PObject po, Spell spell, PObject
* @return list of CharacterSpells from the character spell list
*/
public final List getCharacterSpells(CDOMObject spellSource, final Spell aSpell, final String book,
- final int level)
+ final int level)
{
List csList = new ArrayList<>(getCharacterSpells(spellSource));
// Add in the spells granted by objects
@@ -8317,6 +8179,7 @@ public final List getCharacterSpells(CDOMObject spellSource, fin
/**
* Returns DC for a spell and SpellInfo.
+ *
* @param sp the spell
* @param cs TODO
* @param si the spell info
@@ -8467,6 +8330,7 @@ public int getDC(final Spell sp, PCClass aClass, int spellLevel, int metaDC, CDO
/**
* Returns concentration bonus for a spell and SpellInfo.
+ *
* @param sp the spell
* @param cs TODO
* @param si the spell info
@@ -8495,7 +8359,7 @@ public int getConcentration(final Spell sp, CharacterSpell cs, final SpellInfo s
}
public int getConcentration(final Spell sp, final CharacterSpell aSpell, PCClass aClass, int spellLevel,
- int metaConcentration, CDOMObject ow)
+ int metaConcentration, CDOMObject ow)
{
String bonDomain = "";
if (ow instanceof Domain)
@@ -8539,8 +8403,9 @@ public int getConcentration(final Spell sp, final CharacterSpell aSpell, PCClass
// must be done after spellLevel is set above
int concentration =
- getVariableValue(aSpell, SettingsHandler.getGameAsProperty().get().getSpellBaseConcentration(), classKey).intValue()
- + metaConcentration;
+ getVariableValue(aSpell, SettingsHandler.getGameAsProperty().get().getSpellBaseConcentration(),
+ classKey).intValue()
+ + metaConcentration;
concentration += (int) getTotalBonusTo("CONCENTRATION", "ALLSPELLS");
if (useStatFromSpell)
@@ -8713,8 +8578,7 @@ public void setApplied(BonusObj bonusObj, boolean bool)
if (bool)
{
appliedBonusFacet.add(id, bonusObj);
- }
- else
+ } else
{
appliedBonusFacet.remove(id, bonusObj);
}
@@ -8727,8 +8591,7 @@ public void setSubstitutionLevel(PCClass pcc, PCClassLevel originalClassLevel)
PCClassLevel clvl = originalClassLevel.clone();
clvl.put(StringKey.QUALIFIED_KEY, pcc.getQualifiedKey());
classFacet.setClassLevel(id, pcc, clvl);
- }
- catch (CloneNotSupportedException e)
+ } catch (CloneNotSupportedException e)
{
Logging.errorPrint(e.getLocalizedMessage(), e);
}
@@ -9103,7 +8966,7 @@ public Collection getBonusContainerList()
if (gameMode.isPurchaseStatMode())
{
PointBuyMethod pbm = gameMode.getContext().getReferenceContext()
- .silentlyGetConstructedCDOMObject(PointBuyMethod.class, gameMode.getPurchaseModeMethodName());
+ .silentlyGetConstructedCDOMObject(PointBuyMethod.class, gameMode.getPurchaseModeMethodName());
list.add(pbm);
}
return list;
@@ -9136,8 +8999,7 @@ public void reInheritClassLevels(PCClass pcc)
{
classFacet.setClassLevel(id, pcc, pcl);
}
- }
- catch (CloneNotSupportedException e)
+ } catch (CloneNotSupportedException e)
{
Logging.errorPrint(e.getLocalizedMessage(), e);
}
@@ -9161,7 +9023,8 @@ public void checkSkillModChange()
if (currClass == null)
{
Logging
- .errorPrint("No PCClass found for '" + classKeyName + "' in character's class list: " + newClasses);
+ .errorPrint(
+ "No PCClass found for '" + classKeyName + "' in character's class list: " + newClasses);
return;
}
PCClassLevel classLevel = getActiveClassLevel(currClass, lvlInfo.getClassLevel());
@@ -9170,7 +9033,7 @@ public void checkSkillModChange()
}
public void checkSkillModChangeForLevel(PCClass pcClass, PCLevelInfo pi, PCClassLevel classLevel,
- int characterLevel)
+ int characterLevel)
{
int newSkillPointsGained = pcClass.getSkillPointsForLevel(this, classLevel, characterLevel);
if (pi.getClassKeyName().equals(pcClass.getKeyName()))
@@ -9188,6 +9051,7 @@ public void checkSkillModChangeForLevel(PCClass pcClass, PCLevelInfo pi, PCClass
/**
* Add a chronicle entry.
+ *
* @param chronicleEntry The entry to be added.
*/
public void addChronicleEntry(ChronicleEntry chronicleEntry)
@@ -9197,6 +9061,7 @@ public void addChronicleEntry(ChronicleEntry chronicleEntry)
/**
* Remove a chronicle entry.
+ *
* @param chronicleEntry The entry to be removed.
*/
public void removeChronicleEntry(ChronicleEntry chronicleEntry)
@@ -9274,7 +9139,7 @@ public void addDefaultSpellList(PCClass pcc)
}
double getSizeBonusTo(SizeAdjustment sizeAdjustment, final String bonusType, final List typeList,
- double defaultValue)
+ double defaultValue)
{
for (String type : typeList)
{
@@ -9300,7 +9165,7 @@ public void addDefaultSpellList(PCClass pcc)
* Adds to the provided list any spells that have been granted to the character's class by abilities
* through the use of SPELLKNOWN:CLASS tags.
*
- * @param aClass The character class owning the spell list.
+ * @param aClass The character class owning the spell list.
* @param cSpells The list of spells to be updated.
*/
public void addBonusKnownSpellsToList(CDOMObject aClass, List cSpells)
@@ -9395,8 +9260,7 @@ public int recalcSkillPointMod(PCClass pcClass, final int characterLevel)
if (lockedMonsterSkillPoints > 0)
{
spMod = lockedMonsterSkillPoints;
- }
- else if (characterLevel == 1)
+ } else if (characterLevel == 1)
{
int monSkillPts = (int) getTotalBonusTo("MONSKILLPTS", "NUMBER");
if (monSkillPts != 0)
@@ -9422,9 +9286,9 @@ else if (characterLevel == 1)
int otherSp = spMod - classSp - raceSp; // should mostly be stat related skillpoints
final int classSpMin = (int) getTotalBonusTo("MINCLASSSKILLPOINTS", "NUMBER");
// if a MINCLASSSKILLPOINTS.NUMBER is defined and spMod was lower due to INT penalty
- if (classSpMin>0 && (classSp+otherSp 0 && (classSp + otherSp < classSpMin))
{
- spMod = Math.max(classSpMin,classSp+otherSp)+raceSp;
+ spMod = Math.max(classSpMin, classSp + otherSp) + raceSp;
}
if (characterLevel == 1)
@@ -9440,8 +9304,7 @@ else if (characterLevel == 1)
// Only generate a random age if the user hasn't set one!
bioSetFacet.get(id).randomize("AGE", this);
}
- }
- else
+ } else
{
spMod *= Globals.getSkillMultiplierForLevel(characterLevel);
}
@@ -9563,6 +9426,7 @@ public void setSkillRankValue(Skill sk, PCClass pcc, double value)
/**
* Retrieve the classes that have ranks in this skill. NB: For granted ranks
* this may include null.
+ *
* @param sk The skill to be checked.
* @return The collection of classes with ranks - may include null as a PCClass.
*/
@@ -9673,17 +9537,16 @@ public void calculateKnownSpellsForClassLevel(PCClass pcc)
cs = new CharacterSpell(pcc, spell);
cs.addInfo(spellLevel, 1, Globals.getDefaultSpellBook());
addCharacterSpell(pcc, cs);
- }
- else
+ } else
{
if (cs.getSpellInfoFor(Globals.getDefaultSpellBook(), spellLevel) == null)
{
cs.addInfo(spellLevel, 1, Globals.getDefaultSpellBook());
- }
- else
+ } else
{
// already know this one
- Logging.log(Logging.DEBUG, "We already know about the level: " + spellLevel + " of this character spell, it's in the global default spellbook already.");
+ Logging.debugPrint("We already know about the level: " + spellLevel
+ + " of this character spell, it's in the global default spellbook already.");
}
}
}
@@ -9840,15 +9703,14 @@ public void addSavedAbility(CNAbilitySelection cnas, Object owner, Object locati
addAbility(cnas, owner, location);
}
- public void addAbility(CNAbilitySelection cnas, @SuppressWarnings("UnusedParameters")
- final Object owner, Object location)
+ public void addAbility(CNAbilitySelection cnas, @SuppressWarnings("UnusedParameters") final Object owner,
+ Object location)
{
//TODO Need to handle owner
if (cnas.hasPrerequisites())
{
conditionalFacet.add(id, cnas, location);
- }
- else
+ } else
{
directAbilityFacet.add(id, cnas, location);
}
@@ -9859,14 +9721,13 @@ public void addAbility(CNAbilitySelection cnas, @SuppressWarnings("UnusedParamet
}
public void removeAbility(CNAbilitySelection cnas, @SuppressWarnings("UnusedParameters") Object owner,
- Object location)
+ Object location)
{
//TODO Need to handle owner
if (cnas.hasPrerequisites())
{
conditionalFacet.remove(id, cnas, location);
- }
- else
+ } else
{
directAbilityFacet.remove(id, cnas, location);
}
@@ -9892,12 +9753,10 @@ public List getConsolidatedAssociationList(CDOMObject cdo)
list.addAll(getAssociationList(cna));
}
return list;
- }
- else if (cdo instanceof ChooseDriver)
+ } else if (cdo instanceof ChooseDriver)
{
return getAssociationList((ChooseDriver) cdo);
- }
- else
+ } else
{
//Can't really do a message here because this is heavily done by BonusManager
// Logging
@@ -9931,17 +9790,16 @@ public String getControl(String string)
* Returns the value of a CodeControl, or the default value if the code control has
* not been set in the data.
*
- * @param control
- * The CodeControl for which the value should be returned
+ * @param control The CodeControl for which the value should be returned
* @return The value of a CodeControl, or the default value if the code control has
- * not been set in the data
+ * not been set in the data
*/
public String getControl(CControl control)
{
ObjectKey ok = ObjectKey.getKeyFor(String.class,
- "*" + Objects.requireNonNull(control.getName()));
+ "*" + Objects.requireNonNull(control.getName()));
return Optional.ofNullable(controller.get(ok))
- .orElse(control.getDefaultValue());
+ .orElse(control.getDefaultValue());
}
public boolean hasControl(String string)
@@ -9952,24 +9810,22 @@ public boolean hasControl(String string)
/**
* Returns true if a feature code control is enabled.
*
- * @param feature
- * The feature code control for which the value should be returned
+ * @param feature The feature code control for which the value should be returned
* @return true if a feature code control is enabled; false otherwise
*/
public boolean isFeatureEnabled(String feature)
{
Boolean object = controller.get(ObjectKey.getKeyFor(Boolean.class,
- "*" + Objects.requireNonNull(feature)));
+ "*" + Objects.requireNonNull(feature)));
return (object != null) && object;
}
/**
* Directly solves the given NEPFormula in context to this PlayerCharacter.
*
- * @param formula
- * The NEPFormula to be solved
+ * @param formula The NEPFormula to be solved
* @return The result of solving the given NEPFormula in context to this
- * PlayerCharacter
+ * PlayerCharacter
*/
public T solve(NEPFormula formula)
{
@@ -9977,7 +9833,6 @@ public T solve(NEPFormula formula)
}
/**
- *
* @return the racial size
*/
public int racialSizeInt()
diff --git a/code/src/java/pcgen/core/term/PCCasterLevelTotalTermEvaluator.java b/code/src/java/pcgen/core/term/PCCasterLevelTotalTermEvaluator.java
index 4579b747598..eb66c8fd3e0 100644
--- a/code/src/java/pcgen/core/term/PCCasterLevelTotalTermEvaluator.java
+++ b/code/src/java/pcgen/core/term/PCCasterLevelTotalTermEvaluator.java
@@ -21,7 +21,6 @@
package pcgen.core.term;
import pcgen.cdom.base.Constants;
-import pcgen.core.Equipment;
import pcgen.core.PCClass;
import pcgen.core.PlayerCharacter;
import pcgen.core.character.CharacterSpell;
diff --git a/code/src/java/pcgen/gui2/PCGenFrame.java b/code/src/java/pcgen/gui2/PCGenFrame.java
index 2160dee417e..f9fc90baa7c 100644
--- a/code/src/java/pcgen/gui2/PCGenFrame.java
+++ b/code/src/java/pcgen/gui2/PCGenFrame.java
@@ -85,7 +85,7 @@
import pcgen.gui2.util.ShowMessageGuiObserver;
import pcgen.gui3.GuiAssertions;
import pcgen.gui3.GuiUtility;
-import pcgen.gui3.JFXPanelFromResource;
+import pcgen.gui3.PanelFromResource;
import pcgen.gui3.component.PCGenToolBar;
import pcgen.gui3.dialog.AboutDialog;
import pcgen.gui3.dialog.RememberingChoiceDialog;
@@ -243,12 +243,11 @@ public void run()
if (!alternateStartup)
{
//Do a default startup
+ if (TipOfTheDayHandler.shouldShowTipOfTheDay())
+ {
+ Platform.runLater(PCGenFrame::showTipsOfTheDay);
+ }
SwingUtilities.invokeLater(() -> {
- if (TipOfTheDayHandler.shouldShowTipOfTheDay())
- {
- showTipsOfTheDay();
- }
-
if (!SourceSelectionDialog.skipSourceSelection())
{
showSourceSelectionDialog();
@@ -1296,7 +1295,7 @@ private void updateTitle()
*/
static void showTipsOfTheDay()
{
- var totd = new JFXPanelFromResource<>(
+ var totd = new PanelFromResource<>(
TipOfTheDayController.class,
"TipOfTheDay.fxml"
);
@@ -1560,6 +1559,7 @@ public void run()
updateTitle();
}
+ // TODO there are no examples with licenses. Either remove this or add a test.
private void showLicenses()
{
PropertyContext context = PCGenSettings.OPTIONS_CONTEXT;
@@ -1576,11 +1576,8 @@ private void showLicenses()
{
showLicenseDialog(LanguageBundle.getString("in_specialLicenses"), licenses); //$NON-NLS-1$
}
- for (String license : loader.getOtherLicenses())
- {
- showLicenseDialog(LanguageBundle.getString("in_specialLicenses"), license); //$NON-NLS-1$
- }
-
+ loader.getOtherLicenses()
+ .forEach(license -> showLicenseDialog(LanguageBundle.getString("in_specialLicenses"), license)); //$NON-NLS-1$
}
}
if (loader.hasMatureCampaign() && context.initBoolean(PCGenSettings.OPTION_SHOW_MATURE_ON_LOAD, true))
diff --git a/code/src/java/pcgen/gui2/converter/ConvertPanel.java b/code/src/java/pcgen/gui2/converter/ConvertPanel.java
index b14104856c4..2659a206326 100644
--- a/code/src/java/pcgen/gui2/converter/ConvertPanel.java
+++ b/code/src/java/pcgen/gui2/converter/ConvertPanel.java
@@ -1,16 +1,16 @@
/*
* Copyright (c) 2009 Tom Parker
- *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
@@ -44,6 +44,7 @@
import pcgen.gui2.converter.panel.ConvertSubPanel;
import pcgen.gui2.tools.CursorControlUtilities;
import pcgen.gui2.tools.Utility;
+import pcgen.util.GracefulExit;
public class ConvertPanel extends JPanel
{
@@ -114,7 +115,7 @@ public void progressNotAllowed(ProgressEvent pe)
finishButton = new JButton("Finish");
finishButton.addActionListener(arg0 -> {
PCGenDataConvert.savePrefs();
- System.exit(0);
+ GracefulExit.exit(0);
});
finishButton.setVisible(false);
buttonBox.add(finishButton);
@@ -174,7 +175,7 @@ public void checkExit()
if (response == JOptionPane.OK_OPTION)
{
PCGenDataConvert.savePrefs();
- System.exit(0);
+ GracefulExit.exit(0);
}
}
@@ -208,8 +209,8 @@ private void runNextPanel()
/**
* The Class {@code PreviousButtonListener} ...
- *
- *
+ *
+ *
*/
public class PreviousButtonListener implements ActionListener
{
diff --git a/code/src/java/pcgen/gui2/converter/LSTConverter.java b/code/src/java/pcgen/gui2/converter/LSTConverter.java
index 01d11fa9a5b..c3acc78295b 100644
--- a/code/src/java/pcgen/gui2/converter/LSTConverter.java
+++ b/code/src/java/pcgen/gui2/converter/LSTConverter.java
@@ -1,16 +1,16 @@
/*
* Copyright (c) 2009 Tom Parker
- *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
@@ -30,6 +30,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Observable;
+import java.util.Optional;
import java.util.Set;
import pcgen.base.util.DoubleKeyMapToList;
@@ -117,7 +118,7 @@ public int getNumFilesInCampaign(Campaign campaign)
}
/**
- * Initialise the list of campaigns. This will load the ability
+ * Initialise the list of campaigns. This will load the ability
* categories in advance of the conversion.
* @param campaigns The campaigns or sources to be converted.
*/
@@ -182,7 +183,7 @@ private void startItem(final Campaign campaign)
continue;
}
File in = new File(uri);
- // Use canonical name to stop reruns for the same file referred to using ..
+ // Use canonical name to stop reruns for the same file referred to using ..
URI canonicalUri;
try
{
@@ -223,19 +224,20 @@ private void startItem(final Campaign campaign)
try
{
changeLogWriter.append("\nProcessing ").append(String.valueOf(in)).append("\n");
- String result = load(uri, loader);
- if (result != null)
- {
- try (Writer out = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream(outFile),
- StandardCharsets.UTF_8
- )))
- {
- out.write(result);
- }
- }
+ load(uri, loader)
+ .ifPresent((String result) -> {
+ try (Writer out = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(outFile),
+ StandardCharsets.UTF_8)))
+ {
+ out.write(result);
+ } catch (IOException e)
+ {
+ Logging.errorPrint(e.getLocalizedMessage(), e);
+ }
+ });
}
- catch (PersistenceLayerException | IOException | InterruptedException e)
+ catch (PersistenceLayerException | IOException e)
{
Logging.errorPrint(e.getLocalizedMessage(), e);
}
@@ -299,49 +301,57 @@ private File findSubRoot(File root, File in)
return findSubRoot(root, parent);
}
- private String load(URI uri, Loader loader) throws InterruptedException, PersistenceLayerException
+ private Optional load(URI uri, Loader loader) throws PersistenceLayerException
{
- String dataBuffer;
context.setSourceURI(uri);
context.setExtractURI(uri);
try
{
- dataBuffer = LstFileLoader.readFromURI(uri);
- }
- catch (PersistenceLayerException ple)
- {
- String message = LanguageBundle.getFormattedString("Errors.LstFileLoader.LoadError", //$NON-NLS-1$
- uri, ple.getMessage());
- Logging.errorPrint(message);
- return null;
- }
+ return LstFileLoader.readFromURI(uri)
+ .map((String dataBuffer) -> {
+ StringBuilder resultBuffer = new StringBuilder(dataBuffer.length());
- StringBuilder resultBuffer = new StringBuilder(dataBuffer.length());
- final String aString = dataBuffer;
-
- String[] fileLines = aString.split(LstFileLoader.LINE_SEPARATOR_REGEXP);
- for (int line = 0; line < fileLines.length; line++)
- {
- String lineString = fileLines[line];
- if ((lineString.isEmpty()) || (lineString.charAt(0) == LstFileLoader.LINE_COMMENT_CHAR)
- || lineString.startsWith("SOURCE"))
- {
- resultBuffer.append(lineString);
- }
- else
- {
- List newObj = loader.process(resultBuffer, line, lineString, decider);
- if (newObj != null)
- {
- for (CDOMObject cdo : newObj)
+ String[] fileLines = dataBuffer.split(LstFileLoader.LINE_SEPARATOR_REGEXP);
+ for (int line = 0; line < fileLines.length; line++)
{
- injected.addToListFor(loader, uri, cdo);
+ String lineString = fileLines[line];
+ if ((lineString.isEmpty()) || (lineString.charAt(0) == LstFileLoader.LINE_COMMENT_CHAR)
+ || lineString.startsWith("SOURCE"))
+ {
+ resultBuffer.append(lineString);
+ }
+ else
+ {
+ try
+ {
+ List newObj = loader.process(resultBuffer, line, lineString, decider);
+ if (newObj != null)
+ {
+ for (CDOMObject cdo : newObj)
+ {
+ injected.addToListFor(loader, uri, cdo);
+ }
+ }
+ }
+ catch (PersistenceLayerException | InterruptedException e)
+ {
+ String message = LanguageBundle.getFormattedString("Errors.LstFileLoader.LoadError", //$NON-NLS-1$
+ uri, e.getMessage());
+ Logging.errorPrint(message, e);
+ return null;
+ }
+ }
+ resultBuffer.append("\n");
}
- }
- }
- resultBuffer.append("\n");
+ return resultBuffer.toString();
+ });
+ }
+ catch (PersistenceLayerException ple)
+ {
+ Logging.errorPrint(LanguageBundle.getFormattedString("Errors.LstFileLoader.LoadError", //$NON-NLS-1$
+ uri, ple.getMessage()));
+ return Optional.empty();
}
- return resultBuffer.toString();
}
public Collection getInjectedLoaders()
diff --git a/code/src/java/pcgen/gui2/converter/Loader.java b/code/src/java/pcgen/gui2/converter/Loader.java
index 694ecd0a2fe..8608d5685de 100644
--- a/code/src/java/pcgen/gui2/converter/Loader.java
+++ b/code/src/java/pcgen/gui2/converter/Loader.java
@@ -1,16 +1,16 @@
/*
* Copyright (c) 2009 Tom Parker
- *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
@@ -26,9 +26,8 @@
public interface Loader
{
- public List process(StringBuilder sb, int line, String lineString, ConversionDecider decider)
+ List process(StringBuilder sb, int line, String lineString, ConversionDecider decider)
throws PersistenceLayerException, InterruptedException;
- public List getFiles(Campaign campaign);
-
+ List getFiles(Campaign campaign);
}
diff --git a/code/src/java/pcgen/gui2/converter/ObjectInjector.java b/code/src/java/pcgen/gui2/converter/ObjectInjector.java
index c0f19541e91..71b93a9818e 100644
--- a/code/src/java/pcgen/gui2/converter/ObjectInjector.java
+++ b/code/src/java/pcgen/gui2/converter/ObjectInjector.java
@@ -171,7 +171,7 @@ private boolean processWrite(Campaign campaign, TripleKeyMapToList
- *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
@@ -88,7 +88,8 @@ public boolean performAnalysis(CDOMObject pc)
SettingsHandler.setGame(gameMode.getName());
}
// Globals.emptyLists();
- Globals.sortPObjectListByName(Globals.getCampaignList());
+ // TODO the campaign list is an unmodifiable list, so it is not possible to sort it.
+ // Globals.sortPObjectListByName(Globals.getCampaignList());
return saveGameMode(pc);
}
diff --git a/code/src/java/pcgen/gui2/tabs/SkillInfoTab.java b/code/src/java/pcgen/gui2/tabs/SkillInfoTab.java
index 562881a19d9..5b6e0ac98a5 100644
--- a/code/src/java/pcgen/gui2/tabs/SkillInfoTab.java
+++ b/code/src/java/pcgen/gui2/tabs/SkillInfoTab.java
@@ -1,20 +1,20 @@
/*
* Copyright 2008 Connor Petty
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
*/
package pcgen.gui2.tabs;
@@ -79,7 +79,6 @@
import pcgen.gui2.util.event.ListDataAdapter;
import pcgen.gui2.util.table.TableCellUtilities;
import pcgen.gui2.util.table.TableCellUtilities.SpinnerEditor;
-import pcgen.gui2.util.table.TableCellUtilities.SpinnerRenderer;
import pcgen.gui3.JFXPanelFromResource;
import pcgen.gui3.SimpleHtmlPanelController;
import pcgen.system.LanguageBundle;
diff --git a/code/src/java/pcgen/gui3/JFXPanelFromResource.java b/code/src/java/pcgen/gui3/JFXPanelFromResource.java
index a1e34ae8108..0d471d77b89 100644
--- a/code/src/java/pcgen/gui3/JFXPanelFromResource.java
+++ b/code/src/java/pcgen/gui3/JFXPanelFromResource.java
@@ -112,5 +112,4 @@ public void showAndBlock(String title)
});
lock.join();
}
-
}
diff --git a/code/src/java/pcgen/gui3/PanelFromResource.java b/code/src/java/pcgen/gui3/PanelFromResource.java
new file mode 100644
index 00000000000..be8ca562757
--- /dev/null
+++ b/code/src/java/pcgen/gui3/PanelFromResource.java
@@ -0,0 +1,89 @@
+package pcgen.gui3;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import pcgen.system.LanguageBundle;
+
+import java.text.MessageFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Objects;
+
+/**
+ * A utility class for loading and displaying JavaFX scenes from FXML resources.
+ * This class provides functionality to load FXML files, assign their controllers,
+ * and display the loaded scenes in a new JavaFX stage.
+ *
+ * @param The type of the controller associated with the FXML resource.
+ */
+public class PanelFromResource implements Controllable
+{
+ private static final Logger LOG = Logger.getLogger(PanelFromResource.class.getName());
+
+ private final FXMLLoader fxmlLoader = new FXMLLoader();
+
+ /**
+ * Constructs a new PanelFromResource instance.
+ *
+ * @param klass The class relative to which the FXML resource is located.
+ * @param resourceName The name of the FXML resource file to load.
+ * @throws NullPointerException if the resource cannot be found.
+ */
+ public PanelFromResource(Class extends T> klass, String resourceName)
+ {
+ URL resource = klass.getResource(resourceName);
+ Objects.requireNonNull(resource,
+ () -> MessageFormat.format("Resource {0} not found relative to class {1}", resourceName, klass));
+ LOG.log(Level.FINE, () -> MessageFormat.format(
+ "Loading a scene for resource name {0} (a class {1}). The final location is {2}", resourceName, klass,
+ resource));
+ fxmlLoader.setLocation(resource);
+ fxmlLoader.setResources(LanguageBundle.getBundle());
+ }
+
+ /**
+ * Retrieves the controller associated with the loaded FXML resource.
+ *
+ * @return The controller instance.
+ * @throws IllegalStateException if this method is called outside the JavaFX application thread.
+ */
+ @Override
+ public T getController()
+ {
+ GuiAssertions.assertIsJavaFXThread();
+ return fxmlLoader.getController();
+ }
+
+ /**
+ * Displays the loaded FXML resource as a new JavaFX stage.
+ *
+ * @param title The title of the stage to be displayed.
+ * @throws IllegalStateException if this method is called outside the JavaFX application thread.
+ */
+ public void showAsStage(String title)
+ {
+ GuiAssertions.assertIsJavaFXThread();
+
+ try
+ {
+ // Load the scene from the FXML resource.
+ Scene scene = fxmlLoader.load();
+
+ // Create and configure a new stage.
+ Stage stage = new Stage();
+ stage.setTitle(title);
+ stage.setScene(scene);
+ stage.sizeToScene();
+ stage.show();
+ } catch (IOException e)
+ {
+ LOG.log(Level.SEVERE,
+ MessageFormat.format("Failed to load stream fxml from location {0})", fxmlLoader.getLocation()),
+ e);
+ }
+ }
+}
diff --git a/code/src/java/pcgen/io/ExportHandler.java b/code/src/java/pcgen/io/ExportHandler.java
index 671de1eb7dc..a2f4b83dd5b 100644
--- a/code/src/java/pcgen/io/ExportHandler.java
+++ b/code/src/java/pcgen/io/ExportHandler.java
@@ -32,7 +32,14 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import pcgen.cdom.base.CDOMObject;
@@ -75,13 +82,13 @@
import pcgen.util.enumeration.View;
/**
- * This class deals with exporting a PC to various types of output sheets
- * including XML, HTML, PDF and Text.
- *
- * Very basically it takes a PC (or PCs) and replaces tokens in a character
- * sheet template with the appropriate values from the PC (PCs). Much of the
- * code in here deals with replacing tokens and dealing with the FOR and IIF
- * constructs that can be found in the character sheet templates.
+ * This class deals with exporting a PC to various types of output sheets
+ * including XML, HTML, PDF, and Text.
+ *
+ * Very basically, it takes a PC (or PCs) and replaces tokens in a character
+ * sheet template with the appropriate values from the PC (PCs). Much of the
+ * code in here deals with replacing tokens and dealing with the FOR and IIF
+ * constructs that can be found in the character sheet templates.
*
*/
public abstract class ExportHandler
@@ -104,9 +111,9 @@ public static ExportHandler createExportHandler(File templateFile)
/** A map of output tokens to export */
private static final Map TOKEN_MAP = new HashMap<>();
- /**
+ /**
* A variable to hold the state of whether or not the output token map to
- * be exported is populated or not.
+ * be exported is populated or not.
*/
private static boolean tokenMapPopulated;
@@ -125,7 +132,7 @@ public static ExportHandler createExportHandler(File templateFile)
private final File templateFile;
/**
- * These maps hold the loop variables and parameters of FOR constructs that
+ * These maps hold the loop variables and parameters of FOR constructs that
* will be replaced by their actual values when evaluated.
*/
protected final Map