diff --git a/.github/agents/my-code-review-agent.md b/.github/agents/my-code-review-agent.md
new file mode 100644
index 00000000000..c17ec434ba2
--- /dev/null
+++ b/.github/agents/my-code-review-agent.md
@@ -0,0 +1,8 @@
+---
+name: Code Review Agent
+description: Agent that specilises in code reviews, digging into the why of the change.
+---
+
+# My Agent
+
+Agent that specilises in code reviews, digging into the why of the change.
diff --git a/.github/agents/my-security-agent.md b/.github/agents/my-security-agent.md
new file mode 100644
index 00000000000..5d5fa5c7641
--- /dev/null
+++ b/.github/agents/my-security-agent.md
@@ -0,0 +1,8 @@
+---
+name: Security Review Agent
+description: Security Review Agent
+---
+
+# My Agent
+
+Reviews the code for security vulnerabilities and bad coding practices.
diff --git a/.github/workflows/gradle-release.yml b/.github/workflows/gradle-release.yml
new file mode 100644
index 00000000000..1d3f9245b36
--- /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 25
+ uses: actions/setup-java@v4
+ with:
+ java-version: '25'
+ 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..4034f333f3b
--- /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 25
+ uses: actions/setup-java@v4
+ with:
+ java-version: '25'
+ 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..0c372a0bf96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,8 @@
.settings/
/settings/
+testsuite/
+
# Batch converter
batch-convert.jar
@@ -94,6 +96,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..86677ddba73 100644
--- a/README.md
+++ b/README.md
@@ -12,19 +12,19 @@ It supports numerous game systems, most notably:
# Table of Contents
1. [Installing From Release 6.08](#installing-from-release-608)
-1. [Installing From Release 6.09 (Alpha)](#installing-from-release-609-alpha)
+2. [Installing From Release 6.09 (Alpha)](#installing-from-release-609-alpha)
-1. [PCGen Needs You](#pcgen-needs-you)
+3. [PCGen Needs You](#pcgen-needs-you)
-1. [The Old Wiki](#the-old-wiki)
+4. [The Old Wiki](#the-old-wiki)
-1. [PCGen LST Tutorial](#pcgen-lst-tutorial)
+5. [PCGen LST Tutorial](#pcgen-lst-tutorial)
-1. [Basic Workflow](#basic-workflow)
+6. [Basic Workflow](#basic-workflow)
-1. [Development Setup](#development-setup)
+7. [Development Setup](#development-setup)
-1. [Essential Gradle Tasks](#essential-gradle-tasks)
+8. [Essential Gradle Tasks](#essential-gradle-tasks)
# Installing From Release 6.08
1. Install Java.
@@ -32,9 +32,9 @@ It supports numerous game systems, most notably:
- To check if you have Java installed, see [Install Java](#install-java)
- If you don't have it already, you can get it from [AdoptOpenJDK](https://adoptopenjdk.net/installation.html?variant=openjdk11&jvmVariant=hotspot).
-1. Download and extract the full zip file from https://github.com/PCGen/pcgen/releases/latest.
+2. Download and extract the full zip file from https://github.com/PCGen/pcgen/releases/latest.
-1. You should now be able to run PCGen. The exact invocation depends on your operating system, but you should be able to either double-click to launch the file for your platform.
+3. You should now be able to run PCGen. The exact invocation depends on your operating system, but you should be able to either double-click to launch the file for your platform.
- Windows: `pcgen.exe` (`pcgen.bat` for command-line users)
- Linux: `pcgen.sh`
- Mac: `pcgen.jar` (or `pcgen.dmg` if it exists)
@@ -43,36 +43,36 @@ It supports numerous game systems, most notably:
> Note: Java does not need to be preinstalled with PcGen >6.09.05
## Using Zip bundle
-1. Download and extract the full zip file from https://github.com/PCGen/pcgen/releases/ labled 6.09.xx.
+1. Download and extract the full zip file from https://github.com/PCGen/pcgen/releases/ labeled 6.09.xx.
-1. You should now be able to run PCGen. The exact invocation depends on your operating system, but you should be able to either double-click to launch the file for your platform.
+2. You should now be able to run PCGen. The exact invocation depends on your operating system, but you should be able to either double-click to launch the file for your platform.
- Windows: `pcgen.exe` (`pcgen.bat` for command-line users)
- Linux: `pcgen.sh`
- Mac: `pcgen.sh` (or `pcgen.dmg` if it exists. Launching .jar may throw java errors so generally avoid)
## Using installer (windows and mac only)
-1. Download and extract the full installer from https://github.com/PCGen/pcgen/releases/ labled 6.09.xx.
+1. Download and extract the full installer from https://github.com/PCGen/pcgen/releases/ labeled 6.09.xx.
- Windows: `pcgen-6.09.xx_win_install.exe`
- Mac: `pcgen-6.09.xx.dmg` or `pcgen-6.09.xx.pkg`
-1. Run installer and follow instruction
+2. 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`.
+3. 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. 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. 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.
+2. 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.
+3. Work until the feature or bug is finished. Add tests if needed, especially if new code is added.
+4. Push all work up into your copy of [PCGen]. Try to ensure the build passes BEFORE submitting a pull request.
+5. Submit a pull request from your fork to master and respond to a review by members.
+6. 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
@@ -112,7 +112,7 @@ Check the installed version with:
java -version
For 6.08 development you will want Java with a minimum version of 11.
-For 6.09 development you will want Java with a minimum version of 17.
+For 6.09 development you will want Java with a minimum version of 25.
You can install the latest version from [AdoptOpenJDK](https://adoptopenjdk.net) regardless of your OS, please see instructions there.
### Install Git
@@ -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..b367f07b41c 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 '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,32 @@ ext {
// Installers are placed here
releaseDir = layout.projectDirectory.dir("build/release")
- // JavaFX version
- javaFXVersion = "21.0.5"
+ // Java version. It will affect JavaFX version too.
+ javaVersion = 25
+
+ // The Eclipse Adoptium API will return the latest patch release for the majorJava version set
+ 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 +119,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 +140,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,88 +232,56 @@ 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.14'
+ implementation 'org.springframework:spring-beans:6.2.14'
+ implementation 'org.springframework:spring-core:6.2.14'
+ 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'
-
- 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'
- testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '6.0.1'
- testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '6.0.1'
- testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '6.0.1'
- testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '3.0'
- testImplementation group: 'org.testfx', name: 'testfx-junit5', version: '4.0.18'
- testImplementation group: 'org.testfx', name: 'openjfx-monocle', version: '21.0.2'
-
- testImplementation group: 'org.xmlunit', name: 'xmlunit-matchers', version: '2.11.0'
+ 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 'org.junit.platform:junit-platform-runner:1.14.1'
+ testImplementation 'org.junit.platform:junit-platform-launcher:6.0.1'
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:6.0.1'
+ testImplementation 'org.junit.jupiter:junit-jupiter-params:6.0.1'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:6.0.1'
+ testImplementation 'org.hamcrest:hamcrest:3.0'
+ testImplementation 'org.testfx:testfx-junit5:4.0.18'
+ // 21.0.2 is the latest version. As of Nov 2025, we have moved to OpenJFX 25 so this may cause issues
+ testImplementation 'org.testfx:openjfx-monocle:21.0.2'
+
+ testImplementation 'org.xmlunit:xmlunit-matchers: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-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'
+ pmd 'net.sourceforge.pmd:pmd-ant:7.19.0' // workaround: https://github.com/pmd/pmd/issues/4554
}
ext {
@@ -308,15 +291,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 +315,28 @@ 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.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 +352,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 +388,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 +397,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 +426,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")
@@ -457,8 +441,12 @@ tasks.register("copyToLibs", Copy) {
from configurations.runtimeClasspath
}
+// Fix implicit dependency issues with distribution tasks
+distZip.dependsOn copyToLibs
+distTar.dependsOn copyToLibs
+
tasks.register("copyToOutput", Copy) {
- dependsOn copyToLibs, createExe, converterJar, jar
+ dependsOn copyToLibs, converterJar, jar
doFirst {
println("IN copyToOutput")
@@ -466,7 +454,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 +516,12 @@ tasks.named("build") {
}
tasks.register("downloadJRE") {
- def major = 21
- def archs = ['x64', 'aarch64']
+ notCompatibleWithConfigurationCache("Gradle download extension not compatible")
+
+ def major = project.ext.javaVersion
+ def architectures = ['x64', 'aarch64']
def osList = ['windows', 'mac', 'linux']
+ def baseJreDir = project.ext.jresDir
doLast {
println("Downloading JDKs for use in creating the runtime bundles.")
@@ -540,18 +530,18 @@ tasks.register("downloadJRE") {
def os = "${it}"
def extension = (os == "windows" ? "zip" : "tar.gz")
- archs.each {
+ architectures.each {
def arch = "${it}"
// TODO We don't currently support Windows aarch64, but once Eclipse Adoptium does we should remove this line
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 +560,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 +570,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 +592,7 @@ tasks.register("downloadJRE") {
}
}
- project.delete(archFile)
+ delete(archFile)
}
file("${projectDir}/jre/${os}/jre_${arch}").list().each { f ->
@@ -616,13 +606,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 archs = ['x64', 'aarch64']
+ def major = project.javaVersion
+ def architectures = ['x64', 'aarch64']
def osList = ["windows", "mac", "linux"]
+ def baseJreDir = project.ext.jresDir
+ def projectDirPath = projectDir.absolutePath
inputs.property("major", major)
@@ -633,27 +626,24 @@ tasks.register("downloadJavaFXModules") {
// Build the os part of the filename string. Gluon renamed the mac package to osx
def osPackage = (os == "mac") ? "osx" : os
- archs.each { arch ->
+ architectures.each { arch ->
// build the architecture part of the download filename string
def archAppend
if (arch == "x64") {
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
+ // URLs look like this: https://download2.gluonhq.com/openjfx/25.0.1/openjfx-25.0.1_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 +654,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 +687,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 +700,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 +738,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 +777,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 +792,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 +800,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 +808,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 +816,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 +824,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 +832,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 +855,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 +868,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 +959,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 +971,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..a340e536f11 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,8 +19,9 @@ pmd {
ruleSetFiles = files('code/standards/ruleset.xml')
consoleOutput = true
sourceSets = []
- toolVersion = "7.7.0"
+ toolVersion = "7.18.0"
incrementalAnalysis = true
+ ignoreFailures = false
}
// TODO fix the outstanding bugs and then remove the ignoreFailures
@@ -28,7 +29,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 +40,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/CDOMListObject.java b/code/src/java/pcgen/cdom/base/CDOMListObject.java
index dae0f63053a..6bd4a87263e 100644
--- a/code/src/java/pcgen/cdom/base/CDOMListObject.java
+++ b/code/src/java/pcgen/cdom/base/CDOMListObject.java
@@ -72,7 +72,6 @@ public String getLSTformat()
}
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public boolean isInternal()
{
return false;
diff --git a/code/src/java/pcgen/cdom/base/CDOMObject.java b/code/src/java/pcgen/cdom/base/CDOMObject.java
index 580082415e9..43824565d27 100644
--- a/code/src/java/pcgen/cdom/base/CDOMObject.java
+++ b/code/src/java/pcgen/cdom/base/CDOMObject.java
@@ -1341,7 +1341,6 @@ public String[] getGrantedVariableArray()
* @return The local child of the given child type and child name
*/
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public PCGenScoped getLocalChild(String childType, String childName)
{
//none by default
@@ -1357,7 +1356,6 @@ public PCGenScoped getLocalChild(String childType, String childName)
* @return The List of child types that this CDOMObject contains
*/
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public List getChildTypes()
{
return Collections.emptyList();
@@ -1372,7 +1370,6 @@ public List getChildTypes()
* @return The List of children of the given child type
*/
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public List getChildren(String childType)
{
//none by default
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/cdom/base/PCGenIdentifier.java b/code/src/java/pcgen/cdom/base/PCGenIdentifier.java
index 66061986ecf..792c999ba4a 100644
--- a/code/src/java/pcgen/cdom/base/PCGenIdentifier.java
+++ b/code/src/java/pcgen/cdom/base/PCGenIdentifier.java
@@ -24,6 +24,7 @@
* Generics to have a minimal compile requirement of using an expected identifier rather
* than an arbitrary object.
*/
+@FunctionalInterface
public interface PCGenIdentifier
{
/**
diff --git a/code/src/java/pcgen/cdom/base/PrimitiveCollection.java b/code/src/java/pcgen/cdom/base/PrimitiveCollection.java
index c049624b5f4..75b2e5c181c 100644
--- a/code/src/java/pcgen/cdom/base/PrimitiveCollection.java
+++ b/code/src/java/pcgen/cdom/base/PrimitiveCollection.java
@@ -107,6 +107,7 @@ public PrimitiveCollection invalid()
}
};
+ @FunctionalInterface
public interface PrimLibrary
{
PrimitiveCollection invalid();
diff --git a/code/src/java/pcgen/cdom/base/SortKeyRequired.java b/code/src/java/pcgen/cdom/base/SortKeyRequired.java
index d0597c15bd6..c48604dfb6e 100644
--- a/code/src/java/pcgen/cdom/base/SortKeyRequired.java
+++ b/code/src/java/pcgen/cdom/base/SortKeyRequired.java
@@ -19,6 +19,7 @@
* This is used identify when a SORTKEY is a required part of an object. This avoids
* implicit sorting of certain files (stat, et al).
*/
+@FunctionalInterface
public interface SortKeyRequired
{
/**
diff --git a/code/src/java/pcgen/cdom/content/UserContent.java b/code/src/java/pcgen/cdom/content/UserContent.java
index f03c94bdf25..d97ee0b2479 100644
--- a/code/src/java/pcgen/cdom/content/UserContent.java
+++ b/code/src/java/pcgen/cdom/content/UserContent.java
@@ -97,14 +97,12 @@ public String getExplanation()
}
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public boolean isInternal()
{
return false;
}
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public boolean isType(String type)
{
return false;
diff --git a/code/src/java/pcgen/cdom/enumeration/DisplayLocation.java b/code/src/java/pcgen/cdom/enumeration/DisplayLocation.java
index 95b1fc3d40b..eebd4d886d3 100644
--- a/code/src/java/pcgen/cdom/enumeration/DisplayLocation.java
+++ b/code/src/java/pcgen/cdom/enumeration/DisplayLocation.java
@@ -29,7 +29,6 @@
* in a type-safe fashion, so that they can be quickly compared and use less
* memory when identical DisplayLocations exist.
*/
-@SuppressWarnings("PMD.EQ_COMPARETO_USE_OBJECT_EQUALS")
public final class DisplayLocation implements TypeSafeConstant, Comparable
{
/**
diff --git a/code/src/java/pcgen/cdom/enumeration/FormulaKey.java b/code/src/java/pcgen/cdom/enumeration/FormulaKey.java
index ef0c2574986..b6818faa635 100644
--- a/code/src/java/pcgen/cdom/enumeration/FormulaKey.java
+++ b/code/src/java/pcgen/cdom/enumeration/FormulaKey.java
@@ -38,7 +38,7 @@
* *Important*: This should NOT be used to store items from the DEFINE: token,
* as those are Variables that should be stored using VariableKey
*/
-@SuppressWarnings({"PMD.ClassWithOnlyPrivateConstructorsShouldBeFinal", "checkstyle:FinalClass"})
+@SuppressWarnings("checkstyle:FinalClass")
public class FormulaKey implements TypeSafeConstant
{
diff --git a/code/src/java/pcgen/cdom/enumeration/IntegerKey.java b/code/src/java/pcgen/cdom/enumeration/IntegerKey.java
index df01a99553f..8bb496b4bdb 100644
--- a/code/src/java/pcgen/cdom/enumeration/IntegerKey.java
+++ b/code/src/java/pcgen/cdom/enumeration/IntegerKey.java
@@ -34,7 +34,7 @@
* getSafe(IntegerKey) is called in CDOMObject). The default "default value" is
* zero.
*/
-@SuppressWarnings({"PMD.ClassWithOnlyPrivateConstructorsShouldBeFinal", "checkstyle:FinalClass"})
+@SuppressWarnings("checkstyle:FinalClass")
public class IntegerKey
{
diff --git a/code/src/java/pcgen/cdom/enumeration/ObjectKey.java b/code/src/java/pcgen/cdom/enumeration/ObjectKey.java
index 8a5bcd9587f..479cd832c77 100644
--- a/code/src/java/pcgen/cdom/enumeration/ObjectKey.java
+++ b/code/src/java/pcgen/cdom/enumeration/ObjectKey.java
@@ -88,7 +88,7 @@
* @param
* The class of object stored by this ObjectKey.
*/
-@SuppressWarnings({"PMD.ClassWithOnlyPrivateConstructorsShouldBeFinal", "checkstyle:FinalClass"})
+@SuppressWarnings("checkstyle:FinalClass")
public class ObjectKey
{
diff --git a/code/src/java/pcgen/cdom/facet/analysis/ChallengeRatingFacet.java b/code/src/java/pcgen/cdom/facet/analysis/ChallengeRatingFacet.java
index d95dd166f07..110897f4656 100644
--- a/code/src/java/pcgen/cdom/facet/analysis/ChallengeRatingFacet.java
+++ b/code/src/java/pcgen/cdom/facet/analysis/ChallengeRatingFacet.java
@@ -275,8 +275,7 @@ private Integer getClassRaceCRMod(CharID id, PCClass cl)
{
if (SettingsHandler.getGameAsProperty().get().getClassTypeByName(classType) != null)
{
- Integer crMod = raceFacet.get(id).get(MapKey.CRMOD, classType);
- return crMod;
+ return raceFacet.get(id).get(MapKey.CRMOD, classType);
}
}
else
diff --git a/code/src/java/pcgen/cdom/helper/AbstractProfProvider.java b/code/src/java/pcgen/cdom/helper/AbstractProfProvider.java
index e59584bc96a..1af8861330a 100644
--- a/code/src/java/pcgen/cdom/helper/AbstractProfProvider.java
+++ b/code/src/java/pcgen/cdom/helper/AbstractProfProvider.java
@@ -128,7 +128,6 @@ public boolean providesProficiency(T proficiency)
* given Equipment TYPE.
*/
@Override
- @SuppressWarnings("PMD.AvoidBranchingStatementAsLastInLoop")
public boolean providesEquipmentType(String typeString)
{
if (typeString == null || typeString.isEmpty())
diff --git a/code/src/java/pcgen/cdom/helper/AbstractSimpleProfProvider.java b/code/src/java/pcgen/cdom/helper/AbstractSimpleProfProvider.java
index 33e47f9b6c1..62060692e0e 100644
--- a/code/src/java/pcgen/cdom/helper/AbstractSimpleProfProvider.java
+++ b/code/src/java/pcgen/cdom/helper/AbstractSimpleProfProvider.java
@@ -78,7 +78,6 @@ public boolean providesProficiency(T proficiency)
* @return true, as AbstractSimpleProfProvider is not a conditional object
*/
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public boolean qualifies(PlayerCharacter playerCharacter, Object owner)
{
return true;
@@ -98,7 +97,6 @@ public boolean qualifies(PlayerCharacter playerCharacter, Object owner)
* based on Equipment TYPE
*/
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public boolean providesEquipmentType(String type)
{
return false;
diff --git a/code/src/java/pcgen/cdom/helper/SpringHelper.java b/code/src/java/pcgen/cdom/helper/SpringHelper.java
index 28beabd8765..be8581323b7 100644
--- a/code/src/java/pcgen/cdom/helper/SpringHelper.java
+++ b/code/src/java/pcgen/cdom/helper/SpringHelper.java
@@ -58,7 +58,8 @@ private SpringHelper()
* @param cl The type of bean to be retrieved.
* @return The bean, or null if none exists.
*/
- public static @Nullable T getBean(Class cl)
+ @Nullable
+ public static T getBean(Class cl)
{
String[] beanNamesForType = BEAN_FACTORY.getBeanNamesForType(cl);
if (beanNamesForType.length == 0)
diff --git a/code/src/java/pcgen/cdom/inst/AbstractCategory.java b/code/src/java/pcgen/cdom/inst/AbstractCategory.java
index 19fd1511652..841b9b95b64 100644
--- a/code/src/java/pcgen/cdom/inst/AbstractCategory.java
+++ b/code/src/java/pcgen/cdom/inst/AbstractCategory.java
@@ -53,7 +53,6 @@ public abstract class AbstractCategory> implements Cate
private URI sourceURI;
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public Category getParentCategory()
{
//By default, no hierarchy
@@ -162,7 +161,6 @@ public boolean populate(ReferenceManufacturer parentCrm, ReferenceManufacture
}
@Override
- @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract")
public ManufacturableFactory getParent()
{
return null;
diff --git a/code/src/java/pcgen/cdom/reference/AbstractReferenceManufacturer.java b/code/src/java/pcgen/cdom/reference/AbstractReferenceManufacturer.java
index 16b3da30f2b..4929167c105 100644
--- a/code/src/java/pcgen/cdom/reference/AbstractReferenceManufacturer.java
+++ b/code/src/java/pcgen/cdom/reference/AbstractReferenceManufacturer.java
@@ -1178,7 +1178,7 @@ public void fireUnconstuctedEvent(CDOMReference> ref)
// Lazily create event
if (uEvent == null)
{
- uEvent = new UnconstructedEvent(this, ref); // NOPMD
+ uEvent = new UnconstructedEvent(this, ref);
}
((UnconstructedListener) listeners[i + 1]).unconstructedReferenceFound(uEvent);
}
diff --git a/code/src/java/pcgen/core/Equipment.java b/code/src/java/pcgen/core/Equipment.java
index 6327e28b65e..2e4c1195b5b 100644
--- a/code/src/java/pcgen/core/Equipment.java
+++ b/code/src/java/pcgen/core/Equipment.java
@@ -2651,7 +2651,6 @@ public int canContain(final PlayerCharacter aPC, final Object obj)
* @return Description of the Return Value
*/
@Override
- @SuppressWarnings("PMD.CloneMethodMustImplementCloneable")
public Equipment clone()
{
Equipment eq = null;
diff --git a/code/src/java/pcgen/core/GameMode.java b/code/src/java/pcgen/core/GameMode.java
index 92df328e63f..8661e7e1e04 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
@@ -1222,7 +1222,6 @@ public void setPurchaseMethodName(final String argMethodName)
* @param aPC
* @return purchase mode base score
*/
- @SuppressWarnings("PMD.OneDeclarationPerLine")
public int getPurchaseModeBaseStatScore(final PlayerCharacter aPC)
{
int minVal = getPurchaseScoreMin(aPC);
@@ -1939,7 +1938,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 +1959,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 +2253,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/RollingMethods.java b/code/src/java/pcgen/core/RollingMethods.java
index 3a4130fd2e7..a79063dfaed 100644
--- a/code/src/java/pcgen/core/RollingMethods.java
+++ b/code/src/java/pcgen/core/RollingMethods.java
@@ -242,7 +242,7 @@ private Roll()
* rolls the dice on the randomizer, and pushes the result back onto the stack.
* Logging is performed if it is turned on.
*/
- @SuppressWarnings({"UseOfObsoleteCollectionType", "PMD.ReplaceVectorWithList"})
+ @SuppressWarnings("UseOfObsoleteCollectionType")
@Override
public void run(final Stack stack) throws ParseException
{
diff --git a/code/src/java/pcgen/core/SpellProgressionCache.java b/code/src/java/pcgen/core/SpellProgressionCache.java
index 4e72cefdceb..50846f77b11 100644
--- a/code/src/java/pcgen/core/SpellProgressionCache.java
+++ b/code/src/java/pcgen/core/SpellProgressionCache.java
@@ -322,8 +322,7 @@ public int getMinLevelForSpellLevel(int spellLevel, boolean allowBonus)
*/
if (knownProgression != null)
{
- int lvl = knownProgression.getMinLevelForSpellLevel(spellLevel, allowBonus);
- return lvl;
+ return knownProgression.getMinLevelForSpellLevel(spellLevel, allowBonus);
}
return -1;
diff --git a/code/src/java/pcgen/core/VariableContainer.java b/code/src/java/pcgen/core/VariableContainer.java
index 8e272c96b29..258f547a86a 100644
--- a/code/src/java/pcgen/core/VariableContainer.java
+++ b/code/src/java/pcgen/core/VariableContainer.java
@@ -24,6 +24,7 @@
* small however it will be extended over time as the variable handling routines
* are made common.
*/
+@FunctionalInterface
public interface VariableContainer
{
/**
diff --git a/code/src/java/pcgen/core/VariableProcessor.java b/code/src/java/pcgen/core/VariableProcessor.java
index 591332083eb..72fe71feac6 100644
--- a/code/src/java/pcgen/core/VariableProcessor.java
+++ b/code/src/java/pcgen/core/VariableProcessor.java
@@ -408,8 +408,6 @@ else if ("ELSE".equals(cString))
case MINUS -> total -= valFloat;
case MULTIPLY -> total *= valFloat;
case DIVIDE -> total /= valFloat;
- default -> Logging.errorPrint(
- "In PlayerCharacter.getVariableValue the mode " + mode + " is unsupported.");
}
}
diff --git a/code/src/java/pcgen/core/character/SpellBook.java b/code/src/java/pcgen/core/character/SpellBook.java
index ba0cc9bf3d8..7836d1cbaa5 100644
--- a/code/src/java/pcgen/core/character/SpellBook.java
+++ b/code/src/java/pcgen/core/character/SpellBook.java
@@ -190,7 +190,7 @@ public final void setType(int type)
*/
public final String getTypeName()
{
- String retValue = switch (getType())
+ return switch (getType())
{
case SpellBook.TYPE_KNOWN_SPELLS -> "Known Spell List";
case SpellBook.TYPE_PREPARED_LIST -> "Prepared Spell List";
@@ -198,7 +198,6 @@ public final String getTypeName()
case SpellBook.TYPE_INNATE_SPELLS -> "Innate Spell List";
default -> "Unknown spell list type: " + getType();
};
- return retValue;
}
/**
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/facade/core/EquipmentListFacade.java b/code/src/java/pcgen/facade/core/EquipmentListFacade.java
index e20677440da..742ba56d0b5 100644
--- a/code/src/java/pcgen/facade/core/EquipmentListFacade.java
+++ b/code/src/java/pcgen/facade/core/EquipmentListFacade.java
@@ -37,6 +37,7 @@ public interface EquipmentListFacade extends ListFacade
*/
public void modifyElement(EquipmentFacade equipment);
+ @FunctionalInterface
public static interface EquipmentListListener extends EventListener
{
diff --git a/code/src/java/pcgen/facade/core/EquipmentSetFacade.java b/code/src/java/pcgen/facade/core/EquipmentSetFacade.java
index ced6bc9967b..a6e7662de03 100644
--- a/code/src/java/pcgen/facade/core/EquipmentSetFacade.java
+++ b/code/src/java/pcgen/facade/core/EquipmentSetFacade.java
@@ -122,6 +122,7 @@ public interface EquipmentSetFacade
*/
public String getLocation(EquipmentFacade equip);
+ @FunctionalInterface
public static interface EquipmentTreeListener extends EventListener
{
diff --git a/code/src/java/pcgen/facade/core/GameModeDisplayFacade.java b/code/src/java/pcgen/facade/core/GameModeDisplayFacade.java
index 384d45d38ba..5a4f21dec03 100644
--- a/code/src/java/pcgen/facade/core/GameModeDisplayFacade.java
+++ b/code/src/java/pcgen/facade/core/GameModeDisplayFacade.java
@@ -20,6 +20,7 @@
import pcgen.core.GameMode;
+@FunctionalInterface
public interface GameModeDisplayFacade
{
@Override
diff --git a/code/src/java/pcgen/facade/core/GearBuySellFacade.java b/code/src/java/pcgen/facade/core/GearBuySellFacade.java
index 0e6314663b1..bf249250212 100644
--- a/code/src/java/pcgen/facade/core/GearBuySellFacade.java
+++ b/code/src/java/pcgen/facade/core/GearBuySellFacade.java
@@ -23,6 +23,7 @@
*
*
*/
+@FunctionalInterface
public interface GearBuySellFacade
{
/**
diff --git a/code/src/java/pcgen/facade/core/SpellSupportFacade.java b/code/src/java/pcgen/facade/core/SpellSupportFacade.java
index 87c6c54e252..fc6d5289e70 100644
--- a/code/src/java/pcgen/facade/core/SpellSupportFacade.java
+++ b/code/src/java/pcgen/facade/core/SpellSupportFacade.java
@@ -149,15 +149,18 @@ public static interface SuperNode
{
}
+ @FunctionalInterface
public static interface RootNode extends SuperNode
{
public String getName();
}
+ @FunctionalInterface
public static interface SpellListNode extends RootNode
{
}
+ @FunctionalInterface
public static interface SpellBookNode extends RootNode
{
}
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/doomsdaybook/NameGenPanel.java b/code/src/java/pcgen/gui2/doomsdaybook/NameGenPanel.java
index e9ef412ec96..e5a2b6d1c27 100644
--- a/code/src/java/pcgen/gui2/doomsdaybook/NameGenPanel.java
+++ b/code/src/java/pcgen/gui2/doomsdaybook/NameGenPanel.java
@@ -75,7 +75,7 @@
/**
* Main panel of the random name generator.
*/
-@SuppressWarnings({"UseOfObsoleteCollectionType", "PMD.ReplaceVectorWithList", "PMD.UseArrayListInsteadOfVector"})
+@SuppressWarnings({"UseOfObsoleteCollectionType", "PMD.UseArrayListInsteadOfVector"})
public class NameGenPanel extends JPanel
{
private final Map> categories = new HashMap<>();
diff --git a/code/src/java/pcgen/gui2/facade/SpellSupportFacadeImpl.java b/code/src/java/pcgen/gui2/facade/SpellSupportFacadeImpl.java
index 9ab379a218b..f5430b65ec3 100644
--- a/code/src/java/pcgen/gui2/facade/SpellSupportFacadeImpl.java
+++ b/code/src/java/pcgen/gui2/facade/SpellSupportFacadeImpl.java
@@ -359,8 +359,7 @@ private List buildAvailableMetamagicFeatList(SpellNode spellNode)
{
return Collections.emptyList();
}
- List availableList = new ArrayList<>(characterMetaMagicFeats);
- return availableList;
+ return new ArrayList<>(characterMetaMagicFeats);
}
@Override
diff --git a/code/src/java/pcgen/gui2/prefs/PurchaseModeFrame.java b/code/src/java/pcgen/gui2/prefs/PurchaseModeFrame.java
index b91b45f1e68..280a86683a2 100644
--- a/code/src/java/pcgen/gui2/prefs/PurchaseModeFrame.java
+++ b/code/src/java/pcgen/gui2/prefs/PurchaseModeFrame.java
@@ -991,7 +991,6 @@ private void appendRows(int nrRows)
currentValues = newValues;
}
- @SuppressWarnings("PMD.OneDeclarationPerLine")
private void keepNewValues()
{
// set the current values into the settings
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/gui2/tabs/spells/SpellTreeViewModel.java b/code/src/java/pcgen/gui2/tabs/spells/SpellTreeViewModel.java
index 2c3e9efe499..a5a187ece12 100644
--- a/code/src/java/pcgen/gui2/tabs/spells/SpellTreeViewModel.java
+++ b/code/src/java/pcgen/gui2/tabs/spells/SpellTreeViewModel.java
@@ -128,9 +128,9 @@ public List> getPaths(SuperNode node)
}
path = new TreeViewPath<>(pobj, pathList.toArray());
}
+ // Don't need a default as the compiler will check that we've covered the enum options
default -> throw new InternalError();
}
-
}
else
{
diff --git a/code/src/java/pcgen/gui2/tools/DesktopBrowserLauncher.java b/code/src/java/pcgen/gui2/tools/DesktopBrowserLauncher.java
index eaf3569fbc0..7353d85a805 100644
--- a/code/src/java/pcgen/gui2/tools/DesktopBrowserLauncher.java
+++ b/code/src/java/pcgen/gui2/tools/DesktopBrowserLauncher.java
@@ -61,7 +61,7 @@ public static void viewInBrowser(File file) throws IOException
* @param uri URI to display in browser.
* @throws IOException if the URL is bad or the browser can not be launched
*/
- @SuppressWarnings({"ThrowInsideCatchBlockWhichIgnoresCaughtException", "PMD.PreserveStackTrace"})
+ @SuppressWarnings("ThrowInsideCatchBlockWhichIgnoresCaughtException")
public static void viewInBrowser(URI uri) throws IOException
{
if (Desktop.isDesktopSupported() && DESKTOP.isSupported(Action.BROWSE))
diff --git a/code/src/java/pcgen/gui2/util/DisplayAwareTab.java b/code/src/java/pcgen/gui2/util/DisplayAwareTab.java
index ca7af22575f..91d867e0b8f 100644
--- a/code/src/java/pcgen/gui2/util/DisplayAwareTab.java
+++ b/code/src/java/pcgen/gui2/util/DisplayAwareTab.java
@@ -24,6 +24,7 @@
*
*
*/
+@FunctionalInterface
public interface DisplayAwareTab
{
/**
diff --git a/code/src/java/pcgen/gui2/util/JTreeTable.java b/code/src/java/pcgen/gui2/util/JTreeTable.java
index bc0b74ec1c7..8c49fb92ac7 100644
--- a/code/src/java/pcgen/gui2/util/JTreeTable.java
+++ b/code/src/java/pcgen/gui2/util/JTreeTable.java
@@ -554,7 +554,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
* @param g
**/
@Override
- public void paint(final Graphics g)
+ public void paint(final Graphics g)
{
Rectangle rect = JTreeTable.this.getCellRect(visibleRow, 0, true);
int offset = -rect.y;
diff --git a/code/src/java/pcgen/gui2/util/StatusWorker.java b/code/src/java/pcgen/gui2/util/StatusWorker.java
index f008274de34..85507282333 100644
--- a/code/src/java/pcgen/gui2/util/StatusWorker.java
+++ b/code/src/java/pcgen/gui2/util/StatusWorker.java
@@ -97,7 +97,7 @@ public List getErrors()
}
@Override
- protected List doInBackground()
+ protected List doInBackground()
{
final String oldMessage = statusBar.getContextMessage();
statusBar.startShowingProgress(statusMsg, false);
diff --git a/code/src/java/pcgen/gui2/util/table/Row.java b/code/src/java/pcgen/gui2/util/table/Row.java
index 5a44f3c4416..3a71e96d67b 100644
--- a/code/src/java/pcgen/gui2/util/table/Row.java
+++ b/code/src/java/pcgen/gui2/util/table/Row.java
@@ -21,6 +21,7 @@
/**
*
*/
+@FunctionalInterface
public interface Row
{
public Object getValueAt(int column);
diff --git a/code/src/java/pcgen/gui2/util/treetable/DefaultSortableTreeTableNode.java b/code/src/java/pcgen/gui2/util/treetable/DefaultSortableTreeTableNode.java
index 08cccf78177..cc7f3fd8912 100644
--- a/code/src/java/pcgen/gui2/util/treetable/DefaultSortableTreeTableNode.java
+++ b/code/src/java/pcgen/gui2/util/treetable/DefaultSortableTreeTableNode.java
@@ -25,7 +25,7 @@
import pcgen.gui2.util.table.Row;
-@SuppressWarnings({"UseOfObsoleteCollectionType", "PMD.ReplaceVectorWithList"})
+@SuppressWarnings("UseOfObsoleteCollectionType")
public class DefaultSortableTreeTableNode extends DefaultTreeTableNode implements SortableTreeTableNode
{
diff --git a/code/src/java/pcgen/gui2/util/treeview/TreeViewTableModel.java b/code/src/java/pcgen/gui2/util/treeview/TreeViewTableModel.java
index e6ecc8a67fe..a0da09ecc50 100644
--- a/code/src/java/pcgen/gui2/util/treeview/TreeViewTableModel.java
+++ b/code/src/java/pcgen/gui2/util/treeview/TreeViewTableModel.java
@@ -42,7 +42,7 @@
import pcgen.util.ListMap;
import pcgen.util.Logging;
-@SuppressWarnings({"UseOfObsoleteCollectionType", "PMD.ReplaceVectorWithList", "PMD.UseArrayListInsteadOfVector"})
+@SuppressWarnings({"UseOfObsoleteCollectionType", "PMD.UseArrayListInsteadOfVector"})
public class TreeViewTableModel extends AbstractTreeTableModel implements SortableTreeTableModel
{
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..04a799cf6b7 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
-
+
diff --git a/code/testsuite/PCGfiles/pf_Cleric.pcg b/code/testsuite/PCGfiles/pf_Cleric.pcg
index 7e2b2f29ee1..deec9285db3 100644
--- a/code/testsuite/PCGfiles/pf_Cleric.pcg
+++ b/code/testsuite/PCGfiles/pf_Cleric.pcg
@@ -263,7 +263,6 @@ CHARACTERMAGIC:
CHARACTERDMNOTES:
# Kits
-KIT:Character Traits
# Character Master/Follower
diff --git a/code/testsuite/base-xml.ftl b/code/testsuite/base-xml.ftl
index 5801f06d4e9..2f83a9bf626 100644
--- a/code/testsuite/base-xml.ftl
+++ b/code/testsuite/base-xml.ftl
@@ -1,6 +1,6 @@
<#ftl encoding="UTF-8" strip_whitespace=true >
-<#--
+<#--
# Freemarker template for the character integration tests.
# Copyright James Dempsey, 2013
#
@@ -57,7 +57,7 @@
${class}
#list>
- #if>
+ #if>
<@pcstring tag="TOTALLEVELS"/><@pcstring tag="ECL"/>
@@ -187,7 +187,7 @@
====================================
====================================-->
-<@loop from=0 to=pcvar('COUNT[STATS]-1') ; stat , stat_has_next >
+<@loop from=0 to=pcvar('COUNT[STATS]-1') ; stat , stat_has_next >
<@pcstring tag="STAT.${stat}.LONGNAME"/>
@@ -202,7 +202,7 @@
<@pcstring tag="STAT.${stat}.NOTEMP"/><@pcstring tag="STAT.${stat}.MOD.NOTEMP"/>
-@loop>
+@loop>
<#if weaponCategory?lower_case?contains('both')>
<#if !weaponCategory?lower_case?contains('ranged')>
@@ -852,7 +852,7 @@
FF
-@loop>
+@loop>
<@loop from=0 to=pcvar('countdistinct("ABILITIES","CATEGORY=FEAT","VISIBILITY=DEFAULT[or]VISIBILITY=OUTPUT_ONLY","NATURE=AUTOMATIC")-1') ; feat , feat_has_next >
@@ -866,7 +866,7 @@
FF
-@loop>
+@loop>
<@loop from=0 to=pcvar('COUNT[VFEATS.VISIBLE]-1') ; feat , feat_has_next >
@@ -880,7 +880,7 @@
FT
-@loop>
+@loop>
<@loop from=0 to=pcvar('COUNT[FEATS.HIDDEN]-1') ; feat , feat_has_next >
@@ -1241,7 +1241,7 @@
<#else>
-
+
<#if (pcvar('COUNT[SPELLRACE]') > 0) >
<#assign spellbook = 1 />
@@ -1278,7 +1278,7 @@
#if>
-
+
<@loop from=2 to=pcvar('COUNT[SPELLBOOKS]-1') ; spellbook >
<#assign foo = pcvar('COUNT[SPELLRACE]') />
diff --git a/code/testsuite/base.xml b/code/testsuite/base.xml
index a8616a1fc79..09a73bacfe8 100644
--- a/code/testsuite/base.xml
+++ b/code/testsuite/base.xml
@@ -95,9 +95,9 @@
|HITDICE||INTERESTS|
-|FOR,%lang,0,COUNT[LANGUAGES]-1,1,0|
+|FOR,%lang,0,COUNT[LANGUAGES]-1,1,0|
|LANGUAGES.%lang|
-|ENDFOR|
+|ENDFOR|
|LANGUAGES||LOCATION|
@@ -162,7 +162,7 @@
====================================
====================================-->
-|FOR,%stat,0,COUNT[STATS]-1,1,0|
+|FOR,%stat,0,COUNT[STATS]-1,1,0|
|STAT.%stat.LONGNAME|
@@ -177,7 +177,7 @@
|STAT.%stat.NOTEMP||STAT.%stat.MOD.NOTEMP|
-|ENDFOR|
+|ENDFOR|
-
+
|FOR,%weap,0,COUNT[EQTYPE.WEAPON]-1,1,1|
|IIF(WEAPON.%weap.CATEGORY:BOTH)|
@@ -1008,7 +1008,7 @@
====================================-->
-|FOR,%feat,0,countdistinct("ABILITIES","CATEGORY=FEAT","VISIBILITY=DEFAULT[or]VISIBILITY=OUTPUT_ONLY","NATURE=NORMAL")-1,1,0|
+|FOR,%feat,0,countdistinct("ABILITIES","CATEGORY=FEAT","VISIBILITY=DEFAULT[or]VISIBILITY=OUTPUT_ONLY","NATURE=NORMAL")-1,1,0|
|ABILITY.FEAT.VISIBLE.%feat||ABILITY.FEAT.VISIBLE.%feat.DESC|
@@ -1019,10 +1019,10 @@
FF
-|ENDFOR|
+|ENDFOR|
-|FOR,%feat,0,countdistinct("ABILITIES","CATEGORY=FEAT","VISIBILITY=DEFAULT[or]VISIBILITY=OUTPUT_ONLY","NATURE=AUTOMATIC")-1,1,0|
+|FOR,%feat,0,countdistinct("ABILITIES","CATEGORY=FEAT","VISIBILITY=DEFAULT[or]VISIBILITY=OUTPUT_ONLY","NATURE=AUTOMATIC")-1,1,0|
|ABILITYAUTO.FEAT.VISIBLE.%feat||ABILITYAUTO.FEAT.VISIBLE.%feat.DESC|
@@ -1033,10 +1033,10 @@
FF
-|ENDFOR|
+|ENDFOR|
-|FOR,%feat,0,COUNT[VFEATS.VISIBLE]-1,1,0|
+|FOR,%feat,0,COUNT[VFEATS.VISIBLE]-1,1,0|
|VFEAT.VISIBLE.%feat||VFEAT.VISIBLE.%feat.DESC|
@@ -1047,7 +1047,7 @@
FT
-|ENDFOR|
+|ENDFOR|
|FOR,%feat,0,COUNT[FEATS.HIDDEN]-1,1,0|
@@ -1511,7 +1511,7 @@
====================================
====================================-->
-|%FOLLOWERTYPE.FAMILIAR|
+|%FOLLOWERTYPE.FAMILIAR|
|FOLLOWERTYPE.FAMILIAR.0.NAME|
@@ -1881,7 +1881,7 @@
|ELSE|
-
+
|FOR,%spellrace,COUNT[SPELLRACE],COUNT[SPELLRACE],1,0|
|IIF(%spellrace:0)|
|ELSE|
diff --git a/code/testsuite/csheets/35e_Alice.xml b/code/testsuite/csheets/35e_Alice.xml
index 6c6e3264a2f..1ec316488ac 100644
--- a/code/testsuite/csheets/35e_Alice.xml
+++ b/code/testsuite/csheets/35e_Alice.xml
@@ -1898,7 +1898,7 @@ BIO
-
+
@@ -1968,7 +1968,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/35e_CloudGiantHalfDragon.xml b/code/testsuite/csheets/35e_CloudGiantHalfDragon.xml
index 043261bfc24..738dacbf0a2 100644
--- a/code/testsuite/csheets/35e_CloudGiantHalfDragon.xml
+++ b/code/testsuite/csheets/35e_CloudGiantHalfDragon.xml
@@ -1920,7 +1920,7 @@ BIO
-
+
@@ -2017,7 +2017,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/35e_Jango.xml b/code/testsuite/csheets/35e_Jango.xml
index 37ca2ec0f6d..5c3bd9c6171 100644
--- a/code/testsuite/csheets/35e_Jango.xml
+++ b/code/testsuite/csheets/35e_Jango.xml
@@ -1661,7 +1661,7 @@ BIO
-
+
@@ -1905,7 +1905,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/35e_Lauren.xml b/code/testsuite/csheets/35e_Lauren.xml
index b789c5cece1..0c4e09170bf 100644
--- a/code/testsuite/csheets/35e_Lauren.xml
+++ b/code/testsuite/csheets/35e_Lauren.xml
@@ -1263,7 +1263,7 @@ BIO
-
+
@@ -1302,7 +1302,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/35e_Mallory.xml b/code/testsuite/csheets/35e_Mallory.xml
index a34ad7c9ba8..aaac9559384 100644
--- a/code/testsuite/csheets/35e_Mallory.xml
+++ b/code/testsuite/csheets/35e_Mallory.xml
@@ -1520,7 +1520,7 @@ BIO
-
+
@@ -1677,7 +1677,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/3e_BarJack.xml b/code/testsuite/csheets/3e_BarJack.xml
index 92409d2f50a..dfb25b6a701 100644
--- a/code/testsuite/csheets/3e_BarJack.xml
+++ b/code/testsuite/csheets/3e_BarJack.xml
@@ -1664,7 +1664,7 @@ BIO
-
+
@@ -1790,7 +1790,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/msrd_Elwood.xml b/code/testsuite/csheets/msrd_Elwood.xml
index 48ef0ef18df..9ea68c5a45d 100644
--- a/code/testsuite/csheets/msrd_Elwood.xml
+++ b/code/testsuite/csheets/msrd_Elwood.xml
@@ -2050,9 +2050,9 @@ BIO
-
+
-
+
diff --git a/code/testsuite/csheets/pf_Cleric.xml b/code/testsuite/csheets/pf_Cleric.xml
index e8750108a25..73bd1693f97 100644
--- a/code/testsuite/csheets/pf_Cleric.xml
+++ b/code/testsuite/csheets/pf_Cleric.xml
@@ -876,9 +876,9 @@ BIO
2
- +2
- +0
- +2
+ +0
+ -2
+ +0+0
@@ -888,7 +888,7 @@ BIO
15M
-
+ You draw a light crossbow back by pulling a lever. Loading a light crossbow is a move action that provokes attacks of opportunity.&nl;Normally, operating a light crossbow requires two hands. However, you can shoot, but not load, a light crossbow with one hand at a -2 penalty on attack rolls. You can shoot a light crossbow with each hand, but you take a penalty on attack rolls as if attacking with two light weapons. This penalty is cumulative with the penalty for one-handed firing.+0+0
@@ -900,27 +900,27 @@ BIO
30 ft.
- +2
+ +01d880 ft.
- +2
+ +01d8160 ft.
- +0
+ -21d8240 ft.
- -2
+ -41d8320 ft.
- -4
+ -61d8
@@ -1397,8 +1397,8 @@ BIO
MediumM
-
- WEAPON.RESIZABLE.RANGED.SIMPLE.CONTAINER.PROJECTILE.PIERCING.CROSSBOW.WEAPON GROUP CROSSBOWS.WOODEN
+ You draw a light crossbow back by pulling a lever. Loading a light crossbow is a move action that provokes attacks of opportunity.&nl;Normally, operating a light crossbow requires two hands. However, you can shoot, but not load, a light crossbow with one hand at a -2 penalty on attack rolls. You can shoot a light crossbow with each hand, but you take a penalty on attack rolls as if attacking with two light weapons. This penalty is cumulative with the penalty for one-handed firing.
+ WEAPON.RESIZABLE.RANGED.SIMPLE.CONTAINER.PROJECTILE.PIERCING.CROSSBOW.WEAPON GROUP CROSSBOWS.LIGHTCROSSBOW.WOODEN4
@@ -1881,8 +1881,8 @@ BIO
MediumM
-
- WEAPON.RESIZABLE.RANGED.SIMPLE.CONTAINER.PROJECTILE.PIERCING.CROSSBOW.WEAPON GROUP CROSSBOWS.WOODEN
+ You draw a light crossbow back by pulling a lever. Loading a light crossbow is a move action that provokes attacks of opportunity.&nl;Normally, operating a light crossbow requires two hands. However, you can shoot, but not load, a light crossbow with one hand at a -2 penalty on attack rolls. You can shoot a light crossbow with each hand, but you take a penalty on attack rolls as if attacking with two light weapons. This penalty is cumulative with the penalty for one-handed firing.
+ WEAPON.RESIZABLE.RANGED.SIMPLE.CONTAINER.PROJECTILE.PIERCING.CROSSBOW.WEAPON GROUP CROSSBOWS.LIGHTCROSSBOW.WOODEN4
diff --git a/code/testsuite/csheets/pf_Paladin.xml b/code/testsuite/csheets/pf_Paladin.xml
index 4d74fa51b36..3ec79c95813 100644
--- a/code/testsuite/csheets/pf_Paladin.xml
+++ b/code/testsuite/csheets/pf_Paladin.xml
@@ -3286,7 +3286,7 @@ BIO
Channel Positive Energy
- You can unleash a wave of positive energy dealing 3d6 (DC 15 for half) /day. You can unleash a wave of positive energy. You must choose to deal 3d6 points of positive energy damage to undead creatures or to heal living creatures of 3d6 points of damage. Creatures that take damage from channeled energy receive a DC 15 Will save to halve the damage. Using this ability consumes two uses of her lay on hands ability.
+ You can unleash a wave of positive energy dealing 3d6 (DC 15 for half) 2/day. You can unleash a wave of positive energy. You must choose to deal 3d6 points of positive energy damage to undead creatures or to heal living creatures of 3d6 points of damage. Creatures that take damage from channeled energy receive a DC 15 Will save to halve the damage. Using this ability consumes two uses of her lay on hands ability.PALADINCLASSFEATURES.SPECIALATTACK.SUPERNATURAL.CHANNEL ENERGY.CHANNEL ENERGY POSITIVE.CHANNEL POSITIVE ENERGY0
@@ -4878,7 +4878,7 @@ BIO
-
+
@@ -4917,7 +4917,7 @@ BIO
-
+
diff --git a/code/testsuite/csheets/pf_Rogue.xml b/code/testsuite/csheets/pf_Rogue.xml
index 09a76712e3d..3a9b2eef27c 100644
--- a/code/testsuite/csheets/pf_Rogue.xml
+++ b/code/testsuite/csheets/pf_Rogue.xml
@@ -891,8 +891,8 @@ BIO
+4
+0+0
- +3
- +1
+ +0
+ +4+1+0
@@ -907,8 +907,8 @@ BIO
+8
+0+6
- +3
- +1
+ +0
+ +4+1+0
@@ -923,8 +923,8 @@ BIO
+4
+1+0
- +3
- +1
+ +0
+ +4+1+0
diff --git a/code/testsuite/csheets/pf_goldielocks.xml b/code/testsuite/csheets/pf_goldielocks.xml
index 1b6c14d3eb4..e6b2fcecad2 100644
--- a/code/testsuite/csheets/pf_goldielocks.xml
+++ b/code/testsuite/csheets/pf_goldielocks.xml
@@ -3446,7 +3446,7 @@ BIO
-
+
@@ -3630,7 +3630,7 @@ BIO
-
+
diff --git a/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilities_race.lst b/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilities_race.lst
index 010d52f4ba7..e43f94c80fe 100644
--- a/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilities_race.lst
+++ b/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilities_race.lst
@@ -275,15 +275,15 @@ Silver Tongued KEY:Human ~ Silver Tongued CATEGORY:Special Ability TYPE:Racial
Skill Focus KEY:Focused Study Choice CATEGORY:Choice TYPE:Focused Study Choice STACK:NO MULT:YES CHOOSE:SKILL|TYPE=Charisma|TYPE=Dexterity|TYPE=Intelligence|TYPE=Strength|TYPE=Wisdom ABILITY:FEAT|AUTOMATIC|Skill Focus (%LIST)
###Block: Selections for Mixed Heritage
-# Ability Name Category of Ability Multiple? Choose Ability
-Heart of the Fields CATEGORY:Heart of the... Trait TYPE:Heart of the Trait MULT:YES CHOOSE:NUMCHOICES=1|SKILL|TYPE=Craft|TYPE=Profession ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Fields (%LIST)
-Heart of the Mountain CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Mountain
-Heart of the Sea CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Sea
-Heart of the Slums CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Slums
-Heart of the Snows CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Snows
-Heart of the Streets CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Streets
-Heart of the Sun CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Sun
-Heart of the Wilderness CATEGORY:Heart of the... Trait TYPE:Heart of the Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Wilderness
+# Ability Name Category of Ability Multiple? Choose Ability
+Heart of the Fields CATEGORY:Heart of the... Trait MULT:YES CHOOSE:NUMCHOICES=1|SKILL|TYPE=Craft|TYPE=Profession ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Fields (%LIST)
+Heart of the Mountain CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Mountain
+Heart of the Sea CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Sea
+Heart of the Slums CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Slums
+Heart of the Snows CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Snows
+Heart of the Streets CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Streets
+Heart of the Sun CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Sun
+Heart of the Wilderness CATEGORY:Heart of the... Trait ABILITY:Human Racial Trait|AUTOMATIC|Human ~ Heart of the Wilderness
###Block: Adoptive Parentage Options (a few)
# This is by no means an exhaustive list. Abilities granted are subject to DM approval so feel free to add your own.
diff --git a/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilitycategories.lst b/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilitycategories.lst
index 76f58931862..4b01556a448 100644
--- a/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilitycategories.lst
+++ b/data/pathfinder/paizo/roleplaying_game/advanced_race_guide/arg_abilitycategories.lst
@@ -17,11 +17,11 @@ ABILITYCATEGORY:Elven Spirit Choice VISIBLE:QUALIFY EDITABLE:YES EDITPOOL:NO
# Ability Category Visible Editable? Change Pool? Fractional values? Category of Object Type of Object Plural description for UI Display Location
ABILITYCATEGORY:Elf Elemental Resistance VISIBLE:QUALIFY EDITABLE:YES EDITPOOL:NO FRACTIONALPOOL:NO CATEGORY:Choice TYPE:Elf Elemental Resistance PLURAL:Elf Elemental Resistances DISPLAYLOCATION:Racial Abilities
ABILITYCATEGORY:Adoptive Parentage VISIBLE:NO EDITABLE:NO EDITPOOL:YES FRACTIONALPOOL:NO CATEGORY:Adoptive Parentage
-ABILITYCATEGORY:Heart of the... Trait VISIBLE:NO EDITABLE:NO EDITPOOL:YES FRACTIONALPOOL:NO CATEGORY:Heart of the... Trait
+ABILITYCATEGORY:Heart of the... Trait VISIBLE:NO EDITABLE:NO EDITPOOL:YES FRACTIONALPOOL:NO CATEGORY:Heart of the... Trait
ABILITYCATEGORY:Focused Study Choice VISIBLE:QUALIFY EDITABLE:YES EDITPOOL:NO FRACTIONALPOOL:NO CATEGORY:Choice TYPE:Focused Study Choice PLURAL:Focused Study Choices DISPLAYLOCATION:Racial Abilities
-ABILITYCATEGORY:Heart of the Trait VISIBLE:QUALIFY EDITABLE:YES EDITPOOL:NO CATEGORY:Heart of the... Trait TYPE:Heart of the Trait PLURAL:Heart of the Traits DISPLAYLOCATION:Racial Abilities
+ABILITYCATEGORY:Heart of the Trait VISIBLE:QUALIFY EDITABLE:YES EDITPOOL:NO CATEGORY:Heart of the... Trait TYPE:Heart of the Trait PLURAL:Heart of the Traits DISPLAYLOCATION:Racial Abilities
diff --git a/data/pathfinder/paizo/roleplaying_game/core_rulebook/cr_equip_arms_armor.lst b/data/pathfinder/paizo/roleplaying_game/core_rulebook/cr_equip_arms_armor.lst
index 2800ef6427a..fddf486c579 100644
--- a/data/pathfinder/paizo/roleplaying_game/core_rulebook/cr_equip_arms_armor.lst
+++ b/data/pathfinder/paizo/roleplaying_game/core_rulebook/cr_equip_arms_armor.lst
@@ -299,7 +299,7 @@ Unarmed Strike KEY:Unarmed Strike OUTPUTNAME:Unarmed Strike PROFICIENCY:WEAPO
# Equipment Name Unique Key SORTKEY Output Name Required Weapon Proficiency Type Contains Cost Weight Base Item for EQMOD Crit Mult Crit Range Damage Modifier Wield Category Requires Modification? Range Size Source Page Weapon prop. bonus Magic item aura Magic item caster level Required equipment slot Item construction cost Required feats and spells Special Property Description Visible
Blowgun KEY:Blowgun (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Blowgun TYPE:Weapon.Resizable.Ranged.Simple.Container.Projectile.Piercing.Blowgun.Weapon Group Thrown CONTAINS:UNLIM|Dart COST:2 WT:1 CRITMULT:x2 CRITRANGE:1 DAMAGE:1d2 WIELD:TwoHandsOnly RANGE:20 SIZE:M SOURCEPAGE:p.145 DESC:Blowguns are generally used to deliver debilitating (but rarely fatal) poisons from a distance. They are nearly silent when fired. VISIBLE:NO
Heavy Crossbow KEY:Heavy Crossbow (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Crossbow (Heavy) TYPE:Weapon.Resizable.Ranged.Simple.Container.Projectile.Piercing.Crossbow.Weapon Group Crossbows CONTAINS:UNLIM|Bolt COST:50 WT:8 CRITMULT:x2 CRITRANGE:2 DAMAGE:1d10 WIELD:TwoHandsOnly RANGE:120 SIZE:M SOURCEPAGE:p.145 DESC:You draw a heavy crossbow back by turning a small winch. Loading a heavy crossbow is a fullround action that provokes attacks of opportunity.&nl;Normally, operating a heavy crossbow requires two hands. However, you can shoot, but not load, a heavy crossbow with one hand at a -4 penalty on attack rolls. You can shoot a heavy crossbow with each hand, but you take a penalty on attack rolls as if attacking with two one-handed weapons. This penalty is cumulative with the penalty for one-handed firing. VISIBLE:NO
-Light Crossbow KEY:Light Crossbow (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Crossbow (Light) TYPE:Weapon.Resizable.Ranged.Simple.Container.Projectile.Piercing.Crossbow.Weapon Group Crossbows.LightCrossbow CONTAINS:UNLIM|Bolt COST:35 WT:4 CRITMULT:x2 CRITRANGE:2 DAMAGE:1d8 WIELD:LightCrossbow1 RANGE:80 SIZE:M SOURCEPAGE:p.145 SPROP:You draw a light crossbow back by pulling a lever. Loading a light crossbow is a move action that provokes attacks of opportunity.&nl;Normally, operating a light crossbow requires two hands. However, you can shoot, but not load, a light crossbow with one hand at a -2 penalty on attack rolls. You can shoot a light crossbow with each hand, but you take a penalty on attack rolls as if attacking with two light weapons. This penalty is cumulative with the penalty for onehanded firing. VISIBLE:NO BONUS:WEAPON|TOHIT|-2|!PREEQUIPBOTH:1,TYPE=LightCrossbow
+Light Crossbow KEY:Light Crossbow (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Crossbow (Light) TYPE:Weapon.Resizable.Ranged.Simple.Container.Projectile.Piercing.Crossbow.Weapon Group Crossbows.LightCrossbow CONTAINS:UNLIM|Bolt COST:35 WT:4 CRITMULT:x2 CRITRANGE:2 DAMAGE:1d8 WIELD:LightCrossbow1 RANGE:80 SIZE:M SOURCEPAGE:p.145 SPROP:You draw a light crossbow back by pulling a lever. Loading a light crossbow is a move action that provokes attacks of opportunity.&nl;Normally, operating a light crossbow requires two hands. However, you can shoot, but not load, a light crossbow with one hand at a -2 penalty on attack rolls. You can shoot a light crossbow with each hand, but you take a penalty on attack rolls as if attacking with two light weapons. This penalty is cumulative with the penalty for one-handed firing. VISIBLE:NO BONUS:WEAPON|TOHIT|-2|!PREEQUIPBOTH:1,TYPE=LightCrossbow
Dart KEY:Dart (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Dart TYPE:Weapon.Resizable.Ranged.Simple.Thrown.Piercing.Dart.Weapon Group Thrown COST:0.5 WT:0.5 CRITMULT:x2 CRITRANGE:1 DAMAGE:1d4 WIELD:Light RANGE:20 SIZE:M SOURCEPAGE:p.142 VISIBLE:NO
Javelin KEY:Javelin (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Javelin TYPE:Weapon.Resizable.Ranged.Simple.Thrown.Piercing.Javelin.Spear.Weapon Group Spears.Weapon Group Thrown COST:1 WT:2 CRITMULT:x2 CRITRANGE:1 DAMAGE:1d6 WIELD:OneHandOnly RANGE:30 SIZE:M SOURCEPAGE:p.146 DESC:A javelin is a thin throwing spear. Since it is not designed for melee, you are treated as nonproficient with it and take a -4 penalty on attack rolls if you use a javelin as a melee weapon. VISIBLE:NO
Sling KEY:Sling (Base) SORTKEY:zzBase PROFICIENCY:WEAPON|Sling TYPE:Weapon.Resizable.Ranged.Simple.Container.Projectile.Bludgeoning.Sling.Weapon Group Thrown CONTAINS:UNLIM|Sling Stone COST:0 WT:0 CRITMULT:x2 CRITRANGE:1 DAMAGE:1d4 WIELD:OneHandOnly RANGE:50 SIZE:M SOURCEPAGE:p.148 BONUS:WEAPON|DAMAGE|STR DESC:A sling is little more than a leather cup attached to a pair of strings. Your Strength modifier applies to damage rolls when you use a sling, just as it does for thrown weapons. You can fire, but not load, a sling with one hand. Loading a sling is a move action that requires two hands and provokes attacks of opportunity.&nl;You can hurl ordinary stones with a sling, but stones are not as dense or as round as bullets. Thus, such an attack deals damage as if the weapon were designed for a creature one size category smaller than you and you take a -1 penalty on attack rolls. VISIBLE:NO
diff --git a/docs/acknowledgments/acknowledgments.html b/docs/acknowledgments/acknowledgments.html
index 3a00aa76102..809229dada0 100644
--- a/docs/acknowledgments/acknowledgments.html
+++ b/docs/acknowledgments/acknowledgments.html
@@ -1,6 +1,6 @@
-
+
-
+
Acknowledgments
@@ -32,7 +32,7 @@
make PCGen what it is today.
- In addition the Standards and Licenses used in its creation and
+ In addition, the Standards and Licenses used in its creation and
use are provided here.
As the makeup of PCGen changes in the space of a year,
please check the
-
+
BoD
section on our Wiki for the latest version of this
diff --git a/docs/acknowledgments/bylaws.html b/docs/acknowledgments/bylaws.html
index b131767cc04..75d3deaff2d 100644
--- a/docs/acknowledgments/bylaws.html
+++ b/docs/acknowledgments/bylaws.html
@@ -1,6 +1,6 @@
-
+
-
+
PCGen Bylaws
@@ -28,7 +28,7 @@
The latest version of the Bylaws now reside in the
-
+
Bylaws
section
diff --git a/docs/acknowledgments/contributors.html b/docs/acknowledgments/contributors.html
index a6ad3610aa3..7500f3c0d28 100644
--- a/docs/acknowledgments/contributors.html
+++ b/docs/acknowledgments/contributors.html
@@ -1,6 +1,6 @@
-
+
Point-of-Contact: Mike (Michael J. Eckert) is a
former owner of Citizen Games, LLC which had to close its doors in
2004, like so many others in the d20 after-boom. Source: OgreCave.com
This website and program uses trademarks and/or copyrights owned by Paizo Inc., which are used under Paizo's Community Use Policy. We are expressly prohibited from charging you to use or access this content. This website and program is not published, endorsed, or specifically approved by Paizo Inc. For more information about Paizo's Community Use Policy, please visit paizo.com/communityuse. For more information about Paizo Inc. and Paizo products, please visit paizo.com.